Vim: Znajdowanie plików w podkatalogach

Jak wiadomo, Vim nie jest IDE. I w sumie dobrze. Jednak jest kilka funkcjonalności typowych dla IDE, które by się w nim przydały. Jedną z nich jest łatwe otwieranie plików w projekcie. Jako, że nie ma nic takiego wbudowanego, trzeba sobie poradzić samemu.
Jak mogło by takie wyszukiwanie i otwieranie plików działać? Otóż, w naszym przykładzie, po naciśnięciu ctrl+f i wpisaniu interesującej nas nazwy pliku (np. BasePlace) otrzymujemy taki wynik:
Sposób na uruchomienie tego mechanizmu jest przedstawiony na stronie http://vim.wikia.com/wiki/Find_files_in_subdirectories. Jednakże, jest on dość chaotyczny, a efekt końcowy ma pewne wady. Dlatego przedstawiam sprawę po mojemu.
Cały kod podany poniżej trzeba wstawić do własnego .vimrc. Pierwsza część to funkcja do znajdowania, w niezmienionej postaci:
" Find file in current directory and edit it. function! Find(name) let l:list=system("find . -name '".a:name."' | perl -ne 'print \"$.\\t$_\"'") let l:num=strlen(substitute(l:list, "[^\n]", "", "g")) if l:num < 1 echo "'".a:name."' not found" return endif if l:num != 1 echo l:list let l:input=input("Which ? (CR=nothing)\n") if strlen(l:input)==0 return endif if strlen(substitute(l:input, "[0-9]", "", "g"))>0 echo "Not a number" return endif if l:input<1 || l:input>l:num echo "Out of range" return endif let l:line=matchstr("\n".l:list, "\n".l:input."\t[^\n]*") else let l:line=l:list endif let l:line=substitute(l:line, "^[^\t]*\t./", "", "") execute ":e ".l:line endfunction command! -nargs=1 Find :call Find("<args>")
Następnie wstawiamy funkcję napisaną w Pythonie, również pochodząca ze wcześniej wspomnianej strony. Jest ona odpowiedzialna za sam proces wyszukiwania plików. Jednak tutaj zaszło klika zmian:
- szukanie jest niewrażliwe na wielkość znaków,
- szukanie ignoruje katalogi .svn
- rozpoczynając szukanie, nie trzeba potwierdzić (ale też nie można zmienić) katalogu, w którym się szuka; domyślnie jest to katalog w którym otwarliśmy Vima.
python << EOL import vim def Finder(*args): start_dir = vim.eval('getcwd()') find_cmd = (r'find %s -iname "*%s*" ! -name "*.svn*" -type f -printf %%p:1:-\\n' % (start_dir, args[0])) vim.command("cgete system('%s')" % find_cmd) vim.command('botright copen') EOL command! -nargs=1 Find :py Finder("<args>")
I na koniec pozostało przypisanie sobie funkcji do skrótu ctrl-f:
map! <C-f> <Esc> :Find ; map <C-f> :Find ;
Po :Find jest spacja, aby nie trzeba było jej dopisywać za każdym razem. Teraz wystarczy wykonać :source ~/.vimrc lub zrestartować Vima, a następnie ctrl+f i voilà!
Podobne wpisy:
Autorzy zdjęć: kennymatic






Ja bym polecał raczej plugin do szybkiego otwierania plików typu Command-T albo FuzzyFinder – sam używam tego pierwszego.
Ich działanie polega na tym, że wpisujesz kilka znaków ze ścieżki do pliku i dostajesz listę dopasowań, z której otwierasz plik, który Cię interesuje.
A jak sobie radzi z dużym drzewem katalogów? Nie ma mulenia?
BTW. Zergu jeszcze nie napisał o tym, ale stworzył ostatnio przydatny plugin do skakania po projekcie w symfony https://github.com/zergu/Vim-Project-Jumper – póki co tylko sf 1.4, ale planuje dopisać dla sf2 i railsów.
Muli przy pierwszym użyciu (kilka-kilkanaście sekund przy projekcie na parę tys. plików), ale jak już zindeksuje, to działa normalnie. Czasem chwilę mu zajmie zanim zajarzy dodany niedawno plik – generalnie używam tego pluginu częściej niż NERDTree :)
Do Railsów jest rails.vim, który z tego co się orientuję, umożliwia szybkie przeskakiwanie między modelem/kontrolerem/widokiem/helperem/testem, ale nie wiem dokładnie, mało w RoR piszę i pluginu nie testowałem.