aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ops.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/ops.c')
-rw-r--r--src/nvim/ops.c142
1 files changed, 82 insertions, 60 deletions
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 5921e27282..85b1244fa3 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -79,7 +79,7 @@ static struct yankreg {
} y_regs[NUM_REGISTERS];
static struct yankreg *y_current; /* ptr to current yankreg */
-static int y_append; /* TRUE when appending */
+static bool y_append; /* true when appending */
static struct yankreg *y_previous = NULL; /* ptr to last written yankreg */
static bool clipboard_didwarn_unnamed = false;
@@ -278,7 +278,7 @@ shift_line (
{
int count;
int i, j;
- int p_sw = (int)get_sw_value(curbuf);
+ int p_sw = get_sw_value(curbuf);
count = get_indent(); /* get current indent */
@@ -321,7 +321,7 @@ static void shift_block(oparg_T *oap, int amount)
int total;
char_u *newp, *oldp;
int oldcol = curwin->w_cursor.col;
- int p_sw = (int)get_sw_value(curbuf);
+ int p_sw = get_sw_value(curbuf);
int p_ts = (int)curbuf->b_p_ts;
struct block_def bd;
int incr;
@@ -668,7 +668,7 @@ int get_expr_register(void)
if (new_line == NULL)
return NUL;
if (*new_line == NUL) /* use previous line */
- free(new_line);
+ xfree(new_line);
else
set_expr_line(new_line);
return '=';
@@ -680,7 +680,7 @@ int get_expr_register(void)
*/
void set_expr_line(char_u *new_line)
{
- free(expr_line);
+ xfree(expr_line);
expr_line = new_line;
}
@@ -709,7 +709,7 @@ char_u *get_expr_line(void)
++nested;
rv = eval_to_string(expr_copy, NULL, TRUE);
--nested;
- free(expr_copy);
+ xfree(expr_copy);
return rv;
}
@@ -773,36 +773,35 @@ typedef enum {
/// Obtain the location that would be read when pasting `regname`.
void get_yank_register(int regname, int mode)
{
- int i;
+ y_append = false;
- y_append = FALSE;
- int unnamedclip = cb_flags & CB_UNNAMEDMASK;
- if ((regname == 0 || regname == '"') && !unnamedclip && mode != YREG_YANK && y_previous != NULL) {
+ if (mode == YREG_PASTE && get_clipboard(regname, &y_current, false)) {
+ // y_current is set to clipboard contents.
+ return;
+ } else if (mode != YREG_YANK && (regname == 0 || regname == '"') && y_previous != NULL) {
y_current = y_previous;
return;
}
- i = regname;
- if (VIM_ISDIGIT(i))
- i -= '0';
- else if (ASCII_ISLOWER(i))
- i = CharOrdLow(i) + 10;
- else if (ASCII_ISUPPER(i)) {
- i = CharOrdUp(i) + 10;
- y_append = TRUE;
+
+ int i = 0; // when not 0-9, a-z, A-Z or '-'/'+'/'*': use register 0
+ if (VIM_ISDIGIT(regname))
+ i = regname - '0';
+ else if (ASCII_ISLOWER(regname))
+ i = CharOrdLow(regname) + 10;
+ else if (ASCII_ISUPPER(regname)) {
+ i = CharOrdUp(regname) + 10;
+ y_append = true;
} else if (regname == '-')
i = DELETION_REGISTER;
else if (regname == '*')
i = STAR_REGISTER;
else if (regname == '+')
i = PLUS_REGISTER;
- else /* not 0-9, a-z, A-Z or '-': use register 0 */
- i = 0;
y_current = &(y_regs[i]);
+
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);
}
}
@@ -844,7 +843,7 @@ void put_register(int name, void *reg)
get_yank_register(name, YREG_PUT);
free_yank_all();
*y_current = *(struct yankreg *)reg;
- free(reg);
+ xfree(reg);
set_clipboard(name);
}
@@ -924,11 +923,11 @@ static int stuff_yank(int regname, char_u *p)
{
/* check for read-only register */
if (regname != 0 && !valid_yank_reg(regname, TRUE)) {
- free(p);
+ xfree(p);
return FAIL;
}
if (regname == '_') { /* black hole: don't do anything */
- free(p);
+ xfree(p);
return OK;
}
get_yank_register(regname, YREG_YANK);
@@ -938,8 +937,8 @@ static int stuff_yank(int regname, char_u *p)
STRCPY(lp, *pp);
// TODO(philix): use xstpcpy() in stuff_yank()
STRCAT(lp, p);
- free(p);
- free(*pp);
+ xfree(p);
+ xfree(*pp);
*pp = lp;
} else {
free_yank_all();
@@ -993,7 +992,7 @@ do_execreg (
EMSG(_(e_nolastcmd));
return FAIL;
}
- free(new_last_cmdline); /* don't keep the cmdline containing @: */
+ xfree(new_last_cmdline); /* don't keep the cmdline containing @: */
new_last_cmdline = NULL;
/* Escape all control characters with a CTRL-V */
p = vim_strsave_escaped_ext(
@@ -1007,13 +1006,13 @@ do_execreg (
retval = put_in_typebuf(p + 5, TRUE, TRUE, silent);
else
retval = put_in_typebuf(p, TRUE, TRUE, silent);
- free(p);
+ xfree(p);
} else if (regname == '=') {
p = get_expr_line();
if (p == NULL)
return FAIL;
retval = put_in_typebuf(p, TRUE, colon, silent);
- free(p);
+ xfree(p);
} else if (regname == '.') { /* use last inserted text */
p = get_last_insert_save();
if (p == NULL) {
@@ -1021,7 +1020,7 @@ do_execreg (
return FAIL;
}
retval = put_in_typebuf(p, FALSE, colon, silent);
- free(p);
+ xfree(p);
} else {
get_yank_register(regname, YREG_PASTE);
if (y_current->y_array == NULL)
@@ -1045,7 +1044,7 @@ do_execreg (
}
escaped = vim_strsave_escape_csi(y_current->y_array[i]);
retval = ins_typebuf(escaped, remap, 0, TRUE, silent);
- free(escaped);
+ xfree(escaped);
if (retval == FAIL)
return FAIL;
if (colon && ins_typebuf((char_u *)":", remap, 0, TRUE, silent)
@@ -1111,7 +1110,7 @@ put_in_typebuf (
retval = ins_typebuf(p, esc ? REMAP_NONE : REMAP_YES,
0, TRUE, silent);
if (esc)
- free(p);
+ xfree(p);
}
if (colon && retval == OK)
retval = ins_typebuf((char_u *)":", REMAP_NONE, 0, TRUE, silent);
@@ -1155,7 +1154,7 @@ insert_reg (
return FAIL;
stuffescaped(arg, literally);
if (allocated)
- free(arg);
+ xfree(arg);
} else { /* name or number register */
get_yank_register(regname, YREG_PASTE);
if (y_current->y_array == NULL)
@@ -1805,7 +1804,7 @@ int op_replace(oparg_T *oap, int c)
ml_append(curwin->w_cursor.lnum++, after_p, 0, FALSE);
appended_lines_mark(curwin->w_cursor.lnum, 1L);
oap->end.lnum++;
- free(after_p);
+ xfree(after_p);
}
}
} else {
@@ -2187,7 +2186,7 @@ void op_insert(oparg_T *oap, long count1)
curwin->w_cursor.col = oap->start.col;
check_cursor();
- free(ins_text);
+ xfree(ins_text);
}
}
}
@@ -2300,7 +2299,7 @@ int op_change(oparg_T *oap)
}
check_cursor();
changed_lines(oap->start.lnum + 1, 0, oap->end.lnum + 1, 0L);
- free(ins_text);
+ xfree(ins_text);
}
}
@@ -2342,9 +2341,9 @@ static void free_yank(long n)
long i;
for (i = n; --i >= 0; ) {
- free(y_current->y_array[i]);
+ xfree(y_current->y_array[i]);
}
- free(y_current->y_array);
+ xfree(y_current->y_array);
y_current->y_array = NULL;
}
}
@@ -2508,7 +2507,7 @@ int op_yank(oparg_T *oap, int deleting, int mess)
new_ptr = xmalloc(sizeof(char_u *) * (curr->y_size + y_current->y_size));
for (j = 0; j < curr->y_size; ++j)
new_ptr[j] = curr->y_array[j];
- free(curr->y_array);
+ xfree(curr->y_array);
curr->y_array = new_ptr;
if (yanktype == MLINE) /* MLINE overrides MCHAR and MBLOCK */
@@ -2521,8 +2520,8 @@ int op_yank(oparg_T *oap, int deleting, int mess)
+ STRLEN(y_current->y_array[0]) + 1);
STRCPY(pnew, curr->y_array[--j]);
STRCAT(pnew, y_current->y_array[0]);
- free(curr->y_array[j]);
- free(y_current->y_array[0]);
+ xfree(curr->y_array[j]);
+ xfree(y_current->y_array[0]);
curr->y_array[j++] = pnew;
y_idx = 1;
} else
@@ -2530,7 +2529,7 @@ int op_yank(oparg_T *oap, int deleting, int mess)
while (y_idx < y_current->y_size)
curr->y_array[j++] = y_current->y_array[y_idx++];
curr->y_size = j;
- free(y_current->y_array);
+ xfree(y_current->y_array);
y_current = curr;
}
if (curwin->w_p_rnu) {
@@ -2736,7 +2735,7 @@ do_put (
goto end;
ptr = vim_strsave(get_cursor_pos_ptr());
ml_append(curwin->w_cursor.lnum, ptr, (colnr_T)0, FALSE);
- free(ptr);
+ xfree(ptr);
ptr = vim_strnsave(get_cursor_line_ptr(), curwin->w_cursor.col);
ml_replace(curwin->w_cursor.lnum, ptr, FALSE);
@@ -3050,7 +3049,7 @@ do_put (
STRCAT(newp, ptr);
/* insert second line */
ml_append(lnum, newp, (colnr_T)0, FALSE);
- free(newp);
+ xfree(newp);
oldp = ml_get(lnum);
newp = (char_u *) xmalloc((size_t)(col + yanklen + 1));
@@ -3155,9 +3154,9 @@ error:
end:
if (allocated)
- free(insert_string);
+ xfree(insert_string);
if (regname == '=')
- free(y_array);
+ xfree(y_array);
VIsual_active = FALSE;
@@ -3619,9 +3618,9 @@ int do_join(long count,
curwin->w_set_curswant = TRUE;
theend:
- free(spaces);
+ xfree(spaces);
if (remove_comments)
- free(comments);
+ xfree(comments);
return ret;
}
@@ -3682,7 +3681,7 @@ static int same_leader(linenr_T lnum, int leader1_len, char_u *leader1_flags, in
while (vim_iswhite(line1[idx1]))
++idx1;
}
- free(line1);
+ xfree(line1);
return idx2 == leader2_len && idx1 == leader1_len;
}
@@ -4480,7 +4479,7 @@ int do_addsub(int command, linenr_T Prenum1)
*ptr = NUL;
STRCAT(buf1, buf2);
ins_str(buf1); /* insert the new number */
- free(buf1);
+ xfree(buf1);
}
--curwin->w_cursor.col;
curwin->w_set_curswant = TRUE;
@@ -4557,7 +4556,7 @@ int read_viminfo_register(vir_T *virp, int force)
if (do_it) {
if (size == 0) {
- free(array);
+ xfree(array);
} else if (size < limit) {
y_current->y_array = xrealloc(array, size * sizeof(char_u *));
} else {
@@ -5019,7 +5018,7 @@ static void str_to_reg(struct yankreg *y_ptr, int yank_type, const char_u *str,
ssize_t s_len = extra + line_len;
if (append) {
- free(pp[lnum]);
+ xfree(pp[lnum]);
append = false; // only first line is appended
}
pp[lnum] = s;
@@ -5310,7 +5309,28 @@ static void free_register(struct yankreg *reg)
y_current = curr;
}
-// return target register
+/// Check if the default register (used in an unnamed paste) should be a
+/// clipboard register. This happens when `clipboard=unnamed[plus]` is set
+/// and a provider is available.
+///
+/// @returns the name of of a clipboard register that should be used, or `NUL` if none.
+int get_default_register_name(void)
+{
+ int name = NUL;
+ adjust_clipboard_name(&name, true, false);
+ return name;
+}
+
+/// Determine if register `*name` should be used as a clipboard.
+/// In an unnammed operation, `*name` is `NUL` and will be adjusted to `'*'/'+'` if
+/// `clipboard=unnamed[plus]` is set.
+///
+/// @param name The name of register, or `NUL` if unnamed.
+/// @param quiet Suppress error messages
+/// @param writing if we're setting the contents of the clipboard
+///
+/// @returns the yankreg that should be used, or `NULL`
+/// if the register isn't a clipboard or provider isn't available.
static struct yankreg* adjust_clipboard_name(int *name, bool quiet, bool writing) {
if (*name == '*' || *name == '+') {
if(!eval_has_provider("clipboard")) {
@@ -5345,11 +5365,11 @@ static struct yankreg* adjust_clipboard_name(int *name, bool quiet, bool writing
return NULL;
}
-static void get_clipboard(int name, struct yankreg** target, bool quiet)
+static bool get_clipboard(int name, struct yankreg** target, bool quiet)
{
struct yankreg* reg = adjust_clipboard_name(&name, quiet, false);
if (reg == NULL) {
- return;
+ return false;
}
free_register(reg);
@@ -5410,7 +5430,7 @@ static void get_clipboard(int name, struct yankreg** target, bool quiet)
// 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]);
+ xfree(reg->y_array[reg->y_size-1]);
reg->y_size--;
if (reg->y_type == MAUTO) {
reg->y_type = MLINE;
@@ -5434,18 +5454,20 @@ static void get_clipboard(int name, struct yankreg** target, bool quiet)
}
*target = reg;
- return;
+ return true;
err:
if (reg->y_array) {
for (int i = 0; i < reg->y_size; i++) {
- free(reg->y_array[i]);
+ xfree(reg->y_array[i]);
}
- free(reg->y_array);
+ xfree(reg->y_array);
}
reg->y_array = NULL;
reg->y_size = 0;
EMSG("clipboard: provider returned invalid data");
+ *target = reg;
+ return false;
}
static void set_clipboard(int name)