diff options
Diffstat (limited to 'src/nvim/ops.c')
-rw-r--r-- | src/nvim/ops.c | 171 |
1 files changed, 93 insertions, 78 deletions
diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 53612be697..3be4536f16 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -17,6 +17,7 @@ #include "nvim/change.h" #include "nvim/charset.h" #include "nvim/cursor.h" +#include "nvim/drawscreen.h" #include "nvim/edit.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" @@ -24,7 +25,6 @@ #include "nvim/ex_cmds2.h" #include "nvim/ex_getln.h" #include "nvim/extmark.h" -#include "nvim/fileio.h" #include "nvim/fold.h" #include "nvim/getchar.h" #include "nvim/globals.h" @@ -47,7 +47,6 @@ #include "nvim/os/time.h" #include "nvim/path.h" #include "nvim/plines.h" -#include "nvim/screen.h" #include "nvim/search.h" #include "nvim/state.h" #include "nvim/strings.h" @@ -289,13 +288,13 @@ void shift_line(int left, int round, int amount, int call_changed_bytes) { int count; int i, j; - int p_sw = (int)get_sw_value_indent(curbuf); + const int sw_val = (int)get_sw_value_indent(curbuf); count = get_indent(); // get current indent if (round) { // round off indent - i = count / p_sw; // number of p_sw rounded down - j = count % p_sw; // extra spaces + i = count / sw_val; // number of 'shiftwidth' rounded down + j = count % sw_val; // extra spaces if (j && left) { // first remove extra spaces amount--; } @@ -307,15 +306,15 @@ void shift_line(int left, int round, int amount, int call_changed_bytes) } else { i += amount; } - count = i * p_sw; + count = i * sw_val; } else { // original vi indent if (left) { - count -= p_sw * amount; + count -= sw_val * amount; if (count < 0) { count = 0; } } else { - count += p_sw * amount; + count += sw_val * amount; } } @@ -335,9 +334,8 @@ static void shift_block(oparg_T *oap, int amount) const int oldstate = State; char_u *newp; const int oldcol = curwin->w_cursor.col; - int p_sw = (int)get_sw_value_indent(curbuf); - long *p_vts = curbuf->b_p_vts_array; - const long p_ts = curbuf->b_p_ts; + const int sw_val = (int)get_sw_value_indent(curbuf); + const int ts_val = (int)curbuf->b_p_ts; struct block_def bd; int incr; int i = 0, j = 0; @@ -352,8 +350,8 @@ static void shift_block(oparg_T *oap, int amount) } // total is number of screen columns to be inserted/removed - int total = (int)((unsigned)amount * (unsigned)p_sw); - if ((total / p_sw) != amount) { + int total = (int)((unsigned)amount * (unsigned)sw_val); + if ((total / sw_val) != amount) { return; // multiplication overflow } @@ -388,7 +386,7 @@ static void shift_block(oparg_T *oap, int amount) // OK, now total=all the VWS reqd, and textstart points at the 1st // non-ws char in the block. if (!curbuf->b_p_et) { - tabstop_fromto(ws_vcol, ws_vcol + total, p_ts, p_vts, &i, &j); + tabstop_fromto(ws_vcol, ws_vcol + total, ts_val, curbuf->b_p_vts_array, &i, &j); } else { j = total; } @@ -512,7 +510,7 @@ static void shift_block(oparg_T *oap, int amount) /// Caller must prepare for undo. static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def *bdp) { - int p_ts; + int ts_val; int count = 0; // extra spaces to replace a cut TAB int spaces = 0; // non-zero if cutting a TAB colnr_T offset; // pointer along new line @@ -531,18 +529,18 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def oldp = ml_get(lnum); if (b_insert) { - p_ts = bdp->start_char_vcols; + ts_val = bdp->start_char_vcols; spaces = bdp->startspaces; if (spaces != 0) { - count = p_ts - 1; // we're cutting a TAB + count = ts_val - 1; // we're cutting a TAB } offset = bdp->textcol; } else { // append - p_ts = bdp->end_char_vcols; + ts_val = bdp->end_char_vcols; if (!bdp->is_short) { // spaces = padding after block - spaces = (bdp->endspaces ? p_ts - bdp->endspaces : 0); + spaces = (bdp->endspaces ? ts_val - bdp->endspaces : 0); if (spaces != 0) { - count = p_ts - 1; // we're cutting a TAB + count = ts_val - 1; // we're cutting a TAB } offset = bdp->textcol + bdp->textlen - (spaces != 0); } else { // spaces = padding to block edge @@ -566,7 +564,7 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def assert(count >= 0); // Make sure the allocated size matches what is actually copied below. newp = xmalloc(STRLEN(oldp) + (size_t)spaces + s_len - + (spaces > 0 && !bdp->is_short ? (size_t)p_ts - (size_t)spaces : 0) + + (spaces > 0 && !bdp->is_short ? (size_t)ts_val - (size_t)spaces : 0) + (size_t)count + 1); // copy up to shifted part @@ -585,7 +583,7 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def if (spaces > 0 && !bdp->is_short) { if (*oldp == TAB) { // insert post-padding - memset(newp + offset + spaces, ' ', (size_t)(p_ts - spaces)); + memset(newp + offset + spaces, ' ', (size_t)(ts_val - spaces)); // We're splitting a TAB, don't copy it. oldp++; // We allowed for that TAB, remember this now @@ -998,14 +996,14 @@ static int stuff_yank(int regname, char_u *p) } yankreg_T *reg = get_yank_register(regname, YREG_YANK); if (is_append_register(regname) && reg->y_array != NULL) { - char_u **pp = (char_u **)&(reg->y_array[reg->y_size - 1]); + char **pp = &(reg->y_array[reg->y_size - 1]); char_u *lp = xmalloc(STRLEN(*pp) + STRLEN(p) + 1); STRCPY(lp, *pp); // TODO(philix): use xstpcpy() in stuff_yank() STRCAT(lp, p); xfree(p); xfree(*pp); - *pp = lp; + *pp = (char *)lp; } else { free_register(reg); set_yreg_additional_data(reg, NULL); @@ -1277,7 +1275,7 @@ int insert_reg(int regname, bool literally_arg) return FAIL; } - char_u *arg; + char *arg; if (regname == '.') { // Insert last inserted text. retval = stuff_inserted(NUL, 1L, true); } else if (get_spec_reg(regname, &arg, &allocated, true)) { @@ -1348,7 +1346,7 @@ static void stuffescaped(const char *arg, bool literally) /// @param errmsg give error message when failing /// /// @return true if "regname" is a special register, -bool get_spec_reg(int regname, char_u **argp, bool *allocated, bool errmsg) +bool get_spec_reg(int regname, char **argp, bool *allocated, bool errmsg) { size_t cnt; @@ -1359,15 +1357,15 @@ bool get_spec_reg(int regname, char_u **argp, bool *allocated, bool errmsg) if (errmsg) { check_fname(); // will give emsg if not set } - *argp = (char_u *)curbuf->b_fname; + *argp = curbuf->b_fname; return true; case '#': // alternate file name - *argp = (char_u *)getaltfname(errmsg); // may give emsg if not set + *argp = getaltfname(errmsg); // may give emsg if not set return true; case '=': // result of expression - *argp = get_expr_line(); + *argp = (char *)get_expr_line(); *allocated = true; return true; @@ -1375,18 +1373,18 @@ bool get_spec_reg(int regname, char_u **argp, bool *allocated, bool errmsg) if (last_cmdline == NULL && errmsg) { emsg(_(e_nolastcmd)); } - *argp = last_cmdline; + *argp = (char *)last_cmdline; return true; case '/': // last search-pattern if (last_search_pat() == NULL && errmsg) { emsg(_(e_noprevre)); } - *argp = last_search_pat(); + *argp = (char *)last_search_pat(); return true; case '.': // last inserted text - *argp = get_last_insert_save(); + *argp = (char *)get_last_insert_save(); *allocated = true; if (*argp == NULL && errmsg) { emsg(_(e_noinstext)); @@ -1398,8 +1396,9 @@ bool get_spec_reg(int regname, char_u **argp, bool *allocated, bool errmsg) if (!errmsg) { return false; } - *argp = file_name_at_cursor(FNAME_MESS | FNAME_HYP | (regname == Ctrl_P ? FNAME_EXP : 0), - 1L, NULL); + *argp + = (char *)file_name_at_cursor(FNAME_MESS | FNAME_HYP | (regname == Ctrl_P ? FNAME_EXP : 0), + 1L, NULL); *allocated = true; return true; @@ -1411,7 +1410,7 @@ bool get_spec_reg(int regname, char_u **argp, bool *allocated, bool errmsg) cnt = find_ident_under_cursor(argp, (regname == Ctrl_W ? (FIND_IDENT|FIND_STRING) : FIND_STRING)); - *argp = cnt ? vim_strnsave(*argp, cnt) : NULL; + *argp = cnt ? xstrnsave(*argp, cnt) : NULL; *allocated = true; return true; @@ -1420,11 +1419,11 @@ bool get_spec_reg(int regname, char_u **argp, bool *allocated, bool errmsg) return false; } - *argp = ml_get_buf(curwin->w_buffer, curwin->w_cursor.lnum, false); + *argp = (char *)ml_get_buf(curwin->w_buffer, curwin->w_cursor.lnum, false); return true; case '_': // black hole: always empty - *argp = (char_u *)""; + *argp = ""; return true; } @@ -1927,8 +1926,8 @@ static int op_replace(oparg_T *oap, int c) // times. if (utf_char2cells(c) > 1) { if ((numc & 1) && !bd.is_short) { - ++bd.endspaces; - ++n; + bd.endspaces++; + n++; } numc = numc / 2; } @@ -2961,7 +2960,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) int delcount; int incr = 0; struct block_def bd; - char_u **y_array = NULL; + char **y_array = NULL; linenr_T nr_lines = 0; pos_T new_cursor; int indent; @@ -2970,7 +2969,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) bool first_indent = true; int lendiff = 0; pos_T old_pos; - char_u *insert_string = NULL; + char *insert_string = NULL; bool allocated = false; long cnt; const pos_T orig_start = curbuf->b_op_start; @@ -3093,10 +3092,10 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) * Loop twice: count the number of lines and save them. */ for (;;) { y_size = 0; - ptr = insert_string; + ptr = (char_u *)insert_string; while (ptr != NULL) { if (y_array != NULL) { - y_array[y_size] = ptr; + y_array[y_size] = (char *)ptr; } y_size++; ptr = (char_u *)vim_strchr((char *)ptr, '\n'); @@ -3104,7 +3103,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) if (y_array != NULL) { *ptr = NUL; } - ++ptr; + ptr++; // A trailing '\n' makes the register linewise. if (*ptr == NUL) { y_type = kMTLineWise; @@ -3115,7 +3114,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) if (y_array != NULL) { break; } - y_array = (char_u **)xmalloc(y_size * sizeof(char_u *)); + y_array = xmalloc(y_size * sizeof(char_u *)); } } else { y_size = 1; // use fake one-line yank register @@ -3132,7 +3131,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) y_type = reg->y_type; y_width = reg->y_width; y_size = reg->y_size; - y_array = (char_u **)reg->y_array; + y_array = reg->y_array; } if (curbuf->terminal) { @@ -3341,7 +3340,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) // block spaces = y_width + 1; for (int j = 0; j < yanklen; j++) { - spaces -= lbr_chartabsize(NULL, &y_array[i][j], 0); + spaces -= lbr_chartabsize(NULL, (char_u *)(&y_array[i][j]), 0); } if (spaces < 0) { spaces = 0; @@ -3442,12 +3441,9 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) } } curbuf->b_op_start = curwin->w_cursor; - } - /* - * Line mode: BACKWARD is the same as FORWARD on the previous line - */ - else if (dir == BACKWARD) { - --lnum; + } else if (dir == BACKWARD) { + // Line mode: BACKWARD is the same as FORWARD on the previous line + lnum--; } new_cursor = curwin->w_cursor; @@ -3580,13 +3576,13 @@ 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)) { - if (ml_append(lnum, (char *)y_array[i], (colnr_T)0, false) == FAIL) { + if (ml_append(lnum, y_array[i], (colnr_T)0, false) == FAIL) { goto error; } new_lnum++; } lnum++; - ++nr_lines; + nr_lines++; if (flags & PUT_FIXINDENT) { old_pos = curwin->w_cursor; curwin->w_cursor.lnum = lnum; @@ -3670,8 +3666,8 @@ error: if (col > 1) { curbuf->b_op_end.col = col - 1; if (len > 0) { - curbuf->b_op_end.col -= utf_head_off(y_array[y_size - 1], - y_array[y_size - 1] + len - 1); + curbuf->b_op_end.col -= utf_head_off((char_u *)y_array[y_size - 1], + (char_u *)y_array[y_size - 1] + len - 1); } } else { curbuf->b_op_end.col = 0; @@ -3962,9 +3958,9 @@ static void dis_msg(const char_u *p, bool skip_esc) /// comment. char_u *skip_comment(char_u *line, bool process, bool include_space, bool *is_comment) { - char_u *comment_flags = NULL; + char *comment_flags = NULL; int lead_len; - int leader_offset = get_last_leader_offset((char *)line, (char **)&comment_flags); + int leader_offset = get_last_leader_offset((char *)line, &comment_flags); *is_comment = false; if (leader_offset != -1) { @@ -3986,7 +3982,7 @@ char_u *skip_comment(char_u *line, bool process, bool include_space, bool *is_co return line; } - lead_len = get_leader_len((char *)line, (char **)&comment_flags, false, include_space); + lead_len = get_leader_len((char *)line, &comment_flags, false, include_space); if (lead_len == 0) { return line; @@ -4001,7 +3997,7 @@ char_u *skip_comment(char_u *line, bool process, bool include_space, bool *is_co || *comment_flags == ':') { break; } - ++comment_flags; + comment_flags++; } // If we found a colon, it means that we are not processing a line @@ -4285,7 +4281,7 @@ static int same_leader(linenr_T lnum, int leader1_len, char_u *leader1_flags, in } } else { while (ascii_iswhite(line1[idx1])) { - ++idx1; + idx1++; } } } @@ -4698,7 +4694,7 @@ static int fmt_check_par(linenr_T lnum, int *leader_len, char_u **leader_flags, */ flags = *leader_flags; while (*flags && *flags != ':' && *flags != COM_END) { - ++flags; + flags++; } } @@ -5457,16 +5453,16 @@ void *get_reg_contents(int regname, int flags) return NULL; } - char_u *retval; + char *retval; bool allocated; if (get_spec_reg(regname, &retval, &allocated, false)) { if (retval == NULL) { return NULL; } if (allocated) { - return get_reg_wrap_one_line(retval, flags); + return get_reg_wrap_one_line((char_u *)retval, flags); } - return get_reg_wrap_one_line(vim_strsave(retval), flags); + return get_reg_wrap_one_line(vim_strsave((char_u *)retval), flags); } yankreg_T *reg = get_yank_register(regname, YREG_PASTE); @@ -5557,11 +5553,11 @@ void write_reg_contents(int name, const char_u *str, ssize_t len, int must_appen write_reg_contents_ex(name, str, len, must_append, kMTUnknown, 0L); } -void write_reg_contents_lst(int name, char_u **strings, bool must_append, MotionType yank_type, +void write_reg_contents_lst(int name, char **strings, bool must_append, MotionType yank_type, colnr_T block_len) { if (name == '/' || name == '=') { - char_u *s = strings[0]; + char_u *s = (char_u *)strings[0]; if (strings[0] == NULL) { s = (char_u *)""; } else if (strings[1] != NULL) { @@ -5583,7 +5579,7 @@ void write_reg_contents_lst(int name, char_u **strings, bool must_append, Motion return; } - str_to_reg(reg, yank_type, (char_u *)strings, STRLEN((char_u *)strings), + str_to_reg(reg, yank_type, (char *)strings, STRLEN((char_u *)strings), block_len, true); finish_write_reg(name, reg, old_y_previous); } @@ -5671,7 +5667,7 @@ void write_reg_contents_ex(int name, const char_u *str, ssize_t len, bool must_a if (!(reg = init_write_reg(name, &old_y_previous, must_append))) { return; } - str_to_reg(reg, yank_type, str, (size_t)len, block_len, false); + str_to_reg(reg, yank_type, (char *)str, (size_t)len, block_len, false); finish_write_reg(name, reg, old_y_previous); } @@ -5685,7 +5681,7 @@ void write_reg_contents_ex(int name, const char_u *str, ssize_t len, bool must_a /// @param len length of the string (Ignored when str_list=true.) /// @param blocklen width of visual block, or -1 for "I don't know." /// @param str_list True if str is `char_u **`. -static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type, const char_u *str, size_t len, +static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type, const char *str, size_t len, colnr_T blocklen, bool str_list) FUNC_ATTR_NONNULL_ALL { @@ -5727,9 +5723,8 @@ static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type, const char_u *str } // Grow the register array to hold the pointers to the new lines. - char_u **pp = xrealloc(y_ptr->y_array, - (y_ptr->y_size + newlines) * sizeof(char_u *)); - y_ptr->y_array = (char **)pp; + char **pp = xrealloc(y_ptr->y_array, (y_ptr->y_size + newlines) * sizeof(char_u *)); + y_ptr->y_array = pp; size_t lnum = y_ptr->y_size; // The current line number. @@ -5747,7 +5742,7 @@ static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type, const char_u *str } } else { size_t line_len; - for (const char_u *start = str, *end = str + len; + for (const char_u *start = (char_u *)str, *end = (char_u *)str + len; start < end + extraline; start += line_len + 1, lnum++) { assert(end - start >= 0); @@ -5770,7 +5765,7 @@ static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type, const char_u *str xfree(pp[lnum]); append = false; // only first line is appended } - pp[lnum] = (char_u *)s; + pp[lnum] = s; // Convert NULs to '\n' to prevent truncation. memchrsub(pp[lnum], NUL, '\n', s_len); @@ -5789,7 +5784,7 @@ static void str_to_reg(yankreg_T *y_ptr, MotionType yank_type, const char_u *str void clear_oparg(oparg_T *oap) { - memset(oap, 0, sizeof(oparg_T)); + CLEAR_POINTER(oap); } /// Count the number of bytes, characters and "words" in a line. @@ -6140,6 +6135,23 @@ static void op_colon(oparg_T *oap) // do_cmdline() does the rest } +/// callback function for 'operatorfunc' +static Callback opfunc_cb; + +/// Process the 'operatorfunc' option value. +/// @return OK or FAIL +int set_operatorfunc_option(void) +{ + return option_set_callback_func(p_opfunc, &opfunc_cb); +} + +#if defined(EXITFREE) +void free_operatorfunc_option(void) +{ + callback_free(&opfunc_cb); +} +#endif + /// Handle the "g@" operator: call 'operatorfunc'. static void op_function(const oparg_T *oap) FUNC_ATTR_NONNULL_ALL @@ -6177,7 +6189,10 @@ static void op_function(const oparg_T *oap) // Reset finish_op so that mode() returns the right value. finish_op = false; - (void)call_func_retnr((char *)p_opfunc, 1, argv); + typval_T rettv; + if (callback_call(&opfunc_cb, 1, argv, &rettv)) { + tv_clear(&rettv); + } virtual_op = save_virtual_op; finish_op = save_finish_op; |