在cmdline上自动完成选项值


10

我无法计算尝试执行此操作的次数:

:set foldmethod=syn^I

似乎完成对选项值不起作用!

在某些情况下,选项是复杂的字符串,其中补全可能没有意义。(例如'comments'。)

但是,是否有任何努力为常见用例提供通配符完成功能?

如果没有,我如何使上面的示例起作用?(假设我想完成其中一个字符串['manual', 'indent', 'expr', 'marker', 'syntax']。)

Answers:


3

您可以尝试以下代码:

let s:option_values = {'foldmethod'  : ['manual', 'indent', 'expr', 'marker', 'syntax'],
                     \ 'bufhidden'   : ['hide', 'unload', 'delete', 'wipe'],
                     \ 'virtualedit' : ['block', 'insert', 'all', 'onemore'] ,}

set wildcharm=<c-z>

cnoremap <expr> <tab>
            \ getcmdline() !~# '^\s*set\s\+\w\+=' <bar><bar> wildmenumode() ?
            \ '<c-z>' :
            \ '<c-u>' . substitute(getcmdline(), 'set', 'Set', '') . '<c-z>'

command! -nargs=1 -complete=customlist,s:SetComplete Set exe 'set' <q-args>

function! s:SetComplete(A, L, P) abort
    let option = matchstr(a:A, '^.*\ze=')
    if !has_key(s:option_values, option)
        return
    endif
    let candidates = copy(s:option_values[option])
    call map(candidates, 'option . "=" . v:val')
    return filter(candidates, 'v:val =~ "^" . a:A')
endfunction

首先定义一个字典,s:option_values其目的是包含您的选项(作为其键)及其值(作为其值,即列表)。在此,作为一个例子,3个选项+值被存储:
'foldmethod''bufhidden''virtualedit'

set wildcharm=<c-z>

这行代码设置了'wildcharm'选项,并告诉Vim如果<c-z>在映射中看到它必须激活wildmenu。如果不设置此选项,则在写入<tab>映射时,它将仅插入文字制表符。

cnoremap <expr> <tab>

开始定义一个映射,该定义将在您每次<tab>在命令行上单击时键入表达式的求值。

\ getcmdline() !~# '^\s*set\s\+\w\+=' <bar><bar> wildmenumode() ?

映射会测试命令行是否与pattern匹配,pattern ^\s*set\s\+\w\+=是位于form之后的一行set option=,或者wildmenu是否处于活动状态。

\ '<c-z>' :

如果先前的测试成功,则映射将激活wildmenu。

\ '<c-u>' . substitute(getcmdline(), 'set', 'Set', '') . '<c-z>'

否则,它将用:setcustom命令替换system 命令:Set,并激活wildmenu。

command! -nargs=1 -complete=customlist,s:SetComplete Set exe 'set' <q-args>

定义与该命令:Set具有相同功能的自定义命令:set,不同之处在于它可以使用名称在此处的自定义完成功能s:SetComplete()

function! s:SetComplete(A, L, P) abort

开始定义自定义完成功能。

它必须通过列表返回建议/候选人。
:Set命令将自动向其发送3个参数:

  • 当前正在完成的论点的前导部分(即option=...
  • 整个命令行
  • 光标在其中的位置

请参阅:h :command-completion-customlist以获取更多信息。

let option = matchstr(a:A, '^.*\ze=')

从完成的参数中提取选项的名称。

if !has_key(s:option_values, option)
    return
endif

检查是否option在您的字典中。如果不是,则该函数不返回任何内容。

let candidates = copy(s:option_values[option])

获取该选项可以从字典中获取的值列表的副本。

call map(candidates, 'option . "=" . v:val')

对于列表中的每个值candidates,在字符串前面添加option=option将在其中进行评估)。

return filter(candidates, 'v:val =~ "^" . a:A')

删除candidates其开头与要完成的参数不匹配的项,然后返回结果。


2

AFAIK,我们无法将cmdline-completion添加到不提供cmdline的内置命令中。我们要么用另一个将支持完成的命令“覆盖”该命令(在这里,您可以:Set用大写S字母定义),要么我们侵入vim源代码以添加缺少的内容。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.