From the vim documentation

FUNCTIONS FOR FINDING COMPLETIONS           *complete-functions*

This applies to 'completefunc' and 'omnifunc'.

The function is called in two different ways:
- First the function is called to find the start of the text to be completed.
- Later the function is called to actually find the matches.

On the first invocation the arguments are:
   a:findstart  1
   a:base   empty

The function must return the column where the completion starts.  It must be a
number between zero and the cursor column "col('.')".  This involves looking
at the characters just before the cursor and including those characters that
could be part of the completed item.  The text between this column and the
cursor column will be replaced with the matches.

Special return values:
   -1 If no completion can be done, the completion will be cancelled with an
      error message.
   -2 To cancel silently and stay in completion mode.
   -3 To cancel silently and leave completion mode.

The function will be called twice and only the second time vim will interpret -1 as cancellation? Why?

I tested this with (version 8.0)

function! MyCompletion(findstart, base)
    echomsg "Call MyCompletion" a:findstart
    if a:findstart
        return -1
    " return -1
    return ["foo", "abc", "123"]

So if I can not find a start for completion I have to use a nonlocal variable to remember this or test again?

if findstart
   if test
       s:completion_failed = 1
       return whatever

if s:completion_failed
    return -1

1 Answer 1


Just skimming the vim source code i found this section in edit.c

    /* Return value -2 means the user complete function wants to
     * cancel the complete without an error.
     * Return value -3 does the same as -2 and leaves CTRL-X mode.*/
    if (col == -2)
    return FAIL;
    if (col == -3)
    ctrl_x_mode = 0;
    edit_submode = NULL;
    if (!shortmess(SHM_COMPLETIONMENU))
    return FAIL;

     * Reset extended parameters of completion, when start new
     * completion.
    compl_opt_refresh_always = FALSE;

    if (col < 0)
    col = curs_col;
    compl_col = col;
    if (compl_col > curs_col)
    compl_col = curs_col;

So when the completion function is called, the return values -2 and -3 are handled according to the documentation, but the case -1 is ignored on the first invoke and the value set to curs_col

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.