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.c88
1 files changed, 51 insertions, 37 deletions
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 74ad8e95a2..834cc6698a 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -541,7 +541,7 @@ void ex_sort(exarg_T *eap)
// Also get the longest line length for allocating "sortbuf".
for (linenr_T lnum = eap->line1; lnum <= eap->line2; lnum++) {
char *s = ml_get(lnum);
- int len = (int)strlen(s);
+ int len = ml_get_len(lnum);
if (maxlen < len) {
maxlen = len;
}
@@ -643,8 +643,8 @@ void ex_sort(exarg_T *eap)
}
char *s = ml_get(get_lnum);
- size_t bytelen = strlen(s) + 1; // include EOL in bytelen
- old_count += (bcount_t)bytelen;
+ colnr_T bytelen = ml_get_len(get_lnum) + 1; // include EOL in bytelen
+ old_count += bytelen;
if (!unique || i == 0 || string_compare(s, sortbuf1) != 0) {
// Copy the line into a buffer, it may become invalid in
// ml_append(). And it's needed for "unique".
@@ -652,7 +652,7 @@ void ex_sort(exarg_T *eap)
if (ml_append(lnum++, sortbuf1, 0, false) == FAIL) {
break;
}
- new_count += (bcount_t)bytelen;
+ new_count += bytelen;
}
fast_breakcheck();
if (got_int) {
@@ -740,7 +740,7 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
return FAIL;
}
for (extra = 0, l = line1; l <= line2; l++) {
- char *str = xstrdup(ml_get(l + extra));
+ char *str = xstrnsave(ml_get(l + extra), (size_t)ml_get_len(l + extra));
ml_append(dest + l - line1, str, 0, false);
xfree(str);
if (dest < line1) {
@@ -876,9 +876,8 @@ void ex_copy(linenr_T line1, linenr_T line2, linenr_T n)
curwin->w_cursor.lnum = n;
while (line1 <= line2) {
- // need to use xstrdup() because the line will be unlocked within
- // ml_append()
- char *p = xstrdup(ml_get(line1));
+ // need to make a copy because the line will be unlocked within ml_append()
+ char *p = xstrnsave(ml_get(line1), (size_t)ml_get_len(line1));
ml_append(curwin->w_cursor.lnum, p, 0, false);
xfree(p);
@@ -2008,6 +2007,10 @@ static int check_readonly(int *forceit, buf_T *buf)
/// GETFILE_OPEN_OTHER for successfully opening another file.
int getfile(int fnum, char *ffname_arg, char *sfname_arg, bool setpm, linenr_T lnum, bool forceit)
{
+ if (!check_can_set_curbuf_forceit(forceit)) {
+ return GETFILE_ERROR;
+ }
+
char *ffname = ffname_arg;
char *sfname = sfname_arg;
bool other;
@@ -2463,7 +2466,7 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum
// Since we are starting to edit a file, consider the filetype to be
// unset. Helps for when an autocommand changes files and expects syntax
// highlighting to work in the other file.
- did_filetype = false;
+ curbuf->b_did_filetype = false;
// other_file oldbuf
// false false re-edit same file, buffer is re-used
@@ -2634,14 +2637,14 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum
if (newcol >= 0) { // position set by autocommands
curwin->w_cursor.lnum = newlnum;
curwin->w_cursor.col = newcol;
- check_cursor();
+ check_cursor(curwin);
} else if (newlnum > 0) { // line number from caller or old position
curwin->w_cursor.lnum = newlnum;
check_cursor_lnum(curwin);
if (solcol >= 0 && !p_sol) {
// 'sol' is off: Use last known column.
curwin->w_cursor.col = solcol;
- check_cursor_col();
+ check_cursor_col(curwin);
curwin->w_cursor.coladd = 0;
curwin->w_set_curswant = true;
} else {
@@ -2780,7 +2783,7 @@ void ex_append(exarg_T *eap)
indent = get_indent_lnum(lnum);
}
}
- if (eap->getline == NULL) {
+ 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) {
@@ -2800,7 +2803,8 @@ void ex_append(exarg_T *eap)
// Set State to avoid the cursor shape to be set to MODE_INSERT
// state when getline() returns.
State = MODE_CMDLINE;
- theline = eap->getline(eap->cstack->cs_looplevel > 0 ? -1 : NUL, eap->cookie, indent, true);
+ theline = eap->ea_getline(eap->cstack->cs_looplevel > 0 ? -1 : NUL,
+ eap->cookie, indent, true);
State = save_State;
}
lines_left = Rows - 1;
@@ -3095,8 +3099,9 @@ void sub_set_replacement(SubReplacementString sub)
/// @param[in] save Save pattern to options, history
///
/// @returns true if :substitute can be replaced with a join command
-static bool sub_joining_lines(exarg_T *eap, char *pat, const char *sub, const char *cmd, bool save)
- FUNC_ATTR_NONNULL_ARG(1, 3, 4)
+static bool sub_joining_lines(exarg_T *eap, char *pat, size_t patlen, const char *sub,
+ const char *cmd, bool save)
+ FUNC_ATTR_NONNULL_ARG(1, 4, 5)
{
// TODO(vim): find a generic solution to make line-joining operations more
// efficient, avoid allocating a string that grows in size.
@@ -3134,10 +3139,10 @@ static bool sub_joining_lines(exarg_T *eap, char *pat, const char *sub, const ch
if (save) {
if ((cmdmod.cmod_flags & CMOD_KEEPPATTERNS) == 0) {
- save_re_pat(RE_SUBST, pat, magic_isset());
+ save_re_pat(RE_SUBST, pat, patlen, magic_isset());
}
// put pattern in history
- add_to_history(HIST_SEARCH, pat, true, NUL);
+ add_to_history(HIST_SEARCH, pat, patlen, true, NUL);
}
return true;
@@ -3296,7 +3301,8 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
if (nmatch > 1) { \
sub_firstlnum += (linenr_T)nmatch - 1; \
xfree(sub_firstline); \
- sub_firstline = xstrdup(ml_get(sub_firstlnum)); \
+ sub_firstline = xstrnsave(ml_get(sub_firstlnum), \
+ (size_t)ml_get_len(sub_firstlnum)); \
/* When going beyond the last line, stop substituting. */ \
if (sub_firstlnum <= line2) { \
do_again = true; \
@@ -3327,6 +3333,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
};
char *pat = NULL;
char *sub = NULL; // init for GCC
+ size_t patlen = 0;
int delimiter;
bool has_second_delim = false;
int sublen;
@@ -3378,12 +3385,14 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
which_pat = RE_SEARCH; // use last '/' pattern
}
pat = ""; // empty search pattern
+ patlen = 0;
delimiter = (uint8_t)(*cmd++); // remember delimiter character
has_second_delim = true;
} else { // find the end of the regexp
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
@@ -3410,6 +3419,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
return 0;
}
pat = NULL; // search_regcomp() will use previous pattern
+ patlen = 0;
sub = xstrdup(old_sub.sub);
// Vi compatibility quirk: repeating with ":s" keeps the cursor in the
@@ -3417,7 +3427,7 @@ 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, sub, cmd, cmdpreview_ns <= 0)) {
+ if (sub != NULL && sub_joining_lines(eap, pat, patlen, sub, cmd, cmdpreview_ns <= 0)) {
xfree(sub);
return 0;
}
@@ -3472,7 +3482,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
return 0;
}
- if (search_regcomp(pat, NULL, RE_SUBST, which_pat,
+ if (search_regcomp(pat, patlen, NULL, RE_SUBST, which_pat,
(cmdpreview_ns > 0 ? 0 : SEARCH_HIS), &regmatch) == FAIL) {
if (subflags.do_error) {
emsg(_(e_invcmd));
@@ -3624,7 +3634,8 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
break;
}
if (sub_firstline == NULL) {
- sub_firstline = xstrdup(ml_get(sub_firstlnum));
+ sub_firstline = xstrnsave(ml_get(sub_firstlnum),
+ (size_t)ml_get_len(sub_firstlnum));
}
// Save the line number of the last change for the final
@@ -3761,7 +3772,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
// really update the line, it would change
// what matches. Temporarily replace the line
// and change it back afterwards.
- orig_line = xstrdup(ml_get(lnum));
+ orig_line = xstrnsave(ml_get(lnum), (size_t)ml_get_len(lnum));
char *new_line = concat_str(new_start, sub_firstline + copycol);
// Position the cursor relative to the end of the line, the
@@ -3783,7 +3794,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
highlight_match = true;
update_topline(curwin);
- validate_cursor();
+ validate_cursor(curwin);
redraw_later(curwin, UPD_SOME_VALID);
show_cursor_info_later(true);
update_screen();
@@ -4243,7 +4254,7 @@ skip:
// when interactive leave cursor on the match
if (!subflags.do_ask) {
if (endcolumn) {
- coladvance(MAXCOL);
+ coladvance(curwin, MAXCOL);
} else {
beginline(BL_WHITE | BL_FIX);
}
@@ -4274,7 +4285,7 @@ skip:
if (subflags.do_ask && hasAnyFolding(curwin)) {
// Cursor position may require updating
- changed_window_setting();
+ changed_window_setting(curwin);
}
vim_regfree(regmatch.regprog);
@@ -4289,7 +4300,7 @@ skip:
// Show 'inccommand' preview if there are matched lines.
if (cmdpreview_ns > 0 && !aborting()) {
if (got_quit || profile_passed_limit(timeout)) { // Too slow, disable.
- set_string_option_direct(kOptInccommand, "", 0, SID_NONE);
+ set_option_direct(kOptInccommand, STATIC_CSTR_AS_OPTVAL(""), 0, SID_NONE);
} else if (*p_icm != NUL && pat != NULL) {
if (pre_hl_id == 0) {
pre_hl_id = syn_check_group(S_LEN("Substitute"));
@@ -4384,6 +4395,7 @@ void ex_global(exarg_T *eap)
char delim; // delimiter, normally '/'
char *pat;
+ size_t patlen;
regmmatch_T regmatch;
// When nesting the command works on one line. This allows for
@@ -4419,6 +4431,7 @@ void ex_global(exarg_T *eap)
}
cmd++;
pat = "";
+ patlen = 0;
} else if (*cmd == NUL) {
emsg(_("E148: Regular expression missing from global"));
return;
@@ -4428,6 +4441,7 @@ void ex_global(exarg_T *eap)
delim = *cmd; // get the delimiter
cmd++; // skip delimiter if there is one
pat = cmd; // remember start of pattern
+ patlen = strlen(pat);
cmd = skip_regexp_ex(cmd, delim, magic_isset(), &eap->arg, NULL, NULL);
if (cmd[0] == delim) { // end delimiter found
*cmd++ = NUL; // replace it with a NUL
@@ -4435,7 +4449,7 @@ void ex_global(exarg_T *eap)
}
char *used_pat;
- if (search_regcomp(pat, &used_pat, RE_BOTH, which_pat,
+ if (search_regcomp(pat, patlen, &used_pat, RE_BOTH, which_pat,
SEARCH_HIS, &regmatch) == FAIL) {
emsg(_(e_invcmd));
return;
@@ -4510,7 +4524,7 @@ void global_exe(char *cmd)
if (global_need_beginline) {
beginline(BL_WHITE | BL_FIX);
} else {
- check_cursor(); // cursor may be beyond the end of the line
+ check_cursor(curwin); // cursor may be beyond the end of the line
}
// the cursor may not have moved in the text but a change in a previous
@@ -4569,7 +4583,7 @@ bool prepare_tagpreview(bool undo_sync)
RESET_BINDING(curwin); // don't take over 'scrollbind' and 'cursorbind'
curwin->w_p_diff = false; // no 'diff'
- set_string_option_direct(kOptFoldcolumn, "0", 0, SID_NONE); // no 'foldcolumn'
+ set_option_direct(kOptFoldcolumn, STATIC_CSTR_AS_OPTVAL("0"), 0, SID_NONE); // no 'foldcolumn'
return true;
}
@@ -4588,7 +4602,7 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i
buf_T *cmdpreview_buf = NULL;
// disable file info message
- set_string_option_direct(kOptShortmess, "F", 0, SID_NONE);
+ set_option_direct(kOptShortmess, STATIC_CSTR_AS_OPTVAL("F"), 0, SID_NONE);
// Place cursor on nearest matching line, to undo do_sub() cursor placement.
for (size_t i = 0; i < lines.subresults.size; i++) {
@@ -4622,8 +4636,8 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i
}
char *str = NULL; // construct the line to show in here
- size_t old_line_size = 0;
- size_t line_size = 0;
+ colnr_T old_line_size = 0;
+ colnr_T line_size = 0;
linenr_T linenr_preview = 0; // last line added to preview buffer
linenr_T linenr_origbuf = 0; // last line added to original buffer
linenr_T next_linenr = 0; // next line to show for the match
@@ -4662,21 +4676,21 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i
line = "";
} else {
line = ml_get_buf(orig_buf, next_linenr);
- line_size = strlen(line) + (size_t)col_width + 1;
+ line_size = ml_get_buf_len(orig_buf, next_linenr) + col_width + 1;
// Reallocate if line not long enough
if (line_size > old_line_size) {
- str = xrealloc(str, line_size * sizeof(char));
+ str = xrealloc(str, (size_t)line_size * sizeof(char));
old_line_size = line_size;
}
}
// Put "|lnum| line" into `str` and append it to the preview buffer.
- snprintf(str, line_size, "|%*" PRIdLINENR "| %s", col_width - 3,
+ snprintf(str, (size_t)line_size, "|%*" PRIdLINENR "| %s", col_width - 3,
next_linenr, line);
if (linenr_preview == 0) {
ml_replace_buf(cmdpreview_buf, 1, str, true, false);
} else {
- ml_append_buf(cmdpreview_buf, linenr_preview, str, (colnr_T)line_size, false);
+ ml_append_buf(cmdpreview_buf, linenr_preview, str, line_size, false);
}
linenr_preview += 1;
}
@@ -4689,7 +4703,7 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i
xfree(str);
- set_string_option_direct(kOptShortmess, save_shm_p, 0, SID_NONE);
+ set_option_direct(kOptShortmess, CSTR_AS_OPTVAL(save_shm_p), 0, SID_NONE);
xfree(save_shm_p);
return preview ? 2 : 1;