aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/autoload/provider/clipboard.vim4
-rw-r--r--src/nvim/ops.c64
2 files changed, 65 insertions, 3 deletions
diff --git a/runtime/autoload/provider/clipboard.vim b/runtime/autoload/provider/clipboard.vim
index 04a3068360..458ef6257d 100644
--- a/runtime/autoload/provider/clipboard.vim
+++ b/runtime/autoload/provider/clipboard.vim
@@ -5,7 +5,7 @@ let s:copy = {}
let s:paste = {}
function! s:try_cmd(cmd, ...)
- let out = a:0 ? systemlist(a:cmd, a:1) : systemlist(a:cmd)
+ let out = a:0 ? systemlist(a:cmd, a:1, 1) : systemlist(a:cmd, [''], 1)
if v:shell_error
echo "clipboard: error: ".(len(out) ? out[0] : '')
return ''
@@ -39,7 +39,7 @@ function! s:clipboard.get(reg)
return s:try_cmd(s:paste[a:reg])
endfunction
-function! s:clipboard.set(lines, reg)
+function! s:clipboard.set(lines, regtype, reg)
call s:try_cmd(s:copy[a:reg], a:lines)
endfunction
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 8dfb986714..8a174c2a9e 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -5255,7 +5255,35 @@ static void get_clipboard(int name)
goto err;
}
- list_T *lines = result.vval.v_list;
+ list_T *res = result.vval.v_list, *lines = NULL;
+ if (res->lv_len == 2 && res->lv_first->li_tv.v_type == VAR_LIST) {
+ lines = res->lv_first->li_tv.vval.v_list;
+ if (res->lv_last->li_tv.v_type != VAR_STRING) {
+ goto err;
+ }
+ char_u* regtype = res->lv_last->li_tv.vval.v_string;
+ if (regtype == NULL || strlen((char*)regtype) != 1) {
+ goto err;
+ }
+ switch (regtype[0]) {
+ case 'v': case 'c':
+ reg->y_type = MCHAR;
+ break;
+ case 'V': case 'l':
+ reg->y_type = MLINE;
+ break;
+ case 'b': case Ctrl_V:
+ reg->y_type = MBLOCK;
+ break;
+ default:
+ goto err;
+ }
+ } else {
+ lines = res;
+ // provider did not specify regtype, calculate it below
+ reg->y_type = MAUTO;
+ }
+
reg->y_array = xcalloc(lines->lv_len, sizeof(uint8_t *));
reg->y_size = lines->lv_len;
@@ -5267,6 +5295,25 @@ static void get_clipboard(int name)
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;
+ free(reg->y_array[reg->y_size-1]);
+ reg->y_size--;
+ } else {
+ reg->y_type = MCHAR;
+ }
+ } else if (reg->y_type == MBLOCK) {
+ int maxlen = 0;
+ for (int i = 0; i < reg->y_size; i++) {
+ int rowlen = STRLEN(reg->y_array[i]);
+ if (rowlen > maxlen) {
+ maxlen = rowlen;
+ }
+ }
+ reg->y_width = maxlen-1;
+ }
+
if (!name && p_unc) {
// copy to the unnamed register
copy_register(&y_regs[0], reg);
@@ -5310,6 +5357,21 @@ static void set_clipboard(int name)
list_T *args = list_alloc();
list_append_list(args, lines);
+ char_u regtype;
+ switch (reg->y_type) {
+ case MLINE:
+ regtype = 'V';
+ list_append_string(lines, (char_u*)"", 0);
+ break;
+ case MCHAR:
+ regtype = 'v';
+ break;
+ case MBLOCK:
+ regtype = 'b';
+ break;
+ }
+ list_append_string(args, &regtype, 1);
+
char_u regname = (char_u)name;
list_append_string(args, &regname, 1);