Сбой функции Vimscript autocmd

" ----------------------------------------------------------------------------
" Functions
" ----------------------------------------------------------------------------

function! g:UltiSnips_Complete()
  call UltiSnips#ExpandSnippet()
  if g:ulti_expand_res == 0
    if pumvisible()
      return "\<c-n>"
    else
      call UltiSnips#JumpForwards()
      if g:ulti_jump_forwards_res == 0
        return "\<tab>"
      endif
    endif
  endif
  return ""
endfunction
"
" ----------------------------------------------------------------------------
" Autocmds
" ----------------------------------------------------------------------------

augroup relativenumber
  autocmd InsertEnter,focusLost * :set norelativenumber
  autocmd InsertLeave,focusGained * :set relativenumber
augroup END

autocmd BufEnter * exec "inoremap <silent> " . g:UltiSnipsExpandTrigger . " <c-r>=g:UltiSnips_Complete()<cr>"

Приведенный выше код является концом моего файла.vimrc. Эта функция используется для работы, но после некоторых обновлений (либо YouCompleteMe, либо UltiSnips, неуверенных) эта работа выполняется только тогда, когда я сначала открываю vim в каталоге, а затем открываю файл оттуда. Я думаю, что это как-то связано с autocmd, но, если честно, я даже не знаю, с чего начать. Я попытался изменить событие autocmd на BufRead, но, к сожалению, это не имело значения. Любая помощь приветствуется, спасибо!

РЕДАКТИРОВАТЬ: Если вы думаете, что есть лучшее место, я мог бы опубликовать этот вопрос или вам нужно больше деталей, пожалуйста, сообщите мне! Я рад помочь.

2 ответа

Решение

Кажется, что BufEnter работает до VimEnter. Это проблема, поскольку SnipMate размещает свои сопоставления в VimEnter. Таким образом, самый первый буфер имеет отображение SnipMate вместо вашего собственного. И когда вы переключаетесь на новый буфер, autocmd запускается снова, помещая сопоставление для нового буфера.

Чтобы это исправить, просто сделайте отображение BufEnter буферным локальным отображением. Это означает, что отображение не будет переписано записью отображения SnipMate. А локальное сопоставление буфера имеет приоритет, когда vim пытается запустить разные сопоставления.

autocmd BufEnter * exec "inoremap <buffer> <silent> " . g:UltiSnipsExpandTrigger . " <cr>=g:UltiSnips_Complete()<cr>"

Я могу предложить несколько исправлений:

  1. Вам не нужно помещать отображение в autocmd BufEnter *, если вы хотите, чтобы это отображение было доступно везде, просто добавьте

    exec "inoremap <silent>" g:UltiSnipsExpandTrigger "<c-r>=g:UltiSnips_Complete()<cr>"`
    
  2. Судя по всему, что вам действительно нужно, так это <expr> отображение, что-то вроде этого должно работать лучше:

    exec "inoremap <expr> <silent>" g:UltiSnipsExpandTrigger g:UltiSnips_Complete()
    

ПРИМЕЧАНИЕ: exec принимает несколько аргументов, разделенных пробелами, если вы хотите просто добавить пробел между строками, просто добавьте пробел, вы должны использовать конкатенацию только тогда, когда хотите избежать пробела, который exec автоматически добавит к его аргументам, разделенным пробелами.

Редактировать:

  1. Обновил отображение выражений, чтобы <expr> должен быть первым аргументом.
  2. Поскольку g:UltiSnipsExpandTrigger определяется плагином UltiSnips, он еще не доступен / не определен в вашем vimrc, он поставляется перед всеми плагинами. Следовательно, вы должны поместить этот фрагмент кода в after/plugin/ultisnips_complete.vim, Тогда вы не должны получить ошибку.
Другие вопросы по тегам