BaRud
BaRud

Reputation: 3230

vim update complete popup as I type

I am trying to use complete() in vim so that it reads the value as well.

For example, from vim's complete() example,

inoremap <F5> <C-R>=ListMonths()<CR>

func! ListMonths()
  call complete(col('.'), ['January', 'February', 'March',
    \ 'April', 'May', 'June', 'July', 'August', 'September',
    \ 'October', 'November', 'December'])
  return ''
endfunc

if I type <F5> I will get all the months as a pop up. Now, what I want is, if I type "J", only January, June and July will be shown, "Ju" will give June and July, and so on.

I read the vim-doc, and tried complete_check, but that's not.

Also, I have tried to use omnicomplete example E839 in vimdoc, but I cant properly call it, always getting invalid argument.

Please suggest me the the preferred method of menu with completion as I type, and how to use that.

Upvotes: 3

Views: 311

Answers (1)

Ingo Karkat
Ingo Karkat

Reputation: 172758

First, that example completion does not take an already typed base into account, because it always starts completion at the cursor position (via col('.')).

Second, to get the "refine list as you type" behavior, you need the following setting:

:set completeopt+=longest

Unfortunately, due to a (long known) bug, complete() doesn't consider the 'completeopt' option. You have to use 'completefunc' instead, like in this rewritten example:

fun! CompleteMonths(findstart, base)
    if a:findstart
        " locate the start of the word
        let line = getline('.')
        let start = col('.') - 1
        while start > 0 && line[start - 1] =~ '\a'
            let start -= 1
        endwhile
        return start
    else
        echomsg '**** completing' a:base
        " find months matching with "a:base"
        let res = []
        for m in ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
            if m =~ '^' . a:base
            call add(res, m)
            endif
        endfor
        return res
    endif
endfun
inoremap <F5> <C-o>:set completefunc=CompleteMonths<CR><C-x><C-u>

Upvotes: 3

Related Questions