I am trying to create a command that runs a function, however, I can seem to get custom arguments that are autocompleted when pressing Tab. How would it be possible to set these arguments?

The current command looks like this...

command! -nargs=? UserCommand :lua require('my-plugin').function(<f-args>)

and I want there to be completion for 5, single worded, arguments that will be passed on to a Lua function.

5 Possible Arguments:

  1. terminal
  2. quickfix
  3. internal
  4. bang
  5. float

I've taken a look at telescope.nvim's way of doing this but it seems to do a lot more than just add completion for a few strings.

  • 3
    Are you looking for -complete? See :help :command-completion for details
    – filbranden
    Commented Dec 8, 2021 at 15:22
  • This doesn't exactly help too much. Could you perhaps provide some code that's not already in the help pages?
    – InsertSON
    Commented Dec 8, 2021 at 23:49
  • In that case, you should edit your question to tell us more of what you're trying to accomplish, what you've tried so far and how it isn't working... As is, your question is too open ended, it's hard to figure out exactly what it is that you want...
    – filbranden
    Commented Dec 9, 2021 at 2:00
  • 1
    Thanks for the feedback! I've updated the question to be a little more specific and hopefully less open-ended.
    – InsertSON
    Commented Dec 9, 2021 at 3:22
  • 1
    Sorry about that. I've included the 5 arguments that should be auto-completed.
    – InsertSON
    Commented Dec 10, 2021 at 0:48

1 Answer 1


You can use the -complete=... flag while defining a user-command to program how tab completion should work when the command is used. See :help :command-completion for more details about that flag.

The -complete=... flag has many built-in options to complete common objects in the Vim world, such as file names in paths, buffers, Ex commands, functions, etc.

In your case, it looks like none of those will do the job, so you can use the custom completion, by providing Vim with a function that will return the available options. See :help :command-completion-custom for more details about custom completion.

It's not too hard to write a custom completion function, particularly one that will select options from a fixed list. If you use -complete=custom,... then Vim will filter the options for you using the characters already typed by the user as a prefix.

For example:

function! UserCommandCompletion(_, _, _)
  let valid_args = ['terminal', 'quickfix', 'internal', 'bang', 'float']
  return join(valid_args, "\n")

You can use it in your user command definition with:

command! -nargs=? -complete=custom,UserCommandCompletion UserCommand :lua require('my-plugin').function(<f-args>)

You can then use it with :UserCommand te<Tab> will complete it to terminal. Just :UserCommand <Tab> will offer you the five options (in the order they're defined.)

You can also use the -complete=customlost,... mode. On one hand, in that case returns a list, so you don't need to join it into a muli-line string. On the other, there's a slightly tricky part of filtering the list based on the characters already typed by the user. With some string manipulation, you can get it done.

For example:

function! UserCommandListCompletion(lead, cmd, cursor)
  let valid_args = ['terminal', 'quickfix', 'internal', 'bang', 'float']
  let l = len(a:lead) - 1
  if l >= 0
    let filtered_args = copy(valid_args)
    call filter(filtered_args, {_, v -> v[:l] ==# a:lead})
    if !empty(filtered_args)
      return filtered_args
  return valid_args

command! -nargs=? -complete=customlost,UserCommandListCompletion UserCommand :lua require('my-plugin').function(<f-args>)

This function will try to find the elements of the list starting with the passed lead. (If the lead is empty, or no elements are found, it just returns the full list, so you get all valid options for completion.)

One small advantage of customlist is that you're free to return an option that doesn't start with the same prefix altogether. For example, in the implementation above, you'll get the full list of all valid options if the word being typed is not a valid prefix to at least one of the acceptable options. With the -complete=custom,... implementation a word that's not a valid prefix will simply not yield any completion when Tab is pressed.

  • 1
    An alternative might be to use custom and always return join("\n", [the list]), letting vim's engine do the filtering
    – D. Ben Knoble
    Commented Dec 10, 2021 at 2:56
  • 1
    @D.BenKnoble Yeah that's definitely better! I wonder why the two options work differently from each other, didn't spot that in the docs either... I'll update the answer to mention that (a little bit later this evening.)
    – filbranden
    Commented Dec 10, 2021 at 3:05
  • Works great! Thank you so much for the amazing answer.
    – InsertSON
    Commented Dec 10, 2021 at 4:35
  • Is there a way to accomplish this directly in lua in neovim? Without any vimscript?
    – Danielo515
    Commented Jun 10, 2022 at 7:31

Your Answer

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

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