vim-patch:9.2.0473: Pasting ". register without autocommands breaks TextPut*

Problem:  Pasting ". register without TextPut* autocommands breaks
          subsequent TextPut* autocommands (after 9.2.0470).
Solution: Only decrement add_last_insert if it has been incremented
          (zeertzjq).

closes: vim/vim#20192

a70b7a85af
This commit is contained in:
zeertzjq
2026-05-12 07:31:58 +08:00
parent 871b4b1642
commit 58184d3fa3
2 changed files with 21 additions and 16 deletions

View File

@@ -1401,7 +1401,8 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
? 'c'
: (flags & PUT_LINE ? 'i' : (dir == FORWARD ? 'a' : 'i'));
if (has_event(EVENT_TEXTPUTPRE) || has_event(EVENT_TEXTPUTPOST)) {
bool has_textput_events = has_event(EVENT_TEXTPUTPRE) || has_event(EVENT_TEXTPUTPOST);
if (has_textput_events) {
add_last_insert++;
}
@@ -1444,12 +1445,11 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags)
if (has_event(EVENT_TEXTPUTPRE)) {
put_do_autocmd('.', NULL, NULL, false, dir);
}
if (has_event(EVENT_TEXTPUTPOST)) {
put_do_autocmd('.', NULL, NULL, true, dir);
}
if (--add_last_insert == 0) {
if (has_textput_events && --add_last_insert == 0) {
ga_clear(&last_insert_ga);
}

View File

@@ -5432,22 +5432,27 @@ func Test_TextPutX()
au! TextPutPre
let g:pre_event = []
" Test that recursive ". register calls have the same contents for post and
" pre
au TextPutPre * put . | let g:pre_event = copy(v:event)
au TextPutPost * let g:post_event = copy(v:event)
for round in range(2)
" Recursive ". register calls have the same contents for post and pre.
au TextPutPre * put . | let g:pre_event = copy(v:event)
au TextPutPost * let g:post_event = copy(v:event)
call feedkeys("iinserted\<Esc>", 'x')
norm! ".p
call feedkeys("iinserted\<Esc>", 'x')
norm! ".p
call assert_equal(
\ #{regcontents: ["inserted"], regname: '.',
\ operator: 'p', regtype: 'v', visual: v:false},
\ g:pre_event)
call assert_equal(g:pre_event, g:post_event)
call assert_equal(
\ #{regcontents: ["inserted"], regname: '.',
\ operator: 'p', regtype: 'v', visual: v:false},
\ g:pre_event)
call assert_equal(g:pre_event, g:post_event)
au! TextPutPre
au! TextPutPost
au! TextPutPre
au! TextPutPost
" Pasting ". register without TextPutPre/TextPutPost autocommands should
" not interfere with these autocommands in the next round.
norm! ".p
endfor
unlet g:post_event
unlet g:pre_event