diff options
Diffstat (limited to 'src/nvim/ops.c')
-rw-r--r-- | src/nvim/ops.c | 215 |
1 files changed, 74 insertions, 141 deletions
diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 6233e446e0..4b8382c971 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -24,6 +24,7 @@ #include "nvim/cursor.h" #include "nvim/drawscreen.h" #include "nvim/edit.h" +#include "nvim/errors.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" #include "nvim/eval/userfunc.h" @@ -31,6 +32,7 @@ #include "nvim/ex_cmds_defs.h" #include "nvim/ex_getln.h" #include "nvim/extmark.h" +#include "nvim/file_search.h" #include "nvim/fold.h" #include "nvim/garray.h" #include "nvim/garray_defs.h" @@ -262,12 +264,7 @@ void op_shift(oparg_T *oap, bool curs_top, int amount) foldOpenCursor(); if (oap->line_count > p_report) { - char *op; - if (oap->op_type == OP_RSHIFT) { - op = ">"; - } else { - op = "<"; - } + char *op = oap->op_type == OP_RSHIFT ? ">" : "<"; char *msg_line_single = NGETTEXT("%" PRId64 " line %sed %d time", "%" PRId64 " line %sed %d times", amount); @@ -298,8 +295,10 @@ void op_shift(oparg_T *oap, bool curs_top, int amount) /// @param call_changed_bytes call changed_bytes() void shift_line(bool left, bool round, int amount, int call_changed_bytes) { - const int sw_val = get_sw_value_indent(curbuf); - + int sw_val = get_sw_value_indent(curbuf, left); + if (sw_val == 0) { + sw_val = 1; // shouldn't happen, just in case + } int count = get_indent(); // get current indent if (round) { // round off indent @@ -309,20 +308,14 @@ void shift_line(bool left, bool round, int amount, int call_changed_bytes) amount--; } if (left) { - i -= amount; - if (i < 0) { - i = 0; - } + i = MAX(i - amount, 0); } else { i += amount; } count = i * sw_val; } else { // original vi indent if (left) { - count -= sw_val * amount; - if (count < 0) { - count = 0; - } + count = MAX(count - sw_val * amount, 0); } else { count += sw_val * amount; } @@ -330,7 +323,7 @@ void shift_line(bool left, bool round, int amount, int call_changed_bytes) // Set new indent if (State & VREPLACE_FLAG) { - change_indent(INDENT_SET, count, false, NUL, call_changed_bytes); + change_indent(INDENT_SET, count, false, call_changed_bytes); } else { set_indent(count, call_changed_bytes ? SIN_CHANGED : 0); } @@ -344,7 +337,7 @@ static void shift_block(oparg_T *oap, int amount) const int oldstate = State; char *newp; const int oldcol = curwin->w_cursor.col; - const int sw_val = get_sw_value_indent(curbuf); + const int sw_val = get_sw_value_indent(curbuf, left); const int ts_val = (int)curbuf->b_p_ts; struct block_def bd; int incr; @@ -459,9 +452,7 @@ static void shift_block(oparg_T *oap, int amount) const colnr_T block_space_width = non_white_col - oap->start_vcol; // We will shift by "total" or "block_space_width", whichever is less. - const colnr_T shift_amount = block_space_width < total - ? block_space_width - : total; + const colnr_T shift_amount = MIN(block_space_width, total); // The column to which we will shift the text. const colnr_T destination_col = non_white_col - shift_amount; @@ -575,9 +566,7 @@ static void block_insert(oparg_T *oap, const char *s, size_t slen, bool b_insert // avoid copying part of a multi-byte character offset -= utf_head_off(oldp, oldp + offset); } - if (spaces < 0) { // can happen when the cursor was moved - spaces = 0; - } + spaces = MAX(spaces, 0); // can happen when the cursor was moved assert(count >= 0); // Make sure the allocated size matches what is actually copied below. @@ -763,7 +752,7 @@ char *get_expr_line(void) } nested++; - char *rv = eval_to_string(expr_copy, true); + char *rv = eval_to_string(expr_copy, true, false); nested--; xfree(expr_copy); return rv; @@ -906,7 +895,7 @@ static void typval_to_yankreg(yankreg_T* yankreg, typval_T* val) if (tv_dict_get_tv(dict, "additional_data", &tv) == OK) { if (tv.v_type == VAR_DICT) { - yankreg->additional_data = tv.vval.v_dict; + yankreg->additional_data = NULL; // tv.vval.v_dict; } } break; @@ -1125,16 +1114,6 @@ int do_record(int c) return retval; } -static void set_yreg_additional_data(yankreg_T *reg, dict_T *additional_data) - FUNC_ATTR_NONNULL_ARG(1) -{ - if (reg->additional_data == additional_data) { - return; - } - tv_dict_unref(reg->additional_data); - reg->additional_data = additional_data; -} - /// Stuff string "p" into yank register "regname" as a single line (append if /// uppercase). "p" must have been allocated. /// @@ -1164,7 +1143,7 @@ static int stuff_yank(int regname, char *p) *pp = lp; } else { free_register(reg); - set_yreg_additional_data(reg, NULL); + reg->additional_data = NULL; reg->y_array = xmalloc(sizeof(char *)); reg->y_array[0] = p; reg->y_size = 1; @@ -1506,9 +1485,9 @@ static dict_T* yankreg_to_dict(yankreg_T* yankreg) { } tv_dict_add_str(dict, S_LEN("type"), type); - if (yankreg->additional_data) { - tv_dict_add_dict(dict, S_LEN("additional_data"), yankreg->additional_data); - } + // if (yankreg->additional_data) { + // tv_dict_add_dict(dict, S_LEN("additional_data"), yankreg->additional_data); + // } list_T *const lines = tv_list_alloc((long)yankreg->y_size); @@ -2418,18 +2397,6 @@ bool swapchar(int op_type, pos_T *pos) return false; } - // ~ is OP_NOP, g~ is OP_TILDE, gU is OP_UPPER - if ((op_type == OP_UPPER || op_type == OP_NOP || op_type == OP_TILDE) && c == 0xdf) { - pos_T sp = curwin->w_cursor; - - // Special handling for lowercase German sharp s (ß): convert to uppercase (ẞ). - curwin->w_cursor = *pos; - del_char(false); - ins_char(0x1E9E); - curwin->w_cursor = sp; - return true; - } - int nc = c; if (mb_islower(c)) { if (op_type == OP_ROT13) { @@ -2651,9 +2618,7 @@ void op_insert(oparg_T *oap, int count1) } } } - if (add > len) { - add = len; // short line, point to the NUL - } + add = MIN(add, len); // short line, point to the NUL firstline += add; len -= add; int ins_len = len - pre_textlen - offset; @@ -2815,7 +2780,7 @@ void clear_registers(void) void free_register(yankreg_T *reg) FUNC_ATTR_NONNULL_ALL { - set_yreg_additional_data(reg, NULL); + XFREE_CLEAR(reg->additional_data); if (reg->y_array == NULL) { return; } @@ -2953,7 +2918,7 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) char *pnew = xmalloc(strlen(curr->y_array[curr->y_size - 1]) + strlen(reg->y_array[0]) + 1); STRCPY(pnew, curr->y_array[--j]); - STRCAT(pnew, reg->y_array[0]); + strcat(pnew, reg->y_array[0]); xfree(curr->y_array[j]); xfree(reg->y_array[0]); curr->y_array[j++] = pnew; @@ -3111,13 +3076,13 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) /// /// @param oap Operator arguments. /// @param reg The yank register used. -static void do_autocmd_textputpost(int regname, yankreg_T *reg) +static void do_autocmd_textput(int regname, yankreg_T *reg, enum auto_event evt) FUNC_ATTR_NONNULL_ALL { static bool recursive = false; int len; - if (recursive || !has_event(EVENT_TEXTPUTPOST)) { + if (recursive || !has_event(evt)) { // No autocommand was defined, or we yanked from this autocommand. return; } @@ -3142,7 +3107,7 @@ static void do_autocmd_textputpost(int regname, yankreg_T *reg) (void)tv_dict_add_str(dict, S_LEN("regtype"), buf); // Name of requested register, or empty string for unnamed operation. - len = (*utf_char2len)(regname); + len = utf_char2len(regname); buf[len] = 0; utf_char2bytes(regname, buf); recursive = true; @@ -3150,7 +3115,7 @@ static void do_autocmd_textputpost(int regname, yankreg_T *reg) tv_dict_set_keys_readonly(dict); textlock++; - apply_autocmds(EVENT_TEXTPUTPOST, NULL, NULL, false, curbuf); + apply_autocmds(evt, NULL, NULL, false, curbuf); textlock--; restore_v_event(dict, &save_v_event); @@ -3188,6 +3153,10 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) const pos_T orig_end = curbuf->b_op_end; unsigned cur_ve_flags = get_ve_flags(curwin); + if (reg) { + do_autocmd_textput(regname, reg, EVENT_TEXTPUTPRE); + } + if (flags & PUT_FIXINDENT) { orig_indent = get_indent(); } @@ -3400,9 +3369,7 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) if (y_type == kMTBlockWise) { lnum = curwin->w_cursor.lnum + (linenr_T)y_size + 1; - if (lnum > curbuf->b_ml.ml_line_count) { - lnum = curbuf->b_ml.ml_line_count + 1; - } + lnum = MIN(lnum, curbuf->b_ml.ml_line_count + 1); if (u_save(curwin->w_cursor.lnum - 1, lnum) == FAIL) { goto end; } @@ -3563,9 +3530,7 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) spaces -= win_charsize(cstype, 0, ci.ptr, ci.chr.value, &csarg).width; ci = utfc_next(ci); } - if (spaces < 0) { - spaces = 0; - } + spaces = MAX(spaces, 0); } // Insert the new text. @@ -3630,10 +3595,7 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) // adjust '] mark curbuf->b_op_end.lnum = curwin->w_cursor.lnum - 1; - curbuf->b_op_end.col = bd.textcol + (colnr_T)totlen - 1; - if (curbuf->b_op_end.col < 0) { - curbuf->b_op_end.col = 0; - } + curbuf->b_op_end.col = MAX(bd.textcol + (colnr_T)totlen - 1, 0); curbuf->b_op_end.coladd = 0; if (flags & PUT_CURSEND) { curwin->w_cursor = curbuf->b_op_end; @@ -3641,9 +3603,7 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) // in Insert mode we might be after the NUL, correct for that colnr_T len = get_cursor_line_len(); - if (curwin->w_cursor.col > len) { - curwin->w_cursor.col = len; - } + curwin->w_cursor.col = MIN(curwin->w_cursor.col, len); } else { curwin->w_cursor.lnum = lnum; } @@ -3676,10 +3636,7 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) int first_byte_off = 0; if (VIsual_active) { - end_lnum = curbuf->b_visual.vi_end.lnum; - if (end_lnum < curbuf->b_visual.vi_start.lnum) { - end_lnum = curbuf->b_visual.vi_start.lnum; - } + end_lnum = MAX(curbuf->b_visual.vi_end.lnum, curbuf->b_visual.vi_start.lnum); if (end_lnum > start_lnum) { // "col" is valid for the first line, in following lines // the virtual column needs to be used. Matters for @@ -3778,7 +3735,7 @@ void do_put(int regname, yankreg_T *reg, int dir, int count, int flags) totlen = strlen(y_array[y_size - 1]); char *newp = xmalloc((size_t)ml_get_len(lnum) - (size_t)col + totlen + 1); STRCPY(newp, y_array[y_size - 1]); - STRCAT(newp, ptr); + strcat(newp, ptr); // insert second line ml_append(lnum, newp, 0, false); new_lnum++; @@ -3943,7 +3900,7 @@ error: end: if (reg) { - do_autocmd_textputpost(regname, reg); + do_autocmd_textput(regname, reg, EVENT_TEXTPUTPOST); } if (cmdmod.cmod_flags & CMOD_LOCKMARKS) { @@ -4622,10 +4579,7 @@ void charwise_block_prep(pos_T start, pos_T end, struct block_def *bdp, linenr_T if (ce != cs && start.coladd > 0) { // Part of a tab selected -- but don't double-count it. bdp->start_char_vcols = ce - cs + 1; - bdp->startspaces = bdp->start_char_vcols - start.coladd; - if (bdp->startspaces < 0) { - bdp->startspaces = 0; - } + bdp->startspaces = MAX(bdp->start_char_vcols - start.coladd, 0); startcol++; } } @@ -4725,9 +4679,7 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd) } if (pos.lnum == oap->end.lnum) { length = ml_get_len(oap->end.lnum); - if (oap->end.col >= length) { - oap->end.col = length - 1; - } + oap->end.col = MIN(oap->end.col, length - 1); length = oap->end.col - pos.col + 1; } } @@ -4783,6 +4735,7 @@ bool do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) int pre; // 'X' or 'x': hex; '0': octal; 'B' or 'b': bin static bool hexupper = false; // 0xABC uvarnumber_T n; + bool blank_unsigned = false; // blank: treat as unsigned? bool negative = false; bool was_positive = true; bool visual = VIsual_active; @@ -4793,12 +4746,12 @@ bool do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) pos_T endpos; colnr_T save_coladd = 0; - const bool do_hex = vim_strchr(curbuf->b_p_nf, 'x') != NULL; // "heX" - const bool do_oct = vim_strchr(curbuf->b_p_nf, 'o') != NULL; // "Octal" - const bool do_bin = vim_strchr(curbuf->b_p_nf, 'b') != NULL; // "Bin" - const bool do_alpha = vim_strchr(curbuf->b_p_nf, 'p') != NULL; // "alPha" - // "Unsigned" - const bool do_unsigned = vim_strchr(curbuf->b_p_nf, 'u') != NULL; + const bool do_hex = vim_strchr(curbuf->b_p_nf, 'x') != NULL; // "heX" + const bool do_oct = vim_strchr(curbuf->b_p_nf, 'o') != NULL; // "Octal" + const bool do_bin = vim_strchr(curbuf->b_p_nf, 'b') != NULL; // "Bin" + const bool do_alpha = vim_strchr(curbuf->b_p_nf, 'p') != NULL; // "alPha" + const bool do_unsigned = vim_strchr(curbuf->b_p_nf, 'u') != NULL; // "Unsigned" + const bool do_blank = vim_strchr(curbuf->b_p_nf, 'k') != NULL; // "blanK" if (virtual_active(curwin)) { save_coladd = pos->coladd; @@ -4895,8 +4848,12 @@ bool do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) if (col > pos->col && ptr[col - 1] == '-' && !utf_head_off(ptr, ptr + col - 1) && !do_unsigned) { - negative = true; - was_positive = false; + if (do_blank && col >= 2 && !ascii_iswhite(ptr[col - 2])) { + blank_unsigned = true; + } else { + negative = true; + was_positive = false; + } } } @@ -4911,21 +4868,13 @@ bool do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) // decrement or increment alphabetic character if (op_type == OP_NR_SUB) { if (CHAR_ORD(firstdigit) < Prenum1) { - if (isupper(firstdigit)) { - firstdigit = 'A'; - } else { - firstdigit = 'a'; - } + firstdigit = isupper(firstdigit) ? 'A' : 'a'; } else { firstdigit -= (int)Prenum1; } } else { if (26 - CHAR_ORD(firstdigit) - 1 < Prenum1) { - if (isupper(firstdigit)) { - firstdigit = 'Z'; - } else { - firstdigit = 'z'; - } + firstdigit = isupper(firstdigit) ? 'Z' : 'z'; } else { firstdigit += (int)Prenum1; } @@ -4942,9 +4891,13 @@ bool do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) && !utf_head_off(ptr, ptr + col - 1) && !visual && !do_unsigned) { - // negative number - col--; - negative = true; + if (do_blank && col >= 2 && !ascii_iswhite(ptr[col - 2])) { + blank_unsigned = true; + } else { + // negative number + col--; + negative = true; + } } // get the number value (unsigned) @@ -5001,7 +4954,7 @@ bool do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) } } - if (do_unsigned && negative) { + if ((do_unsigned || blank_unsigned) && negative) { if (subtract) { // sticking at zero. n = 0; @@ -5032,11 +4985,7 @@ bool do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) } while (todel-- > 0) { if (c < 0x100 && isalpha(c)) { - if (isupper(c)) { - hexupper = true; - } else { - hexupper = false; - } + hexupper = isupper(c); } // del_char() will mark line needing displaying del_char(false); @@ -5076,7 +5025,7 @@ bool do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) buf2[i++] = ((n >> --bits) & 0x1) ? '1' : '0'; } - buf2[i] = '\0'; + buf2[i] = NUL; } else if (pre == 0) { vim_snprintf(buf2, ARRAY_SIZE(buf2), "%" PRIu64, (uint64_t)n); } else if (pre == '0') { @@ -5098,7 +5047,7 @@ bool do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) } } *ptr = NUL; - STRCAT(buf1, buf2); + strcat(buf1, buf2); ins_str(buf1); // insert the new number endpos = curwin->w_cursor; if (curwin->w_cursor.col) { @@ -5516,9 +5465,7 @@ static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type, const char *str, for (char **ss = (char **)str; *ss != NULL; ss++, lnum++) { size_t ss_len = strlen(*ss); pp[lnum] = xmemdupz(*ss, ss_len); - if (ss_len > maxlen) { - maxlen = ss_len; - } + maxlen = MAX(maxlen, ss_len); } } else { size_t line_len; @@ -5527,9 +5474,7 @@ static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type, const char *str, start += line_len + 1, lnum++) { assert(end - start >= 0); line_len = (size_t)((char *)xmemscan(start, '\n', (size_t)(end - start)) - start); - if (line_len > maxlen) { - maxlen = line_len; - } + maxlen = MAX(maxlen, line_len); // When appending, copy the previous line and free it after. size_t extra = append ? strlen(pp[--lnum]) : 0; @@ -5552,7 +5497,7 @@ static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type, const char *str, } y_ptr->y_type = yank_type; y_ptr->y_size = lnum; - set_yreg_additional_data(y_ptr, NULL); + XFREE_CLEAR(y_ptr->additional_data); y_ptr->timestamp = os_time(); if (yank_type == kMTBlockWise) { y_ptr->y_width = (blocklen == -1 ? (colnr_T)maxlen - 1 : blocklen); @@ -6019,9 +5964,7 @@ static void get_op_vcol(oparg_T *oap, colnr_T redo_VIsual_vcol, bool initial) if (!redo_VIsual_busy) { getvvcol(curwin, &(oap->end), &start, NULL, &end); - if (start < oap->start_vcol) { - oap->start_vcol = start; - } + oap->start_vcol = MIN(oap->start_vcol, start); if (end > oap->end_vcol) { if (initial && *p_sel == 'e' && start >= 1 @@ -6040,9 +5983,7 @@ static void get_op_vcol(oparg_T *oap, colnr_T redo_VIsual_vcol, bool initial) for (curwin->w_cursor.lnum = oap->start.lnum; curwin->w_cursor.lnum <= oap->end.lnum; curwin->w_cursor.lnum++) { getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &end); - if (end > oap->end_vcol) { - oap->end_vcol = end; - } + oap->end_vcol = MAX(oap->end_vcol, end); } } else if (redo_VIsual_busy) { oap->end_vcol = oap->start_vcol + redo_VIsual_vcol - 1; @@ -6176,9 +6117,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) // redo_VIsual.rv_line_count and redo_VIsual.rv_vcol. oap->start = curwin->w_cursor; curwin->w_cursor.lnum += redo_VIsual.rv_line_count - 1; - if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) { - curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; - } + curwin->w_cursor.lnum = MIN(curwin->w_cursor.lnum, curbuf->b_ml.ml_line_count); VIsual_mode = redo_VIsual.rv_mode; if (redo_VIsual.rv_vcol == MAXCOL || VIsual_mode == 'v') { if (VIsual_mode == 'v') { @@ -6466,9 +6405,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) case OP_JOIN_NS: case OP_JOIN: - if (oap->line_count < 2) { - oap->line_count = 2; - } + oap->line_count = MAX(oap->line_count, 2); if (curwin->w_cursor.lnum + oap->line_count - 1 > curbuf->b_ml.ml_line_count) { beep_flush(); @@ -6867,9 +6804,7 @@ void finish_yankreg_from_object(yankreg_T *reg, bool clipboard_adjust) size_t maxlen = 0; for (size_t i = 0; i < reg->y_size; i++) { size_t rowlen = strlen(reg->y_array[i]); - if (rowlen > maxlen) { - maxlen = rowlen; - } + maxlen = MAX(maxlen, rowlen); } assert(maxlen <= INT_MAX); reg->y_width = MAX(reg->y_width, (int)maxlen - 1); @@ -6973,9 +6908,7 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet) size_t maxlen = 0; for (size_t i = 0; i < reg->y_size; i++) { size_t rowlen = strlen(reg->y_array[i]); - if (rowlen > maxlen) { - maxlen = rowlen; - } + maxlen = MAX(maxlen, rowlen); } assert(maxlen <= INT_MAX); reg->y_width = (int)maxlen - 1; |