Vim 8.0 mystery: `: r!` Команда в обработчике `: au BufRead`, вызывающая нежелательные побочные эффекты - PullRequest
1 голос
/ 28 января 2020

У меня есть следующие строки в моем .vimrc:

:function GitCommitMsg()
:  set tw=62
:  if getline(1) == ""
:    1 
:    r!git diff -w --minimal --cached
:    1d
:  endif
:  set syntax=diff
:endf 
:au BufRead,BufNewFile COMMIT_EDITMSG call GitCommitMsg()

В течение многих лет вышеприведенное прекрасно работало с Vim 7.x, но стало плохо работать под Vim 8 на Ubuntu 18.

Внутри оператора if выполняется новый коммит. Идея состоит в том, чтобы предоставить некоторый контент при создании нового коммита, но в противном случае оставить сообщение в покое.

Когда выполняется этот интерьер, ни set tw=62, ни set syntax=diff не вступают в силу. Наблюдаемые значения 72 и gitcommit соответственно.

Каким-то образом условный вызов :r! вызывает проблему. Если мы закомментируем это:

:function GitCommitMsg()
:  set tw=62
:  if getline(1) == ""
:    1 
":    r!git diff -w --minimal --cached
:    1d
:  endif
:  set syntax=diff
:endf 
:au BufRead,BufNewFile COMMIT_EDITMSG call GitCommitMsg()

, тогда set tw=62 и set syntax=diff вступят в силу во всех случаях.

Обратите внимание, что :r!git diff работает: вывод git diff ... загружается в буфер, а ведущая пустая строка удаляется 1d.

Причина не в частности git diff или контент, который он производит; проблема сохраняется независимо от того, какие выходные данные команды мы читаем с :r!. Так, например, это все еще имеет проблему:

:function GitCommitMsg()
:  set tw=62
:  if getline(1) == ""
:    1 
:    r!echo foo
:    1d
:  endif
:  set syntax=diff
:endf 
:au BufRead,BufNewFile COMMIT_EDITMSG call GitCommitMsg()

Как мы можем прочитать вывод команды в буфер в середине обработки au без нежелательных побочных эффектов, таких как засорение настроек?

1 Ответ

2 голосов
/ 29 января 2020

Простое изменение BufRead,BufNewFile на BufWinEnter должно исправить вашу проблему.

Проблема, вероятно, связана с тем, что во время BufRead существует только буфер, но окно для него не выбран (или даже еще не создан). Чтобы обойти эту проблему, Vim использует некоторые причуды, поэтому ваш сценарий может быть запущен в контексте какого-то временного окна (попробуйте отследить значение win_getid()), и после этого Vim скопирует локальные параметры окна (такие как tw). ) из "последнего использованного окна" и т. д.

Еще один момент заключается в том, что произвольные команды Ex должны иметь контекст окна для запуска (например, есть win_execute(), но нет buf_execute()). Следовательно, выполнение :read может также привести к манипулированию «временными».

Ну, это скорее предположение, чем объяснение, но я надеюсь, что вы поняли идею.

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