diff options
Diffstat (limited to 'src/nvim/ops.c')
-rw-r--r-- | src/nvim/ops.c | 195 |
1 files changed, 124 insertions, 71 deletions
diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 2bc92ce295..b8b639265c 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -267,14 +267,14 @@ void op_shift(oparg_T *oap, int curs_top, int amount) msg_attr_keep((char *)IObuff, 0, true, false); } - /* - * Set "'[" and "']" marks. - */ - curbuf->b_op_start = oap->start; - curbuf->b_op_end.lnum = oap->end.lnum; - curbuf->b_op_end.col = (colnr_T)STRLEN(ml_get(oap->end.lnum)); - if (curbuf->b_op_end.col > 0) { - curbuf->b_op_end.col--; + if (!cmdmod.lockmarks) { + // Set "'[" and "']" marks. + curbuf->b_op_start = oap->start; + curbuf->b_op_end.lnum = oap->end.lnum; + curbuf->b_op_end.col = (colnr_T)STRLEN(ml_get(oap->end.lnum)); + if (curbuf->b_op_end.col > 0) { + curbuf->b_op_end.col--; + } } changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L, true); @@ -381,8 +381,8 @@ static void shift_block(oparg_T *oap, int amount) } } for (; ascii_iswhite(*bd.textstart);) { - // TODO: is passing bd.textstart for start of the line OK? - incr = lbr_chartabsize_adv(bd.textstart, &bd.textstart, (bd.start_vcol)); + // TODO(fmoralesc): is passing bd.textstart for start of the line OK? + incr = lbr_chartabsize_adv(bd.textstart, &bd.textstart, bd.start_vcol); total += incr; bd.start_vcol += incr; } @@ -694,9 +694,11 @@ void op_reindent(oparg_T *oap, Indenter how) "%" PRId64 " lines indented ", i), (int64_t)i); } - // set '[ and '] marks - curbuf->b_op_start = oap->start; - curbuf->b_op_end = oap->end; + if (!cmdmod.lockmarks) { + // set '[ and '] marks + curbuf->b_op_start = oap->start; + curbuf->b_op_end = oap->end; + } } /* @@ -1435,6 +1437,11 @@ int op_delete(oparg_T *oap) return FAIL; } + if (VIsual_select && oap->is_VIsual) { + // Use the register given with CTRL_R, defaults to zero + oap->regname = VIsual_select_reg; + } + mb_adjust_opend(oap); /* @@ -1731,13 +1738,15 @@ int op_delete(oparg_T *oap) msgmore(curbuf->b_ml.ml_line_count - old_lcount); setmarks: - if (oap->motion_type == kMTBlockWise) { - curbuf->b_op_end.lnum = oap->end.lnum; - curbuf->b_op_end.col = oap->start.col; - } else { - curbuf->b_op_end = oap->start; + if (!cmdmod.lockmarks) { + if (oap->motion_type == kMTBlockWise) { + curbuf->b_op_end.lnum = oap->end.lnum; + curbuf->b_op_end.col = oap->start.col; + } else { + curbuf->b_op_end = oap->start; + } + curbuf->b_op_start = oap->start; } - curbuf->b_op_start = oap->start; return OK; } @@ -2002,9 +2011,11 @@ static int op_replace(oparg_T *oap, int c) check_cursor(); changed_lines(oap->start.lnum, oap->start.col, oap->end.lnum + 1, 0L, true); - // Set "'[" and "']" marks. - curbuf->b_op_start = oap->start; - curbuf->b_op_end = oap->end; + if (!cmdmod.lockmarks) { + // Set "'[" and "']" marks. + curbuf->b_op_start = oap->start; + curbuf->b_op_end = oap->end; + } return OK; } @@ -2073,11 +2084,11 @@ void op_tilde(oparg_T *oap) redraw_curbuf_later(INVERTED); } - /* - * Set '[ and '] marks. - */ - curbuf->b_op_start = oap->start; - curbuf->b_op_end = oap->end; + if (!cmdmod.lockmarks) { + // Set '[ and '] marks. + curbuf->b_op_start = oap->start; + curbuf->b_op_end = oap->end; + } if (oap->line_count > p_report) { smsg(NGETTEXT("%" PRId64 " line changed", @@ -2196,19 +2207,22 @@ void op_insert(oparg_T *oap, long count1) // doing block_prep(). When only "block" is used, virtual edit is // already disabled, but still need it when calling // coladvance_force(). + // coladvance_force() uses get_ve_flags() to get the 'virtualedit' + // state for the current window. To override that state, we need to + // set the window-local value of ve_flags rather than the global value. if (curwin->w_cursor.coladd > 0) { - unsigned old_ve_flags = ve_flags; + unsigned old_ve_flags = curwin->w_ve_flags; - ve_flags = VE_ALL; if (u_save_cursor() == FAIL) { return; } + curwin->w_ve_flags = VE_ALL; coladvance_force(oap->op_type == OP_APPEND ? oap->end_vcol + 1 : getviscol()); if (oap->op_type == OP_APPEND) { --curwin->w_cursor.col; } - ve_flags = old_ve_flags; + curwin->w_ve_flags = old_ve_flags; } // Get the info about the block before entering the text block_prep(oap, &bd, oap->start.lnum, true); @@ -2766,17 +2780,15 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) } } - /* - * Set "'[" and "']" marks. - */ - curbuf->b_op_start = oap->start; - curbuf->b_op_end = oap->end; - if (yank_type == kMTLineWise) { - curbuf->b_op_start.col = 0; - curbuf->b_op_end.col = MAXCOL; + if (!cmdmod.lockmarks) { + // Set "'[" and "']" marks. + curbuf->b_op_start = oap->start; + curbuf->b_op_end = oap->end; + if (yank_type == kMTLineWise) { + curbuf->b_op_start.col = 0; + curbuf->b_op_end.col = MAXCOL; + } } - - return; } // Copy a block range into a register. @@ -2801,7 +2813,7 @@ static void yank_copy_line(yankreg_T *reg, struct block_def *bd, size_t y_idx, if (exclude_trailing_space) { int s = bd->textlen + bd->endspaces; - while (ascii_iswhite(*(bd->textstart + s - 1)) && s > 0) { + while (s > 0 && ascii_iswhite(*(bd->textstart + s - 1))) { s = s - utf_head_off(bd->textstart, bd->textstart + s - 1) - 1; pnew--; } @@ -2906,6 +2918,9 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) char_u *insert_string = NULL; bool allocated = false; long cnt; + const pos_T orig_start = curbuf->b_op_start; + const pos_T orig_end = curbuf->b_op_end; + unsigned int cur_ve_flags = get_ve_flags(); if (flags & PUT_FIXINDENT) { orig_indent = get_indent(); @@ -2976,7 +2991,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) eol = (*(cursor_pos + utfc_ptr2len(cursor_pos)) == NUL); } - bool ve_allows = (ve_flags == VE_ALL || ve_flags == VE_ONEMORE); + bool ve_allows = (cur_ve_flags == VE_ALL || cur_ve_flags == VE_ONEMORE); bool eof = curbuf->b_ml.ml_line_count == curwin->w_cursor.lnum && one_past_line; if (ve_allows || !(eol || eof)) { @@ -3152,7 +3167,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) yanklen = (int)STRLEN(y_array[0]); - if (ve_flags == VE_ALL && y_type == kMTCharWise) { + if (cur_ve_flags == VE_ALL && y_type == kMTCharWise) { if (gchar_cursor() == TAB) { int viscol = getviscol(); long ts = curbuf->b_p_ts; @@ -3181,7 +3196,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) colnr_T endcol2 = 0; if (dir == FORWARD && c != NUL) { - if (ve_flags == VE_ALL) { + if (cur_ve_flags == VE_ALL) { getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2); } else { getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col); @@ -3195,9 +3210,8 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) } col += curwin->w_cursor.coladd; - if (ve_flags == VE_ALL - && (curwin->w_cursor.coladd > 0 - || endcol2 == curwin->w_cursor.col)) { + if (cur_ve_flags == VE_ALL + && (curwin->w_cursor.coladd > 0 || endcol2 == curwin->w_cursor.col)) { if (dir == FORWARD && c == NUL) { col++; } @@ -3456,6 +3470,9 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) curwin->w_cursor.col -= first_byte_off; } } else { + linenr_T new_lnum = new_cursor.lnum; + size_t len; + // Insert at least one line. When y_type is kMTCharWise, break the first // line in two. for (cnt = 1; cnt <= count; cnt++) { @@ -3472,6 +3489,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) STRCAT(newp, ptr); // insert second line ml_append(lnum, newp, (colnr_T)0, false); + new_lnum++; xfree(newp); oldp = ml_get(lnum); @@ -3487,10 +3505,11 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) } for (; i < y_size; i++) { - if ((y_type != kMTCharWise || i < y_size - 1) - && ml_append(lnum, y_array[i], (colnr_T)0, false) - == FAIL) { - goto error; + if ((y_type != kMTCharWise || i < y_size - 1)) { + if (ml_append(lnum, y_array[i], (colnr_T)0, false) == FAIL) { + goto error; + } + new_lnum++; } lnum++; ++nr_lines; @@ -3540,6 +3559,10 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) extmark_splice(curbuf, (int)new_cursor.lnum-1, col + 1, 0, 0, 0, (int)y_size+1, 0, totsize+2, kExtmarkUndo); } + + if (cnt == 1) { + new_lnum = lnum; + } } error: @@ -3567,11 +3590,12 @@ error: // Put the '] mark on the first byte of the last inserted character. // Correct the length for change in indent. - curbuf->b_op_end.lnum = lnum; - col = (colnr_T)STRLEN(y_array[y_size - 1]) - lendiff; + curbuf->b_op_end.lnum = new_lnum; + len = STRLEN(y_array[y_size - 1]); + col = (colnr_T)len - lendiff; if (col > 1) { curbuf->b_op_end.col = col - 1 - utf_head_off(y_array[y_size - 1], - y_array[y_size - 1] + col - 1); + y_array[y_size - 1] + len - 1); } else { curbuf->b_op_end.col = 0; } @@ -3590,8 +3614,12 @@ error: } curwin->w_cursor.col = 0; } else { - curwin->w_cursor.lnum = lnum; + curwin->w_cursor.lnum = new_lnum; curwin->w_cursor.col = col; + curbuf->b_op_end = curwin->w_cursor; + if (col > 1) { + curbuf->b_op_end.col = col - 1; + } } } else if (y_type == kMTLineWise) { // put cursor on first non-blank in first inserted line @@ -3610,6 +3638,10 @@ error: curwin->w_set_curswant = TRUE; end: + if (cmdmod.lockmarks) { + curbuf->b_op_start = orig_start; + curbuf->b_op_end = orig_end; + } if (allocated) { xfree(insert_string); } @@ -3629,14 +3661,16 @@ end: */ void adjust_cursor_eol(void) { + unsigned int cur_ve_flags = get_ve_flags(); + if (curwin->w_cursor.col > 0 && gchar_cursor() == NUL - && (ve_flags & VE_ONEMORE) == 0 + && (cur_ve_flags & VE_ONEMORE) == 0 && !(restart_edit || (State & INSERT))) { // Put the cursor on the last character in the line. dec_cursor(); - if (ve_flags == VE_ALL) { + if (cur_ve_flags == VE_ALL) { colnr_T scol, ecol; // Coladd is set to the width of the last character. @@ -3954,7 +3988,7 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions // and setup the array of space strings lengths for (t = 0; t < (linenr_T)count; t++) { curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t)); - if (t == 0 && setmark) { + if (t == 0 && setmark && !cmdmod.lockmarks) { // Set the '[ mark. curwin->w_buffer->b_op_start.lnum = curwin->w_cursor.lnum; curwin->w_buffer->b_op_start.col = (colnr_T)STRLEN(curr); @@ -4075,7 +4109,7 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions ml_replace(curwin->w_cursor.lnum, newp, false); - if (setmark) { + if (setmark && !cmdmod.lockmarks) { // Set the '] mark. curwin->w_buffer->b_op_end.lnum = curwin->w_cursor.lnum; curwin->w_buffer->b_op_end.col = sumsize; @@ -4213,8 +4247,10 @@ static void op_format(oparg_T *oap, int keep_cursor) redraw_curbuf_later(INVERTED); } - // Set '[ mark at the start of the formatted area - curbuf->b_op_start = oap->start; + if (!cmdmod.lockmarks) { + // Set '[ mark at the start of the formatted area + curbuf->b_op_start = oap->start; + } // For "gw" remember the cursor position and put it back below (adjusted // for joined and split lines). @@ -4236,8 +4272,10 @@ static void op_format(oparg_T *oap, int keep_cursor) old_line_count = curbuf->b_ml.ml_line_count - old_line_count; msgmore(old_line_count); - // put '] mark on the end of the formatted area - curbuf->b_op_end = curwin->w_cursor; + if (!cmdmod.lockmarks) { + // put '] mark on the end of the formatted area + curbuf->b_op_end = curwin->w_cursor; + } if (keep_cursor) { curwin->w_cursor = saved_cursor; @@ -4324,7 +4362,7 @@ void format_lines(linenr_T line_count, int avoid_fex) int leader_len = 0; // leader len of current line int next_leader_len; // leader len of next line char_u *leader_flags = NULL; // flags for leader of current line - char_u *next_leader_flags; // flags for leader of next line + char_u *next_leader_flags = NULL; // flags for leader of next line bool advance = true; int second_indent = -1; // indent for second line (comment aware) bool first_par_line = true; @@ -4441,7 +4479,14 @@ void format_lines(linenr_T line_count, int avoid_fex) leader_len, leader_flags, next_leader_len, next_leader_flags)) { - is_end_par = true; + // Special case: If the next line starts with a line comment + // and this line has a line comment after some text, the + // paragraph doesn't really end. + if (next_leader_flags == NULL + || STRNCMP(next_leader_flags, "://", 3) != 0 + || check_linecomment(get_cursor_line_ptr()) == MAXCOL) { + is_end_par = true; + } } /* @@ -4835,7 +4880,7 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd) // Set '[ mark if something changed. Keep the last end // position from do_addsub(). - if (change_cnt > 0) { + if (change_cnt > 0 && !cmdmod.lockmarks) { curbuf->b_op_start = startpos; } @@ -5189,11 +5234,13 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) } } - // set the '[ and '] marks - curbuf->b_op_start = startpos; - curbuf->b_op_end = endpos; - if (curbuf->b_op_end.col > 0) { - curbuf->b_op_end.col--; + if (!cmdmod.lockmarks) { + // set the '[ and '] marks + curbuf->b_op_start = startpos; + curbuf->b_op_end = endpos; + if (curbuf->b_op_end.col > 0) { + curbuf->b_op_end.col--; + } } theend: @@ -6006,6 +6053,8 @@ static void op_function(const oparg_T *oap) { const TriState save_virtual_op = virtual_op; const bool save_finish_op = finish_op; + const pos_T orig_start = curbuf->b_op_start; + const pos_T orig_end = curbuf->b_op_end; if (*p_opfunc == NUL) { emsg(_("E774: 'operatorfunc' is empty")); @@ -6039,6 +6088,10 @@ static void op_function(const oparg_T *oap) virtual_op = save_virtual_op; finish_op = save_finish_op; + if (cmdmod.lockmarks) { + curbuf->b_op_start = orig_start; + curbuf->b_op_end = orig_end; + } } } |