Reputation: 58617
I have the following lines in my .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()
For years, the above has worked fine with Vim 7.x, but has started to misbehave under Vim 8 on Ubuntu 18.
The interior of the if
statement is executed for new commits. The idea is to supply some content when making a new commit, but otherwise leave the message alone.
When that interior executes, then neither the set tw=62
nor the set syntax=diff
take effect. The observed values are 72
and gitcommit
, respectively.
Somehow, the conditional :r!
invocation is causing the issue. If we comment it out:
: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()
then set tw=62
and set syntax=diff
take effect in all cases.
Note that the :r!git diff
does work: the output of git diff ...
is loaded into the buffer, and the leading empty line is deleted by 1d
.
The cause isn't specifically git diff
or the content it produces; the problem persists regardless of what command's output we read with :r!
. So, for instance, this still has the problem:
: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()
How can we read the output of a command into the buffer in the middle of au
processing without unwanted side effects like settings being clobbered?
Upvotes: 2
Views: 62
Reputation: 15186
Simply changing BufRead,BufNewFile
to BufWinEnter
should fix your issue.
The problem is probably due to the fact that at the time of BufRead
only the buffer exists, but the window for it is not chosen (or even not created yet). To workaround this issue Vim makes use of some quirks, so your script may be running in the context of some temporary window (try to trace win_getid()
value), and after that Vim will copy window-local options (such as tw
) from "last used window" and so on.
Another point is that arbitrary Ex commands must have a window context to run (for instance, there's win_execute()
, but there's no buf_execute()
). Hence executing :read
could also result in manipulating "temporaries".
Well, this probably was a speculation rather than an explanation, but I hope you got the idea.
Upvotes: 3