Przejdź do treści

Widziałeś kiedyś pliki *.swp? Kilka słów o plikach tymczasowych w Vimie

Jeśli nie jesteś użytkownikiem edytora Vim, to ten artykuł może nie być dla Ciebie. Jeśli jednak ciekawi Cię co chciałbym Ci dziś pokazać to zapraszam do niniejszego artykułu.

Baner promujący artykuł

Vim

Nie będę w tym artykule rozpisywał się dlaczego jestem użytkownikiem tego edytora. Nie chcę też pisać o jego korzyściach (pomimo tego, że jest to pierwszy artykuł na jego temat).

Chcę Ci powiedzieć jak przyjemnie zaczęło mi się korzystać z edytora, kiedy ustawiłem w konfiguracji pewną opcję. Dzięki jednej linijce konfiguracji dałem sobie kolejny zastrzyk empatii dla tego edytora.

Przechodząc do sedna.

Jestem przekonany, że wiele razy wpadałeś w konsternację kiedy widziałeś / widziałaś (oczywiście nie piszę artykułów tylko do mężczyzn, jednak nie będę za każdym razem pisał obu form) sytuację podobną do tej:

Mnogość plików tymczasowych powala.

Po co są pliki *.swp?

Edytor Vim w domyślnej konfiguracji tworzy pliki wymiany (ang. swap) w tym samym katalogu co plik źródłowy. Trzyma w nich zmiany, których jeszcze nie zapisałeś. Po to, aby móc je odzyskać, kiedy np. komputer się wyłączy (np. z powodu braku amunicji w baterii). Kopię oryginalnej wersji pliku Vim robi osobnym mechanizmem (opcje backup i writebackup).

Z jednej strony jest to sympatyczne, bo wiesz gdzie jest taki plik z kopią. Jednak z drugiej strony widzisz “prawie”1 zawsze zdublowaną strukturę plików, kiedy otworzysz np. kilka instancji edytora.

Jak sobie poradzić?

Możemy ustawić, aby edytor zapisywał pliki z backupami gdzieś indziej, np. w katalogu z konfiguracjami edytora - w katalogu domowym użytkownika tj. ~/.vim/swp/.

Wskazówka

Przed dodaniem magicznej linijki, zobacz co aktualnie kryje się pod zmienną directory wydając polecenie (w otworzonym edytorze):

set directory

# albo

echo &directory

Dla przykładu mój wynik:

directory=.,~/tmp,/var/tmp,/tmp

Jeśli chciałbyś dopisać katalog na początek listy to możesz to zrobić za pomocą polecenia:

set directory^=$HOME/.vim/swp/

# Poskutkuje to zmianą wartości w zmiennej "directory" na:
directory=$HOME/.vim/swp/,.,~/tmp,/var/tmp,/tmp

Aby dopisać na koniec listy, wykorzystaj operator +=, np.

set directory+=$HOME/.vim/swp/

# Poskutkuje to zmianą wartości w zmiennej "directory" na:
directory=.,~/tmp,/var/tmp,/tmp,$HOME/.vim/swp/

Druga opcja nie rozwiąże problemu. Edytor będzie sprawdzał, czy może zapisać pliki tymczasowe w kolejnych katalogach. Zacznie od ., czyli od katalogu w którym edytowany jest plik.

Czy mogę wyświetlić moje pliki tymczasowe?

Oczywiście. Uruchom narzędzie, które jest schowane pod przełącznikiem -r:

Copy + paste

vim -r

Polecenie przeszukuje katalogi (ustawione w zmiennej directory) oraz prezentuje stan plików o rozszerzeniu .swp.

Kiedy narzędzie nie znajdzie nic, zwróci coś w tym stylu:

Swap files found:
   In directory ~/.vim/swp/:
      -- none --
   In current directory:
      -- none --
   In directory ~/tmp:
      -- none --
   In directory /var/tmp:
      -- none --
   In directory /tmp:
      -- none --

Ups… mamy problem

W tej sytuacji w katalogu ~/.vim/swp/ edytor będzie tworzyły pliki z rozszerzeniem .swp, ale bez kropki (.) na początku nazwy (kropkę dostają tylko pliki wymiany zapisywane obok edytowanego pliku).

Gdy głębiej się zastanowisz, to sytuacja nie przewiduje pewnego przypadku.

Co jeśli będę chciał edytować dwa pliki index.html?
Czy utworzą się wtedy dwa pliki index.html.swp?

Nie. No bo jakim cudem mogły by istnieć dwa pliki o tej samej nazwie w tym samym katalogu?

Vim sprawdzi, do którego pliku należy istniejący plik wymiany. Jeśli do innego, po cichu utworzy kolejny: index.html.swo, potem index.html.swn itd. Błąd zobaczysz dopiero wtedy, gdy plik wymiany należy do tego samego pliku (np. jest otwarty w innym oknie albo edytor wcześniej się wysypał):

E325: ATTENTION
Found a swap file by the name "~/.vim/swp/index.html.swp"
    ...

Edytor da nam możliwość odzyskania niezapisanych zmian z pliku wymiany (polecenie :recover).

Więcej na temat błędu znajdziesz w pomocy :h e325.

Co teraz? Jak rozpoznać, który plik wymiany należy do którego index.html?

Spokojnie. Wystarczy drobna poprawka i będzie śmigać.

Dodaj “slesza” (/) do Twojej ścieżki. Vim rozpozna, że chcesz by pliki tymczasowe posiadały w nazwie strukturę katalogów w której się znajdują. Tym samym unikniesz kolizji!

Poprawne ustawienie katalogu z plikami tymczasowymi:

set directory^=$HOME/.vim/swp//

Dodaj powyższą linijkę do pliku ~/.vimrc.

Przykład jak wyglądają pliki tymczasowe, kiedy otwarte są dwa pliki index.html. Problem solved!

Droga na skróty

Jeśli chcesz mieć święty spokój to najlepiej jest uruchomić Vima z opcją -n. Opcja ta powoduje, że plik tymczasowy nigdy nie zostanie stworzony przez uruchomioną instancję programu. Tym samym nigdy nie będziesz mieć możliwości przywrócenie stanu pliku do poprzedniego. Coś za coś.

Copy + paste

vim -n

Albo!

Podczas uruchomionego edytora możesz zmienić opcję updatecount na 0, co daje podobny efekt, tzn. nie są rejestrowane zmiany w pliku. Co ciekawe, już stworzony plik .swp nie zostanie usunięty.

set uc=0

Albo…

Możesz zastosować nową opcję w konfiguracji, aby nie tworzyć tego rodzaju plików tymczasowych. Dodaj następującą linijkę w pliku .vimrc:

set noswapfile

Teraz będziesz mieć święty spokój.

•

Podsumowanie

Aby wydzielić pliki *.swp do zewnętrznego katalogu:

1) Stwórz katalog na pliki tymczasowe:

Copy + paste

mkdir ~/.vim/swp/

2) Dopisz do pliku .vimrc:

set directory^=$HOME/.vim/swp//

Bibliografia

Wersja angielska artykułu dostępna jest tutaj: vi.stackexchange.com/a/179/13884

•

  1. Dla przypomnienia: “prawie robi wielką różnicę”. ↩

Cya! 👋