有没有办法在Vim脚本中使用两个自定义的完整函数?

cen*_*ack 8 vim

有没有办法实现以下目标?

command! -nargs=* -complete=customlist,CustomFunc1 -complete=customlist,CustomFunc2 Foo call MyFunction(<f-args>)
Run Code Online (Sandbox Code Playgroud)

当从vim cmd行调用函数Foo时,用户将能够tab-complete 两个参数.自动完成将从两个不同的列表中拉出.

例如

:Foo arg1 good<TAB> whi<TAB>
Run Code Online (Sandbox Code Playgroud)

<TAB>完成单词.

:Foo arg1 goodyear white
Run Code Online (Sandbox Code Playgroud)

ib.*_*ib. 7

有足够的信息通过其参数传递给完成函数.知道要完成的命令行中的当前光标位置,可以确定当前正在编辑的参数的编号.这里是将该数字作为唯一完成建议返回的函数.

" Custom completion function for the command 'Foo'
function! FooComplete(arg, line, pos)
    let l = split(a:line[:a:pos-1], '\%(\%(\%(^\|[^\\]\)\\\)\@<!\s\)\+', 1)
    let n = len(l) - index(l, 'Foo') - 1
    return [string(n)]
endfunction
Run Code Online (Sandbox Code Playgroud)

用调用完成特定参数的函数之一替换最后一行(如果它们已经写入).例如,

let funcs = ['FooCompleteFirst', 'FooCompleteSecond']
return call(funcs[n], [a:arg, a:line, a:pos])
Run Code Online (Sandbox Code Playgroud)

请注意,必须在命令名称之前忽略以空格分隔的单词,因为这些单词可能是范围的限制,或者计数(两者都允许空格),如果命令具有其中之一.

用于将命令行拆分为参数的正则表达式考虑了转义的空格,它是参数的一部分,而不是分隔符.(当然,如果命令有多个可能的参数,则完成函数应该在建议的候选者中转义空格.)


And*_*dev 5

vim 没有内置方法可以做到这一点。在这种情况下我要做的是将逻辑嵌入到完成函数中。当您设置 时-complete=customlist,CompletionFunction,将使用三个参数调用指定的函数,按以下顺序:

  • 目前的论点
  • 到目前为止的整个命令行
  • 光标位置

因此,您可以分析这些并调用另一个函数,具体取决于您是否在第二个参数上。这是一个例子:

command! -nargs=* -complete=customlist,FooComplete Foo call Foo(<f-args>)
function! Foo(...)
  " ...
endfunction

function! FooComplete(current_arg, command_line, cursor_position)
  " split by whitespace to get the separate components:
  let parts = split(a:command_line, '\s\+')

  if len(parts) > 2
    " then we're definitely finished with the first argument:
    return SecondCompletion(a:current_arg)
  elseif len(parts) > 1 && a:current_arg =~ '^\s*$'
    " then we've entered the first argument, but the current one is still blank:
    return SecondCompletion(a:current_arg)
  else
    " we're still on the first argument:
    return FirstCompletion(a:current_arg)
  endif
endfunction

function! FirstCompletion(arg)
  " ...
endfunction

function! SecondCompletion(arg)
  " ...
endfunction
Run Code Online (Sandbox Code Playgroud)

此示例的一个问题是,包含空格的补全会失败,因此如果有可能出现这种情况,您将必须进行更仔细的检查。