10

In Vim, when I am in insert mode, and I want to use file-name completion, I want the search path to be relative to the current file, not the current working directory. For instance, if in insert mode I type the following:

./^X^F

The completion menu is showing me files in the :pwd, but I would rather see the files in %:p:h listed.

Is there an option that I can set to fix this, and if not what do you suggest as a workaround?

3 Answers 3

13

If you

:set autochdir

you'll get the behavior you desire. However, if you need to keep the working directory (e.g. to easily open other project files), you'd have to save / restore the CWD with autocmds:

:autocmd InsertEnter * let save_cwd = getcwd() | set autochdir
:autocmd InsertLeave * set noautochdir | execute 'cd' fnameescape(save_cwd)
1
  • 2
    Thank you! autochdir was great for C-X, C-F, but annoying when I'm 4 levels deep in a project and I want to :tabe May 28, 2015 at 10:15
5

@Ingo Karkat's answer is nice, but I am a little hesitant to put that in my vimrc, because even the help page for 'autochdir' gives a note that it's useage will break some plugins.

I have come up with my own solution which may be very niche to my use-cases:

inoremap ./<C-X><C-F> <C-O>:lcd %:p:h<CR><C-X><C-F>

I plan on extracting it out into a function and setting a variable for the pwd before the lcs command is issued and then resetting it at some point in time. It would be nice if there was a menu autocmd.

I may or may not use this, but I thought I would throw out another solution.

1
  • It's implied in your answer but please note that this has the side effect of changing the current working directory for the current window.
    – sitaktif
    Apr 3, 2020 at 7:05
0

I have this in my .vimrc:

" [relative autocomplete]
" ==============================================================================
" Vim's file autocomplete (C-X C-F) works only in an absolute path (using the
" current working directory) as base. But in most languages, you want to use
" relative imports, and file autocomplete doesn't work there. For that, I use
" <C-X><C-X><C-F>:

function! s:EnableRelativeAutocomplete() abort
  let b:relative_autocomplete_cleanup_pending = 1
  lcd %:p:h
endfunction

function! s:DisableRelativeAutocomplete() abort
  if exists('b:relative_autocomplete_cleanup_pending') && b:relative_autocomplete_cleanup_pending
    lcd -
    let b:relative_autocomplete_cleanup_pending = 0
  endif
endfunction

inoremap <C-x><C-x><C-f> <C-o>:call <SID>EnableRelativeAutocomplete()<CR><C-x><C-f>

augroup relative_file_autocomplete
  autocmd!
  autocmd InsertLeave * call s:DisableRelativeAutocomplete()
augroup END

It will change the working directory to the current file's when using <C-x><C-x><C-f> and back to the previous directory when leaving insert mode, if needed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.