diff --git a/runtime/pack/dist/opt/osc52/autoload/osc52.vim b/runtime/pack/dist/opt/osc52/autoload/osc52.vim index 3471329d7f..bad4bc388d 100644 --- a/runtime/pack/dist/opt/osc52/autoload/osc52.vim +++ b/runtime/pack/dist/opt/osc52/autoload/osc52.vim @@ -16,13 +16,20 @@ def OSCMessage(id: number) sent_message = true enddef -export def Paste(reg: string): tuple> +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> 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 index 0000000000..32448367fb --- /dev/null +++ b/src/testdir/dumps/Test_osc52_paste_05.dump @@ -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| diff --git a/src/testdir/test_plugin_osc52.vim b/src/testdir/test_plugin_osc52.vim index f14d3b8c16..afb13ef908 100644 --- a/src/testdir/test_plugin_osc52.vim +++ b/src/testdir/test_plugin_osc52.vim @@ -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, "\:au TextPutPost * let g:test = 1\") + call TermWait(buf) + + call term_sendkeys(buf, "\"+p") + call TermWait(buf) + + call term_sendkeys(buf, "\]52;c;" .. + \ base64_encode(str2blob(["test"])) .. "\\\") + call TermWait(buf) + + call VerifyScreenDump(buf, 'Test_osc52_paste_05', {}) + call StopVimInTerminal(buf) endfunc diff --git a/src/version.c b/src/version.c index 10a787cacb..692c510e6b 100644 --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 482, /**/ 481, /**/