]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.1973: some minor problems with clipboard provider code v9.1.1973
authorFoxe Chen <chen.foxe@gmail.com>
Fri, 12 Dec 2025 07:44:14 +0000 (08:44 +0100)
committerChristian Brabandt <cb@256bit.org>
Fri, 12 Dec 2025 07:44:14 +0000 (08:44 +0100)
Problem:  some minor problems with clipboard provider code
          (after v9.1.1972)
Solution: Fix minor issues (Foxe Chen)

- allow empty register type for paste function to mean automatic
- fix internal inc_clip_provider() and dec_clip_provider() functions not
  setting the pause count correctly
- don't call paste function when yanking

closes: #18909

Signed-off-by: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
runtime/doc/eval.txt
src/clipboard.c
src/register.c
src/testdir/test_eval_stuff.vim
src/version.c

index ebb6d5ba73b6fbdd6f2161ef99b5ee1848f56588..6bd012033ff891bcaaa60f80c17b8e364226881d 100644 (file)
@@ -1,4 +1,4 @@
-*eval.txt*     For Vim version 9.1.  Last change: 2025 Dec 11
+*eval.txt*     For Vim version 9.1.  Last change: 2025 Dec 12
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -5343,7 +5343,8 @@ The "paste" callback takes the following arguments in the following order:
 
 It should return a |list| or |tuple| containing the following elements in
 order:
-       1. Register type (and optional width) conforming to |setreg()|
+       1. Register type (and optional width) conforming to |setreg()|.  If it
+          is an empty string, then the type is automatically chosen.
        2. A |list| of strings to return to Vim, each representing a line.
 
                                                *clipboard-providers-copy*
index 51f70543030ebce8eca2c4e286247dfe3d3fbc8a..6d321e5c0bb6d64a423a29b346dbb9099b19e2a8 100644 (file)
@@ -3934,8 +3934,8 @@ clip_provider_paste(char_u *reg, char_u *provider)
        }
        *curval++ = NULL;
 
