vimscript для Ultisnips + совместимость Deoplete - PullRequest
2 голосов
/ 17 апреля 2020

Мне интересно, как написать функцию, которая перегружает <TAB>.

Сначала она проверила бы, есть ли фрагмент, который нужно завершить, и есть ли фрагмент, затем разверните его.

В противном случае мне бы хотелось, чтобы функция проверила, есть ли пробел перед курсором (или мы на новой строке) до нажатия клавиши Tab. Если это так, то это следует делать регулярно <tab>. В противном случае, я бы хотел, чтобы он вызывал

deoplete#manual_complete()

Если только меню не открыто, в этом случае я смогу прокрутить его.

Вот моя попытка (Который не работает полностью) и некоторые настройки для справки:

let g:ulti_expand_or_jump_res = 0 "default value, just set once

function! Ulti_ExpandOrJump_and_getRes()
  call UltiSnips#ExpandSnippetOrJump()
  return g:ulti_expand_or_jump_res
endfunction

inoremap <silent><expr> <tab>
  \ (Ulti_ExpandOrJump_and_getRes() > 0) ? "\<C-y>"
  \ : pumvisible() ? "\<C-n>" :
  \ <SID>check_back_space() ? "\<TAB>" :
  \ deoplete#manual_complete()

function! s:check_back_space() abort "{{{
  let col = col('.') - 1
  return !col || getline('.')[col - 1] =~ '\s'
endfunction "}}}

Как ни странно, когда я нажимаю tab, в правом нижнем углу vim читается, что я набрал "^ I", что очень странно.

Причина, по которой у меня нет триггера расширения ultisnips в качестве "tab", заключается в том, что он запрещает использование tab для deoplete (по любой причине.)

1 Ответ

1 голос
/ 17 апреля 2020

Я полагаю, что основная проблема, с которой вы столкнулись, заключается в том, что UltiSnips#ExpandSnippetOrJump() попытается переместить курсор, и это проблема отображения <expr> в режиме вставки. Использование <C-R>=...<CR> вместо этого должно заставить его работать. (По крайней мере, это то, что использует пример в документации UltiSnips.)

Я бы также рекомендовал использовать одну функцию для обработки всех случаев Tab вместо довольно длинной однострочной. Таким образом, вы можете использовать if s и задокументировать каждый случай отдельно.

Я также думаю, что для случая, когда вы расширяетесь или переходите на UltiSnips, вы хотите расширить ничего, кроме <C-y>, верно?

Собираем все вместе:

function! HandleTab() abort
  " First, try to expand or jump on UltiSnips.
  call UltiSnips#ExpandSnippetOrJump()
  if g:ulti_expand_or_jump_res > 0
    return ""
  endif
  " Then, check if we're in a completion menu
  if pumvisible()
    return "\<C-n>"
  endif
  " Then check if we're indenting.
  let col = col('.') - 1
  if !col || getline('.')[col - 1] =~ '\s'
    return "\<Tab>"
  endif
  " Finally, trigger deoplete completion.
  return deoplete#manual_complete()
endfunction

inoremap <silent> <Tab> <C-R>=HandleTab()<CR>

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

...