本節所用命令的幫助入口:
:help lookupfile
前面我們講過通過”:find”命令打開指定的文件,不過使用”:find”命令并不是非常的方便:一是如果項目比較大、文件比較多,find查找起來很慢;二是必須輸入全部的文件名,不能使用正規表達式查找。
我們也介紹過VIM提供的文件瀏覽插件,你可以在瀏覽器中根據目錄去查找,但這種方式在瀏覽目錄時比較方便,查找一個已知名字(或知道部分名字)的文件效率就比較低了。
相比之下,在source insight中查找文件非常簡單,只要輸入部分的文件名,就可以找到符合條件的文件。
我一直被這個問題所困擾,直到有一天,在www.vim.org上發現了一個非常出色的插件,才徹底解決了查找文件效率低下的問題,它的功能毫不遜于source insight。在給該插件投票時,我選擇了“Life Changing”。是的,它改變了我的生活!
這個插件的名字是:lookupfile!
Lookupfile插件可以在下面的鏈接下載:
http://www.vim.org/scripts/script.php?script_id=1581
它使用VIM 7.0提供的插入模式下的下拉菜單補全功能,因此只能在VIM 7.0及以上版本中使用。
下載該插件后,把它解壓到你的~/.vim目錄中,就完成了安裝。然后在VIM中執行”:helptags ~/.vim/doc”命令,生成help文件索引,然后就可以使用”:help lookupfile”命令查看lookupfile插件的幫助文件了。
注:windows用戶需要把這個插件解壓在你的$VIM/vimfiles或$HOME/vimfiles目錄。
Lookupfile插件還需要最新的genutils支持,因此,需要下載genutils:
http://www.vim.org/scripts/script.php?script_id=197
這個插件提供了一些通用的函數,可供其它的腳本使用。它的安裝方法也是在~/.vim目錄解壓就可以了。需要注意的是,最新版本的genutils使用了新的自動加載方式,所以和以前的版本不兼容。如果你的其它插件需要使用genutils的舊版本的話,你需要參照genutils的說明進行配置,以便使新舊兩個版本能協同工作。
現在我們介紹lookupfile插件。雖然名字為lookupfile,其實這個插件它不僅能用來查找文件,還可以在打開的緩沖區中查找,按目錄查找,等等。
[項目文件查找]
Lookupfile在查找文件時,需要使用tag文件。它可以使用前面文章中提到的使用“ctags”命令生成的tag文件,不過查找效率會比較低。因此我們會專門為它生成一個包含項目中所有文件名的tag文件。
我編寫了下面的shell腳本,為vim70的源代碼,生成一個文件名tag文件。
#!/bin/sh
# generate tag file for lookupfile plugin
echo -e "!_TAG_FILE_SORTED\t2\t/2=foldcase/" > filenametags
find . -not -regex '.*\.\(png\|gif\)' -type f -printf "%f\t%p\t1\n" | \
sort -f >> filenametags
回想一下我們在“使用tag文件和taglist插件 (一)”一文中介紹的tag文件的格式。再對照腳本命令來看:
- echo命令用來生成filenametags文件中的“!_TAG_FILE_SORTED”行,表明此tag文件是經過排序的。
- find命令用來查找所有類型為普通文件,文件后綴名不是.png和.gif的文件,找到的文件按“文件名\t文件路徑\t1”的格式輸出出來。
- sort命令則把find命令的輸出重新排序,然后寫入filenametags文件中
在~/src/vim70/目錄下運行該腳本,會生成一個名為filenametags的文件,包含了vim70目錄下的所有文件的名字及其所在目錄。
現在我們需要讓lookupfile插件知道到哪去找文件名tag文件。我們假定VIM當前工作目錄為~/src/vim70/,執行下面的命令:
:let g:LookupFile_TagExpr = '"./filenametags"'
注:如果不設定g:LookupFile_TagExpr的值,那么lookupfile插件會以tags選項定義的文件作為它的tag文件。
現在我們就可以使用lookupfile來打開文件了,按“<F5>”或輸入“: LookupFile”在當前窗口上方打開一個lookupfile小窗口,開始輸入文件名(至少4個字符),隨著你的輸入,符合條件的文件就列在下拉列表中了。文件名可以使用VIM的正則表達式,這大大方便了文件的查找。你可以用“CTRL-N”和“CTRL-P”(或者用上、下光標鍵)來在下拉列表中選擇你所需的文件。選中文件后,按回車,就可以前一個窗口中打開此文件。
下圖是使用lookupfile插件查找文件的一個例子:
在屏幕最上方的窗口就是lookupfile窗口,在這個窗口中輸入“gui.*x11”幾個字符,查找到6個匹配文件,使用CTRL-N選中gui_x11.c文件,然后按回車,就會在前一個窗口中打開src/gui_x11.c文件,lookupfile窗口也自動關閉了。是不是非常方便?
[緩沖區查找]
在開發過程中,我經常會同時打開數十甚至上百個文件。即使是使用BufExplorer插件,想在這么多buffer中切換到自己所要的文件,也不是件容易的事。
Lookupfile插件提供了一個按緩沖區名字查找緩沖區的方式,只要輸入緩沖區的名字(可以是正則表達式),它就可以把匹配的緩沖區列在下拉列表中,同時還會列出該緩沖區內文件的路徑,當你的buffer中有多個同名文件時,這可以幫你迅速找到你想要的文件。
使用“:LUBufs”命令開始在緩沖區中查找,輸入緩沖區的名字,在你輸入的過程中,符合條件的緩沖區就顯示在下拉列表中了,選中所需緩沖區后,按回車,就會切換你所選的緩沖區。下圖是一個示例:
[瀏覽目錄]
Lookupfile插件還提供了目錄瀏覽的功能,使用“:LUWalk”打開lookupfile窗口后,就可以輸入目錄,lookupfile會在下拉列表中列出這個目錄中的所有子目錄及文件供選擇,如果選擇了目錄,就會顯示這個目錄下的子目錄和文件;如果選擇了文件,就在VIM中打開這個文件。
下圖是使用LUWalk的一個抓圖:
Lookupfile插件還提供了LUPath和LUArgs兩個功能,這兩個功能我用的不多,就不在這里介紹了。感興趣的朋友讀一下lookupfile的幫助頁。
[Lookupfile配置]
Lookupfile插件提供了一些配置選項,通過調整這些配置選項,使它更符合你的工作習慣。下面是我的vimrc中關于lookupfile的設置,供參考:
""""""""""""""""""""""""""""""
" lookupfile setting
""""""""""""""""""""""""""""""
let g:LookupFile_MinPatLength = 2 "最少輸入2個字符才開始查找
let g:LookupFile_PreserveLastPattern = 0 "不保存上次查找的字符串
let g:LookupFile_PreservePatternHistory = 1 "保存查找歷史
let g:LookupFile_AlwaysAcceptFirst = 1 "回車打開第一個匹配項目
let g:LookupFile_AllowNewFiles = 0 "不允許創建不存在的文件
if filereadable("./filenametags") "設置tag文件的名字
let g:LookupFile_TagExpr = '"./filenametags"'
endif
nmap <silent> <leader>lk <Plug>LookupFile<cr> "映射LookupFile為,lk
nmap <silent> <leader>ll :LUBufs<cr> "映射LUBufs為,ll
nmap <silent> <leader>lw :LUWalk<cr> "映射LUWalk為,lw
有了上面的定義,當我輸入”,lk”時,就會在tag文件中查找指定的文件名;當輸入”,ll”時,就會在當前已打開的buffer中查找指定名字的buffer;當輸入”,lw”時,就會在指定目錄結構中查找。
另外,我還在項目相關的配置文件vim70sx.vim(參考本系列第4篇文章)中加入了lookupfile所使用的tag文件的信息:
let g:LookupFile_TagExpr = '"filenametags"'
這樣,在恢復前次會話時就給lookupfile插件定義了tag文件。
在用lookupfile插件查找文件時,是區分文件名的大小寫的,如果想進行忽略大小寫的匹配,可以使用VIM忽略大小寫的正則表達式,即在文件名的前面加上“\c”字符。舉個例子,當你輸入“\cab.c”時,你可能會得到“ab.c”、“Ab.c”、“AB.c”……。
注:如果想加快lookupfile忽略大小寫查找的速度,在生成文件名tag文件時,使用混合大小寫排序。這在本系列的第5篇文章中有所提及。
通常情況下我都進行忽略大小寫的查找,每次都輸入“\c”很麻煩。沒關系,lookupfile插件提供了擴展功能,把下面這段代碼加入你的vimrc中,就可以每次在查找文件時都忽略大小寫查找了:
" lookup file with ignore case
function! LookupFile_IgnoreCaseFunc(pattern)
let _tags = &tags
try
let &tags = eval(g:LookupFile_TagExpr)
let newpattern = '\c' . a:pattern
let tags = taglist(newpattern)
catch
echohl ErrorMsg | echo "Exception: " . v:exception | echohl NONE
return ""
finally
let &tags = _tags
endtry
" Show the matches for what is typed so far.
let files = map(tags, 'v:val["filename"]')
return files
endfunction
let g:LookupFile_LookupFunc = 'LookupFile_IgnoreCaseFunc'
有時在LUBufs時也需要忽略緩沖區名字的大小寫,我是通過直接修改lookupfile插件的方法,在LUBufs查找的字符串前都加上“\c”,使之忽略大小寫。如果你不想這樣,可以每次在緩沖區名字前手動加上“\c”。
本文關于Lookupfile插件就介紹這么多,請閱讀幫助頁獲取更多的信息。
這是一個非常好的插件,希望能為更多人喜愛!
也歡迎大家多交流使用中的心得和疑問。
來自:http://blog.csdn.net/easwy/archive/2007/03/12/1527228.aspx