Hi Vim developers,

I found a discrepancy between the two methods for custom insert-mode completion, 'completefunc' and complete(). The latter doesn't respect the ':set completeopt+=longest' setting; its completions always expand to the first match, not just the longest common text of matches. I see no reason for not observing that setting, and think that this is a bug in the complete() function.

This can be reproduced starting from Vim 7.0 up to 7.2.323, on Windows/x86 and Linux/x86.

To reproduce, source attached file, which contains both types of (calendar-month) completion functions, taken from the Vim help:

vim -N -u NONE
:source complete(func).vim
iM<F5><CR>
M<F6><CR><Esc>
" Both complete() and 'completefunc' expand to the first match, "March".
:set completeopt+=longest
iM<F5><CR>
M<F6><CR>
" complete() still expands to the full first match, "March".
" 'completefunc' correctly just inserts the longest common string, "Ma".

-- regards, ingo

PS: Speaking of discrepancies, another glaring one is that complete() takes {startCol}, so range is [1, col('.')], but 'completefunc' has a zero-based range of [0, col('.')[. Sadly, it would be even more stupid to change any of those two now to correct the inconsistency.
--
  -- Ingo Karkat -- /^-- /^-- /^-- /^-- /^-- /^-- http://ingo-karkat.de/ --
  --      http://vim.sourceforge.net/account/profile.php?user_id=9713    --
inoremap <F5> <C-R>=ListMonths()<CR>

func! ListMonths()
    " locate the start of the word
    let line = getline('.')
    let start = col('.') - 1
    while start > 0 && line[start - 1] =~ '\a'
        let start -= 1
    endwhile
    " find months matching with "base"
    let base = strpart(line, start, (col('.') - start))
    let res = []
    for m in ['January', 'February', 'March', 'April', 'May', 'June', 'July', 
'August', 'September', 'October', 'November', 'December']
        if m =~ '^' . base
        call add(res, m)
        endif
    endfor
    call complete(start + 1, res)
    return ''
endfunc

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
    " 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 <F6> <C-o>:set completefunc=CompleteMonths<CR><C-x><C-u>

-- 
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php

Raspunde prin e-mail lui