aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Linse <bjorn.linse@gmail.com>2015-03-28 20:57:06 +0100
committerBjörn Linse <bjorn.linse@gmail.com>2015-04-05 11:34:13 +0200
commit7422843f5c86b0dc18e26e5a2436f9d8e7013e12 (patch)
treef9550d3dbb463e8bcc8482151d02822a1cb0538d
parent34dba3d7cd43b4797d60f636dc9c7c3040a56f3c (diff)
downloadrneovim-7422843f5c86b0dc18e26e5a2436f9d8e7013e12.tar.gz
rneovim-7422843f5c86b0dc18e26e5a2436f9d8e7013e12.tar.bz2
rneovim-7422843f5c86b0dc18e26e5a2436f9d8e7013e12.zip
clipboard: improve the handling of newlines in `get_clipboard`
This makes the interpretion consistent with the way newlines are used in the VIMENC format, while keeping the same fallback behaviour when regtype is unspecified. Also check both cases explicitly in the tests.
-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')