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.c57
1 files changed, 38 insertions, 19 deletions
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 99dee939fc..216bab4dda 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -153,6 +153,10 @@ int get_op_type(int char1, int char2)
if (opchars[i][0] == char1 && opchars[i][1] == char2) {
break;
}
+ if (i == (int)(ARRAY_SIZE(opchars) - 1)) {
+ internal_error("get_op_type()");
+ break;
+ }
}
return i;
}
@@ -1408,8 +1412,10 @@ int op_delete(oparg_T *oap)
free_register(&y_regs[9]); /* free register "9 */
for (n = 9; n > 1; n--)
y_regs[n] = y_regs[n - 1];
- y_previous = &y_regs[1];
- y_regs[1].y_array = NULL; /* set register "1 to empty */
+ if (!is_append_register(oap->regname)) {
+ y_previous = &y_regs[1];
+ }
+ y_regs[1].y_array = NULL; // set register "1 to empty
reg = &y_regs[1];
op_yank_reg(oap, false, reg, false);
}
@@ -2605,17 +2611,16 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg)
static bool recursive = false;
if (recursive || !has_event(EVENT_TEXTYANKPOST)) {
- // No autocommand was defined
- // or we yanked from this autocommand.
+ // No autocommand was defined, or we yanked from this autocommand.
return;
}
recursive = true;
- // set v:event to a dictionary with information about the yank
+ // Set the v:event dictionary with information about the yank.
dict_T *dict = get_vim_var_dict(VV_EVENT);
- // the yanked text
+ // The yanked text contents.
list_T *const list = tv_list_alloc((ptrdiff_t)reg->y_size);
for (size_t i = 0; i < reg->y_size; i++) {
tv_list_append_string(list, (const char *)reg->y_array[i], -1);
@@ -2623,17 +2628,21 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg)
tv_list_set_lock(list, VAR_FIXED);
tv_dict_add_list(dict, S_LEN("regcontents"), list);
- // the register type
+ // Register type.
char buf[NUMBUFLEN+2];
format_reg_type(reg->y_type, reg->y_width, buf, ARRAY_SIZE(buf));
tv_dict_add_str(dict, S_LEN("regtype"), buf);
- // name of requested register or the empty string for an unnamed operation.
+ // Name of requested register, or empty string for unnamed operation.
buf[0] = (char)oap->regname;
buf[1] = NUL;
tv_dict_add_str(dict, S_LEN("regname"), buf);
- // kind of operation (yank/delete/change)
+ // Motion type: inclusive or exclusive.
+ tv_dict_add_special(dict, S_LEN("inclusive"),
+ oap->inclusive ? kSpecialVarTrue : kSpecialVarFalse);
+
+ // Kind of operation: yank, delete, change).
buf[0] = (char)get_op_char(oap->op_type);
buf[1] = NUL;
tv_dict_add_str(dict, S_LEN("operator"), buf);
@@ -2786,8 +2795,8 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
}
if (!curbuf->terminal) {
- // Autocommands may be executed when saving lines for undo, which may make
- // y_array invalid. Start undo now to avoid that.
+ // Autocommands may be executed when saving lines for undo. This might
+ // make y_array invalid, so we start undo now to avoid that.
if (u_save(curwin->w_cursor.lnum, curwin->w_cursor.lnum + 1) == FAIL) {
return;
}
@@ -2992,9 +3001,10 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
/* add a new line */
if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) {
if (ml_append(curbuf->b_ml.ml_line_count, (char_u *)"",
- (colnr_T)1, FALSE) == FAIL)
+ (colnr_T)1, false) == FAIL) {
break;
- ++nr_lines;
+ }
+ nr_lines++;
}
/* get the old line and advance to the position to insert at */
oldp = get_cursor_line_ptr();
@@ -3181,8 +3191,8 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
newp = (char_u *) xmalloc((size_t)(STRLEN(ptr) + totlen + 1));
STRCPY(newp, y_array[y_size - 1]);
STRCAT(newp, ptr);
- /* insert second line */
- ml_append(lnum, newp, (colnr_T)0, FALSE);
+ // insert second line
+ ml_append(lnum, newp, (colnr_T)0, false);
xfree(newp);
oldp = ml_get(lnum);
@@ -3704,10 +3714,16 @@ int do_join(size_t count,
cend -= spaces[t];
memset(cend, ' ', (size_t)(spaces[t]));
}
+
+ // If deleting more spaces than adding, the cursor moves no more than
+ // what is added if it is inside these spaces.
+ const int spaces_removed = (int)((curr - curr_start) - spaces[t]);
+
mark_col_adjust(curwin->w_cursor.lnum + t, (colnr_T)0, (linenr_T)-t,
- (long)(cend - newp + spaces[t] - (curr - curr_start)));
- if (t == 0)
+ (long)(cend - newp - spaces_removed), spaces_removed);
+ if (t == 0) {
break;
+ }
curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t - 1));
if (remove_comments)
curr += comments[t - 1];
@@ -4135,14 +4151,14 @@ format_lines (
if (next_leader_len > 0) {
(void)del_bytes(next_leader_len, false, false);
mark_col_adjust(curwin->w_cursor.lnum, (colnr_T)0, 0L,
- (long)-next_leader_len);
+ (long)-next_leader_len, 0);
} else if (second_indent > 0) { // the "leader" for FO_Q_SECOND
int indent = (int)getwhitecols_curline();
if (indent > 0) {
(void)del_bytes(indent, FALSE, FALSE);
mark_col_adjust(curwin->w_cursor.lnum,
- (colnr_T)0, 0L, (long)-indent);
+ (colnr_T)0, 0L, (long)-indent, 0);
}
}
curwin->w_cursor.lnum--;
@@ -5601,6 +5617,9 @@ static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing)
if (explicit_cb_reg) {
target = &y_regs[*name == '*' ? STAR_REGISTER : PLUS_REGISTER];
+ if (writing && (cb_flags & (*name == '*' ? CB_UNNAMED : CB_UNNAMEDPLUS))) {
+ clipboard_needs_update = false;
+ }
goto end;
} else { // unnamed register: "implicit" clipboard
if (writing && clipboard_delay_update) {