I would like to know how I could set up script names auto completion in vim ?

For example let's say I have myscript.sh in ~/bin and ~/bin is in my $PATH, I would like to type mys in vim and get auto completion. I think it should be possible with CTRL-X CTRL-U or CTRL-X CTRL-O but not sure how.

Note: I've already an Omni completion set up by let &runtimepath pointing to a vim program directory.

Thanks for your help !

  • You shouldn’t need to change runtimepath to enable or setup an omni completion, so I’m not sure I follow that
    – D. Ben Knoble
    Sep 24, 2020 at 12:54
  • Sorry maybe I am not clear enough, I am using a program that enables vim auto completion and the doc states to add: :let &runtimepath.=','.$MYPROGRAM_VIMPATH and :set completeopt=longest,menuone in .vimrc to activate auto completion. I just wanted to notice this such that I do not break this auto completion.
    – jeremy
    Sep 24, 2020 at 12:58
  • Interesting... I don’t think it’s relevant, but I wonder if you could share a link to the program? Most plugins don’t require such a manual manipulation of rtp.
    – D. Ben Knoble
    Sep 24, 2020 at 13:03
  • Sure here the doc: plumed.org/doc-v2.5/user-doc/html/_vim_syntax.html
    – jeremy
    Sep 24, 2020 at 13:09
  • 2
    That doc doesn't really follow vim best practice. You could instead put the syntax file in ~/.vim/after/syntax/plumed.vim and then write an ftdetect to set the filetype (thereby setting the syntax) for the appropriate files. This is what most language plugins do, except they don't use after (and, however you install your plugins, they get automatically put on the runtimepath)
    – D. Ben Knoble
    Sep 24, 2020 at 13:34

1 Answer 1


One way is to write a custom completer:

function ShellCmd(findstart, base) abort
  if a:findstart
    " ... some logic here to find the start of a word
    " ... example near `:help E839`
    return split($PATH, ':')
          \ ->map({_,v -> glob(v.'/*', v:true, v:true, v:true)})
          \ ->flatten()
          \ ->map({_,v -> fnamemodify(v, ':t')})
          \ ->filter({_,v -> v =~# a:base})

If you only want to match commands that start with a:base, you should change the last filter to v =~# '^'.a:base.

Assign this to completefunc and use <C-x><C-u>.

When writing a custom command, you can use -complete=shellcmd.

  • Thanks a lot this does the trick ! However I am not sure I got your comments: "If you only want to match commands that start with a:base, you should change the last filter to v =~# '^'.a:base" and "When writing a custom command, you can use -complete=shellcmd". I am at a basic level on vim, could you give examples maybe ?
    – jeremy
    Sep 24, 2020 at 14:01
  • 1
    @jeremy help is your friend; in this case, :help pattern for the first and :help command-complete for the second. For the first, the matching is currently unanchored, so completions for « vim » will return all shell executables in path that contain vim—even those that dont start with vim! This may or may not be want you want, so you can anchor the start of the match if you need to. The custom command piece isn’t really relevant to you, but when defining a command (:help :command) you can give it your own completion as well.
    – D. Ben Knoble
    Sep 24, 2020 at 14:04
  • Ok got it, thanks once more !
    – jeremy
    Sep 24, 2020 at 14:13

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.