aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAufar Gilbran <aufargilbran@gmail.com>2020-08-29 02:18:46 +0800
committerAufar Gilbran <aufargilbran@gmail.com>2020-09-11 10:33:20 +0800
commitba59ee9a15d1febec7eebf0c91e949c17d8bbc0c (patch)
tree25a03676a53c285a71c5c9463b2282ef5a976c60 /src
parent9a6fd99a4b316425328affacdbd1e6868753dee5 (diff)
downloadrneovim-ba59ee9a15d1febec7eebf0c91e949c17d8bbc0c.tar.gz
rneovim-ba59ee9a15d1febec7eebf0c91e949c17d8bbc0c.tar.bz2
rneovim-ba59ee9a15d1febec7eebf0c91e949c17d8bbc0c.zip
ex_docmd: merge parse_state_T with exarg_T
Diffstat (limited to 'src')
-rw-r--r--src/nvim/ex_cmds_defs.h4
-rw-r--r--src/nvim/ex_docmd.c270
2 files changed, 94 insertions, 180 deletions
diff --git a/src/nvim/ex_cmds_defs.h b/src/nvim/ex_cmds_defs.h
index 1f0560ae48..ff5088ea5e 100644
--- a/src/nvim/ex_cmds_defs.h
+++ b/src/nvim/ex_cmds_defs.h
@@ -169,6 +169,10 @@ struct exarg {
LineGetter getline; ///< Function used to get the next line
void *cookie; ///< argument for getline()
cstack_T *cstack; ///< condition stack for ":if" etc.
+ 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
+ bool did_sandbox; ///< when true did sandbox++
};
#define FORCE_BIN 1 // ":edit ++bin file"
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 73c4332543..9b0e05b19f 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -137,32 +137,6 @@ struct dbg_stuff {
except_T *current_exception;
};
-typedef struct {
- // parsed results
- exarg_T *eap;
- char_u *parsed_upto; // local we've parsed up to so far
- char_u *cmd; // start of command
- char_u *after_modifier;
-
- // errors
- char_u *errormsg;
-
- // globals that need to be updated
- cmdmod_T cmdmod;
- int sandbox;
- int msg_silent;
- int emsg_silent;
- bool ex_pressedreturn;
- long p_verbose;
-
- // other side-effects
- bool set_eventignore;
- long verbose_save;
- int save_msg_silent;
- int did_esilent;
- bool did_sandbox;
-} parse_state_T;
-
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_docmd.c.generated.h"
#endif
@@ -1235,89 +1209,6 @@ static char_u *skip_colon_white(const char_u *p, bool skipleadingwhite)
return (char_u *)p;
}
-static void parse_state_to_global(const parse_state_T *parse_state)
-{
- cmdmod = parse_state->cmdmod;
- sandbox = parse_state->sandbox;
- msg_silent = parse_state->msg_silent;
- emsg_silent = parse_state->emsg_silent;
- ex_pressedreturn = parse_state->ex_pressedreturn;
- p_verbose = parse_state->p_verbose;
-
- if (parse_state->set_eventignore) {
- set_string_option_direct(
- (char_u *)"ei", -1, (char_u *)"all", OPT_FREE, SID_NONE);
- }
-}
-
-static void parse_state_from_global(parse_state_T *parse_state)
-{
- memset(parse_state, 0, sizeof(*parse_state));
- parse_state->cmdmod = cmdmod;
- parse_state->sandbox = sandbox;
- parse_state->msg_silent = msg_silent;
- parse_state->emsg_silent = emsg_silent;
- parse_state->ex_pressedreturn = ex_pressedreturn;
- parse_state->p_verbose = p_verbose;
-}
-
-//
-// Parse one Ex command.
-//
-// This has no side-effects, except for modifying parameters
-// passed in by pointer.
-//
-// The `out` should be zeroed, and its `ea` member initialised,
-// before calling this function.
-//
-static bool parse_one_cmd(
- char_u **cmdlinep,
- parse_state_T *const out,
- cstack_T *cstack,
- LineGetter fgetline,
- void *fgetline_cookie)
-{
- exarg_T ea = {
- .line1 = 1,
- .line2 = 1,
- };
- *out->eap = ea;
-
- // "#!anything" is handled like a comment.
- if ((*cmdlinep)[0] == '#' && (*cmdlinep)[1] == '!') {
- return false;
- }
-
- /*
- * Repeat until no more command modifiers are found.
- * The "ea" structure holds the arguments that can be used.
- */
- ea.cmd = *cmdlinep;
- ea.cmdlinep = cmdlinep;
- ea.getline = fgetline;
- ea.cookie = fgetline_cookie;
- ea.cstack = cstack;
- if (parse_command_modifiers(&ea, out, &out->errormsg) == FAIL) {
- return false;
- }
- out->after_modifier = ea.cmd;
-
- // 3. Skip over the range to find the command. Let "p" point to after it.
- //
- // We need the command to know what kind of range it uses.
-
- out->cmd = ea.cmd;
- ea.cmd = skip_range(ea.cmd, NULL);
- if (*ea.cmd == '*') {
- ea.cmd = skipwhite(ea.cmd + 1);
- }
- out->parsed_upto = find_command(&ea, NULL);
-
- *out->eap = ea;
-
- return true;
-}
-
/*
* Execute one Ex command.
*
@@ -1346,12 +1237,16 @@ static char_u * do_one_cmd(char_u **cmdlinep,
linenr_T lnum;
long n;
char_u *errormsg = NULL; // error message
+ char_u *after_modifier = NULL;
exarg_T ea;
int save_msg_scroll = msg_scroll;
- parse_state_T parsed;
cmdmod_T save_cmdmod;
const int save_reg_executing = reg_executing;
+ char_u *cmd;
+ memset(&ea, 0, sizeof(ea));
+ ea.line1 = 1;
+ ea.line2 = 1;
ex_nesting_level++;
/* When the last file has not been edited :q has to be typed twice. */
@@ -1369,29 +1264,43 @@ static char_u * do_one_cmd(char_u **cmdlinep,
*/
save_cmdmod = cmdmod;
- parse_state_from_global(&parsed);
- parsed.eap = &ea;
- parsed.verbose_save = -1;
- parsed.save_msg_silent = -1;
- parsed.did_esilent = 0;
- parsed.did_sandbox = false;
- bool parse_success = parse_one_cmd(cmdlinep, &parsed, cstack, fgetline, cookie);
- parse_state_to_global(&parsed);
+ // "#!anything" is handled like a comment.
+ if ((*cmdlinep)[0] == '#' && (*cmdlinep)[1] == '!') {
+ goto doend;
+ }
- // Update locals from parse_one_cmd()
- errormsg = parsed.errormsg;
- p = parsed.parsed_upto;
+ /*
+ * Repeat until no more command modifiers are found.
+ * The "ea" structure holds the arguments that can be used.
+ */
+ ea.cmd = *cmdlinep;
+ ea.cmdlinep = cmdlinep;
+ ea.getline = fgetline;
+ ea.cookie = cookie;
+ ea.cstack = cstack;
- if (!parse_success) {
+ if (parse_command_modifiers(&ea, &errormsg) == FAIL) {
goto doend;
}
+ after_modifier = ea.cmd;
+
ea.skip = (did_emsg
|| got_int
|| current_exception
|| (cstack->cs_idx >= 0
&& !(cstack->cs_flags[cstack->cs_idx] & CSF_ACTIVE)));
+ // 3. Skip over the range to find the command. Let "p" point to after it.
+ //
+ // We need the command to know what kind of range it uses.
+ cmd = ea.cmd;
+ ea.cmd = skip_range(ea.cmd, NULL);
+ if (*ea.cmd == '*') {
+ ea.cmd = skipwhite(ea.cmd + 1);
+ }
+ p = find_command(&ea, NULL);
+
// Count this line for profiling if skip is TRUE.
if (do_profiling == PROF_YES
&& (!ea.skip || cstack->cs_idx == 0
@@ -1461,7 +1370,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
}
}
- ea.cmd = parsed.cmd;
+ ea.cmd = cmd;
if (parse_cmd_address(&ea, &errormsg) == FAIL) {
goto doend;
}
@@ -1542,8 +1451,8 @@ static char_u * do_one_cmd(char_u **cmdlinep,
if (!(flags & DOCMD_VERBOSE)) {
// If the modifier was parsed OK the error must be in the following
// command
- if (parsed.after_modifier != NULL) {
- append_command(parsed.after_modifier);
+ if (after_modifier != NULL) {
+ append_command(after_modifier);
} else {
append_command(*cmdlinep);
}
@@ -2018,12 +1927,12 @@ static char_u * do_one_cmd(char_u **cmdlinep,
// 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 && parsed.did_esilent > 0) {
- emsg_silent -= parsed.did_esilent;
+ if (ea.cmdidx == CMD_try && ea.did_esilent > 0) {
+ emsg_silent -= ea.did_esilent;
if (emsg_silent < 0) {
emsg_silent = 0;
}
- parsed.did_esilent = 0;
+ ea.did_esilent = 0;
}
// 7. Execute the command.
@@ -2082,8 +1991,8 @@ doend:
? cmdnames[(int)ea.cmdidx].cmd_name
: (char_u *)NULL);
- if (parsed.verbose_save >= 0) {
- p_verbose = parsed.verbose_save;
+ if (ea.verbose_save >= 0) {
+ p_verbose = ea.verbose_save;
}
if (cmdmod.save_ei != NULL) {
/* Restore 'eventignore' to the value before ":noautocmd". */
@@ -2099,13 +2008,13 @@ doend:
cmdmod = save_cmdmod;
reg_executing = save_reg_executing;
- if (parsed.save_msg_silent != -1) {
+ if (ea.save_msg_silent != -1) {
// messages could be enabled for a serious error, need to check if the
// counters don't become negative
- if (!did_emsg || msg_silent > parsed.save_msg_silent) {
- msg_silent = parsed.save_msg_silent;
+ if (!did_emsg || msg_silent > ea.save_msg_silent) {
+ msg_silent = ea.save_msg_silent;
}
- emsg_silent -= parsed.did_esilent;
+ emsg_silent -= ea.did_esilent;
if (emsg_silent < 0) {
emsg_silent = 0;
}
@@ -2119,7 +2028,7 @@ doend:
msg_col = 0;
}
- if (parsed.did_sandbox) {
+ if (ea.did_sandbox) {
sandbox--;
}
@@ -2140,13 +2049,13 @@ doend:
// - Increment "sandbox" for ":sandbox"
// Return FAIL when the command is not to be executed.
// May set "errormsg" to an error message.
-int parse_command_modifiers(exarg_T *eap, parse_state_T *const out, char_u **errormsg)
+int parse_command_modifiers(exarg_T *eap, char_u **errormsg)
{
char_u *p;
memset(&cmdmod, 0, sizeof(cmdmod));
- out->verbose_save = -1;
- out->save_msg_silent = -1;
+ eap->verbose_save = -1;
+ eap->save_msg_silent = -1;
for (;; ) {
/*
@@ -2164,7 +2073,7 @@ int parse_command_modifiers(exarg_T *eap, parse_state_T *const out, char_u **err
|| getline_equal(eap->getline, eap->cookie, getexline))
&& curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
eap->cmd = (char_u *)"+";
- out->ex_pressedreturn = true;
+ ex_pressedreturn = true;
}
// ignore comment and empty lines
@@ -2172,7 +2081,7 @@ int parse_command_modifiers(exarg_T *eap, parse_state_T *const out, char_u **err
return FAIL;
}
if (*eap->cmd == NUL) {
- out->ex_pressedreturn = true;
+ ex_pressedreturn = true;
return FAIL;
}
@@ -2184,44 +2093,44 @@ int parse_command_modifiers(exarg_T *eap, parse_state_T *const out, char_u **err
// When adding an entry, also modify cmd_exists().
case 'a': if (!checkforcmd(&eap->cmd, "aboveleft", 3))
break;
- out->cmdmod.split |= WSP_ABOVE;
+ cmdmod.split |= WSP_ABOVE;
continue;
case 'b': if (checkforcmd(&eap->cmd, "belowright", 3)) {
- out->cmdmod.split |= WSP_BELOW;
+ cmdmod.split |= WSP_BELOW;
continue;
}
if (checkforcmd(&eap->cmd, "browse", 3)) {
- out->cmdmod.browse = true;
+ cmdmod.browse = true;
continue;
}
if (!checkforcmd(&eap->cmd, "botright", 2)) {
break;
}
- out->cmdmod.split |= WSP_BOT;
+ cmdmod.split |= WSP_BOT;
continue;
case 'c': if (!checkforcmd(&eap->cmd, "confirm", 4))
break;
- out->cmdmod.confirm = true;
+ cmdmod.confirm = true;
continue;
case 'k': if (checkforcmd(&eap->cmd, "keepmarks", 3)) {
- out->cmdmod.keepmarks = true;
+ cmdmod.keepmarks = true;
continue;
}
if (checkforcmd(&eap->cmd, "keepalt", 5)) {
- out->cmdmod.keepalt = true;
+ cmdmod.keepalt = true;
continue;
}
if (checkforcmd(&eap->cmd, "keeppatterns", 5)) {
- out->cmdmod.keeppatterns = true;
+ cmdmod.keeppatterns = true;
continue;
}
if (!checkforcmd(&eap->cmd, "keepjumps", 5)) {
break;
}
- out->cmdmod.keepjumps = true;
+ cmdmod.keepjumps = true;
continue;
case 'f': { // only accept ":filter {pat} cmd"
@@ -2231,7 +2140,7 @@ int parse_command_modifiers(exarg_T *eap, parse_state_T *const out, char_u **err
break;
}
if (*p == '!') {
- out->cmdmod.filter_force = true;
+ cmdmod.filter_force = true;
p = skipwhite(p + 1);
if (*p == NUL || ends_excmd(*p)) {
break;
@@ -2241,8 +2150,8 @@ int parse_command_modifiers(exarg_T *eap, parse_state_T *const out, char_u **err
if (p == NULL || *p == NUL) {
break;
}
- out->cmdmod.filter_regmatch.regprog = vim_regcomp(reg_pat, RE_MAGIC);
- if (out->cmdmod.filter_regmatch.regprog == NULL) {
+ cmdmod.filter_regmatch.regprog = vim_regcomp(reg_pat, RE_MAGIC);
+ if (cmdmod.filter_regmatch.regprog == NULL) {
break;
}
eap->cmd = p;
@@ -2254,60 +2163,61 @@ int parse_command_modifiers(exarg_T *eap, parse_state_T *const out, char_u **err
|| *p == NUL || ends_excmd(*p))
break;
eap->cmd = p;
- out->cmdmod.hide = true;
+ cmdmod.hide = true;
continue;
case 'l': if (checkforcmd(&eap->cmd, "lockmarks", 3)) {
- out->cmdmod.lockmarks = true;
+ cmdmod.lockmarks = true;
continue;
}
if (!checkforcmd(&eap->cmd, "leftabove", 5)) {
break;
}
- out->cmdmod.split |= WSP_ABOVE;
+ cmdmod.split |= WSP_ABOVE;
continue;
case 'n':
if (checkforcmd(&eap->cmd, "noautocmd", 3)) {
- if (out->cmdmod.save_ei == NULL) {
+ if (cmdmod.save_ei == NULL) {
// Set 'eventignore' to "all". Restore the
// existing option value later.
- out->cmdmod.save_ei = vim_strsave(p_ei);
- out->set_eventignore = true;
+ cmdmod.save_ei = vim_strsave(p_ei);
+ set_string_option_direct((char_u *)"ei", -1,
+ (char_u *)"all", OPT_FREE, SID_NONE);
}
continue;
}
if (!checkforcmd(&eap->cmd, "noswapfile", 3)) {
break;
}
- out->cmdmod.noswapfile = true;
+ cmdmod.noswapfile = true;
continue;
case 'r': if (!checkforcmd(&eap->cmd, "rightbelow", 6))
break;
- out->cmdmod.split |= WSP_BELOW;
+ cmdmod.split |= WSP_BELOW;
continue;
case 's': if (checkforcmd(&eap->cmd, "sandbox", 3)) {
- if (!out->did_sandbox) {
- out->sandbox++;
+ if (!eap->did_sandbox) {
+ sandbox++;
}
- out->did_sandbox = true;
+ eap->did_sandbox = true;
continue;
}
if (!checkforcmd(&eap->cmd, "silent", 3)) {
break;
}
- if (out->save_msg_silent == -1) {
- out->save_msg_silent = out->msg_silent;
+ if (eap->save_msg_silent == -1) {
+ eap->save_msg_silent = msg_silent;
}
- out->msg_silent++;
+ msg_silent++;
if (*eap->cmd == '!' && !ascii_iswhite(eap->cmd[-1])) {
// ":silent!", but not "silent !cmd"
eap->cmd = skipwhite(eap->cmd + 1);
- out->emsg_silent++;
- out->did_esilent++;
+ emsg_silent++;
+ eap->did_esilent++;
}
continue;
@@ -2316,13 +2226,13 @@ int parse_command_modifiers(exarg_T *eap, parse_state_T *const out, char_u **err
eap, &eap->cmd, ADDR_TABS, eap->skip, false, 1);
if (tabnr == MAXLNUM) {
- out->cmdmod.tab = tabpage_index(curtab) + 1;
+ cmdmod.tab = tabpage_index(curtab) + 1;
} else {
if (tabnr < 0 || tabnr > LAST_TAB_NR) {
- out->errormsg = (char_u *)_(e_invrange);
+ *errormsg = (char_u *)_(e_invrange);
return false;
}
- out->cmdmod.tab = tabnr + 1;
+ cmdmod.tab = tabnr + 1;
}
eap->cmd = p;
continue;
@@ -2330,30 +2240,30 @@ int parse_command_modifiers(exarg_T *eap, parse_state_T *const out, char_u **err
if (!checkforcmd(&eap->cmd, "topleft", 2)) {
break;
}
- out->cmdmod.split |= WSP_TOP;
+ cmdmod.split |= WSP_TOP;
continue;
case 'u': if (!checkforcmd(&eap->cmd, "unsilent", 3))
break;
- if (out->save_msg_silent == -1) {
- out->save_msg_silent = out->msg_silent;
+ if (eap->save_msg_silent == -1) {
+ eap->save_msg_silent = msg_silent;
}
- out->msg_silent = 0;
+ msg_silent = 0;
continue;
case 'v': if (checkforcmd(&eap->cmd, "vertical", 4)) {
- out->cmdmod.split |= WSP_VERT;
+ cmdmod.split |= WSP_VERT;
continue;
}
if (!checkforcmd(&p, "verbose", 4))
break;
- if (out->verbose_save < 0) {
- out->verbose_save = out->p_verbose;
+ if (eap->verbose_save < 0) {
+ eap->verbose_save = p_verbose;
}
if (ascii_isdigit(*eap->cmd)) {
- out->p_verbose = atoi((char *)eap->cmd);
+ p_verbose = atoi((char *)eap->cmd);
} else {
- out->p_verbose = 1;
+ p_verbose = 1;
}
eap->cmd = p;
continue;