Mercurial > vim
diff src/ex_docmd.c @ 22699:e82579016863 v8.2.1898
patch 8.2.1898: command modifier parsing always uses global cmdmod
Commit: https://github.com/vim/vim/commit/e10044015841711b989f9a898d427bcc1fdb4c32
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Oct 24 20:49:43 2020 +0200
patch 8.2.1898: command modifier parsing always uses global cmdmod
Problem: Command modifier parsing always uses global cmdmod.
Solution: Pass in cmdmod_T to use. Rename struct fields consistently.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 24 Oct 2020 21:00:05 +0200 |
parents | c996700d569f |
children | 51bc501a13ca |
line wrap: on
line diff
--- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -1711,7 +1711,6 @@ do_one_cmd( char *errormsg = NULL; // error message char_u *after_modifier = NULL; exarg_T ea; // Ex command arguments - int save_msg_scroll = msg_scroll; cmdmod_T save_cmdmod; int save_reg_executing = reg_executing; int ni; // set when Not Implemented @@ -1762,7 +1761,7 @@ do_one_cmd( ea.cstack = cstack; starts_with_colon = *skipwhite(ea.cmd) == ':'; #endif - if (parse_command_modifiers(&ea, &errormsg, FALSE) == FAIL) + if (parse_command_modifiers(&ea, &errormsg, &cmdmod, FALSE) == FAIL) goto doend; apply_cmdmod(&cmdmod); @@ -2598,7 +2597,7 @@ doend: ? cmdnames[(int)ea.cmdidx].cmd_name : (char_u *)NULL); #endif - undo_cmdmod(save_msg_scroll); + undo_cmdmod(&cmdmod); cmdmod = save_cmdmod; reg_executing = save_reg_executing; @@ -2633,25 +2632,31 @@ ex_errmsg(char *msg, char_u *arg) /* * Parse and skip over command modifiers: * - update eap->cmd - * - store flags in "cmdmod". + * - store flags in "cmod". * - Set ex_pressedreturn for an empty command line. - * - set msg_silent for ":silent" - * - set 'eventignore' to "all" for ":noautocmd" * When "skip_only" is TRUE the global variables are not changed, except for * "cmdmod". + * When "skip_only" is FALSE then undo_cmdmod() must be called later to free + * any cmod_filter_regmatch.regprog. * Call apply_cmdmod() to get the side effects of the modifiers: * - Increment "sandbox" for ":sandbox" * - set p_verbose for ":verbose" + * - set msg_silent for ":silent" + * - set 'eventignore' to "all" for ":noautocmd" * Return FAIL when the command is not to be executed. * May set "errormsg" to an error message. */ int -parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only) +parse_command_modifiers( + exarg_T *eap, + char **errormsg, + cmdmod_T *cmod, + int skip_only) { char_u *p; int starts_with_colon = FALSE; - CLEAR_FIELD(cmdmod); + CLEAR_POINTER(cmod); // Repeat until no more command modifiers are found. for (;;) @@ -2690,51 +2695,51 @@ parse_command_modifiers(exarg_T *eap, ch // When adding an entry, also modify cmd_exists(). case 'a': if (!checkforcmd(&eap->cmd, "aboveleft", 3)) break; - cmdmod.split |= WSP_ABOVE; + cmod->cmod_split |= WSP_ABOVE; continue; case 'b': if (checkforcmd(&eap->cmd, "belowright", 3)) { - cmdmod.split |= WSP_BELOW; + cmod->cmod_split |= WSP_BELOW; continue; } if (checkforcmd(&eap->cmd, "browse", 3)) { #ifdef FEAT_BROWSE_CMD - cmdmod.browse = TRUE; + cmod->cmod_flags |= CMOD_BROWSE; #endif continue; } if (!checkforcmd(&eap->cmd, "botright", 2)) break; - cmdmod.split |= WSP_BOT; + cmod->cmod_split |= WSP_BOT; continue; case 'c': if (!checkforcmd(&eap->cmd, "confirm", 4)) break; #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) - cmdmod.confirm = TRUE; + cmod->cmod_flags |= CMOD_CONFIRM; #endif continue; case 'k': if (checkforcmd(&eap->cmd, "keepmarks", 3)) { - cmdmod.keepmarks = TRUE; + cmod->cmod_flags |= CMOD_KEEPMARKS; continue; } if (checkforcmd(&eap->cmd, "keepalt", 5)) { - cmdmod.keepalt = TRUE; + cmod->cmod_flags |= CMOD_KEEPALT; continue; } if (checkforcmd(&eap->cmd, "keeppatterns", 5)) { - cmdmod.keeppatterns = TRUE; + cmod->cmod_flags |= CMOD_KEEPPATTERNS; continue; } if (!checkforcmd(&eap->cmd, "keepjumps", 5)) break; - cmdmod.keepjumps = TRUE; + cmod->cmod_flags |= CMOD_KEEPJUMPS; continue; case 'f': // only accept ":filter {pat} cmd" @@ -2746,7 +2751,7 @@ parse_command_modifiers(exarg_T *eap, ch break; if (*p == '!') { - cmdmod.filter_force = TRUE; + cmod->cmod_filter_force = TRUE; p = skipwhite(p + 1); if (*p == NUL || ends_excmd(*p)) break; @@ -2765,9 +2770,9 @@ parse_command_modifiers(exarg_T *eap, ch break; if (!skip_only) { - cmdmod.filter_regmatch.regprog = + cmod->cmod_filter_regmatch.regprog = vim_regcomp(reg_pat, RE_MAGIC); - if (cmdmod.filter_regmatch.regprog == NULL) + if (cmod->cmod_filter_regmatch.regprog == NULL) break; } eap->cmd = p; @@ -2779,48 +2784,48 @@ parse_command_modifiers(exarg_T *eap, ch || *p == NUL || ends_excmd(*p)) break; eap->cmd = p; - cmdmod.hide = TRUE; + cmod->cmod_flags |= CMOD_HIDE; continue; case 'l': if (checkforcmd(&eap->cmd, "lockmarks", 3)) { - cmdmod.lockmarks = TRUE; + cmod->cmod_flags |= CMOD_LOCKMARKS; continue; } if (!checkforcmd(&eap->cmd, "leftabove", 5)) break; - cmdmod.split |= WSP_ABOVE; + cmod->cmod_split |= WSP_ABOVE; continue; case 'n': if (checkforcmd(&eap->cmd, "noautocmd", 3)) { - cmdmod.cmod_flags |= CMOD_NOAUTOCMD; + cmod->cmod_flags |= CMOD_NOAUTOCMD; continue; } if (!checkforcmd(&eap->cmd, "noswapfile", 3)) break; - cmdmod.noswapfile = TRUE; + cmod->cmod_flags |= CMOD_NOSWAPFILE; continue; case 'r': if (!checkforcmd(&eap->cmd, "rightbelow", 6)) break; - cmdmod.split |= WSP_BELOW; + cmod->cmod_split |= WSP_BELOW; continue; case 's': if (checkforcmd(&eap->cmd, "sandbox", 3)) { - cmdmod.cmod_flags |= CMOD_SANDBOX; + cmod->cmod_flags |= CMOD_SANDBOX; continue; } if (!checkforcmd(&eap->cmd, "silent", 3)) break; - cmdmod.cmod_flags |= CMOD_SILENT; + cmod->cmod_flags |= CMOD_SILENT; if (*eap->cmd == '!' && !VIM_ISWHITE(eap->cmd[-1])) { // ":silent!", but not "silent !cmd" eap->cmd = skipwhite(eap->cmd + 1); - cmdmod.cmod_flags |= CMOD_ERRSILENT; + cmod->cmod_flags |= CMOD_ERRSILENT; } continue; @@ -2832,7 +2837,7 @@ parse_command_modifiers(exarg_T *eap, ch ADDR_TABS, eap->skip, skip_only, FALSE, 1); if (tabnr == MAXLNUM) - cmdmod.tab = tabpage_index(curtab) + 1; + cmod->cmod_tab = tabpage_index(curtab) + 1; else { if (tabnr < 0 || tabnr > LAST_TAB_NR) @@ -2840,7 +2845,7 @@ parse_command_modifiers(exarg_T *eap, ch *errormsg = _(e_invrange); return FAIL; } - cmdmod.tab = tabnr + 1; + cmod->cmod_tab = tabnr + 1; } } eap->cmd = p; @@ -2848,25 +2853,25 @@ parse_command_modifiers(exarg_T *eap, ch } if (!checkforcmd(&eap->cmd, "topleft", 2)) break; - cmdmod.split |= WSP_TOP; + cmod->cmod_split |= WSP_TOP; continue; case 'u': if (!checkforcmd(&eap->cmd, "unsilent", 3)) break; - cmdmod.cmod_flags |= CMOD_UNSILENT; + cmod->cmod_flags |= CMOD_UNSILENT; continue; case 'v': if (checkforcmd(&eap->cmd, "vertical", 4)) { - cmdmod.split |= WSP_VERT; + cmod->cmod_split |= WSP_VERT; continue; } if (!checkforcmd(&p, "verbose", 4)) break; if (vim_isdigit(*eap->cmd)) - cmdmod.cmod_verbose = atoi((char *)eap->cmd); + cmod->cmod_verbose = atoi((char *)eap->cmd); else - cmdmod.cmod_verbose = 1; + cmod->cmod_verbose = 1; eap->cmd = p; continue; } @@ -2899,7 +2904,10 @@ apply_cmdmod(cmdmod_T *cmod) if ((cmod->cmod_flags & (CMOD_SILENT | CMOD_UNSILENT)) && cmod->cmod_save_msg_silent == 0) + { cmod->cmod_save_msg_silent = msg_silent + 1; + cmod->cmod_save_msg_scroll = msg_scroll; + } if (cmod->cmod_flags & CMOD_SILENT) ++msg_silent; if (cmod->cmod_flags & CMOD_UNSILENT) @@ -2911,68 +2919,68 @@ apply_cmdmod(cmdmod_T *cmod) ++cmod->cmod_did_esilent; } - if ((cmod->cmod_flags & CMOD_NOAUTOCMD) && cmdmod.cmod_save_ei == NULL) + if ((cmod->cmod_flags & CMOD_NOAUTOCMD) && cmod->cmod_save_ei == NULL) { // Set 'eventignore' to "all". // First save the existing option value for restoring it later. - cmdmod.cmod_save_ei = vim_strsave(p_ei); + cmod->cmod_save_ei = vim_strsave(p_ei); set_string_option_direct((char_u *)"ei", -1, (char_u *)"all", OPT_FREE, SID_NONE); } } /* - * Undo and free contents of "cmdmod". + * Undo and free contents of "cmod". */ void -undo_cmdmod(int save_msg_scroll) -{ - if (cmdmod.cmod_verbose_save > 0) - { - p_verbose = cmdmod.cmod_verbose_save - 1; - cmdmod.cmod_verbose_save = 0; +undo_cmdmod(cmdmod_T *cmod) +{ + if (cmod->cmod_verbose_save > 0) + { + p_verbose = cmod->cmod_verbose_save - 1; + cmod->cmod_verbose_save = 0; } #ifdef HAVE_SANDBOX - if (cmdmod.cmod_did_sandbox) + if (cmod->cmod_did_sandbox) { --sandbox; - cmdmod.cmod_did_sandbox = FALSE; - } -#endif - - if (cmdmod.cmod_save_ei != NULL) + cmod->cmod_did_sandbox = FALSE; + } +#endif + + if (cmod->cmod_save_ei != NULL) { // Restore 'eventignore' to the value before ":noautocmd". - set_string_option_direct((char_u *)"ei", -1, cmdmod.cmod_save_ei, - OPT_FREE, SID_NONE); - free_string_option(cmdmod.cmod_save_ei); - cmdmod.cmod_save_ei = NULL; - } - - if (cmdmod.filter_regmatch.regprog != NULL) - vim_regfree(cmdmod.filter_regmatch.regprog); - - if (cmdmod.cmod_save_msg_silent > 0) + set_string_option_direct((char_u *)"ei", -1, cmod->cmod_save_ei, + OPT_FREE, SID_NONE); + free_string_option(cmod->cmod_save_ei); + cmod->cmod_save_ei = NULL; + } + + if (cmod->cmod_filter_regmatch.regprog != NULL) + vim_regfree(cmod->cmod_filter_regmatch.regprog); + + if (cmod->cmod_save_msg_silent > 0) { // messages could be enabled for a serious error, need to check if the // counters don't become negative - if (!did_emsg || msg_silent > cmdmod.cmod_save_msg_silent - 1) - msg_silent = cmdmod.cmod_save_msg_silent - 1; - emsg_silent -= cmdmod.cmod_did_esilent; + if (!did_emsg || msg_silent > cmod->cmod_save_msg_silent - 1) + msg_silent = cmod->cmod_save_msg_silent - 1; + emsg_silent -= cmod->cmod_did_esilent; if (emsg_silent < 0) emsg_silent = 0; // Restore msg_scroll, it's set by file I/O commands, even when no // message is actually displayed. - msg_scroll = save_msg_scroll; + msg_scroll = cmod->cmod_save_msg_scroll; // "silent reg" or "silent echo x" inside "redir" leaves msg_col // somewhere in the line. Put it back in the first column. if (redirecting()) msg_col = 0; - cmdmod.cmod_save_msg_silent = 0; - cmdmod.cmod_did_esilent = 0; + cmod->cmod_save_msg_silent = 0; + cmod->cmod_did_esilent = 0; } } @@ -5130,7 +5138,8 @@ check_more( if (message) { #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) - if ((p_confirm || cmdmod.confirm) && curbuf->b_fname != NULL) + if ((p_confirm || (cmdmod.cmod_flags & CMOD_CONFIRM)) + && curbuf->b_fname != NULL) { char_u buff[DIALOG_MSG_SIZE]; @@ -5450,7 +5459,7 @@ ex_win_close( if (need_hide && !buf_hide(buf) && !forceit) { #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) - if ((p_confirm || cmdmod.confirm) && p_write) + if ((p_confirm || (cmdmod.cmod_flags & CMOD_CONFIRM)) && p_write) { bufref_T bufref; @@ -6106,7 +6115,7 @@ ex_splitview(exarg_T *eap) #endif #ifdef FEAT_BROWSE char_u dot_path[] = "."; - int browse_flag = cmdmod.browse; + int save_cmod_flags = cmdmod.cmod_flags; #endif int use_tab = eap->cmdidx == CMD_tabedit || eap->cmdidx == CMD_tabfind @@ -6122,7 +6131,7 @@ ex_splitview(exarg_T *eap) #ifdef FEAT_QUICKFIX // A ":split" in the quickfix window works like ":new". Don't want two // quickfix windows. But it's OK when doing ":tab split". - if (bt_quickfix(curbuf) && cmdmod.tab == 0) + if (bt_quickfix(curbuf) && cmdmod.cmod_tab == 0) { if (eap->cmdidx == CMD_split) eap->cmdidx = CMD_new; @@ -6145,7 +6154,7 @@ ex_splitview(exarg_T *eap) # endif #endif #ifdef FEAT_BROWSE - if (cmdmod.browse + if ((cmdmod.cmod_flags & CMOD_BROWSE) && eap->cmdidx != CMD_vnew && eap->cmdidx != CMD_new) { @@ -6171,7 +6180,7 @@ ex_splitview(exarg_T *eap) eap->arg = fname; } } - cmdmod.browse = FALSE; // Don't browse again in do_ecmd(). + cmdmod.cmod_flags &= ~CMOD_BROWSE; // Don't browse again in do_ecmd(). #endif /* @@ -6179,7 +6188,7 @@ ex_splitview(exarg_T *eap) */ if (use_tab) { - if (win_new_tabpage(cmdmod.tab != 0 ? cmdmod.tab + if (win_new_tabpage(cmdmod.cmod_tab != 0 ? cmdmod.cmod_tab : eap->addr_count == 0 ? 0 : (int)eap->line2 + 1) != FAIL) { @@ -6189,7 +6198,7 @@ ex_splitview(exarg_T *eap) if (curwin != old_curwin && win_valid(old_curwin) && old_curwin->w_buffer != curbuf - && !cmdmod.keepalt) + && (cmdmod.cmod_flags & CMOD_KEEPALT) == 0) old_curwin->w_alt_fnum = curbuf->b_fnum; } } @@ -6198,11 +6207,7 @@ ex_splitview(exarg_T *eap) { // Reset 'scrollbind' when editing another file, but keep it when // doing ":split" without arguments. - if (*eap->arg != NUL -# ifdef FEAT_BROWSE - || cmdmod.browse -# endif - ) + if (*eap->arg != NUL) RESET_BINDING(curwin); else do_check_scrollbind(FALSE); @@ -6210,7 +6215,7 @@ ex_splitview(exarg_T *eap) } # ifdef FEAT_BROWSE - cmdmod.browse = browse_flag; + cmdmod.cmod_flags = save_cmod_flags; # endif # if defined(FEAT_SEARCHPATH) || defined(FEAT_BROWSE) @@ -6383,7 +6388,7 @@ ex_resize(exarg_T *eap) need_mouse_correct = TRUE; # endif n = atol((char *)eap->arg); - if (cmdmod.split & WSP_VERT) + if (cmdmod.cmod_split & WSP_VERT) { if (*eap->arg == '-' || *eap->arg == '+') n += wp->w_width; @@ -6564,7 +6569,7 @@ do_exedit( else if ((eap->cmdidx != CMD_split && eap->cmdidx != CMD_vsplit) || *eap->arg != NUL #ifdef FEAT_BROWSE - || cmdmod.browse + || (cmdmod.cmod_flags & CMOD_BROWSE) #endif ) { @@ -6653,7 +6658,7 @@ do_exedit( && curwin != old_curwin && win_valid(old_curwin) && old_curwin->w_buffer != curbuf - && !cmdmod.keepalt) + && (cmdmod.cmod_flags & CMOD_KEEPALT) == 0) old_curwin->w_alt_fnum = curbuf->b_fnum; ex_no_reprint = TRUE; @@ -6798,7 +6803,7 @@ ex_read(exarg_T *eap) return; #ifdef FEAT_BROWSE - if (cmdmod.browse) + if (cmdmod.cmod_flags & CMOD_BROWSE) { char_u *browseFile; @@ -7238,8 +7243,8 @@ ex_wincmd(exarg_T *eap) else if (!eap->skip) { // Pass flags on for ":vertical wincmd ]". - postponed_split_flags = cmdmod.split; - postponed_split_tab = cmdmod.tab; + postponed_split_flags = cmdmod.cmod_split; + postponed_split_tab = cmdmod.cmod_tab; do_window(*eap->arg, eap->addr_count > 0 ? eap->line2 : 0L, xchar); postponed_split_flags = 0; postponed_split_tab = 0; @@ -7642,7 +7647,7 @@ ex_redir(exarg_T *eap) if (fname == NULL) return; #ifdef FEAT_BROWSE - if (cmdmod.browse) + if (cmdmod.cmod_flags & CMOD_BROWSE) { char_u *browseFile; @@ -8314,8 +8319,8 @@ ex_pedit(exarg_T *eap) ex_stag(exarg_T *eap) { postponed_split = -1; - postponed_split_flags = cmdmod.split; - postponed_split_tab = cmdmod.tab; + postponed_split_flags = cmdmod.cmod_split; + postponed_split_tab = cmdmod.cmod_tab; ex_tag_cmd(eap, cmdnames[eap->cmdidx].cmd_name + 1); postponed_split_flags = 0; postponed_split_tab = 0;