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.c171
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;