From c30f2ac25de1235e4cd743fe1a16be20c14e140b Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Wed, 15 Jul 2015 13:59:05 +0200 Subject: clipboard: handle middle-click paste correctly. Also handle clipboard errors more like vim: paste from unnamed register if clipboard provider fails. --- src/nvim/normal.c | 6 ++++++ src/nvim/ops.c | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/nvim/normal.c b/src/nvim/normal.c index a5eb54bb68..95e1c3d113 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -2016,6 +2016,9 @@ do_mouse ( if (regname == '.') insert_reg(regname, true); else { + if (regname == 0 && eval_has_provider("clipboard")) { + regname = '*'; + } if ((State & REPLACE_FLAG) && !yank_register_mline(regname)) insert_reg(regname, true); else { @@ -2279,6 +2282,9 @@ do_mouse ( * Middle mouse click: Put text before cursor. */ if (which_button == MOUSE_MIDDLE) { + if (regname == 0 && eval_has_provider("clipboard")) { + regname = '*'; + } if (yank_register_mline(regname)) { if (mouse_past_bottom) dir = FORWARD; diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 063ad154f1..8a7ced138b 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -765,7 +765,10 @@ yankreg_T *get_yank_register(int regname, int mode) if (mode == YREG_PASTE && get_clipboard(regname, ®, false)) { // reg is set to clipboard contents. return reg; - } else if (mode != YREG_YANK && (regname == 0 || regname == '"') && y_previous != NULL) { + } else if (mode != YREG_YANK + && (regname == 0 || regname == '"' || regname == '*' || regname == '+') + && y_previous != NULL) { + // in case clipboard not available, paste from previous used register return y_previous; } -- cgit From 8047570b708c27b68e9a3a50c11de932c3eeab41 Mon Sep 17 00:00:00 2001 From: Björn Linse Date: Wed, 15 Jul 2015 18:06:35 +0200 Subject: clipboard: add tests for error fallback and middleclick paste --- .../clipboard/autoload/provider/clipboard.vim | 24 ---------- .../clipboard/clipboard_provider_spec.lua | 53 +++++++++++++++++++++- .../fixtures/autoload/provider/clipboard.vim | 28 ++++++++++++ 3 files changed, 80 insertions(+), 25 deletions(-) delete mode 100644 test/functional/clipboard/autoload/provider/clipboard.vim create mode 100644 test/functional/fixtures/autoload/provider/clipboard.vim diff --git a/test/functional/clipboard/autoload/provider/clipboard.vim b/test/functional/clipboard/autoload/provider/clipboard.vim deleted file mode 100644 index d88b68464e..0000000000 --- a/test/functional/clipboard/autoload/provider/clipboard.vim +++ /dev/null @@ -1,24 +0,0 @@ -let g:test_clip = { '+': [''], '*': [''], } - -let s:methods = {} - -let g:cliplossy = 0 - -function! s:methods.get(reg) - if g:cliplossy - " behave like pure text clipboard - return g:test_clip[a:reg][0] - else - "behave like VIMENC clipboard - return g:test_clip[a:reg] - end -endfunction - -function! s:methods.set(lines, regtype, reg) - let g:test_clip[a:reg] = [a:lines, a:regtype] -endfunction - - -function! provider#clipboard#Call(method, args) - return call(s:methods[a:method],a:args,s:methods) -endfunction diff --git a/test/functional/clipboard/clipboard_provider_spec.lua b/test/functional/clipboard/clipboard_provider_spec.lua index 9282a66240..f6d6188d82 100644 --- a/test/functional/clipboard/clipboard_provider_spec.lua +++ b/test/functional/clipboard/clipboard_provider_spec.lua @@ -92,7 +92,7 @@ end) describe('clipboard usage', function() before_each(function() clear() - execute('let &rtp = "test/functional/clipboard,".&rtp') + execute('let &rtp = "test/functional/fixtures,".&rtp') execute('call getreg("*")') -- force load of provider end) @@ -197,6 +197,17 @@ describe('clipboard usage', function() expect('some more') end) + it('pastes unnamed register if the provider fails', function() + insert('the text') + feed('yy') + execute("let g:cliperror = 1") + feed('"*p') + expect([[ + the text + the text]]) + end) + + describe('with clipboard=unnamed', function() -- the basic behavior of unnamed register should be the same -- even when handled by clipboard provider @@ -261,6 +272,16 @@ describe('clipboard usage', function() expect("indeed star") end) + it('unamed operations work even if the provider fails', function() + insert('the text') + feed('yy') + execute("let g:cliperror = 1") + feed('p') + expect([[ + the text + the text]]) + end) + end) it('supports :put', function() @@ -335,4 +356,34 @@ describe('clipboard usage', function() 'Howdy!', }, 'v'}, eval("g:test_clip['*']")) end) + + it('handles middleclick correctly', function() + local screen = Screen.new(30, 5) + screen:attach() + insert([[ + the source + a target]]) + feed('gg"*ywwyw') + -- clicking depends on the exact visual layout, so expect it: + screen:expect([[ + the ^source | + a target | + ~ | + ~ | + | + ]], nil, {{bold = true, foreground = Screen.colors.Blue}}) + + feed('<0,1>') + expect([[ + the source + the a target]]) + + -- on error, fall back to unnamed register + execute("let g:cliperror = 1") + feed('<6,1>') + expect([[ + the source + the a sourcetarget]]) + end) + end) diff --git a/test/functional/fixtures/autoload/provider/clipboard.vim b/test/functional/fixtures/autoload/provider/clipboard.vim new file mode 100644 index 0000000000..a28484169a --- /dev/null +++ b/test/functional/fixtures/autoload/provider/clipboard.vim @@ -0,0 +1,28 @@ +let g:test_clip = { '+': [''], '*': [''], } + +let s:methods = {} + +let g:cliplossy = 0 +let g:cliperror = 0 + +function! s:methods.get(reg) + if g:cliperror + return 0 + end + if g:cliplossy + " behave like pure text clipboard + return g:test_clip[a:reg][0] + else + "behave like VIMENC clipboard + return g:test_clip[a:reg] + end +endfunction + +function! s:methods.set(lines, regtype, reg) + let g:test_clip[a:reg] = [a:lines, a:regtype] +endfunction + + +function! provider#clipboard#Call(method, args) + return call(s:methods[a:method],a:args,s:methods) +endfunction -- cgit