diff options
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;    } | 
