Vim: Znajdowanie plików w podkatalogach
Jak wiadomo, Vim nie jest IDE. I w sumie dobrze. Jednak jest kilka funkcjonalności, 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 może działać takie wyszukiwanie? Otóż, w naszym przykładzie, po naciśnięciu ctrl+f i wpisaniu interesującej nas nazwy pliku (np. BestPlace) otrzymujemy taki wynik:
Rozwiązanie tego problemu jest przedstawione na stronie http://vim.wikia.com/wiki/Find_files_in_subdirectories. Jednakże, jest ono dość chaotyczne, a efekt końcowy ma pewne wady. Dlatego przedstwiamy sprawę po naszemu.
Cały kod podany poniżej trzeba wstwić 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("")
Następnie funkcja w Pythonie, również pochodząca ze wcześniej wspomnianej strony. 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("")
I na koniec przypisanie sobie funkcji do klawisza:
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à!
