💾 Archived View for gemini.susa.net › Vim › vim_user_complete.gmi captured on 2023-11-04 at 11:40:04. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2021-11-30)

-=-=-=-=-=-=-

Vim User Completions

Sometimes I want to be able to complete from a set of fixed strings. Dictionary completion is useful for this, since I just create a file with a list of words, but it's limited to single words, and doesn't give the option of info (e.g. docs on function parameters).

The way to approach this seems to be user completions, which work pretty much like omni-completions. You provide a function that a) identifies the initial string to complete, if any, and b) returns a list of matches for the completion menu.

My goal here is to provide Vimscript functions for auto-complete. This is useful to me, and allows me to customise other completions beyond functions while I'm learning Vimscript.

In the example below, I have already loaded the list of Vim's functions into the script-local list 'l:funcs'.

" Our complete function identifies the base string to complete or else
" populates the complete list, depending on how it is called.
function! MyVimFuncs(findstart, base)
    if a:findstart
        " locate the start of the word
        let line = getline('.')
        let idx = col('.') - 1
        
        while idx > 0 && line[idx - 1] =~ '\a'
            let idx -= 1
        endwhile
        return idx
    else
        " find values matching a:base
        let res = []
        for m in s:funcs
            if m.word =~ '^' . a:base
                call add(res, m)
            endif
        endfor

        return res
    endif
endfunction

A snippet of the file I read is shown below, followed by the code that loads it. The file format is simply the completion string, a comma, and then the rest of the line is taken as the 'info'. If there is no comma, then the line is assumed to be just the completion string.

abs,abs({expr})          Float or Number  absolute value of {expr}
acos,acos({expr})           Float   arc cosine of {expr}
add,add({object}, {item})       List/Blob   append {item} to {object}
and,and({expr}, {expr})     Number  bitwise AND
append,append({lnum}, {text})       Number  append {text} below line {lnum}

The completion list is formed using the following code:

let s:funcs = []

" Build the list of Vim function for auto-complete
let s:funcsList = readfile("/home/kevin/.vim/dict/vim_functions.txt")

for str in s:funcsList
    let dm = {}
    let dm.type = 'f'

    let idx = stridx(str, ',')
    if idx < 0
        let dm.word = str
    else
        let f = strpart(str, 0, idx)
        let i = strpart(str, idx+1)
        let dm.word = f
        let dm.info = i
    endif
    
    call add(s:funcs, dm)
endfor

Then all we need to do is set the 'completefunc' variable and Ctrl-X_Ctrl-U will trigger our completions.

set completefunc=MyVimFuncs