Есть ли способ использовать две пользовательские, полные функции в Vim-скрипте? - PullRequest
8 голосов
/ 04 августа 2011

Есть ли способ достичь следующего?

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

Пользователь сможет завершить табуляцию двумя аргументами при вызове функции Foo из строки vim cmd.Автозаполнение будет извлекать из двух разных списков.

например

:Foo arg1 good<TAB> whi<TAB>

Нажатие <TAB> завершает слова.

:Foo arg1 goodyear white

Ответы [ 2 ]

7 голосов
/ 04 августа 2011

Достаточная информация передается функции завершения через ее аргументы.Зная текущую позицию курсора в командной строке для завершения, можно определить номер аргумента, который в данный момент редактируется.Здесь это функция, которая возвращает это число как единственное предложение о завершении.

" 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

Замените последнюю строку вызовом одной из функций, завершающих определенный аргумент (если они уже записаны).Например,

let funcs = ['FooCompleteFirst', 'FooCompleteSecond']
return call(funcs[n], [a:arg, a:line, a:pos])

Обратите внимание, что необходимо игнорировать слова, разделенные пробелами, перед именем команды, поскольку это могут быть ограничения диапазона или количество (пробелы допускаются в обоих), еслиКоманда имеет один из них.

Регулярное выражение, используемое для разбиения командной строки на аргументы, учитывает экранированный пробел, являющийся частью аргумента, а не разделителем.(Конечно, функции завершения должны избегать пробелов в предложенных кандидатах, как обычно, если команда имеет более одного возможного аргумента.)

1 голос
/ 04 августа 2011

Для 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

Одна из проблем этого примера заключается в том, что он завершится неудачно для завершений, содержащих пробелы, поэтому, если это возможно, вам придется проводить более тщательные проверки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...