summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ex_cmds.h6
-rw-r--r--src/ex_docmd.c155
-rw-r--r--src/proto/ex_docmd.pro3
-rw-r--r--src/structs.h23
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c8
6 files changed, 115 insertions, 82 deletions
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
index 0b52c11ee0..d53b6df6d2 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -1884,12 +1884,6 @@ struct exarg
#ifdef FEAT_EVAL
cstack_T *cstack; // condition stack for ":if" etc.
#endif
- long verbose_save; // saved value of p_verbose
- int save_msg_silent; // saved value of msg_silent
- int did_esilent; // how many times emsg_silent was incremented
-#ifdef HAVE_SANDBOX
- int did_sandbox; // when TRUE did ++sandbox
-#endif
};
#define FORCE_BIN 1 // ":edit ++bin file"
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 665a46146d..1e1b8e3a46 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -1764,6 +1764,7 @@ do_one_cmd(
#endif
if (parse_command_modifiers(&ea, &errormsg, FALSE) == FAIL)
goto doend;
+ apply_cmdmod(&cmdmod);
after_modifier = ea.cmd;
@@ -2515,12 +2516,12 @@ do_one_cmd(
// The :try command saves the emsg_silent flag, reset it here when
// ":silent! try" was used, it should only apply to :try itself.
- if (ea.cmdidx == CMD_try && ea.did_esilent > 0)
+ if (ea.cmdidx == CMD_try && cmdmod.cmod_did_esilent > 0)
{
- emsg_silent -= ea.did_esilent;
+ emsg_silent -= cmdmod.cmod_did_esilent;
if (emsg_silent < 0)
emsg_silent = 0;
- ea.did_esilent = 0;
+ cmdmod.cmod_did_esilent = 0;
}
/*
@@ -2597,15 +2598,10 @@ doend:
? cmdnames[(int)ea.cmdidx].cmd_name : (char_u *)NULL);
#endif
- undo_cmdmod(&ea, save_msg_scroll);
+ undo_cmdmod(save_msg_scroll);
cmdmod = save_cmdmod;
reg_executing = save_reg_executing;
-#ifdef HAVE_SANDBOX
- if (ea.did_sandbox)
- --sandbox;
-#endif
-
if (ea.nextcmd && *ea.nextcmd == NUL) // not really a next command
ea.nextcmd = NULL;
@@ -2641,10 +2637,11 @@ ex_errmsg(char *msg, char_u *arg)
* - Set ex_pressedreturn for an empty command line.
* - set msg_silent for ":silent"
* - set 'eventignore' to "all" for ":noautocmd"
- * - set p_verbose for ":verbose"
- * - Increment "sandbox" for ":sandbox"
* When "skip_only" is TRUE the global variables are not changed, except for
* "cmdmod".
+ * Call apply_cmdmod() to get the side effects of the modifiers:
+ * - Increment "sandbox" for ":sandbox"
+ * - set p_verbose for ":verbose"
* Return FAIL when the command is not to be executed.
* May set "errormsg" to an error message.
*/
@@ -2655,8 +2652,6 @@ parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only)
int starts_with_colon = FALSE;
CLEAR_FIELD(cmdmod);
- eap->verbose_save = -1;
- eap->save_msg_silent = -1;
// Repeat until no more command modifiers are found.
for (;;)
@@ -2800,14 +2795,7 @@ parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only)
case 'n': if (checkforcmd(&eap->cmd, "noautocmd", 3))
{
- if (cmdmod.save_ei == NULL && !skip_only)
- {
- // Set 'eventignore' to "all". Restore the
- // existing option value later.
- cmdmod.save_ei = vim_strsave(p_ei);
- set_string_option_direct((char_u *)"ei", -1,
- (char_u *)"all", OPT_FREE, SID_NONE);
- }
+ cmdmod.cmod_flags |= CMOD_NOAUTOCMD;
continue;
}
if (!checkforcmd(&eap->cmd, "noswapfile", 3))
@@ -2822,37 +2810,18 @@ parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only)
case 's': if (checkforcmd(&eap->cmd, "sandbox", 3))
{
-#ifdef HAVE_SANDBOX
- if (!skip_only)
- {
- if (!eap->did_sandbox)
- ++sandbox;
- eap->did_sandbox = TRUE;
- }
-#endif
+ cmdmod.cmod_flags |= CMOD_SANDBOX;
continue;
}
if (!checkforcmd(&eap->cmd, "silent", 3))
break;
- if (!skip_only)
- {
- if (eap->save_msg_silent == -1)
- eap->save_msg_silent = msg_silent;
- ++msg_silent;
- }
+ cmdmod.cmod_flags |= CMOD_SILENT;
if (*eap->cmd == '!' && !VIM_ISWHITE(eap->cmd[-1]))
{
// ":silent!", but not "silent !cmd"
eap->cmd = skipwhite(eap->cmd + 1);
- if (!skip_only)
- {
- ++emsg_silent;
- ++eap->did_esilent;
- }
- cmdmod.emsg_silent = TRUE;
+ cmdmod.cmod_flags |= CMOD_ERRSILENT;
}
- else
- cmdmod.msg_silent = TRUE;
continue;
case 't': if (checkforcmd(&p, "tab", 3))
@@ -2884,12 +2853,7 @@ parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only)
case 'u': if (!checkforcmd(&eap->cmd, "unsilent", 3))
break;
- if (!skip_only)
- {
- if (eap->save_msg_silent == -1)
- eap->save_msg_silent = msg_silent;
- msg_silent = 0;
- }
+ cmdmod.cmod_flags |= CMOD_UNSILENT;
continue;
case 'v': if (checkforcmd(&eap->cmd, "vertical", 4))
@@ -2899,15 +2863,10 @@ parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only)
}
if (!checkforcmd(&p, "verbose", 4))
break;
- if (!skip_only)
- {
- if (eap->verbose_save < 0)
- eap->verbose_save = p_verbose;
- if (vim_isdigit(*eap->cmd))
- p_verbose = atoi((char *)eap->cmd);
- else
- p_verbose = 1;
- }
+ if (vim_isdigit(*eap->cmd))
+ cmdmod.cmod_verbose = atoi((char *)eap->cmd);
+ else
+ cmdmod.cmod_verbose = 1;
eap->cmd = p;
continue;
}
@@ -2918,32 +2877,89 @@ parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only)
}
/*
+ * Apply the command modifiers. Saves current state in "cmdmod", call
+ * undo_cmdmod() later.
+ */
+ void
+apply_cmdmod(cmdmod_T *cmod)
+{
+#ifdef HAVE_SANDBOX
+ if ((cmod->cmod_flags & CMOD_SANDBOX) && !cmod->cmod_did_sandbox)
+ {
+ ++sandbox;
+ cmod->cmod_did_sandbox = TRUE;
+ }
+#endif
+ if (cmod->cmod_verbose > 0)
+ {
+ if (cmod->cmod_verbose_save == 0)
+ cmod->cmod_verbose_save = p_verbose + 1;
+ p_verbose = cmod->cmod_verbose;
+ }
+
+ if ((cmod->cmod_flags & (CMOD_SILENT | CMOD_UNSILENT))
+ && cmod->cmod_save_msg_silent == 0)
+ cmod->cmod_save_msg_silent = msg_silent + 1;
+ if (cmod->cmod_flags & CMOD_SILENT)
+ ++msg_silent;
+ if (cmod->cmod_flags & CMOD_UNSILENT)
+ msg_silent = 0;
+
+ if (cmod->cmod_flags & CMOD_ERRSILENT)
+ {
+ ++emsg_silent;
+ ++cmod->cmod_did_esilent;
+ }
+
+ if ((cmod->cmod_flags & CMOD_NOAUTOCMD) && cmdmod.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);
+ set_string_option_direct((char_u *)"ei", -1,
+ (char_u *)"all", OPT_FREE, SID_NONE);
+ }
+}
+
+/*
* Undo and free contents of "cmdmod".
*/
void
-undo_cmdmod(exarg_T *eap, int save_msg_scroll)
+undo_cmdmod(int save_msg_scroll)
{
- if (eap->verbose_save >= 0)
- p_verbose = eap->verbose_save;
+ if (cmdmod.cmod_verbose_save > 0)
+ {
+ p_verbose = cmdmod.cmod_verbose_save - 1;
+ cmdmod.cmod_verbose_save = 0;
+ }
- if (cmdmod.save_ei != NULL)
+#ifdef HAVE_SANDBOX
+ if (cmdmod.cmod_did_sandbox)
+ {
+ --sandbox;
+ cmdmod.cmod_did_sandbox = FALSE;
+ }
+#endif
+
+ if (cmdmod.cmod_save_ei != NULL)
{
// Restore 'eventignore' to the value before ":noautocmd".
- set_string_option_direct((char_u *)"ei", -1, cmdmod.save_ei,
+ set_string_option_direct((char_u *)"ei", -1, cmdmod.cmod_save_ei,
OPT_FREE, SID_NONE);
- free_string_option(cmdmod.save_ei);
+ 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 (eap->save_msg_silent != -1)
+ if (cmdmod.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 > eap->save_msg_silent)
- msg_silent = eap->save_msg_silent;
- emsg_silent -= eap->did_esilent;
+ 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 (emsg_silent < 0)
emsg_silent = 0;
// Restore msg_scroll, it's set by file I/O commands, even when no
@@ -2954,6 +2970,9 @@ undo_cmdmod(exarg_T *eap, int save_msg_scroll)
// 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;
}
}
diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro
index 7d46f15d51..32fada57fa 100644
--- a/src/proto/ex_docmd.pro
+++ b/src/proto/ex_docmd.pro
@@ -7,7 +7,8 @@ void *getline_cookie(char_u *(*fgetline)(int, void *, int, getline_opt_T), void
char_u *getline_peek(char_u *(*fgetline)(int, void *, int, getline_opt_T), void *cookie);
char *ex_errmsg(char *msg, char_u *arg);
int parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only);
-void undo_cmdmod(exarg_T *eap, int save_msg_scroll);
+void apply_cmdmod(cmdmod_T *cmod);
+void undo_cmdmod(int save_msg_scroll);
int parse_cmd_address(exarg_T *eap, char **errormsg, int silent);
int checkforcmd(char_u **pp, char *cmd, int len);
char_u *skip_option_env_lead(char_u *start);
diff --git a/src/structs.h b/src/structs.h
index f01598e7ad..98f8c9a51d 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -625,6 +625,7 @@ typedef struct
*/
typedef struct
{
+ int cmod_flags; // CMOD_ flags, see below
int hide; // TRUE when ":hide" was used
# ifdef FEAT_BROWSE_CMD
int browse; // TRUE to invoke file dialog
@@ -640,13 +641,29 @@ typedef struct
int lockmarks; // TRUE when ":lockmarks" was used
int keeppatterns; // TRUE when ":keeppatterns" was used
int noswapfile; // TRUE when ":noswapfile" was used
- char_u *save_ei; // saved value of 'eventignore'
regmatch_T filter_regmatch; // set by :filter /pat/
int filter_force; // set for :filter!
- int msg_silent; // TRUE when ":silent" was used
- int emsg_silent; // TRUE when ":silent!" was used
+
+ int cmod_verbose; // non-zero to set 'verbose'
+
+ // values for undo_cmdmod()
+ char_u *cmod_save_ei; // saved value of 'eventignore'
+#ifdef HAVE_SANDBOX
+ int cmod_did_sandbox; // set when "sandbox" was incremented
+#endif
+ long cmod_verbose_save; // if 'verbose' was set: value of
+ // p_verbose plus one
+ int cmod_save_msg_silent; // if non-zero: saved value of
+ // msg_silent + 1
+ int cmod_did_esilent; // incremented when emsg_silent is
} cmdmod_T;
+#define CMOD_SANDBOX 0x01
+#define CMOD_SILENT 0x02
+#define CMOD_ERRSILENT 0x04
+#define CMOD_UNSILENT 0x08
+#define CMOD_NOAUTOCMD 0x10
+
#define MF_SEED_LEN 8
struct memfile
diff --git a/src/version.c b/src/version.c
index a1ee33e1ac..cdf0be38c2 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1897,
+/**/
1896,
/**/
1895,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index 4219577086..4c5c8d9aae 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -1831,12 +1831,12 @@ generate_cmdmods(cctx_T *cctx)
isn_T *isn;
// TODO: use more modifiers in the command
- if (cmdmod.msg_silent || cmdmod.emsg_silent)
+ if (cmdmod.cmod_flags & (CMOD_SILENT | CMOD_ERRSILENT))
{
if ((isn = generate_instr(cctx, ISN_SILENT)) == NULL)
return FAIL;
- isn->isn_arg.number = cmdmod.emsg_silent;
- cctx->ctx_silent = cmdmod.emsg_silent ? 2 : 1;
+ isn->isn_arg.number = (cmdmod.cmod_flags & CMOD_ERRSILENT) != 0;
+ cctx->ctx_silent = (cmdmod.cmod_flags & CMOD_ERRSILENT) ? 2 : 1;
}
return OK;
}
@@ -7187,7 +7187,7 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
}
generate_cmdmods(&cctx);
- undo_cmdmod(&ea, save_msg_scroll);
+ undo_cmdmod(save_msg_scroll);
cmdmod = save_cmdmod;
// Skip ":call" to get to the function name.