Как вы используете локальные буферные автокоманды в VimScript?

Я пытаюсь написать фрагмент VimL, чтобы позволить пользователю переключать подсветку нежелательного конечного пробела с помощью горячей клавиши. (Это мой первый в истории скрипт Vim, помимо копирования в мой .vimrc итак… крупинка соли:P)

Я хотел бы, чтобы "мы в настоящее время выделяем замыкающие пробелы?" быть специфичным для буфера состоянием; но у меня много проблем с выяснением того, как автокоманды взаимодействуют с буферами.

Например, вот мой первый удар в augroup локального буфера autocmd s:

augroup  ExtraWhitespace
   au!
   au BufEnter    <buffer=abuf> match ExtraWhitespace /\s\+$/
   au InsertEnter <buffer=abuf> match ExtraWhitespace /\s\+\%#\@<!$/
   au InsertLeave <buffer=abuf> match ExtraWhiteSpace /\s\+$/
augroup END

… К сожалению, это сразу же срабатывает при вызове:

Error detected while processing function ToggleExtraWhitespace: 
line   19:
E680: <buffer=0>: invalid buffer number 
line   20:
E680: <buffer=0>: invalid buffer number 
line   21:
E680: <buffer=0>: invalid buffer number 
No matching autocommands

Я не понимаю почему <abuf> является 0, когда bufnr('%') является 1 или как заставить автокоманды выполняться для буфера 1 вместо. (Конечно 0 является недействительным!)


На данный момент я поменялся <buffer=abuf> за *; но это портит функциональность этой функции, когда загружено несколько буферов, и это плохо. Так что любая помощь в выяснении этого приветствуется. /=

1 ответ

Во-первых, я не знаю как <buffer=abuf> работает. Документация для этого кажется противоречивой. Похоже, поведение для <buffer=abuf> был изменен / исправлен с помощью патча 7.4.637, до того, как он вызывал проблемы, даже если использовался правильно. <buffer=abuf> должен использоваться только когда работает autocmd. Таким образом, ваша функция, вероятно, сработала бы, если бы вы вызвали ее в VimEnter или BufAdd.


Следующая измененная версия того, что вы пытались, который не использует <buffer=abuf>

  augroup ExtraWhitespace
     autocmd! * <buffer>
     autocmd BufEnter    <buffer> match ExtraWhitespace /\s\+$/
     autocmd InsertEnter <buffer> match ExtraWhitespace /\s\+\%#\@<!$/
     autocmd InsertLeave <buffer> match ExtraWhitespace /\s\+$/
  augroup END

Первое, что вы должны заметить, это то, что au! был заменен на autocmd! * <buffer>, au! не должно быть там, так как это удалит все autocmd в группе ExtraWhitespace из всех буферов. Это означает, что вы можете определить его только в одном буфере. (autocmd! * <buffer> удаляет только autocmds в текущем буфере)

Второе, на что стоит обратить внимание: <buffer> используется. Это означает, что autocmd будет создан только для текущего буфера при вызове функции. Буфер локальный autocmd должен вызываться для каждого буфера, который вы хотите определить.


Другие разные комментарии

У тебя есть

fun! HighlightExtraWhitespace()
   if exists('b:ews') && b:ews == 1
     "echom "-- Adding ExtraWhitespace hilighting"
      highlight ExtraWhitespace ctermbg=red guibg=red
   else
     "echom "-- Removing ExtraWhitespace hilighting"
      highlight clear ExtraWhitespace
   endif
endfun
au ColorScheme * call HighlightExtraWhitespace()

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

autocmd ColorScheme * highlight ExtraWhitespace ctermbg=red guibg=red

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

Другие вопросы по тегам