如何让 vim 假装拥有来自复杂树的平面源目录?
How to make vim pretend to have a flat source directory from a complex tree?
我经常发现自己在目录结构类似于这样的项目中工作:
a/
x/
file1.h
y/
file2.h
z/
file3.h
b/
u/
file4.cpp
file5.h
v/
file6.cpp
file7.cpp
w/
源文件分布在所有目录中。
我有一个快捷方式,这样说 Ctrl+n 会打开一个 :tabnew
提示符,但我仍然觉得仅通过 typing/auto-completing 目录来找到我想要的文件很麻烦,因为我有记住我要打开的特定文件所在的位置。
我可以 vim 假装整个目录结构是扁平的,或者更确切地说是查找然后打开吗?我仍然希望自动完成。
当然,理论上可能存在名称冲突,但在大多数情况下,即使技术上可以,您也不会在不同的目录中拥有相同名称的文件。
所以我想要的是源目录看起来像这样:
file1.h
file2.h
file3.h
file4.cpp
file5.h
file6.cpp
file7.cpp
允许我输入类似 :magiccommand f<TAB>2<TAB>
的内容来打开 a/y/file2.h
。
有几个 fuzzyfinders 可以帮助实现这一点——我什至很久以前就写过一个。
您也可以坚持使用原版 Vim 并使用 starstar: :sp **/f*2<tab>
。
如果您正确设置 'path'
,您还可以输入 :find +sp f<tab>
(但它似乎不适用于 :tabedit
)。
:help 'path'
在你的情况下,是这样的:
:set path=/path/to/a/**,/path/to/b/**
然后:tabf file4.cpp
。因此,将您的快捷方式更改为 :tabfind
而不是 :tabnew
。
我还建议您考虑使用 ctags
,因为这样您就可以使用 :tag MyExcellentFunction
(或 :stag ..
或 :tab stag ...
).
如果您最终使用标签并将 tags
文件放在项目根目录中,这将帮助您:
function! SetUpPath(filepath)
setlocal path=
for l:tagfile in tagfiles()
let l:tagpath = fnamemodify(l:tagfile, ":h")
execute "setlocal path+=" . fnameescape(l:tagpath) . '/**'
endfor
setlocal path-=.
setlocal path-=
setlocal path-=
endfunction
autocmd BufEnter * call SetUpPath(fnamemodify(expand("<afile>"), ":p"))
(如果您愿意,也可以修改为查找 .git 或 .svn 目录。)
我最终使用了受 答案启发的解决方案,它基本上独立于项目及其树结构。
map <C-b> :tabfind
imap <C-b> <C-o><C-b>
set path=.,,**,/usr/include
缺点是我不应该在我的主目录或类似的完整目录中使用 <C-b>
。但为此我建议回退到:
map <C-n> :tabnew
imap <C-n> <C-o><C-n>
我经常发现自己在目录结构类似于这样的项目中工作:
a/
x/
file1.h
y/
file2.h
z/
file3.h
b/
u/
file4.cpp
file5.h
v/
file6.cpp
file7.cpp
w/
源文件分布在所有目录中。
我有一个快捷方式,这样说 Ctrl+n 会打开一个 :tabnew
提示符,但我仍然觉得仅通过 typing/auto-completing 目录来找到我想要的文件很麻烦,因为我有记住我要打开的特定文件所在的位置。
我可以 vim 假装整个目录结构是扁平的,或者更确切地说是查找然后打开吗?我仍然希望自动完成。 当然,理论上可能存在名称冲突,但在大多数情况下,即使技术上可以,您也不会在不同的目录中拥有相同名称的文件。
所以我想要的是源目录看起来像这样:
file1.h
file2.h
file3.h
file4.cpp
file5.h
file6.cpp
file7.cpp
允许我输入类似 :magiccommand f<TAB>2<TAB>
的内容来打开 a/y/file2.h
。
有几个 fuzzyfinders 可以帮助实现这一点——我什至很久以前就写过一个。
您也可以坚持使用原版 Vim 并使用 starstar: :sp **/f*2<tab>
。
如果您正确设置 'path'
,您还可以输入 :find +sp f<tab>
(但它似乎不适用于 :tabedit
)。
:help 'path'
在你的情况下,是这样的:
:set path=/path/to/a/**,/path/to/b/**
然后:tabf file4.cpp
。因此,将您的快捷方式更改为 :tabfind
而不是 :tabnew
。
我还建议您考虑使用 ctags
,因为这样您就可以使用 :tag MyExcellentFunction
(或 :stag ..
或 :tab stag ...
).
如果您最终使用标签并将 tags
文件放在项目根目录中,这将帮助您:
function! SetUpPath(filepath)
setlocal path=
for l:tagfile in tagfiles()
let l:tagpath = fnamemodify(l:tagfile, ":h")
execute "setlocal path+=" . fnameescape(l:tagpath) . '/**'
endfor
setlocal path-=.
setlocal path-=
setlocal path-=
endfunction
autocmd BufEnter * call SetUpPath(fnamemodify(expand("<afile>"), ":p"))
(如果您愿意,也可以修改为查找 .git 或 .svn 目录。)
我最终使用了受
map <C-b> :tabfind
imap <C-b> <C-o><C-b>
set path=.,,**,/usr/include
缺点是我不应该在我的主目录或类似的完整目录中使用 <C-b>
。但为此我建议回退到:
map <C-n> :tabnew
imap <C-n> <C-o><C-n>