-       if (STRLEN(reg_type) <= 0
-               || get_yank_type(&reg_type, &yank_type, &block_len) == FAIL)
+       if (*reg_type != NUL && (STRLEN(reg_type) <= 0
+               || get_yank_type(&reg_type, &yank_type, &block_len) == FAIL))
        {
            emsg(e_invalid_argument);
            goto free_lstval;
@@ -3977,7 +3977,7 @@ exit:
 // This prevents unnecessary calls when accessing the provider often in an
 // interval.
 //
-// If -1 then allow provider callback to be called then set to zero. Default
+// If -1 then allow provider callback to be called then set to one. Default
 // value (is allowed) is -2.
 static int star_pause_count = -2, plus_pause_count = -2;
 
@@ -4031,15 +4031,19 @@ call_clip_provider_set(int reg)
     void
 inc_clip_provider(void)
 {
-    plus_pause_count = plus_pause_count == -2 ? -1 : plus_pause_count + 1;
-    star_pause_count = star_pause_count == -2 ? -1 : star_pause_count + 1;
+    plus_pause_count = (plus_pause_count == -2
+       || plus_pause_count == -1) ? -1 : plus_pause_count + 1;
+    star_pause_count = (star_pause_count == -2
+       || star_pause_count == -1) ? -1 : star_pause_count + 1;
 }
 
     void
 dec_clip_provider(void)
 {
-    plus_pause_count = plus_pause_count == -1 ? -1 : plus_pause_count - 1;
-    star_pause_count = star_pause_count == -1 ? -1 : star_pause_count - 1;
+    if (plus_pause_count != -2)
+       plus_pause_count = plus_pause_count == -1 ? -1 : plus_pause_count - 1;
+    if (star_pause_count != -2)
+       star_pause_count = star_pause_count == -1 ? -1 : star_pause_count - 1;
 
     if (plus_pause_count == 0 || plus_pause_count == -1)
        plus_pause_count = -2;
index 589d07f715500364c916084c02ed808e6a33c48b..12fe8ebb149b9bd0448f3c1c30726e51cc8773ee 100644 (file)
@@ -1420,6 +1420,7 @@ op_yank(oparg_T *oap, int deleting, int mess)
     }
 
 #ifdef FEAT_CLIPBOARD_PROVIDER
+    inc_clip_provider();
     if (curr == &y_regs[REAL_PLUS_REGISTER])
        call_clip_provider_set('+');
     else if (curr == &y_regs[STAR_REGISTER])
@@ -1467,6 +1468,9 @@ op_yank(oparg_T *oap, int deleting, int mess)
 #if defined(FEAT_EVAL)
     if (!deleting && has_textyankpost())
        yank_do_autocmd(oap, y_current);
+#endif
+#ifdef FEAT_CLIPBOARD_PROVIDER
+    dec_clip_provider();
 #endif
     return OK;
 
index 49fa9509e3ecca68180a46d44764e905a293cc82..eb0eaca5327104d45517551e2c5a9ec9bf154db5 100644 (file)
@@ -754,6 +754,7 @@ func s:Paste(reg)
 
   elseif l:t == "count"
     let g:vim_paste_count[a:reg] += 1
+    let g:vim_test = "hello"
     return ("c", ["hello"])
 
   elseif l:t == "store"
@@ -1073,14 +1074,82 @@ func Test_clipboard_provider_accessed_once()
   call assert_equal(1, g:vim_paste_count['+'])
   call assert_equal(1, g:vim_paste_count['*'])
 
+  call assert_equal(0, g:vim_copy_count['+'])
+  call assert_equal(0, g:vim_copy_count['*'])
+
+  let g:vim_paste_count = {'*': 0, '+': 0}
+
   call execute(':global/quick/:yank +')
   call execute(':global/quick/:yank *')
 
   call assert_equal(1, g:vim_copy_count['+'])
   call assert_equal(1, g:vim_copy_count['*'])
 
+  call assert_equal(0, g:vim_paste_count['+'])
+  call assert_equal(0, g:vim_paste_count['*'])
+
   bw!
   set clipmethod&
 endfunc
 
+" Test if the copying does not call the paste callback, and pasting does not all
+" the copy callback.
+func Test_clipboard_provider_copy_paste_independent()
+  let v:clipproviders["test"] = {
+        \ "paste": {
+        \       '+': function("s:Paste"),
+        \       '*': function("s:Paste")
+        \   },
+        \ "copy": {
+        \       '+': function("s:Copy"),
+        \       '*': function("s:Copy")
+        \   }
+        \ }
+  set clipmethod=test
+
+  let g:vim_paste = "count"
+  let g:vim_paste_count = {'*': 0, '+': 0}
+  let g:vim_copy_count = {'*': 0, '+': 0}
+
+  new
+
+  put +
+
+  put *
+
+  bw!
+
+  call getreg("+")
+  call getreg("*")
+
+  call assert_equal(0, g:vim_copy_count['*'])
+  call assert_equal(0, g:vim_copy_count['+'])
+
+  let g:vim_paste_count = {'*': 0, '+': 0}
+
+  " Emitting TextYankPost event may cause a clipboard access
+  augroup Test
+    autocmd!
+    autocmd TextYankPost * let g:test = 2
+  augroup END
+
+  new
+  call setline(1, "The quick brown fox jumps over the lazy dog")
+
+  yank +
+
+  yank *
+
+  bw!
+  autocmd! Test
+
+  call setreg("+", "hello")
+  call setreg("*", "hello")
+
+  call assert_equal(0, g:vim_paste_count['*'])
+  call assert_equal(0, g:vim_paste_count['+'])
+
+  set clipmethod&
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
index e754b6021f6e3d17d362276a3bd3fc767784ec8a..43bb41282ccf90de8d0392da3616cf08b238df0c 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1973,
 /**/
     1972,
 /**/