You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The issue is due to the fact that when we reload a buffer, BufEnter is fired but not BufLeave.
We need an event to hook into and save the state of the ticks synchronization, so that we can restore it if necessary on BufEnter. IOW, we need a replacement for BufLeave; I think BufUnload is the only possible event which can play this role.
It could be added into the list of events in this line:
During my limited tests, it seemed to fix the issue. I can send you a PR if you think it's the right fix.
Note that BufReadPre can't help here, because b:changedtick is incremented by 1 on BufReadPre when reloading a buffer.
Btw, why does the autocmd listen to BufReadPre?
AFAICT, its goal is to save the state of the ticks synchronization.
But it seems we can't do that on BufReadPre; either b:changedtick is incremented by 1 when reloading a buffer:
$ touch /tmp/file{1..2} && vim -Nu NONE -S <(cat <<'EOF'
let g:abuf = 'expand("<abuf>")'
eval getcompletion('buf*', 'event')
\->filter({_,v -> v !~# 'Cmd$'})
\->map({_,v -> execute(printf(
\ 'au %s * unsilent echom "%s in buf "..%s..": tick is "..getbufvar(%s, "changedtick")'
\ , v, v, g:abuf, g:abuf))})
call map(range(10), {_,v -> execute('pu='..v)})
undo
EOF
) /tmp/file1
:mess clear
:e
:mess
BufUnload in buf 1: tick is 34
"/tmp/file1" 0L, 0C
BufRead in buf 1: tick is 35
BufReadPost in buf 1: tick is 35
BufEnter in buf 1: tick is 36
BufWinEnter in buf 1: tick is 36
" notice how the tick was 34 on BufUnload, and then 35 on BufRead
or it has already been initialized to 1 when loading a new file (it happens a little earlier on BufNew):
$ touch /tmp/file{1..2} && vim -Nu NONE -S <(cat <<'EOF'
let g:abuf = 'expand("<abuf>")'
eval getcompletion('buf*', 'event')
\->filter({_,v -> v !~# 'Cmd$'})
\->map({_,v -> execute(printf(
\ 'au %s * unsilent echom "%s in buf "..%s..": tick is "..getbufvar(%s, "changedtick")'
\ , v, v, g:abuf, g:abuf))})
call map(range(10), {_,v -> execute('pu='..v)})
undo
EOF
) /tmp/file1
:mess clear
:e /tmp/file2
:mess
BufNew in buf 2: tick is 1
BufAdd in buf 2: tick is 1
BufCreate in buf 2: tick is 1
BufLeave in buf 1: tick is 34
BufWinLeave in buf 1: tick is 34
BufUnload in buf 1: tick is 34
BufReadPre in buf 2: tick is 1
"/tmp/file2" 0L, 0C
BufRead in buf 2: tick is 1
BufReadPost in buf 2: tick is 1
BufEnter in buf 2: tick is 2
BufWinEnter in buf 2: tick is 2
" notice how the tick is initialized to 1 on BufNew, and unchanged on BufRead
In both cases, b:changedtick has been altered on BufReadPre, so there's no guarantee that the state of the ticks synchronization has been preserved.
Is there some case where BufReadPre is useful?
The text was updated successfully, but these errors were encountered:
svermeulen
added a commit
to svermeulen/vim-repeat
that referenced
this issue
May 23, 2020
Describe the bug
.
may fail to repeat a command after reloading a buffer.To Reproduce
Run this shell command (you'll need to update the path to the plugin):
C-b
to exchange the position of thea
andb
characters.:w
to save the buffer.h
to move the cursor (necessary to prevent theCursorMoved
autocmd from fixing the bug by accident).:e
to reload the buffer..
to repeat the customC-b
command.Result: the buffer contains
baac
.Expected behavior
The buffer contains
abc
.Screenshots
Environment
Additional context
The issue is due to the fact that when we reload a buffer,
BufEnter
is fired but notBufLeave
.We need an event to hook into and save the state of the ticks synchronization, so that we can restore it if necessary on
BufEnter
. IOW, we need a replacement forBufLeave
; I thinkBufUnload
is the only possible event which can play this role.It could be added into the list of events in this line:
vim-repeat/autoload/repeat.vim
Line 161 in c947ad2
Which would give:
During my limited tests, it seemed to fix the issue. I can send you a PR if you think it's the right fix.
Note that
BufReadPre
can't help here, becauseb:changedtick
is incremented by 1 onBufReadPre
when reloading a buffer.Btw, why does the autocmd listen to
BufReadPre
?AFAICT, its goal is to save the state of the ticks synchronization.
But it seems we can't do that on
BufReadPre
; eitherb:changedtick
is incremented by 1 when reloading a buffer:or it has already been initialized to 1 when loading a new file (it happens a little earlier on
BufNew
):In both cases,
b:changedtick
has been altered onBufReadPre
, so there's no guarantee that the state of the ticks synchronization has been preserved.Is there some case where
BufReadPre
is useful?The text was updated successfully, but these errors were encountered: