Od ponad 4 lat do edycji wszystkiego co ma litery używam Vim. Dzięki jego niesamowitym możliwościom konfiguracji, mój vimrc nie raz zmieniał się w zależności od zadań jakim musiał sprostać. Od ponad pół roku pracuje jako programista i chyba nie muszę tłumaczyć jak bardzo praca nad własnym małym projektem różni się od rozwijania aplikacji nad którą pracuje paręnaście osób.
Poniższy opis to zbiór "sztuczek" jakie odkryłem i jakich nauczyłem się używać na co dzień, w pracy nad dużą aplikacją.
Wyszukiwanie
Znalezienie odpowiedniego fragmentu kodu, to zazwyczaj połowa sukcesu. Gdyby projekt zawierał się w paru plikach, każdy byłby w stanie szybko wskazać odpowiednią linijkę. Tylko że nigdy nie wiadomo czego tak naprawdę szukamy, aż do momentu znalezienia. A wtedy i tak okazuje się, że kod napisany został przez kogoś innego. Dlatego właśnie potrzebne jest narzędzie, które które rozwiąże ten problem za nas.
grep
Aby nie używać surowego grep i przełączać
się między Vim a kolejną konsolą, polecam plugin
grep.vim. Z interfejsu
jaki udostępnia, najczęściej używam :Rgrep za pomocą którego można
przeszukać całe drzewo katalogów. Oprócz wyrażenia i najwyższego katalogu
można podać również dopuszczalne rozszerzenie pliku, co dodatkowo przyspiesza
proces wyszukiwania.
Exuberant Ctags
Exuberant Ctags to indekser, który początkowo był częścią Vim. Obecnie jest to osobny projekt, używany także przez wiele innych narzędzi.
Osobiście indeksuję jedynie kod Pythona, ale program działa podobno dla co
najmniej 41 języków. Aby
zaindeksować źródła, używam trochę przekombinowanego polecenia, bo chociaż
ctags powinien sam znaleźć odpowiednie pliki to mam wrażenie, że flaga -R
nie do końca działa:
cd $HOME/mojprojekt find . -name "*.py" | xargs ctags -a --language-force=python
Po zakończeniu działania, utworzony zostanie plik tags. Teraz trzeba
wykorzystać te informacje w Vim. To jakich indeksów używamy, można sprawdzić
wpisując
:echo &tags ./tags,./TAGS,tags,TAGS
Jeśli indeksujemy zewnętrzny kod (na przykład jakąś bibliotekę), można to zrobić w wydzielonym do tego katalogu, poza obecnym projektem. Wtedy trzeba jawnie dołączyć kolejny plik wygenerowany przez ctags:
:set tags=./tags,tags,/home/me/.tags/django.ctags,/home/me/.tags/gtk.ctags
Ponieważ nazwa nie ma znaczenia, wszystkie indeksy bibliotek trzymam w jednym
katalogu i zapisuje jako <nazwa biblioteki>.ctags.
Teraz przejść można do najciekawszego, czyli użycia wygenerowanych danych.
Załóżmy, że przeglądając kod aplikacji napisanej w django, natrafiłem na
użycie klasy UserProfile. Czym jest UserProfile? Jak tego używać? Aby się
tego dowiedzieć można zajrzeć do *khe* *khe* dokumentacji. Można też
obejrzeć źródła klasy.
W dokumentacji Vim, po wpisaniu :h tagsrch, dostaniemy obszerny opis jak używać indeksu. Oczywiście warto to przeczytać, lecz ja i tak przedstawię te fragmenty manuala, które sam najczęściej wykorzystuję.
Wracając do UserProfile - pierwszą możliwością odnalezienia klasy jest
wpisanie polecenia
:tag UserProfile
Jeśli znalezione zostało więcej niż jedno pasujące miejsce, pojawia się stosowna informacja, na przykład "znacznik 1 z 6 lub więcej" i przeniesieni zostajemy w pierwsze pasujące miejsce. Analogicznie, wpisując:
:<N>tag UserProfile
przeniesieni zostajemy do <N>-tego znalezionego wystąpienia UserProfile. W
takich przypadkach o wiele wygodniejsze może być więc użycie interaktywnego
:tjump UserProfile.
Polecenie :tag jest fajne, jeśli znamy chociażby początek nazwy (użycie
<Tab> uzupełniania słowo), ale trochę bez sensu wydaje się wpisywanie
wyrazu, na którym właśnie mam ustawiony kursor. W takim przypadku, do
dyspozycji mamy skrót g Ctrl-] (:h g_CTRL-]), który jest skrótem dla
:tjump.
Śledzenie importów
W śledzeniu przebiegu programu, bardzo pomocny może okazać się skrót
gf. Edytując poniższy
fragment (znak | oznacza miejsce gdzie znajduje się kursor)
from django.db import models from userprofile.model|s import UserProfile
po wpisaniu <Esc>gf, rozpoczynam edycję pliku userprofile/models.py. Vim
sam znajdzie odpowiedni plik, sprawdzając wszystkie ścieżki ustawione w zmiennej
path:
:echo &path .,/usr/include,,
To samo polecenie nie zadziała więc dla django.db, chyba że dodamy kolejny
katalog:
:set path+=/usr/lib/python2.6/site-packages
Należy jednak być świadomym sposobu w jaki używana jest zmienna path oraz
tego, że nie jest ona wykorzystywana jedynie do wyszukiwania plików. Ten sam
mechanizm może być również stosowany na przykład do uzupełniania kodu, co przy
zbyt wielu plikach do sprawdzenia może okazać się niewydajne.
Uzupełnianie kodu
Wielu programistów, za kryterium w wyborze edytora/IDE przyjmuje automatyczne
podpowiadanie składni.
Osobiście wolę jawnie określić kiedy oczekuje podpowiedzi.
supertab.vim chowa pod
klawiszem <Tab> wszystkie tradycyjne tryby dopełniania w Vim. Jeśli chcemy
zmienić obecny sposób podpowiedzi, wystarczy wpisać :SuperTabHelp i wybrać
inny.
Więcej o uzupełnianiu składni można przeczytać w innym wpisie.
Monitorowanie skoków
Używając w dużej ilości poleceń szybkiego przemieszczenia łatwo się pogubić.
Parę skoków wystarczy, żeby zapomnieć gdzie byłem jeszcze przed chwilą. Ten
problem można rozwiązać używając jump
motions.
Każdy skok rejestrowany jest przez edytor, a ich lista dostępna jest pod
poleceniem :jumps.
Dwa najczęściej używane przeze mnie polecenia to Ctrl-o oraz Ctrl-i, czyli skok wstecz i do przodu.
Bufory
Każdy nowy plik otwierany jest w buforze. Każdy z buforów, o ile nie zostanie jawnie zamknięty, dostępny jest przez cały czas życia Vima. Stan buforów obejrzeć można wydając polecenie :ls:
:ls 1 #a "userprofile/models.py" wiersz 1 2 %a + "userprofile/forms.py" wiersz 86 3 a "settings.py" wiersz 0
Jeśli chcę powrócić do edycji pliku, który kiedyś zamknąłem (ale jego bufor
wciąż jest w pamięci), mogę to zrobić używając polecenia :b<numer>. Kursor
ustawiony zostanie w tym samym miejscu co przy zamykaniu pliku.
denial
26.10.2009
Też kiedyś bawiłem się vimem, ale skończyłem po jakimś czasie. Jak widze całą stronę opisu konfiguracji podstawowych rzeczy to odechciewa się używania tego edytora. Widziałem Twoją konfigurację, którą udostępniłeś, wszystko ładnie działa, więc widocznie da się poustawiać wszystko. Tylko jak będę chciał coś zmienić to się pewnie znów wkurzę i zmarnuje zbyt dużo czasu. Od niedawna używam eclipse+pydev(od niedawna w pełni opensourcowy)+aptana i muszę powiedzieć, że jestem pod wrażeniem, tak dobrego uzupełniania kodu dawno nie widziałem, świetny debugger, refaktoring i masa innych funkcjonalności, nic więcej nie potrzeba. Wiadomo eclipse zżera troche zasobów, ale trzeba mieć naprawdę starą maszynę, żeby to przeszkadzało. 3/4 ramu i tak siedzi i się marnuje :)
Husio
26.10.2009
Vim, jak każde narzędzie o ogromnych możliwościach, wymaga wielu godzin poświęconych na naukę. Wystarczy znać parę komend, żeby można go było używać jak zwykłego edytora, ale potrzeba wielu miesięcy nauki, żeby używać go efektywnie. Jednak czas poświęcony na zapamiętanie tych pozornie losowych ciągów liter, zwraca się z nawiązką, gdy chce aby mój edytor robił coś, czego nie potrafi żaden inny.
Do tego wzorowa dokumentacja i dobra społeczność - nie wydaje mi się, żeby jakikolwiek inny edytor/IDE mógł z tym konkurować
*khe*emacs*khe*;)denial
28.10.2009
No właśnie, wiele godzin poświęconych na naukę... Wolę te godziny przeznaczyć na pisanie programów. Ogólnie zauważyłem, że w moim przypadku praca z vimem nie przyśpiesza klepania kodu. Lubię vima jako edytor do konsoli, ale do tworzenia większych projektów już nie :)