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