diff options
author | Björn Linse <bjorn.linse@gmail.com> | 2015-03-29 12:39:52 +0200 |
---|---|---|
committer | Björn Linse <bjorn.linse@gmail.com> | 2015-04-05 11:34:14 +0200 |
commit | adcf268a72827be38510b1830b67b287dec50c4a (patch) | |
tree | e427da7ecc32909e3ef31f97b3bb3b146f1fad84 /src | |
parent | db92fcdba3f596838f524a049efe1c7e82bb734f (diff) | |
download | rneovim-adcf268a72827be38510b1830b67b287dec50c4a.tar.gz rneovim-adcf268a72827be38510b1830b67b287dec50c4a.tar.bz2 rneovim-adcf268a72827be38510b1830b67b287dec50c4a.zip |
clipboard: handle clipboard reading directly in `get_yank_register`
This makes :<c-r>* work as expected and
avoids clobbering zero register ("0) when pasting unnamed clipboard
Helped-By: Scott Prager <splinterofchaos@gmail.com>
Helped-By: Michael Reed <m.reed@mykolab.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/ops.c | 112 |
1 files changed, 61 insertions, 51 deletions
diff --git a/src/nvim/ops.c b/src/nvim/ops.c index f0caaad97b..572b557ad3 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -53,7 +53,7 @@ /* * Registers: - * 0 = unnamed register, for normal yanks and puts + * 0 = register for latest (unnamed) yank * 1..9 = registers '1' to '9', for deletes * 10..35 = registers 'a' to 'z' * 36 = delete register '-' @@ -68,7 +68,6 @@ #define NUM_REGISTERS 39 #define CB_UNNAMEDMASK (CB_UNNAMED | CB_UNNAMEDPLUS) -#define CB_LATEST (-1) /* * Each yank register is an array of pointers to lines. */ @@ -748,21 +747,37 @@ valid_yank_reg ( return FALSE; } -/* - * Set y_current and y_append, according to the value of "regname". - * Cannot handle the '_' register. - * Must only be called with a valid register name! - * - * If regname is 0 and writing, use register 0 - * If regname is 0 and reading, use previous register - */ -void get_yank_register(int regname, int writing) +typedef enum { + YREG_PASTE, + YREG_YANK, + YREG_PUT, +} yreg_mode_t; + +/// Set y_current and y_append, according to the value of `regname`. +/// Cannot handle the '_' (black hole) register. +/// Must only be called with a valid register name! +/// +/// @param regname The name of the register used or 0 for the unnamed register +/// @param mode One of the following three flags: +/// +/// `YREG_PASTE`: +/// Prepare for pasting the register `regname`. With no regname specified, +/// read from last written register, or from unnamed clipboard (depending on the +/// `clipboard=unnamed` option). Queries the clipboard provider if necessary. +/// +/// `YREG_YANK`: +/// Preparare for yanking into `regname`. With no regname specified, +/// yank into `"0` register. Update `y_previous` for next unnamed paste. +/// +/// `YREG_PUT`: +/// Obtain the location that would be read when pasting `regname`. +void get_yank_register(int regname, int mode) { int i; y_append = FALSE; int unnamedclip = cb_flags & CB_UNNAMEDMASK; - if ((regname == 0 || regname == '"') && !unnamedclip && !writing && y_previous != NULL) { + if ((regname == 0 || regname == '"') && !unnamedclip && mode != YREG_YANK && y_previous != NULL) { y_current = y_previous; return; } @@ -783,8 +798,12 @@ void get_yank_register(int regname, int writing) else /* not 0-9, a-z, A-Z or '-': use register 0 */ i = 0; y_current = &(y_regs[i]); - if (writing) /* remember the register we write into for do_put() */ + if (mode == YREG_YANK) { + // remember the written register for unnamed paste y_previous = y_current; + } else if (mode == YREG_PASTE) { + get_clipboard(regname, &y_current, false); + } } @@ -798,8 +817,7 @@ get_register ( int copy /* make a copy, if FALSE make register empty. */ ) FUNC_ATTR_NONNULL_RET { - get_yank_register(name, 0); - get_clipboard(name, false); + get_yank_register(name, YREG_PASTE); struct yankreg *reg = xmalloc(sizeof(struct yankreg)); *reg = *y_current; @@ -823,7 +841,7 @@ get_register ( */ void put_register(int name, void *reg) { - get_yank_register(name, 0); + get_yank_register(name, YREG_PUT); free_yank_all(); *y_current = *(struct yankreg *)reg; free(reg); @@ -839,7 +857,7 @@ int yank_register_mline(int regname) return FALSE; if (regname == '_') /* black hole is always empty */ return FALSE; - get_yank_register(regname, FALSE); + get_yank_register(regname, YREG_PASTE); return y_current->y_type == MLINE; } @@ -913,7 +931,7 @@ static int stuff_yank(int regname, char_u *p) free(p); return OK; } - get_yank_register(regname, TRUE); + get_yank_register(regname, YREG_YANK); if (y_append && y_current->y_array != NULL) { char_u **pp = &(y_current->y_array[y_current->y_size - 1]); char_u *lp = xmalloc(STRLEN(*pp) + STRLEN(p) + 1); @@ -967,8 +985,6 @@ do_execreg ( } execreg_lastc = regname; - get_clipboard(regname, false); - if (regname == '_') /* black hole: don't stuff anything */ return OK; @@ -1007,7 +1023,7 @@ do_execreg ( retval = put_in_typebuf(p, FALSE, colon, silent); free(p); } else { - get_yank_register(regname, FALSE); + get_yank_register(regname, YREG_PASTE); if (y_current->y_array == NULL) return FAIL; @@ -1132,8 +1148,6 @@ insert_reg ( if (regname != NUL && !valid_yank_reg(regname, FALSE)) return FAIL; - get_clipboard(regname, false); - if (regname == '.') /* insert last inserted text */ retval = stuff_inserted(NUL, 1L, TRUE); else if (get_spec_reg(regname, &arg, &allocated, TRUE)) { @@ -1143,7 +1157,7 @@ insert_reg ( if (allocated) free(arg); } else { /* name or number register */ - get_yank_register(regname, FALSE); + get_yank_register(regname, YREG_PASTE); if (y_current->y_array == NULL) retval = FAIL; else { @@ -1290,7 +1304,7 @@ cmdline_paste_reg ( { long i; - get_yank_register(regname, FALSE); + get_yank_register(regname, YREG_PASTE); if (y_current->y_array == NULL) return FAIL; @@ -1397,7 +1411,7 @@ int op_delete(oparg_T *oap) beep_flush(); return OK; } - get_yank_register(oap->regname, TRUE); /* yank into specif'd reg. */ + get_yank_register(oap->regname, YREG_YANK); /* yank into specif'd reg. */ if (op_yank(oap, TRUE, FALSE) == OK) /* yank without message */ did_yank = TRUE; } @@ -1423,14 +1437,14 @@ int op_delete(oparg_T *oap) if (oap->regname == 0 && oap->motion_type != MLINE && oap->line_count == 1) { oap->regname = '-'; - get_yank_register(oap->regname, TRUE); + get_yank_register(oap->regname, YREG_YANK); if (op_yank(oap, TRUE, FALSE) == OK) did_yank = TRUE; oap->regname = 0; } if(oap->regname == 0 && did_yank) { - set_clipboard(CB_LATEST); + set_clipboard(0); } /* * If there's too much stuff to fit in the yank register, then get a @@ -2372,7 +2386,7 @@ int op_yank(oparg_T *oap, int deleting, int mess) return OK; if (!deleting) /* op_delete() already set y_current */ - get_yank_register(oap->regname, TRUE); + get_yank_register(oap->regname, YREG_YANK); curr = y_current; /* append to existing contents */ @@ -2620,8 +2634,6 @@ do_put ( int allocated = FALSE; long cnt; - get_clipboard(regname, false); - if (flags & PUT_FIXINDENT) orig_indent = get_indent(); @@ -2694,7 +2706,7 @@ do_put ( y_array = &insert_string; } } else { - get_yank_register(regname, FALSE); + get_yank_register(regname, YREG_PASTE); y_type = y_current->y_type; y_width = y_current->y_width; @@ -3233,7 +3245,6 @@ void ex_display(exarg_T *eap) continue; /* did not ask for this register */ } - get_clipboard(name, true); if (i == -1) { if (y_previous != NULL) @@ -3243,6 +3254,8 @@ void ex_display(exarg_T *eap) } else yb = &(y_regs[i]); + get_clipboard(name, &yb, true); + if (name == vim_tolower(redir_reg) || (redir_reg == '"' && yb == y_previous)) continue; /* do not list register being written to, the @@ -4500,7 +4513,7 @@ int read_viminfo_register(vir_T *virp, int force) return TRUE; /* too many errors, pretend end-of-file */ do_it = FALSE; } - get_yank_register(*str++, FALSE); + get_yank_register(*str++, YREG_PUT); if (!force && y_current->y_array != NULL) do_it = FALSE; @@ -4661,12 +4674,10 @@ char_u get_reg_type(int regname, long *reglen) return MCHAR; } - get_clipboard(regname, false); - if (regname != NUL && !valid_yank_reg(regname, FALSE)) return MAUTO; - get_yank_register(regname, FALSE); + get_yank_register(regname, YREG_PASTE); if (y_current->y_array != NULL) { if (reglen != NULL && y_current->y_type == MBLOCK) @@ -4722,8 +4733,6 @@ void *get_reg_contents(int regname, int flags) if (regname != NUL && !valid_yank_reg(regname, FALSE)) return NULL; - get_clipboard(regname, false); - char_u *retval; int allocated; if (get_spec_reg(regname, &retval, &allocated, FALSE)) { @@ -4735,7 +4744,7 @@ void *get_reg_contents(int regname, int flags) return get_reg_wrap_one_line(vim_strsave(retval), flags); } - get_yank_register(regname, FALSE); + get_yank_register(regname, YREG_PASTE); if (y_current->y_array == NULL) return NULL; @@ -4796,7 +4805,7 @@ static bool init_write_reg(int name, struct yankreg **old_y_previous, *old_y_previous = y_previous; *old_y_current = y_current; - get_yank_register(name, true); + get_yank_register(name, YREG_YANK); if (!y_append && !must_append) { free_yank_all(); } @@ -5302,7 +5311,7 @@ static void free_register(struct yankreg *reg) } // return target register -static struct yankreg* adjust_clipboard_name(int *name, bool quiet) { +static struct yankreg* adjust_clipboard_name(int *name, bool quiet, bool writing) { if (*name == '*' || *name == '+') { if(!eval_has_provider("clipboard")) { if (!quiet) { @@ -5310,7 +5319,7 @@ static struct yankreg* adjust_clipboard_name(int *name, bool quiet) { } } return &y_regs[*name == '*' ? STAR_REGISTER : PLUS_REGISTER]; - } else if ((*name == NUL || *name == CB_LATEST) && (cb_flags & CB_UNNAMEDMASK)) { + } else if ((*name == NUL) && (cb_flags & CB_UNNAMEDMASK)) { if(!eval_has_provider("clipboard")) { if (!quiet && !clipboard_didwarn_unnamed) { msg((char_u*)"clipboard: provider not available, ignoring clipboard=unnamed[plus]"); @@ -5319,15 +5328,15 @@ static struct yankreg* adjust_clipboard_name(int *name, bool quiet) { return NULL; } struct yankreg* target; - if (*name == CB_LATEST) { - target = y_current; - } else { - target = &y_regs[0]; - } if (cb_flags & CB_UNNAMEDPLUS) { *name = '+'; + target = &y_regs[STAR_REGISTER]; } else { *name = '*'; + target = &y_regs[PLUS_REGISTER]; + } + if (writing) { + target = y_current; } return target; // unnamed register } @@ -5335,9 +5344,9 @@ static struct yankreg* adjust_clipboard_name(int *name, bool quiet) { return NULL; } -static void get_clipboard(int name, bool quiet) +static void get_clipboard(int name, struct yankreg** target, bool quiet) { - struct yankreg* reg = adjust_clipboard_name(&name, quiet); + struct yankreg* reg = adjust_clipboard_name(&name, quiet, false); if (reg == NULL) { return; } @@ -5423,6 +5432,7 @@ static void get_clipboard(int name, bool quiet) reg->y_width = maxlen-1; } + *target = reg; return; err: @@ -5439,7 +5449,7 @@ err: static void set_clipboard(int name) { - struct yankreg* reg = adjust_clipboard_name(&name, false); + struct yankreg* reg = adjust_clipboard_name(&name, false, true); if (reg == NULL) { return; } |