From 77eb278adf71987c159e5a8dcbaf1e83841cb168 Mon Sep 17 00:00:00 2001 From: Antoine Date: Thu, 12 Jun 2025 18:18:23 +0200 Subject: [PATCH] fix(clipboard): enable cache for function providers #34470 Problem: With these settings, copy/pasting `blockwise-visual` (with `CTRL+V`) incorrectly pastes as a `linewise` mode because `regtype` is ignored: vim.opt.clipboard = 'unnamedplus' vim.g.clipboard = 'osc52' To reproduce: press `CTRL+V` and select some characters press `p` and observe that it is pasted in `linewise` mode. Solution: Enable the [clipboard.vim](https://github.com/neovim/neovim/blob/master/runtime/autoload/provider/clipboard.vim#L281-L283)) cache for function providers, so that `regtype` is maintained for the OSC52 clipboard provider. (cherry picked from commit ac12dc49cc35241acc6d4ea36f035ab5a5d9cfe3) --- runtime/autoload/provider/clipboard.vim | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/runtime/autoload/provider/clipboard.vim b/runtime/autoload/provider/clipboard.vim index 32d8841b72..c1b9d4337c 100644 --- a/runtime/autoload/provider/clipboard.vim +++ b/runtime/autoload/provider/clipboard.vim @@ -268,13 +268,11 @@ function! provider#clipboard#Executable() abort endfunction function! s:clipboard.get(reg) abort - if type(s:paste[a:reg]) == v:t_func - return s:paste[a:reg]() - elseif s:selections[a:reg].owner > 0 + if s:selections[a:reg].owner > 0 return s:selections[a:reg].data end - let clipboard_data = s:try_cmd(s:paste[a:reg]) + let clipboard_data = type(s:paste[a:reg]) == v:t_func ? s:paste[a:reg]() : s:try_cmd(s:paste[a:reg]) if match(&clipboard, '\v(unnamed|unnamedplus)') >= 0 \ && type(clipboard_data) == v:t_list \ && get(s:selections[a:reg].data, 0, []) ==# clipboard_data @@ -294,13 +292,12 @@ function! s:clipboard.set(lines, regtype, reg) abort return 0 end - if type(s:copy[a:reg]) == v:t_func - call s:copy[a:reg](a:lines, a:regtype) - return 0 - end - - if s:cache_enabled == 0 - call s:try_cmd(s:copy[a:reg], a:lines) + if s:cache_enabled == 0 || type(s:copy[a:reg]) == v:t_func + if type(s:copy[a:reg]) == v:t_func + call s:copy[a:reg](a:lines, a:regtype) + else + call s:try_cmd(s:copy[a:reg], a:lines) + endif "Cache it anyway we can compare it later to get regtype of the yank let s:selections[a:reg] = copy(s:selection) let s:selections[a:reg].data = [a:lines, a:regtype]