3

I'd like to use <C-X> <C-F> to autocomplete a long filename in insert mode, say /foo/bar/baz.txt. When I type in /f, I can press <C-X> <C-F> to complete to /foo/. However, after typing /foo/b, I'll need to press <C-X> <C-F> again to complete to /foo/bar/. After typing /foo/bar/b, I'll need to press <C-X> <C-F> one more time to get to /foo/bar/baz.txt. Is there any way to keep the completion menu alive inbetween directory slashes / for longer filenames?

  • Welcome to Vi and Vim! – filbranden May 19 at 22:32
  • 1
    Thanks! I'm surprised I haven't gotten an answer yet, and I can't find anything off of Google or :help. Do people use <C-X> <C-F> regularly? Or is this functionality usually handled by a plugin? – identicon May 20 at 12:58
  • 2
    @identicon patience is a virtue... the question has only been around for 15 hours. I use <C-X><C-F> regularly, but I've never minded typing it each time. – D. Ben Knoble May 20 at 13:43
1

(Untested) You'll need a vim that supports CompleteDonePre. You can check with

echo has('##CompleteDonePre') ? 'supported' : 'not supported'

If you have this event, you can use the following autocommand:

augroup ContinueFileCompletion
  autocmd!
  autocmd CompleteDonePre * if complete_info()['mode'] ==# 'files' | call feedkeys("\<C-x>\<C-f>", 'n') | endif
augroup END

Notes

  1. You might be able to get away with normal! <C-x><C-f> instead of call feedkeys(...); I'm not sure in this case, since we're doing this from an autocommand
  2. You could modify this to also check if the completed item was a directory. I would probably extract a function at this point and call it in the autocommand, but the check could be something like
let compinfo = complete_info()
let compitem = compinfo['items'][compinfo['selected']]
" use compitem, which is a dictionary... (:help complete-items)
  1. This doesn't handle aborted completions; you can check if the dictionary v:completed_item is empty for that (I think—the help says "if completion failed", and the event is triggered when "something was completed or abandoning completion"). empty(v:completed_item) would do the trick.
| improve this answer | |
  • 1
    Hm. Since this doesn't check for failed completion, it's very possible you'll get stuck in a loop with this. – D. Ben Knoble May 20 at 13:57
  • This looks like it works, but I don't seem to have a Vim supporting CompleteDonePre... Regardless, thanks for coming up with a way to do this! I'll give you the selected answer. As for a plugin approach, YouCompleteMe (in @Dmitry's answer) works, as well as fzf. – identicon May 21 at 17:04
0

YouCompleteMe plugin does the thing. But it may be overwhelming if you need only file path autocompletion. YCM is not so easy to use, it is python dependant, requires compilation, much space on disk and works with certain file types. To enable it on any file type you have to specify one of acceptable. For example:

:set filetype=python

Then you just type path in text and it completes on each slash. As bonus you will get fuzzy search.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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