]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0482: runtime(osc52): triggered twice with TextPutPoste autocmd v9.2.0482
authorFoxe Chen <chen.foxe@gmail.com>
Fri, 15 May 2026 02:09:24 +0000 (02:09 +0000)
committerChristian Brabandt <cb@256bit.org>
Fri, 15 May 2026 02:09:24 +0000 (02:09 +0000)
Problem:  runtime(osc52): triggered twice with TextPutPoste autocmd
Solution: Detect recursive trigger and return null (Foxe Chen)

closes: #20216

Signed-off-by: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
runtime/pack/dist/opt/osc52/autoload/osc52.vim
src/testdir/dumps/Test_osc52_paste_05.dump [new file with mode: 0644]
src/testdir/test_plugin_osc52.vim
src/version.c

index 3471329d7f9bfb02162b217868cf2d521d625b06..bad4bc388d7ff52cd9181a7593a413896acfdf51 100644 (file)
@@ -16,13 +16,20 @@ def OSCMessage(id: number)
   sent_message = true
 enddef
 
-export def Paste(reg: string): tuple<string, list<string>>
+var loop_timerid: number = -1
+
+export def Paste(reg: string): any
   # Check if user has indicated that the terminal does not support OSC 52 paste
   # (or has disabled it)
   if get(g:, 'osc52_disable_paste', 0)
     return ("c", [])
   endif
 
+  if loop_timerid != -1
+    # This will result in the register being unchanged
+    return null
+  endif
+
   # Some terminals like Kitty respect the selection type parameter on both X11
   # and Wayland. If the terminal doesn't then the selection type parameter
   # should be ignored (no-op)
@@ -61,6 +68,14 @@ export def Paste(reg: string): tuple<string, list<string>>
     endif
   endtry
 
+  # A TextPutPost autocmd may cause this function to be called twice, which is
+  # technically intended behaviour, however it is not necessary for this plugin.
+  # To prevent this, return immediately if we have not returned back to the main
+  # loop since the last "paste" call.
+  loop_timerid = timer_start(0, (_) => {
+    loop_timerid = -1
+  })
+
   if interrupt
     echo "Interrupted while waiting for OSC 52 response"
     return ("c", [""])
diff --git a/src/testdir/dumps/Test_osc52_paste_05.dump b/src/testdir/dumps/Test_osc52_paste_05.dump
new file mode 100644 (file)
index 0000000..3244836
--- /dev/null
@@ -0,0 +1,20 @@
+| +0&#ffffff0@74
+|h|e|l@1|o| @69
+>t|e|s|t| @70
+|w|o|r|l|d|!| @68
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|3|,|1| @10|A|l@1| 
index f14d3b8c16cb10ed3cca7b016f2224b427ca500b..afb13ef908ad1d9f0cee2739794557619fa3518d 100644 (file)
@@ -90,6 +90,20 @@ func Test_osc52_paste()
 
   call VerifyScreenDump(buf, 'Test_osc52_paste_04', {})
 
+  " Test that TextPutPost (e.g. from hlyank plugin) doesn't make "paste"
+  " callback be called twice for osc52.
+  call term_sendkeys(buf, "\<Esc>:au TextPutPost * let g:test = 1\<CR>")
+  call TermWait(buf)
+
+  call term_sendkeys(buf, "\"+p")
+  call TermWait(buf)
+
+  call term_sendkeys(buf, "\<Esc>]52;c;" ..
+        \ base64_encode(str2blob(["test"])) .. "\<Esc>\\")
+  call TermWait(buf)
+
+  call VerifyScreenDump(buf, 'Test_osc52_paste_05', {})
+
   call StopVimInTerminal(buf)
 endfunc
 
index 10a787cacb11a04d4d8ebcd4b1579bd7522ec00e..692c510e6b75594412ba4844eb8b0e909b856dfa 100644 (file)
@@ -729,6 +729,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    482,
 /**/
     481,
 /**/