diff options
Diffstat (limited to 'src/nvim/ex_cmds.c')
-rw-r--r-- | src/nvim/ex_cmds.c | 88 |
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), ®match) == 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, ®match) == 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; |