diff options
Diffstat (limited to 'src/nvim/ex_cmds.c')
-rw-r--r-- | src/nvim/ex_cmds.c | 163 |
1 files changed, 96 insertions, 67 deletions
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index e369397047..74ad8e95a2 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -18,6 +18,7 @@ #include "nvim/arglist.h" #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" +#include "nvim/autocmd_defs.h" #include "nvim/buffer.h" #include "nvim/buffer_defs.h" #include "nvim/buffer_updates.h" @@ -25,6 +26,7 @@ #include "nvim/change.h" #include "nvim/channel.h" #include "nvim/charset.h" +#include "nvim/cmdexpand_defs.h" #include "nvim/cmdhist.h" #include "nvim/cursor.h" #include "nvim/decoration.h" @@ -34,6 +36,7 @@ #include "nvim/edit.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" +#include "nvim/eval/typval_defs.h" #include "nvim/ex_cmds.h" #include "nvim/ex_cmds2.h" #include "nvim/ex_cmds_defs.h" @@ -41,22 +44,25 @@ #include "nvim/ex_eval.h" #include "nvim/ex_getln.h" #include "nvim/extmark.h" +#include "nvim/extmark_defs.h" #include "nvim/fileio.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/getchar.h" -#include "nvim/gettext.h" +#include "nvim/gettext_defs.h" #include "nvim/globals.h" #include "nvim/help.h" #include "nvim/highlight.h" +#include "nvim/highlight_defs.h" #include "nvim/highlight_group.h" #include "nvim/indent.h" #include "nvim/input.h" #include "nvim/macros_defs.h" #include "nvim/main.h" #include "nvim/mark.h" +#include "nvim/mark_defs.h" #include "nvim/mbyte.h" #include "nvim/memline.h" +#include "nvim/memline_defs.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/mouse.h" @@ -64,11 +70,14 @@ #include "nvim/normal.h" #include "nvim/ops.h" #include "nvim/option.h" +#include "nvim/option_defs.h" #include "nvim/option_vars.h" #include "nvim/optionstr.h" #include "nvim/os/fs.h" +#include "nvim/os/fs_defs.h" #include "nvim/os/input.h" #include "nvim/os/os.h" +#include "nvim/os/os_defs.h" #include "nvim/os/shell.h" #include "nvim/os/time.h" #include "nvim/path.h" @@ -77,6 +86,7 @@ #include "nvim/profile.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" +#include "nvim/regexp_defs.h" #include "nvim/search.h" #include "nvim/spell.h" #include "nvim/state_defs.h" @@ -84,6 +94,7 @@ #include "nvim/terminal.h" #include "nvim/types_defs.h" #include "nvim/ui.h" +#include "nvim/ui_defs.h" #include "nvim/undo.h" #include "nvim/vim_defs.h" #include "nvim/window.h" @@ -284,12 +295,12 @@ void ex_align(exarg_T *eap) // to the right. if (has_tab) { while (new_indent > 0) { - (void)set_indent(new_indent, 0); + set_indent(new_indent, 0); if (linelen(NULL) <= width) { // Now try to move the line as much as possible to // the right. Stop when it moves too far. do { - (void)set_indent(++new_indent, 0); + set_indent(++new_indent, 0); } while (linelen(NULL) <= width); new_indent--; break; @@ -302,7 +313,7 @@ void ex_align(exarg_T *eap) if (new_indent < 0) { new_indent = 0; } - (void)set_indent(new_indent, 0); // set indent + set_indent(new_indent, 0); // set indent } changed_lines(curbuf, eap->line1, 0, eap->line2 + 1, 0, true); curwin->w_cursor = save_curpos; @@ -342,13 +353,13 @@ static int linelen(int *has_tab) static char *sortbuf1; static char *sortbuf2; -static int sort_lc; ///< sort using locale -static int sort_ic; ///< ignore case -static int sort_nr; ///< sort on number -static int sort_rx; ///< sort on regex instead of skipping it -static int sort_flt; ///< sort on floating number +static bool sort_lc; ///< sort using locale +static bool sort_ic; ///< ignore case +static bool sort_nr; ///< sort on number +static bool sort_rx; ///< sort on regex instead of skipping it +static bool sort_flt; ///< sort on floating number -static int sort_abort; ///< flag to indicate if sorting has been interrupted +static bool sort_abort; ///< flag to indicate if sorting has been interrupted /// Struct to store info to be sorted. typedef struct { @@ -395,18 +406,16 @@ static int sort_compare(const void *s1, const void *s2) // number. if (sort_nr) { if (l1.st_u.num.is_number != l2.st_u.num.is_number) { - result = l1.st_u.num.is_number - l2.st_u.num.is_number; + result = l1.st_u.num.is_number > l2.st_u.num.is_number ? 1 : -1; } else { result = l1.st_u.num.value == l2.st_u.num.value ? 0 - : l1.st_u.num.value > l2.st_u.num.value - ? 1 - : -1; + : l1.st_u.num.value > l2.st_u.num.value ? 1 : -1; } } else if (sort_flt) { result = l1.st_u.value_flt == l2.st_u.value_flt - ? 0 : l1.st_u.value_flt > l2.st_u.value_flt - ? 1 : -1; + ? 0 + : l1.st_u.value_flt > l2.st_u.value_flt ? 1 : -1; } else { // We need to copy one line into "sortbuf1", because there is no // guarantee that the first pointer becomes invalid when obtaining the @@ -451,7 +460,7 @@ void ex_sort(exarg_T *eap) regmatch.regprog = NULL; sorti_T *nrs = xmalloc(count * sizeof(sorti_T)); - sort_abort = sort_ic = sort_lc = sort_rx = sort_nr = sort_flt = 0; + sort_abort = sort_ic = sort_lc = sort_rx = sort_nr = sort_flt = false; size_t format_found = 0; bool change_occurred = false; // Buffer contents changed. @@ -465,10 +474,10 @@ void ex_sort(exarg_T *eap) } else if (*p == 'r') { sort_rx = true; } else if (*p == 'n') { - sort_nr = 1; + sort_nr = true; format_found++; } else if (*p == 'f') { - sort_flt = 1; + sort_flt = true; format_found++; } else if (*p == 'b') { sort_what = STR2NR_BIN + STR2NR_FORCE; @@ -522,7 +531,7 @@ void ex_sort(exarg_T *eap) // From here on "sort_nr" is used as a flag for any integer number // sorting. - sort_nr += sort_what; + sort_nr |= sort_what; // Make an array with all line numbers. This avoids having to copy all // the lines into allocated memory. @@ -619,7 +628,8 @@ void ex_sort(exarg_T *eap) goto sortend; } - bcount_t old_count = 0, new_count = 0; + bcount_t old_count = 0; + bcount_t new_count = 0; // Insert the lines in the sorted order below the last one. linenr_T lnum = eap->line2; @@ -1305,7 +1315,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); - (void)call_shell(cmd, (ShellOpts)flags, NULL); + call_shell(cmd, (ShellOpts)flags, NULL); if (msg_silent == 0) { msg_didout = true; } @@ -1462,7 +1472,7 @@ void append_redir(char *const buf, const size_t buflen, const char *const opt, } } -void print_line_no_prefix(linenr_T lnum, int use_number, int list) +void print_line_no_prefix(linenr_T lnum, int use_number, bool list) { char numbuf[30]; @@ -1475,9 +1485,9 @@ void print_line_no_prefix(linenr_T lnum, int use_number, int list) } /// Print a text line. Also in silent mode ("ex -s"). -void print_line(linenr_T lnum, int use_number, int list) +void print_line(linenr_T lnum, int use_number, bool list) { - int save_silent = silent_mode; + bool save_silent = silent_mode; // apply :filter /pat/ if (message_filtered(ml_get(lnum))) { @@ -1486,7 +1496,7 @@ void print_line(linenr_T lnum, int use_number, int list) msg_start(); silent_mode = false; - info_message = true; // use os_msg(), not os_errmsg() + info_message = true; // use stdout, not stderr print_line_no_prefix(lnum, use_number, list); if (save_silent) { msg_putchar('\n'); @@ -1566,7 +1576,7 @@ void ex_file(exarg_T *eap) void ex_update(exarg_T *eap) { if (curbufIsChanged()) { - (void)do_write(eap); + do_write(eap); } } @@ -1582,7 +1592,7 @@ void ex_write(exarg_T *eap) if (eap->usefilter) { // input lines to shell command do_bang(1, eap, false, true, false); } else { - (void)do_write(eap); + do_write(eap); } } @@ -1605,7 +1615,7 @@ static int check_writable(const char *fname) /// @return FAIL for failure, OK otherwise. int do_write(exarg_T *eap) { - int other; + bool other; char *fname = NULL; // init to shut up gcc int retval = FAIL; char *free_fname = NULL; @@ -1724,7 +1734,7 @@ int do_write(exarg_T *eap) // If 'filetype' was empty try detecting it now. if (*curbuf->b_p_ft == NUL) { if (augroup_exists("filetypedetect")) { - (void)do_doautocmd("filetypedetect BufRead", true, NULL); + do_doautocmd("filetypedetect BufRead", true, NULL); } do_modelines(0); } @@ -1774,7 +1784,7 @@ theend: /// @param other writing under other name /// /// @return OK if it's OK, FAIL if it is not. -int check_overwrite(exarg_T *eap, buf_T *buf, char *fname, char *ffname, int other) +int check_overwrite(exarg_T *eap, buf_T *buf, char *fname, char *ffname, bool other) { // Write to another file or b_flags set or not writing the whole file: // overwriting only allowed with '!' @@ -1815,8 +1825,6 @@ int check_overwrite(exarg_T *eap, buf_T *buf, char *fname, char *ffname, int oth // For ":w! filename" check that no swap file exists for "filename". if (other && !emsg_silent) { char *dir; - char *p; - char *swapname; // We only try the first entry in 'directory', without checking if // it's writable. If the "." directory is not writable the write @@ -1828,10 +1836,10 @@ int check_overwrite(exarg_T *eap, buf_T *buf, char *fname, char *ffname, int oth STRCPY(dir, "."); } else { dir = xmalloc(MAXPATHL); - p = p_dir; + char *p = p_dir; copy_option_part(&p, dir, MAXPATHL, ","); } - swapname = makeswapname(fname, ffname, curbuf, dir); + char *swapname = makeswapname(fname, ffname, curbuf, dir); xfree(dir); if (os_path_exists(swapname)) { if (p_confirm || (cmdmod.cmod_flags & CMOD_CONFIRM)) { @@ -1998,11 +2006,11 @@ static int check_readonly(int *forceit, buf_T *buf) /// GETFILE_NOT_WRITTEN for "not written" error, /// GETFILE_SAME_FILE for success /// GETFILE_OPEN_OTHER for successfully opening another file. -int getfile(int fnum, char *ffname_arg, char *sfname_arg, int setpm, linenr_T lnum, int forceit) +int getfile(int fnum, char *ffname_arg, char *sfname_arg, bool setpm, linenr_T lnum, bool forceit) { char *ffname = ffname_arg; char *sfname = sfname_arg; - int other; + bool other; int retval; char *free_me = NULL; @@ -2179,7 +2187,7 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum | ((flags & ECMD_FORCEIT) ? CCGD_FORCEIT : 0) | (eap == NULL ? 0 : CCGD_EXCMD))) { if (fnum == 0 && other_file && ffname != NULL) { - (void)setaltfname(ffname, sfname, newlnum < 0 ? 0 : newlnum); + setaltfname(ffname, sfname, newlnum < 0 ? 0 : newlnum); } goto theend; } @@ -2270,7 +2278,7 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum // Existing memfile. oldbuf = true; set_bufref(&bufref, buf); - (void)buf_check_timestamp(buf); + buf_check_timestamp(buf); // Check if autocommands made buffer invalid or changed the current // buffer. if (!bufref_valid(&bufref) || curbuf != old_curbuf.br_buf) { @@ -2295,10 +2303,19 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum // If the current buffer was empty and has no file name, curbuf // is returned by buflist_new(), nothing to do here. if (buf != curbuf) { + // Should only be possible to get here if the cmdwin is closed, or + // if it's opening and its buffer hasn't been set yet (the new + // buffer is for it). + assert(cmdwin_buf == NULL); + const int save_cmdwin_type = cmdwin_type; + win_T *const save_cmdwin_win = cmdwin_win; + win_T *const save_cmdwin_old_curwin = cmdwin_old_curwin; // BufLeave applies to the old buffer. cmdwin_type = 0; + cmdwin_win = NULL; + cmdwin_old_curwin = NULL; // Be careful: The autocommands may delete any buffer and change // the current buffer. @@ -2314,7 +2331,11 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum const bufref_T save_au_new_curbuf = au_new_curbuf; set_bufref(&au_new_curbuf, buf); apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf); + cmdwin_type = save_cmdwin_type; + cmdwin_win = save_cmdwin_win; + cmdwin_old_curwin = save_cmdwin_old_curwin; + if (!bufref_valid(&au_new_curbuf)) { // New buffer has been deleted. delbuf_msg(new_name); // Frees new_name. @@ -2606,7 +2627,7 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum // If the window options were changed may need to set the spell language. // Can only do this after the buffer has been properly setup. if (did_get_winopts && curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL) { - (void)parse_spelllang(curwin); + parse_spelllang(curwin); } if (command == NULL) { @@ -2669,7 +2690,7 @@ int do_ecmd(int fnum, char *ffname, char *sfname, exarg_T *eap, linenr_T newlnum } if (curbuf->b_kmap_state & KEYMAP_INIT) { - (void)keymap_init(); + keymap_init(); } RedrawingDisabled--; @@ -2722,7 +2743,7 @@ void ex_append(exarg_T *eap) linenr_T lnum = eap->line2; int indent = 0; char *p; - int empty = (curbuf->b_ml.ml_flags & ML_EMPTY); + bool empty = (curbuf->b_ml.ml_flags & ML_EMPTY); // the ! flag toggles autoindent if (eap->forceit) { @@ -2824,7 +2845,7 @@ void ex_append(exarg_T *eap) if (empty) { ml_delete(2, false); - empty = 0; + empty = false; } } State = MODE_NORMAL; @@ -3144,7 +3165,7 @@ static char *sub_grow_buf(char **new_start, int *new_start_len, int needed_len) // substitution into (and some extra space to avoid // too many calls to xmalloc()/free()). *new_start_len = needed_len + 50; - *new_start = xmalloc((size_t)(*new_start_len)); + *new_start = xcalloc(1, (size_t)(*new_start_len)); **new_start = NUL; new_end = *new_start; } else { @@ -3154,8 +3175,11 @@ static char *sub_grow_buf(char **new_start, int *new_start_len, int needed_len) size_t len = strlen(*new_start); needed_len += (int)len; if (needed_len > *new_start_len) { + size_t prev_new_start_len = (size_t)(*new_start_len); *new_start_len = needed_len + 50; + size_t added_len = (size_t)(*new_start_len) - prev_new_start_len; *new_start = xrealloc(*new_start, (size_t)(*new_start_len)); + memset(*new_start + prev_new_start_len, 0, added_len); } new_end = *new_start + len; } @@ -3261,7 +3285,7 @@ static int check_regexp_delim(int c) /// /// @param cmdpreview_ns The namespace to show 'inccommand' preview highlights. /// If <= 0, preview shouldn't be shown. -/// @return 0, 1 or 2. See show_cmdpreview() for more information on what the return value means. +/// @return 0, 1 or 2. See cmdpreview_may_show() for more information on the meaning. static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_ns, const handle_T cmdpreview_bufnr) { @@ -3301,7 +3325,8 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n .do_number = false, .do_ic = kSubHonorOptions }; - char *pat = NULL, *sub = NULL; // init for GCC + char *pat = NULL; + char *sub = NULL; // init for GCC int delimiter; bool has_second_delim = false; int sublen; @@ -3499,7 +3524,8 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n colnr_T copycol; colnr_T matchcol; colnr_T prev_matchcol = MAXCOL; - char *new_end, *new_start = NULL; + char *new_end; + char *new_start = NULL; int new_start_len = 0; char *p1; bool did_sub = false; @@ -3949,11 +3975,11 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n current_match.start.col = start_col; textlock++; - (void)vim_regsub_multi(®match, - sub_firstlnum - regmatch.startpos[0].lnum, - sub, new_end, sublen, - REGSUB_COPY | REGSUB_BACKSLASH - | (magic_isset() ? REGSUB_MAGIC : 0)); + vim_regsub_multi(®match, + sub_firstlnum - regmatch.startpos[0].lnum, + sub, new_end, sublen, + REGSUB_COPY | REGSUB_BACKSLASH + | (magic_isset() ? REGSUB_MAGIC : 0)); textlock--; sub_nsubs++; did_sub = true; @@ -3969,7 +3995,8 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n // TODO(bfredl): this has some robustness issues, look into later. bcount_t replaced_bytes = 0; - lpos_T start = regmatch.startpos[0], end = regmatch.endpos[0]; + lpos_T start = regmatch.startpos[0]; + lpos_T end = regmatch.endpos[0]; for (i = 0; i < nmatch - 1; i++) { replaced_bytes += (bcount_t)strlen(ml_get((linenr_T)(lnum_start + i))) + 1; } @@ -4262,7 +4289,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("icm", -1, "", OPT_FREE, SID_NONE); + set_string_option_direct(kOptInccommand, "", 0, SID_NONE); } else if (*p_icm != NUL && pat != NULL) { if (pre_hl_id == 0) { pre_hl_id = syn_check_group(S_LEN("Substitute")); @@ -4541,8 +4568,8 @@ bool prepare_tagpreview(bool undo_sync) curwin->w_p_wfh = true; RESET_BINDING(curwin); // don't take over 'scrollbind' and 'cursorbind' curwin->w_p_diff = false; // no 'diff' - set_string_option_direct("fdc", -1, // no 'foldcolumn' - "0", OPT_FREE, SID_NONE); + + set_string_option_direct(kOptFoldcolumn, "0", 0, SID_NONE); // no 'foldcolumn' return true; } @@ -4561,10 +4588,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("shm", -1, "F", OPT_FREE, SID_NONE); - - // Update the topline to ensure that main window is on the correct line - update_topline(curwin); + set_string_option_direct(kOptShortmess, "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++) { @@ -4576,8 +4600,10 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i } // Else: All matches are above, do_sub() already placed cursor. } + // Update the topline to ensure that main window is on the correct line + update_topline(curwin); + // Width of the "| lnum|..." column which displays the line numbers. - linenr_T highest_num_line = 0; int col_width = 0; // Use preview window only when inccommand=split and range is not just the current line bool preview = (*p_icm == 's') && (eap->line1 != old_cusr.lnum || eap->line2 != old_cusr.lnum); @@ -4587,8 +4613,11 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i assert(cmdpreview_buf != NULL); if (lines.subresults.size > 0) { - highest_num_line = kv_last(lines.subresults).end.lnum; - col_width = (int)log10(highest_num_line) + 1 + 3; + SubResult last_match = kv_last(lines.subresults); + // `last_match.end.lnum` may be 0 when using 'n' flag. + linenr_T highest_lnum = MAX(last_match.start.lnum, last_match.end.lnum); + assert(highest_lnum > 0); + col_width = (int)log10(highest_lnum) + 1 + 3; } } @@ -4645,7 +4674,7 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i snprintf(str, line_size, "|%*" PRIdLINENR "| %s", col_width - 3, next_linenr, line); if (linenr_preview == 0) { - ml_replace_buf(cmdpreview_buf, 1, str, true); + ml_replace_buf(cmdpreview_buf, 1, str, true, false); } else { ml_append_buf(cmdpreview_buf, linenr_preview, str, (colnr_T)line_size, false); } @@ -4660,7 +4689,7 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i xfree(str); - set_string_option_direct("shm", -1, save_shm_p, OPT_FREE, SID_NONE); + set_string_option_direct(kOptShortmess, save_shm_p, 0, SID_NONE); xfree(save_shm_p); return preview ? 2 : 1; @@ -4669,7 +4698,7 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i /// :substitute command. void ex_substitute(exarg_T *eap) { - (void)do_sub(eap, profile_zero(), 0, 0); + do_sub(eap, profile_zero(), 0, 0); } /// :substitute command preview callback. |