As @muru mentioned, there are no options to configure the directory from which to complete path and file names. It always uses the working directory of the window.
I've written a couple of functions and mappings to help with this. Behind the scenes, they change the local working directory (using :lcd
) temporarily, then restore the previous working directory when done.
Elephant
For reasons unknown to even me, I've called this micro-plugin Elephant.
Here's the code (copied from my Vim config on GitHub):
let g:elephant_map = {
\ 'f': function('elephant#current_file'),
\ 'p': function('elephant#vcs_project')
\ }
function! elephant#prompt(base)
let l:Fcn = get(g:elephant_map, a:base, function('elephant#identity'))
let l:basedir = l:Fcn()
execute 'lcd' l:basedir
let l:file = fnamemodify(input(l:basedir.'/', '', 'file'), ':p')
lcd -
return fnamemodify(l:file, ':.')
endfunction
function! s:elephant_init()
let l:base = getchar()
return elephant#prompt(nr2char(l:base))
endfunction
function! elephant#identity()
return '.'
endfunction
function! elephant#vcs_project()
return fnamemodify(finddir('.git', '.;'), ':h')
endfunction
function! elephant#current_file()
return expand('%:h')
endfunction
inoremap <silent> <expr> <C-R><C-E> <SID>elephant_init()
cnoremap <silent> <C-R><C-E> <C-R>=<SID>elephant_init()<CR>
How to use it
Using these mappings happens in 3 steps.
1. Invoke the mapping
In Insert mode or Command-line mode, invoke the mapping using <C-R><C-E>
.
2. Choose a directory
Type a single character to choose which root directory you want completion from. The code above provides two types of roots:
f
- The directory that the current file (buffer) resides in
p
- The base directory of the Git project the current file belongs to
3. Enter the path or file name
You will be prompted to enter the path or file name relative to the directory specified, with completion available. Press Enter
when finished.
Some notes
- This doesn't provide inline completion in Insert mode the way
<C-X><C-F>
does; instead, you will be typing the path or file name on the Command-line prompt (where :
commands go). Upon pressing Enter
, the path will be inserted into the buffer.
- The same is true in Command-line mode, which can sometimes be confusing when you hit
Enter
and forget that you still have to hit Enter
to issue whatever command you were just typing.
- Other directory functions can be registered by adding them into
g:elephant_map
.
- The path inserted will be the full, absolute path. The script can be tweaked to change that behaviour, but I haven't got around to it.
path
either). It depends on what your intended use for vim-rooter is. Depending on what you want from it, we could use other plugins. Aside: I use youcompleteme, which completes paths from the directory of the current buffer if you start typing./
. See reddit.com/r/vim/comments/216jdd/…