Sesje#
Sesja to specjalny plik, w którym zapisany zostaje bieżący stan pewnych aspektów programu związanych z aktualnie otwartymi plikami. W programie Notepad++ plik sesji może zapamiętywać m.in.:
- Ścieżkę i kolejność wszystkich otwartych plików.
- Aktualnie wybrany plik i odpowiadający mu widok.
- Aktualne zaznaczenia i pozycje kursora we wszystkich otwartych plikach.
- Aktualne zakładki i język we wszystkich otwartych plikach.
W ujęciu praktycznym sesje stanowią osobny/dodatkowych mechanizm usprawniający prace programistyczne. Im większy projekt, im większa liczba plików, tym większe znaczenie sesji. Warto poświęcić nieco czasu na dokładniejsze przeanalizowanie implementacji sesji w NPP, by w przyszłości czas zaoszczędzony na otwieraniu/przełączaniu między wieloma plikami przeznaczyć na inne zadania.
Domyślna sesja#
Przy standardowych ustawieniach Notepad++ przechowuje stan bieżącej sesji w domyślnym pojedynczym pliku NPP\session.xml
. Plik ten jest automatycznie aktualizowany (tj. ponownie zapisywany) jedynie przy prawidłowym zamknięciu NPP. Jest to bardzo istotne, bo w przypadku niestandardowego zamknięcia (np. zabijając proces notepad++.exe
) plik domyślnej sesji posiada poprzedni niezmieniony stan.
W opcjach programu możemy dodatkowo kontrolować:
- Automatyczne tworzenie i zapis pliku
session.xml
- wybieramy u góry na Pasku menu kolejnoUstawienia >> Ustawienia... >> Kopia zapasowa >> Zapamiętywanie sesji i cykliczne kopie zapasowe >> Pamiętaj bieżącą sesję do następnego uruchomienia
. Po odznaczeniu tej opcji pliksession.xml
nie będzie tworzony ani aktualizowany. - Domyślne rozszerzenie pliku sesji przy ręcznym zapisie # - wybieramy u góry na Pasku menu kolejno
Ustawienia >> Ustawienia... >> Inne >> Rozszerzenie pliku sesji
. Ustawienie nie wpływa na rozszerzenie domyślnego pliku sesji, tzn. wciąż jest nim pliksession.xml
. Ustawienie konkretnego rozszerzenia dla pliku sesji powoduje, że ręczne przeciągnięcie takiego pliku w obszar głównego okna programu odtworzy sesję.
Tworzenie i automatyczne zapisywanie domyślnego pliku sesji można potraktować jako jeden z elementów kopii zapasowej naszej pracy, dlatego warto pozostawić tę opcję trwale włączoną.
Budowa sesji#
Sesja, podobnie zresztą jak cała konfiguracja w NPP, to plik tekstowy bazujący na specjalnej XML-owej składni. Położenie, nazwa czy samo rozszerzenie pliku jest nieistotne, ważna jest prawidłowa zawartość tego pliku. Załóżmy, że nasze główne okno programu jest w następującym stanie:
Mamy zatem główne okno programu w trybie podwójnego widoku, gdzie w pierwszym widoku (aktywnym) otworzono pliki polish.xml
i english.xml
(wybrany), a w drugim widoku otworzono pliki french.xml
(wybrany) i italian.xml
. Po zamknięciu i ponownym uruchomieniu NPP zawartość pliku
jest następująca:NPP\session.xml
<NotepadPlus>
<Session activeView="0">
<mainView activeIndex="1">
<File firstVisibleLine="0" xOffset="0" scrollWidth="872" startPos="0" endPos="0" selMode="0" lang="XML" encoding="-1" userReadOnly="no" filename="D:\_test\NPPClean\localization\polish.xml" backupFilePath="" originalFileLastModifTimestamp="992742051" originalFileLastModifTimestampHigh="30770798" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="0" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="688" startPos="0" endPos="0" selMode="0" lang="XML" encoding="-1" userReadOnly="no" filename="D:\_test\NPPClean\localization\english.xml" backupFilePath="" originalFileLastModifTimestamp="-993743108" originalFileLastModifTimestampHigh="30779776" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="6881388" mapWrapIndentMode="-1" mapIsWrap="no" />
</mainView>
<subView activeIndex="0">
<File firstVisibleLine="0" xOffset="0" scrollWidth="824" startPos="0" endPos="0" selMode="0" lang="XML" encoding="-1" userReadOnly="no" filename="D:\_test\NPPClean\localization\french.xml" backupFilePath="" originalFileLastModifTimestamp="-993516542" originalFileLastModifTimestampHigh="30779776" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="1139802112" mapWrapIndentMode="-1" mapIsWrap="no" />
<File firstVisibleLine="0" xOffset="0" scrollWidth="960" startPos="0" endPos="0" selMode="0" lang="XML" encoding="-1" userReadOnly="no" filename="D:\_test\NPPClean\localization\italian.xml" backupFilePath="" originalFileLastModifTimestamp="-1488766285" originalFileLastModifTimestampHigh="30772454" mapFirstVisibleDisplayLine="-1" mapFirstVisibleDocLine="-1" mapLastVisibleDocLine="-1" mapNbLine="-1" mapHigherPos="-1" mapWidth="-1" mapHeight="-1" mapKByteInDoc="6881388" mapWrapIndentMode="-1" mapIsWrap="no" />
</subView>
</Session>
</NotepadPlus>
Zaczynając od najbardziej zewnętrznego znacznika całość można scharakteryzować następująco:
<NotepadPlus>
- główny węzeł pliku (tzw. korzeń), którego nazwa wskazuje, że mamy do czynienia z jakimś plikiem konfiguracyjnym programu Notepad++.<Session>
- pojedynczy węzeł sesji wewnątrz korzenia<NotepadPlus>
informujący o tym, że mamy do czynienia z plikiem sesji. Węzeł posiada jeden atrybutactiveView
, którego wartość wskazuje na aktualnie wybrany widok (0
- pierwszy widok jest aktywny,1
- drugi widok jest aktywny).<mainView>
lub<subView>
- pojedynczy węzeł widoku wewnątrz<Session>
opisujący stan jednego z widoków. Oba węzły widoku mają taką samą strukturę. AtrybutactiveIndex
wskazuje, który plik w danym widoku jest aktywny. Węzły widoku mogą zawierać dowolną liczbę kolejnych węzłów pliku<File>
. Kolejność węzłów pliku wewnątrz węzłów widoku jest zgodna z kolejnością plików przy zapisie/odczycie sesji. Węzły widoku istnieją zawsze, nawet jeśli nie zawierają żadnych plików, i w takim wypadku są puste:<mainView activeIndex="0" />
lub<subView activeIndex="0" />
.<File>
- jeden lub większa liczba węzłów pliku wewnątrz jednego z węzłów widoku<mainView>
lub<subView>
. Węzeł pliku ma szereg atrybutów opisujących stan danego pliku:Pozycja atrybutu Nazwa atrybutu Typ wartości atrybutu Opis 0 firstVisibleLine
number Indeks (numeracja od 0) wskazujący na pierwszą widoczną linię. W praktyce odpowiada on za stan pionowego paska przewijania. Wartość indeksu można zmienić przewijając plik w pionie. 1 xOffset
number Indeks (numeracja od 0) wskazujący na pierwszy widoczny znak w pierwszej widocznej linii. W praktyce odpowiada on za stan poziomego paska przewijania. Wartość indeksu można zmienić przewijając plik w poziomie. 2 scrollWidth
number Liczba pikseli wyrażająca pionową szerokość danego pliku. Przy pierwszym otworzeniu pliku (jeszcze bez żadnego pionowego przewinięcia) wartość wyraża widoczną pionową szerokość pliku. Po wykonaniu jakiegoś pionowego przewinięcia ustalana jest bieżąca pionowa szerokość pliku w danym miejscu. Dopiero po przewinięciu pliku na sam koniec ustalona zostanie całkowita pionowa szerokość pliku. Po ustaleniu całkowitej szerokości pliku wartość tego atrybut nie ulega zmianie, niezależnie od przyszłej pozycji pionowego paska przewijania. 3 startPos
number Indeks (numeracja od 0) wskazujący początkową pozycję w ostatnim zaznaczeniu. Zakresem są wszystkie znaki w pliku, zatem maksymalna wartość jest równa długości pliku (wartość length
widoczna na Pasku stanu). Bez wykonania zaznaczeniastartPos
jest równeendPos
.4 endPos
number Indeks (numeracja od 0) wskazujący końcową pozycję w ostatnim zaznaczeniu. Zakresem są wszystkie znaki w pliku, zatem maksymalna wartość jest równa długości pliku (wartość length
widoczna na Pasku stanu). Bez wykonania zaznaczeniaendPos
jest równestartPos
.5 selMode
number 6 lang
string Nazwa języka używanego do podświetlania składni. 7 encoding
number Numer wskazuje na zastosowane kodowanie znaków w pliku. Wartość -1
oznacza ANSI, UTF-8 (z/bez BOM), UCS-2BE BOM, UCS-2 LE BOM i kilka innych. Pozostałym kodowaniom przypisano osobne numery (EncodingMapper.cpp
).8 userReadOnly
string Wartość "no"
oznacza, że plik ma odblokowaną edycję. Wartość"yes"
oznacza, że plik ma zablokowaną edycję. Stan blokady edycji kontrolujemy wybierając u góry na Pasku menu kolejnoEdycja >> Zablokuj edycję
lub poprzez menu kontekstowe karty.9 filename
string Pełna ścieżka do pliku. 10 backupFilePath
string Pełna ścieżka kopii zapasowej dla pliku (jeśli plik kopii istnieje). 11 originalFileLastModifTimestamp
number Młodsza część liczby wskazującej na czas ostatniej modyfikacji pliku (szczegóły). 12 originalFileLastModifTimestampHigh
number Starsza część liczby wskazującej na czas ostatniej modyfikacji pliku (szczegóły). 13 mapFirstVisibleDisplayLine
number 14 mapFirstVisibleDocLine
number 15 mapLastVisibleDocLine
number 16 mapNbLine
number 17 mapHigherPos
number 18 mapWidth
number 19 mapHeight
number 20 mapKByteInDoc
number 21 mapWrapIndentMode
number 22 mapIsWrap
string
Zarządzanie wieloma sesjami#
W programie Notepad++ mamy wiele możliwości nawigacji po plikach. Wszystkie one charakteryzują się tym, że kiedy otworzymy stosunkowo dużą liczbę plików, to manewrowanie nimi będzie coraz mniej komfortowe (np. ze względu na pojawianie się pasków przewijania). Problem narasta wraz ze złożonością projektu, nad którym aktualnie pracujemy. Z własnego doświadczenia wiem, że im mniejsza liczba otwartych plików tym większy komfort pracy z programem. Nie chodzi tu nawet o szybkość działania samego programu przy wielu otwartych plikach, bo ta wciąż pozostaje na bardzo wysokim poziomie, ale o skuteczne zapanowanie nad całością. Zwykle modyfikujemy jeden lub kilka plików w danej chwili, dlatego otwieranie wszystkich plików projektu, nawet przy najdrobniejszej zmianie jednego z nich, mija się z celem.
Do podziału projektu na mniejsze szybko dostępne części idealnie nadają się pliki sesji. Każda sesja powinna zawierać niewielki podzbiór plików, który można wyodrębniać kierując się różnymi kryteriami:
- Baza - pliki tworzące trzon całego projektu.
- Biblioteki - wspólne pliki wykorzystywane w różnych miejscach projektu.
- Kategorie - pliki stanowiące odrębne części projektu.
- Najczęściej zmieniane - pliki pochodzące ze wszystkich powyższych, które najczęściej modyfikujemy.
- Całość - wszystkie możliwe pliki, co może być użyteczne przy hurtowym przeszukiwaniu i podmianie pewnych fragmentów.
Utworzenie wyspecjalizowanych sesji dla projektu to dopiero połowa sukcesu. Także i tutaj, podobnie zresztą jak przy nawigacji po plikach, przydałoby się jakieś GUI pozwalające w wygodny sposób zarządzać tymi sesjami. Do najważniejszych jego cech można zaliczyć:
- Tworzenie sesji w dowolnym folderze.
- Edycję/modyfikację/nadpisywanie już utworzonych sesji.
- Grupowania sesji w osobne kategorie.
- Eksplorator dla utworzonych sesji (z podglądem plików wchodzących w skład każdej z sesji).
- Wczytywanie pojedynczej sesji lub kilku wybranych sesji.
- Wczytywanie pojedynczych plików wchodzących w skład każdej z sesji.
Rozwiązanie wbudowane wprost w Notepad++ nie oferuje niczego szczególnego, ale wszystkie te niedostatki uzupełnimy z nawiązką stosując odpowiednią wtyczkę.
Wbudowany zapis i odczyt dodatkowych sesji#
Program Notepad++, obok domyślnego pliku sesji NPP\session.xml
, obsługuje także dowolną liczbę innych plików sesji. Nazwa i rozszerzenie takiego pliku jest dobrowolna, ale jego zawartość musi być zgodna z XML-ową składnią wyrażającą sesje w NPP. Całość opiera się na dwóch bazowych poleceniach:
- Zapis dodatkowej sesji - wybieramy u góry na Pasku menu kolejno
Plik >> Zapisz sesję...
Odczyt dodatkowej sesji - wybieramy u góry na Pasku menu kolejno
Plik >> Załaduj sesję...
W przywołanym oknie można wybrać tylko jeden plik sesji.Trzeba wyraźnie zaznaczyć, że polecenie to potrafi automatycznie oczyścić wybrany plik sesji z nieaktualnych wpisów #. W praktyce oznacza to, że jeśli w pliku sesji znajduje się jakiś węzeł
<File>
, którego atrybutfilename
wskazuje na nieistniejący plik, to węzeł ten zostanie automatycznie usunięty z wybranego pliku sesji.W pewnych sytuacjach automatyczne oczyszczanie może okazać się kłopotliwe, np. kiedy mamy utworzonych wiele plików sesji, gdzie każdy z nich zawiera wiele ścieżek do konkretnych plików, i z jakiegoś powodu usuniemy lub przeniesiemy pliki wskazywane przez te sesje w inne miejsce. Próba odczytania takiej sesji spowoduje jej automatycznie wysprzątanie, a to utrudni późniejsze odtworzenie oryginalnej struktury sesji z już poprawionymi ścieżkami. Nie ma możliwości wyłączenia tego oczyszczania (bug 7931). Najprostszym rozwiązaniem tego problemu może być cykliczne wykonywanie kopii zapasowych wszystkich plików sesji, z których (w razie potrzeby) odbudujemy oryginalną strukturę zapamiętywanych przez nie plików.
Manewrowanie wieloma plikami sesji za pomocą powyższych poleceń nie jest wygodne, choć w początkowych fazach rozwoju programu była to jedyna namiastka czegoś na kształt menedżera projektów. Co prawda można to nieco usprawnić, tj. ustawiając w opcjach programu domyślne rozszerzenie dla pliku sesji, dzięki czemu będzie działało przeciąganie pliku/plików sesji do głównego okna programu, ale dla wygodnego zarządzania sesjami jest to niewystarczające. Warto sięgnąć po jakiś dedykowany menedżer sesji, który będzie bazował na powyższych poleceniach, ale z jednoczesnym rozszerzeniem ich możliwości.
Zewnętrzny menedżer sesji#
Największą swobodę przy zarządzaniu wieloma plikami sesji zapewniają zewnętrzne menedżery sesji. W przypadku Notepada++ możemy skorzystać z następujących wtyczek:
Osobiście korzystam z pierwszego rozwiązania gdyż jest bardziej uniwersalne (zawiera eksploratora plików). Najlepiej samemu przeanalizować obie wtyczki i wybrać tę, która będzie nam najbardziej odpowiadać.