aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ex_cmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/ex_cmds.c')
-rw-r--r--src/nvim/ex_cmds.c127
1 files changed, 60 insertions, 67 deletions
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 834cc6698a..a98de05815 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -34,6 +34,7 @@
#include "nvim/digraph.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/typval_defs.h"
@@ -203,7 +204,7 @@ void do_ascii(exarg_T *eap)
IObuff[iobuff_len++] = ' ';
}
IObuff[iobuff_len++] = '<';
- if (utf_iscomposing(c)) {
+ if (utf_iscomposing_first(c)) {
IObuff[iobuff_len++] = ' '; // Draw composing char on top of a space.
}
iobuff_len += (size_t)utf_char2bytes(c, IObuff + iobuff_len);
@@ -310,9 +311,7 @@ void ex_align(exarg_T *eap)
}
}
}
- if (new_indent < 0) {
- new_indent = 0;
- }
+ new_indent = MAX(new_indent, 0);
set_indent(new_indent, 0); // set indent
}
changed_lines(curbuf, eap->line1, 0, eap->line2 + 1, 0, true);
@@ -542,9 +541,7 @@ void ex_sort(exarg_T *eap)
for (linenr_T lnum = eap->line1; lnum <= eap->line2; lnum++) {
char *s = ml_get(lnum);
int len = ml_get_len(lnum);
- if (maxlen < len) {
- maxlen = len;
- }
+ maxlen = MAX(maxlen, len);
colnr_T start_col = 0;
colnr_T end_col = len;
@@ -704,11 +701,6 @@ sortend:
/// @return FAIL for failure, OK otherwise
int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
{
- linenr_T l;
- linenr_T extra; // Num lines added before line1
- linenr_T num_lines; // Num lines moved
- linenr_T last_line; // Last line in file after adding new text
-
if (dest >= line1 && dest < line2) {
emsg(_("E134: Cannot move a range of lines into itself"));
return FAIL;
@@ -719,11 +711,9 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
if (dest == line1 - 1 || dest == line2) {
// Move the cursor as if lines were moved (see below) to be backwards
// compatible.
- if (dest >= line1) {
- curwin->w_cursor.lnum = dest;
- } else {
- curwin->w_cursor.lnum = dest + (line2 - line1) + 1;
- }
+ curwin->w_cursor.lnum = dest >= line1
+ ? dest
+ : dest + (line2 - line1) + 1;
return OK;
}
@@ -732,13 +722,16 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
bcount_t extent_byte = end_byte - start_byte;
bcount_t dest_byte = ml_find_line_or_offset(curbuf, dest + 1, NULL, true);
- num_lines = line2 - line1 + 1;
+ linenr_T num_lines = line2 - line1 + 1; // Num lines moved
// First we copy the old text to its new location -- webb
// Also copy the flag that ":global" command uses.
if (u_save(dest, dest + 1) == FAIL) {
return FAIL;
}
+
+ linenr_T l;
+ linenr_T extra; // Num lines added before line1
for (extra = 0, l = line1; l <= line2; l++) {
char *str = xstrnsave(ml_get(l + extra), (size_t)ml_get_len(l + extra));
ml_append(dest + l - line1, str, 0, false);
@@ -761,7 +754,7 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
//
// And Finally we adjust the marks we put at the end of the file back to
// their final destination at the new text position -- webb
- last_line = curbuf->b_ml.ml_line_count;
+ linenr_T last_line = curbuf->b_ml.ml_line_count; // Last line in file after adding new text
mark_adjust_nofold(line1, line2, last_line - line2, 0, kExtmarkNOOP);
disable_fold_update++;
@@ -837,9 +830,7 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
if (line1 < dest) {
dest += num_lines + 1;
last_line = curbuf->b_ml.ml_line_count;
- if (dest > last_line + 1) {
- dest = last_line + 1;
- }
+ dest = MIN(dest, last_line + 1);
changed_lines(curbuf, line1, 0, dest, 0, false);
} else {
changed_lines(curbuf, dest + 1, 0, line1 + num_lines, 0, false);
@@ -969,13 +960,13 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit, bool do_in, bool do_out
char *t = xmalloc(len);
*t = NUL;
if (newcmd != NULL) {
- STRCAT(t, newcmd);
+ strcat(t, newcmd);
}
if (ins_prevcmd) {
- STRCAT(t, prevcmd);
+ strcat(t, prevcmd);
}
char *p = t + strlen(t);
- STRCAT(t, trailarg);
+ strcat(t, trailarg);
xfree(newcmd);
newcmd = t;
@@ -1028,8 +1019,8 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit, bool do_in, bool do_out
}
newcmd = xmalloc(strlen(prevcmd) + 2 * strlen(p_shq) + 1);
STRCPY(newcmd, p_shq);
- STRCAT(newcmd, prevcmd);
- STRCAT(newcmd, p_shq);
+ strcat(newcmd, prevcmd);
+ strcat(newcmd, p_shq);
free_newcmd = true;
}
if (addr_count == 0) { // :!
@@ -1169,7 +1160,7 @@ static void do_filter(linenr_T line1, linenr_T line2, exarg_T *eap, char *cmd, b
linenr_T read_linecount = curbuf->b_ml.ml_line_count;
// Pass on the kShellOptDoOut flag when the output is being redirected.
- call_shell(cmd_buf, (ShellOpts)(kShellOptFilter | shell_flags), NULL);
+ call_shell(cmd_buf, kShellOptFilter | shell_flags, NULL);
xfree(cmd_buf);
did_check_timestamps = false;
@@ -1314,7 +1305,7 @@ void do_shell(char *cmd, int flags)
// This ui_cursor_goto is required for when the '\n' resulted in a "delete line
// 1" command to the terminal.
ui_cursor_goto(msg_row, msg_col);
- call_shell(cmd, (ShellOpts)flags, NULL);
+ call_shell(cmd, flags, NULL);
if (msg_silent == 0) {
msg_didout = true;
}
@@ -2270,6 +2261,16 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum
if (buf == NULL) {
goto theend;
}
+ // autocommands try to edit a file that is goind to be removed, abort
+ if (buf_locked(buf)) {
+ // window was split, but not editing the new buffer, reset b_nwindows again
+ if (oldwin == NULL
+ && curwin->w_buffer != NULL
+ && curwin->w_buffer->b_nwindows > 1) {
+ curwin->w_buffer->b_nwindows--;
+ }
+ goto theend;
+ }
if (curwin->w_alt_fnum == buf->b_fnum && prev_alt_fnum != 0) {
// reusing the buffer, keep the old alternate file
curwin->w_alt_fnum = prev_alt_fnum;
@@ -2356,9 +2357,9 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum
win_T *the_curwin = curwin;
buf_T *was_curbuf = curbuf;
- // Set w_closing to avoid that autocommands close the window.
+ // Set w_locked to avoid that autocommands close the window.
// Set b_locked for the same reason.
- the_curwin->w_closing = true;
+ the_curwin->w_locked = true;
buf->b_locked++;
if (curbuf == old_curbuf.br_buf) {
@@ -2374,7 +2375,7 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum
// Autocommands may have closed the window.
if (win_valid(the_curwin)) {
- the_curwin->w_closing = false;
+ the_curwin->w_locked = false;
}
buf->b_locked--;
@@ -2704,7 +2705,7 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum
*so_ptr = 999; // force cursor to be vertically centered in the window
}
update_topline(curwin);
- curwin->w_scbind_pos = curwin->w_topline;
+ curwin->w_scbind_pos = plines_m_win_fill(curwin, 1, curwin->w_topline);
*so_ptr = n;
redraw_curbuf_later(UPD_NOT_VALID); // redraw this buffer later
}
@@ -2783,10 +2784,14 @@ void ex_append(exarg_T *eap)
indent = get_indent_lnum(lnum);
}
}
- if (eap->ea_getline == NULL) {
+ if (*eap->arg == '|') {
+ // Get the text after the trailing bar.
+ theline = xstrdup(eap->arg + 1);
+ *eap->arg = NUL;
+ } else if (eap->ea_getline == NULL) {
// No getline() function, use the lines that follow. This ends
// when there is no more.
- if (eap->nextcmd == NULL || *eap->nextcmd == NUL) {
+ if (eap->nextcmd == NULL) {
break;
}
p = vim_strchr(eap->nextcmd, NL);
@@ -2796,6 +2801,8 @@ void ex_append(exarg_T *eap)
theline = xmemdupz(eap->nextcmd, (size_t)(p - eap->nextcmd));
if (*p != NUL) {
p++;
+ } else {
+ p = NULL;
}
eap->nextcmd = p;
} else {
@@ -2926,9 +2933,7 @@ void ex_z(exarg_T *eap)
} else {
bigness = curwin->w_height_inner - 3;
}
- if (bigness < 1) {
- bigness = 1;
- }
+ bigness = MAX(bigness, 1);
char *x = eap->arg;
char *kind = x;
@@ -3001,19 +3006,9 @@ void ex_z(exarg_T *eap)
break;
}
- if (start < 1) {
- start = 1;
- }
-
- if (end > curbuf->b_ml.ml_line_count) {
- end = curbuf->b_ml.ml_line_count;
- }
-
- if (curs > curbuf->b_ml.ml_line_count) {
- curs = curbuf->b_ml.ml_line_count;
- } else if (curs < 1) {
- curs = 1;
- }
+ start = MAX(start, 1);
+ end = MIN(end, curbuf->b_ml.ml_line_count);
+ curs = MIN(MAX(curs, 1), curbuf->b_ml.ml_line_count);
for (linenr_T i = start; i <= end; i++) {
if (minus && i == lnum) {
@@ -3083,8 +3078,8 @@ void sub_get_replacement(SubReplacementString *const ret_sub)
void sub_set_replacement(SubReplacementString sub)
{
xfree(old_sub.sub);
- if (sub.additional_elements != old_sub.additional_elements) {
- tv_list_unref(old_sub.additional_elements);
+ if (sub.additional_data != old_sub.additional_data) {
+ xfree(old_sub.additional_data);
}
old_sub = sub;
}
@@ -3100,7 +3095,7 @@ void sub_set_replacement(SubReplacementString sub)
///
/// @returns true if :substitute can be replaced with a join command
static bool sub_joining_lines(exarg_T *eap, char *pat, size_t patlen, const char *sub,
- const char *cmd, bool save)
+ const char *cmd, bool save, bool keeppatterns)
FUNC_ATTR_NONNULL_ARG(1, 4, 5)
{
// TODO(vim): find a generic solution to make line-joining operations more
@@ -3138,7 +3133,7 @@ static bool sub_joining_lines(exarg_T *eap, char *pat, size_t patlen, const char
}
if (save) {
- if ((cmdmod.cmod_flags & CMOD_KEEPPATTERNS) == 0) {
+ if (!keeppatterns) {
save_re_pat(RE_SUBST, pat, patlen, magic_isset());
}
// put pattern in history
@@ -3346,6 +3341,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
linenr_T old_line_count = curbuf->b_ml.ml_line_count;
char *sub_firstline; // allocated copy of first sub line
bool endcolumn = false; // cursor in last column when done
+ const bool keeppatterns = cmdmod.cmod_flags & CMOD_KEEPPATTERNS;
PreviewLines preview_lines = { KV_INITIAL_VALUE, 0 };
static int pre_hl_id = 0;
pos_T old_cursor = curwin->w_cursor;
@@ -3392,12 +3388,12 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
which_pat = RE_LAST; // use last used regexp
delimiter = (uint8_t)(*cmd++); // remember delimiter character
pat = cmd; // remember start of search pat
- patlen = strlen(pat);
cmd = skip_regexp_ex(cmd, delimiter, magic_isset(), &eap->arg, NULL, NULL);
if (cmd[0] == delimiter) { // end delimiter found
*cmd++ = NUL; // replace it with a NUL
has_second_delim = true;
}
+ patlen = strlen(pat);
}
// Small incompatibility: vi sees '\n' as end of the command, but in
@@ -3406,11 +3402,11 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
cmd = skip_substitute(cmd, delimiter);
sub = xstrdup(p);
- if (!eap->skip && cmdpreview_ns <= 0) {
+ if (!eap->skip && !keeppatterns && cmdpreview_ns <= 0) {
sub_set_replacement((SubReplacementString) {
.sub = xstrdup(sub),
.timestamp = os_time(),
- .additional_elements = NULL,
+ .additional_data = NULL,
});
}
} else if (!eap->skip) { // use previous pattern and substitution
@@ -3427,7 +3423,8 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
endcolumn = (curwin->w_curswant == MAXCOL);
}
- if (sub != NULL && sub_joining_lines(eap, pat, patlen, sub, cmd, cmdpreview_ns <= 0)) {
+ if (sub != NULL && sub_joining_lines(eap, pat, patlen, sub, cmd, cmdpreview_ns <= 0,
+ keeppatterns)) {
xfree(sub);
return 0;
}
@@ -3454,9 +3451,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
}
eap->line1 = eap->line2;
eap->line2 += (linenr_T)i - 1;
- if (eap->line2 > curbuf->b_ml.ml_line_count) {
- eap->line2 = curbuf->b_ml.ml_line_count;
- }
+ eap->line2 = MIN(eap->line2, curbuf->b_ml.ml_line_count);
}
// check for trailing command or garbage
@@ -3720,10 +3715,8 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
print_line_no_prefix(lnum, subflags.do_number, subflags.do_list);
getvcol(curwin, &curwin->w_cursor, &sc, NULL, NULL);
- curwin->w_cursor.col = regmatch.endpos[0].col - 1;
- if (curwin->w_cursor.col < 0) {
- curwin->w_cursor.col = 0;
- }
+ curwin->w_cursor.col = MAX(regmatch.endpos[0].col - 1, 0);
+
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &ec);
curwin->w_cursor.col = regmatch.startpos[0].col;
if (subflags.do_number || curwin->w_p_nu) {
@@ -4107,7 +4100,7 @@ skip:
// the line as reference, because the substitute may
// have changed the number of characters. Same for
// "prev_matchcol".
- STRCAT(new_start, sub_firstline + copycol);
+ strcat(new_start, sub_firstline + copycol);
matchcol = (colnr_T)strlen(sub_firstline) - matchcol;
prev_matchcol = (colnr_T)strlen(sub_firstline)
- prev_matchcol;