aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/ops.c24
-rw-r--r--test/functional/clipboard/autoload/provider/clipboard.vim2
-rw-r--r--test/functional/clipboard/clipboard_provider_spec.lua45
3 files changed, 56 insertions, 15 deletions
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index e73868a0fa..f0caaad97b 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -5360,10 +5360,13 @@ static void get_clipboard(int name, bool quiet)
goto err;
}
char_u* regtype = res->lv_last->li_tv.vval.v_string;
- if (regtype == NULL || strlen((char*)regtype) != 1) {
+ if (regtype == NULL || strlen((char*)regtype) > 1) {
goto err;
}
switch (regtype[0]) {
+ case 0:
+ reg->y_type = MAUTO;
+ break;
case 'v': case 'c':
reg->y_type = MCHAR;
break;
@@ -5393,15 +5396,23 @@ static void get_clipboard(int name, bool quiet)
reg->y_array[i++] = (uint8_t *)xstrdup((char *)li->li_tv.vval.v_string);
}
- if (reg->y_type == MAUTO) {
- if (reg->y_size > 0 && strlen((char*)reg->y_array[reg->y_size-1]) == 0) {
- reg->y_type = MLINE;
+ if (reg->y_size > 0 && strlen((char*)reg->y_array[reg->y_size-1]) == 0) {
+ // a known-to-be charwise yank might have a final linebreak
+ // but otherwise there is no line after the final newline
+ if (reg->y_type != MCHAR) {
free(reg->y_array[reg->y_size-1]);
reg->y_size--;
- } else {
+ if (reg->y_type == MAUTO) {
+ reg->y_type = MLINE;
+ }
+ }
+ } else {
+ if (reg->y_type == MAUTO) {
reg->y_type = MCHAR;
}
- } else if (reg->y_type == MBLOCK) {
+ }
+
+ if (reg->y_type == MBLOCK) {
int maxlen = 0;
for (int i = 0; i < reg->y_size; i++) {
int rowlen = STRLEN(reg->y_array[i]);
@@ -5453,6 +5464,7 @@ static void set_clipboard(int name)
break;
case MBLOCK:
regtype = 'b';
+ list_append_string(lines, (char_u*)"", 0);
break;
}
list_append_string(args, &regtype, 1);
diff --git a/test/functional/clipboard/autoload/provider/clipboard.vim b/test/functional/clipboard/autoload/provider/clipboard.vim
index 6c05a19fc3..c7fd630782 100644
--- a/test/functional/clipboard/autoload/provider/clipboard.vim
+++ b/test/functional/clipboard/autoload/provider/clipboard.vim
@@ -7,7 +7,7 @@ function! s:methods.get(reg)
endfunction
function! s:methods.set(lines, regtype, reg)
- let g:test_clip[a:reg] = a:lines
+ let g:test_clip[a:reg] = [a:lines, a:regtype]
endfunction
diff --git a/test/functional/clipboard/clipboard_provider_spec.lua b/test/functional/clipboard/clipboard_provider_spec.lua
index f1e011f12d..363dcb1d11 100644
--- a/test/functional/clipboard/clipboard_provider_spec.lua
+++ b/test/functional/clipboard/clipboard_provider_spec.lua
@@ -73,7 +73,7 @@ describe('clipboard usage', function()
insert("some words")
feed('^"*dwdw"*P')
expect('some ')
- eq({'some '}, eval("g:test_clip['*']"))
+ eq({{'some '}, 'v'}, eval("g:test_clip['*']"))
end)
it('supports separate "* and "+ when the provider supports it', function()
@@ -90,19 +90,36 @@ describe('clipboard usage', function()
secound line
first line]])
-- linewise selection should be encoded as an extra newline
- eq({'third line', ''}, eval("g:test_clip['+']"))
- eq({'secound line', ''}, eval("g:test_clip['*']"))
+ eq({{'third line', ''}, 'V'}, eval("g:test_clip['+']"))
+ eq({{'secound line', ''}, 'V'}, eval("g:test_clip['*']"))
end)
- it('handles null bytes', function()
+ it('handles null bytes when pasting and in getreg', function()
insert("some\022000text\n\022000very binary\022000")
feed('"*y-+"*p')
- eq({'some\ntext', '\nvery binary\n',''}, eval("g:test_clip['*']"))
+ eq({{'some\ntext', '\nvery binary\n',''}, 'V'}, eval("g:test_clip['*']"))
expect("some\00text\n\00very binary\00\nsome\00text\n\00very binary\00")
-- test getreg/getregtype
eq('some\ntext\n\nvery binary\n\n', eval("getreg('*', 1)"))
eq("V", eval("getregtype('*')"))
+
+ -- getreg supports three arguments
+ eq('some\ntext\n\nvery binary\n\n', eval("getreg('*', 1, 0)"))
+ eq({'some\ntext', '\nvery binary\n'}, eval("getreg('*', 1, 1)"))
+ end)
+
+ it('support autodectection of regtype', function()
+ execute("let g:test_clip['*'] = ['linewise stuff','']")
+ execute("let g:test_clip['+'] = ['charwise','stuff']")
+ eq("V", eval("getregtype('*')"))
+ eq("v", eval("getregtype('+')"))
+ insert("just some text")
+ feed('"*p"+p')
+ expect([[
+ just some text
+ lcharwise
+ stuffinewise stuff]])
end)
it('support blockwise operations', function()
@@ -115,6 +132,11 @@ describe('clipboard usage', function()
very much
blocktext]])
eq("\0225", eval("getregtype('*')"))
+ feed('gg4l<c-v>j4l"+ygg"+P')
+ expect([[
+ muchvery much
+ ktextblocktext]])
+ eq({{' much', 'ktext', ''}, 'b'}, eval("g:test_clip['+']"))
end)
it('supports setreg', function()
@@ -126,13 +148,20 @@ describe('clipboard usage', function()
textxplicitly
lines
]])
+ execute('call setreg("+", "blocky\\nindeed", "b")')
+ feed('"+p')
+ expect([[
+ esblockyetted
+ teindeedxtxplicitly
+ lines
+ ]])
end)
it('supports let @+ (issue #1427)', function()
execute("let @+ = 'some'")
execute("let @* = ' other stuff'")
- eq({'some'}, eval("g:test_clip['+']"))
- eq({' other stuff'}, eval("g:test_clip['*']"))
+ eq({{'some'}, 'v'}, eval("g:test_clip['+']"))
+ eq({{' other stuff'}, 'v'}, eval("g:test_clip['*']"))
feed('"+p"*p')
expect('some other stuff')
execute("let @+ .= ' more'")
@@ -151,7 +180,7 @@ describe('clipboard usage', function()
insert("some words")
feed('^"*dwdw"*P')
expect('words')
- eq({'words'}, eval("g:test_clip['*']"))
+ eq({{'words'}, 'v'}, eval("g:test_clip['*']"))
execute("let g:test_clip['*'] = ['linewise stuff','']")
feed('p')