mirror of
https://github.com/vim/vim.git
synced 2026-05-28 00:21:37 +02:00
patch 9.2.0484: TextPutPre triggers clipboard provider callback twice
Problem: TextPutPre triggers clipboard provider callback twice
when do_put() runs autocommands that themselves request
the clipboard.
Solution: Guard do_put() and put_do_autocmd() with
inc_clip_provider()/dec_clip_provider() so the provider
is queried at most once per put operation (Foxe Chen).
closes: #20215
Signed-off-by: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
77b8a12f82
commit
bec23ef65c
+30
-2
@@ -1196,6 +1196,16 @@ put_do_autocmd(
|
||||
if (list == NULL)
|
||||
return;
|
||||
|
||||
// Make sure regcontents will be up to date
|
||||
# ifdef FEAT_CLIPBOARD_PROVIDER
|
||||
inc_clip_provider();
|
||||
call_clip_provider_request(regname);
|
||||
# endif
|
||||
# ifdef FEAT_CLIPBOARD
|
||||
if (clipmethod != CLIPMETHOD_PROVIDER)
|
||||
regname = may_get_selection(regname);
|
||||
# endif
|
||||
|
||||
if (regname == '.')
|
||||
{
|
||||
if (last_insert_ga.ga_data != NULL)
|
||||
@@ -1231,6 +1241,9 @@ put_do_autocmd(
|
||||
(void)dict_add_string_len(v_event, "operator", buf, (int)buflen);
|
||||
|
||||
add_regtype_to_dict(regname, v_event, buf, sizeof(buf));
|
||||
# ifdef FEAT_CLIPBOARD_PROVIDER
|
||||
dec_clip_provider();
|
||||
# endif
|
||||
|
||||
(void)dict_add_bool(v_event, "visual", VIsual_active);
|
||||
|
||||
@@ -1713,6 +1726,7 @@ do_put(
|
||||
adjust_clip_reg(®name);
|
||||
#endif
|
||||
#ifdef FEAT_CLIPBOARD_PROVIDER
|
||||
inc_clip_provider();
|
||||
call_clip_provider_request(regname);
|
||||
#endif
|
||||
#ifdef FEAT_CLIPBOARD
|
||||
@@ -1749,6 +1763,11 @@ do_put(
|
||||
// TextPutPost after TextPutPre.
|
||||
if (has_textputpre())
|
||||
put_do_autocmd('.', NULL, NULL, false, dir);
|
||||
#endif
|
||||
#ifdef FEAT_CLIPBOARD_PROVIDER
|
||||
dec_clip_provider();
|
||||
#endif
|
||||
#ifdef FEAT_EVAL
|
||||
if (has_textputpost())
|
||||
put_do_autocmd('.', NULL, NULL, true, dir);
|
||||
|
||||
@@ -1771,7 +1790,12 @@ do_put(
|
||||
insert_string.string = expr_result;
|
||||
else if (get_spec_reg(regname, &insert_string.string, &allocated, TRUE)
|
||||
&& insert_string.string == NULL)
|
||||
{
|
||||
#ifdef FEAT_CLIPBOARD_PROVIDER
|
||||
dec_clip_provider();
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// Autocommands may be executed when saving lines for undo. This might
|
||||
// make "y_array" invalid, so we start undo now to avoid that.
|
||||
@@ -2001,8 +2025,8 @@ do_put(
|
||||
// move to start of next multi-byte character
|
||||
curwin->w_cursor.col += (*mb_ptr2len)(ml_get_cursor());
|
||||
else
|
||||
if (c != TAB || cur_ve_flags != VE_ALL)
|
||||
++curwin->w_cursor.col;
|
||||
if (c != TAB || cur_ve_flags != VE_ALL)
|
||||
++curwin->w_cursor.col;
|
||||
++col;
|
||||
}
|
||||
else
|
||||
@@ -2521,6 +2545,10 @@ end:
|
||||
curbuf->b_op_end = orig_end;
|
||||
}
|
||||
|
||||
#ifdef FEAT_CLIPBOARD_PROVIDER
|
||||
dec_clip_provider();
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
if (has_textputpost())
|
||||
{
|
||||
|
||||
@@ -1127,6 +1127,52 @@ func Test_clipboard_provider_accessed_once()
|
||||
|
||||
bw!
|
||||
|
||||
new
|
||||
" Emitting TextPutPre/TextPutPost/TextYankPost may cause a clipboard access
|
||||
"
|
||||
" Note that TextPutPost will always cause a second clipboard access, since a
|
||||
" TextPutPre may have changed the clipboard, meaning another "paste" call is
|
||||
" needed to make sure everything is up to date.
|
||||
augroup TextAutocmd
|
||||
autocmd!
|
||||
autocmd TextPutPost * let g:putpost = 1
|
||||
autocmd TextPutPre * let g:putpre = 1
|
||||
autocmd TextYankPost * let g:yankpost = 1
|
||||
augroup END
|
||||
|
||||
let g:putpost = 0
|
||||
let g:putpre = 0
|
||||
let g:yankpost = 0
|
||||
|
||||
let g:vim_paste_count = {'*': 0, '+': 0}
|
||||
let g:vim_copy_count = {'*': 0, '+': 0}
|
||||
|
||||
call setline(1, "hello world!")
|
||||
|
||||
yank +
|
||||
|
||||
yank *
|
||||
|
||||
put +
|
||||
|
||||
put *
|
||||
|
||||
call assert_equal(2, g:vim_paste_count['+'])
|
||||
call assert_equal(1, g:vim_copy_count['+'])
|
||||
|
||||
call assert_equal(2, g:vim_paste_count['*'])
|
||||
call assert_equal(1, g:vim_copy_count['*'])
|
||||
|
||||
call assert_equal(1, g:putpost)
|
||||
call assert_equal(1, g:putpre)
|
||||
call assert_equal(1, g:yankpost)
|
||||
|
||||
bw!
|
||||
unlet g:putpost
|
||||
unlet g:putpre
|
||||
unlet g:yankpost
|
||||
autocmd! TextAutocmd
|
||||
|
||||
set clipmethod&
|
||||
set clipboard&
|
||||
endfunc
|
||||
|
||||
@@ -729,6 +729,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
484,
|
||||
/**/
|
||||
483,
|
||||
/**/
|
||||
|
||||
Reference in New Issue
Block a user