Reputation: 34628
I often find myself working in projects with directory structures similar to this:
a/
x/
file1.h
y/
file2.h
z/
file3.h
b/
u/
file4.cpp
file5.h
v/
file6.cpp
file7.cpp
w/
where source files are spread over all the directories.
I have a shortcut such that saying Ctrl+n opens a :tabnew
prompt, but I still find it cumbersome to find the file I want myself by just typing/auto-completing the directories, as I have to remember where a particular file that I want to open lives.
Can I get vim to pretend the entire directory structure to be flat, or rather do a find and then open? I'd like to still have auto completion. Of course, there could be name clashes in theory, but for most cases you wont have files of the same name in separate directories even if you technically could.
So what I want is for the source directory to appear as if it looked like this:
file1.h
file2.h
file3.h
file4.cpp
file5.h
file6.cpp
file7.cpp
Allowing me to type something like :magiccommand f<TAB>2<TAB>
to open a/y/file2.h
.
Upvotes: 1
Views: 96
Reputation: 34628
I wound up using a solution inspired by dash-tom-bang's answer, which is essentially independent of the project and its tree structure.
map <C-b> :tabfind
imap <C-b> <C-o><C-b>
set path=.,,**,/usr/include
The drawback is that I shouldn't use <C-b>
in my home directory or a similarly full directory. But for that I recommend to fallback to:
map <C-n> :tabnew
imap <C-n> <C-o><C-n>
Upvotes: 0
Reputation: 17853
:help 'path'
In your case, something like this:
:set path=/path/to/a/**,/path/to/b/**
Then :tabf file4.cpp
. So change your shortcut to be :tabfind
instead of :tabnew
.
I'd also suggest that you look into using ctags
, because then you can jump directly to symbols in any file in your project with :tag MyExcellentFunction
(or :stag ..
or :tab stag ...
).
If you do end up using tags and drop your tags
file in the project root, this'll help you out:
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"))
(This could also be modified to look for .git or .svn directories if that's your pleasure.)
Upvotes: 1
Reputation: 32926
There exists several fuzzyfinders that help to accomplish that -- I even wrote one a long time ago.
You can also stick to vanilla Vim and use starstar: :sp **/f*2<tab>
.
If you set 'path'
correctly, you could also type :find +sp f<tab>
(it doesn't seem to work with :tabedit
though).
Upvotes: 3