refactor(cmd): unify execute_cmd with do_one_cmd

This commit is contained in:
Lewis Russell
2022-07-27 15:42:56 +01:00
parent dc24cb668c
commit dc2745e9ea
3 changed files with 102 additions and 124 deletions

View File

@@ -505,6 +505,11 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error
OBJ_TO_BOOL(cmdinfo.magic.file, magic.file, ea.argt & EX_XFILE, "'magic.file'"); OBJ_TO_BOOL(cmdinfo.magic.file, magic.file, ea.argt & EX_XFILE, "'magic.file'");
OBJ_TO_BOOL(cmdinfo.magic.bar, magic.bar, ea.argt & EX_TRLBAR, "'magic.bar'"); OBJ_TO_BOOL(cmdinfo.magic.bar, magic.bar, ea.argt & EX_TRLBAR, "'magic.bar'");
if (cmdinfo.magic.file) {
ea.argt |= EX_XFILE;
} else {
ea.argt &= ~EX_XFILE;
}
} else { } else {
cmdinfo.magic.file = ea.argt & EX_XFILE; cmdinfo.magic.file = ea.argt & EX_XFILE;
cmdinfo.magic.bar = ea.argt & EX_TRLBAR; cmdinfo.magic.bar = ea.argt & EX_TRLBAR;

View File

@@ -37,34 +37,34 @@
// 4. Add documentation in ../doc/xxx.txt. Add a tag for both the short and // 4. Add documentation in ../doc/xxx.txt. Add a tag for both the short and
// long name of the command. // long name of the command.
#define EX_RANGE 0x001 // allow a linespecs #define EX_RANGE 0x001u // allow a linespecs
#define EX_BANG 0x002 // allow a ! after the command name #define EX_BANG 0x002u // allow a ! after the command name
#define EX_EXTRA 0x004 // allow extra args after command name #define EX_EXTRA 0x004u // allow extra args after command name
#define EX_XFILE 0x008 // expand wildcards in extra part #define EX_XFILE 0x008u // expand wildcards in extra part
#define EX_NOSPC 0x010 // no spaces allowed in the extra part #define EX_NOSPC 0x010u // no spaces allowed in the extra part
#define EX_DFLALL 0x020 // default file range is 1,$ #define EX_DFLALL 0x020u // default file range is 1,$
#define EX_WHOLEFOLD 0x040 // extend range to include whole fold also #define EX_WHOLEFOLD 0x040u // extend range to include whole fold also
// when less than two numbers given // when less than two numbers given
#define EX_NEEDARG 0x080 // argument required #define EX_NEEDARG 0x080u // argument required
#define EX_TRLBAR 0x100 // check for trailing vertical bar #define EX_TRLBAR 0x100u // check for trailing vertical bar
#define EX_REGSTR 0x200 // allow "x for register designation #define EX_REGSTR 0x200u // allow "x for register designation
#define EX_COUNT 0x400 // allow count in argument, after command #define EX_COUNT 0x400u // allow count in argument, after command
#define EX_NOTRLCOM 0x800 // no trailing comment allowed #define EX_NOTRLCOM 0x800u // no trailing comment allowed
#define EX_ZEROR 0x1000 // zero line number allowed #define EX_ZEROR 0x1000u // zero line number allowed
#define EX_CTRLV 0x2000 // do not remove CTRL-V from argument #define EX_CTRLV 0x2000u // do not remove CTRL-V from argument
#define EX_CMDARG 0x4000 // allow "+command" argument #define EX_CMDARG 0x4000u // allow "+command" argument
#define EX_BUFNAME 0x8000 // accepts buffer name #define EX_BUFNAME 0x8000u // accepts buffer name
#define EX_BUFUNL 0x10000 // accepts unlisted buffer too #define EX_BUFUNL 0x10000u // accepts unlisted buffer too
#define EX_ARGOPT 0x20000 // allow "++opt=val" argument #define EX_ARGOPT 0x20000u // allow "++opt=val" argument
#define EX_SBOXOK 0x40000 // allowed in the sandbox #define EX_SBOXOK 0x40000u // allowed in the sandbox
#define EX_CMDWIN 0x80000 // allowed in cmdline window #define EX_CMDWIN 0x80000u // allowed in cmdline window
#define EX_MODIFY 0x100000 // forbidden in non-'modifiable' buffer #define EX_MODIFY 0x100000u // forbidden in non-'modifiable' buffer
#define EX_FLAGS 0x200000 // allow flags after count in argument #define EX_FLAGS 0x200000u // allow flags after count in argument
#define EX_LOCK_OK 0x1000000 // command can be executed when textlock is #define EX_LOCK_OK 0x1000000u // command can be executed when textlock is
// set; when missing disallows editing another // set; when missing disallows editing another
// buffer when current buffer is locked // buffer when current buffer is locked
#define EX_KEEPSCRIPT 0x4000000 // keep sctx of where command was invoked #define EX_KEEPSCRIPT 0x4000000u // keep sctx of where command was invoked
#define EX_PREVIEW 0x8000000 // allow incremental command preview #define EX_PREVIEW 0x8000000u // allow incremental command preview
#define EX_FILES (EX_XFILE | EX_EXTRA) // multiple extra files allowed #define EX_FILES (EX_XFILE | EX_EXTRA) // multiple extra files allowed
#define EX_FILE1 (EX_FILES | EX_NOSPC) // 1 file, defaults to current file #define EX_FILE1 (EX_FILES | EX_NOSPC) // 1 file, defaults to current file
#define EX_WORD1 (EX_EXTRA | EX_NOSPC) // one extra word allowed #define EX_WORD1 (EX_EXTRA | EX_NOSPC) // one extra word allowed

View File

@@ -1563,8 +1563,70 @@ err:
return false; return false;
} }
static void execute_cmd0(int *retv, exarg_T *eap, char **errormsg, bool preview) static int execute_cmd0(int *retv, exarg_T *eap, char **errormsg, bool preview)
{ {
// If filename expansion is enabled, expand filenames
if (eap->argt & EX_XFILE) {
if (expand_filename(eap, eap->cmdlinep, errormsg) == FAIL) {
return FAIL;
}
}
// Accept buffer name. Cannot be used at the same time with a buffer
// number. Don't do this for a user command.
if ((eap->argt & EX_BUFNAME) && *eap->arg != NUL && eap->addr_count == 0
&& !IS_USER_CMDIDX(eap->cmdidx)) {
if (eap->args == NULL) {
// If argument positions are not specified, search the argument for the buffer name.
// :bdelete, :bwipeout and :bunload take several arguments, separated by spaces:
// find next space (skipping over escaped characters).
// The others take one argument: ignore trailing spaces.
char *p;
if (eap->cmdidx == CMD_bdelete || eap->cmdidx == CMD_bwipeout
|| eap->cmdidx == CMD_bunload) {
p = skiptowhite_esc(eap->arg);
} else {
p = eap->arg + STRLEN(eap->arg);
while (p > eap->arg && ascii_iswhite(p[-1])) {
p--;
}
}
eap->line2 = buflist_findpat(eap->arg, p, (eap->argt & EX_BUFUNL) != 0,
false, false);
eap->addr_count = 1;
eap->arg = skipwhite(p);
} else {
// If argument positions are specified, just use the first argument
eap->line2 = buflist_findpat(eap->args[0],
eap->args[0] + eap->arglens[0],
(eap->argt & EX_BUFUNL) != 0, false, false);
eap->addr_count = 1;
// Shift each argument by 1
for (size_t i = 0; i < eap->argc - 1; i++) {
eap->args[i] = eap->args[i + 1];
}
// Make the last argument point to the NUL terminator at the end of string
eap->args[eap->argc - 1] = eap->args[eap->argc - 1] + eap->arglens[eap->argc - 1];
eap->argc -= 1;
eap->arg = eap->args[0];
}
if (eap->line2 < 0) { // failed
return FAIL;
}
}
// The :try command saves the emsg_silent flag, reset it here when
// ":silent! try" was used, it should only apply to :try itself.
if (eap->cmdidx == CMD_try && cmdmod.cmod_did_esilent > 0) {
emsg_silent -= cmdmod.cmod_did_esilent;
if (emsg_silent < 0) {
emsg_silent = 0;
}
cmdmod.cmod_did_esilent = 0;
}
// Execute the command // Execute the command
if (IS_USER_CMDIDX(eap->cmdidx)) { if (IS_USER_CMDIDX(eap->cmdidx)) {
// Execute a user-defined command. // Execute a user-defined command.
@@ -1583,6 +1645,8 @@ static void execute_cmd0(int *retv, exarg_T *eap, char **errormsg, bool preview)
*errormsg = _(eap->errmsg); *errormsg = _(eap->errmsg);
} }
} }
return OK;
} }
/// Execute an Ex command using parsed command line information. /// Execute an Ex command using parsed command line information.
@@ -1644,58 +1708,6 @@ int execute_cmd(exarg_T *eap, CmdParseInfo *cmdinfo, bool preview)
(void)hasFolding(eap->line2, NULL, &eap->line2); (void)hasFolding(eap->line2, NULL, &eap->line2);
} }
// If filename expansion is enabled, expand filenames
if (cmdinfo->magic.file) {
if (expand_filename(eap, eap->cmdlinep, &errormsg) == FAIL) {
goto end;
}
}
// Accept buffer name. Cannot be used at the same time with a buffer
// number. Don't do this for a user command.
if ((eap->argt & EX_BUFNAME) && *eap->arg != NUL && eap->addr_count == 0
&& !IS_USER_CMDIDX(eap->cmdidx)) {
if (eap->args == NULL) {
// If argument positions are not specified, search the argument for the buffer name.
// :bdelete, :bwipeout and :bunload take several arguments, separated by spaces:
// find next space (skipping over escaped characters).
// The others take one argument: ignore trailing spaces.
char *p;
if (eap->cmdidx == CMD_bdelete || eap->cmdidx == CMD_bwipeout
|| eap->cmdidx == CMD_bunload) {
p = skiptowhite_esc(eap->arg);
} else {
p = eap->arg + STRLEN(eap->arg);
while (p > eap->arg && ascii_iswhite(p[-1])) {
p--;
}
}
eap->line2 = buflist_findpat(eap->arg, p, (eap->argt & EX_BUFUNL) != 0,
false, false);
eap->addr_count = 1;
eap->arg = skipwhite(p);
} else {
// If argument positions are specified, just use the first argument
eap->line2 = buflist_findpat(eap->args[0],
eap->args[0] + eap->arglens[0],
(eap->argt & EX_BUFUNL) != 0, false, false);
eap->addr_count = 1;
// Shift each argument by 1
for (size_t i = 0; i < eap->argc - 1; i++) {
eap->args[i] = eap->args[i + 1];
}
// Make the last argument point to the NUL terminator at the end of string
eap->args[eap->argc - 1] = eap->args[eap->argc - 1] + eap->arglens[eap->argc - 1];
eap->argc -= 1;
eap->arg = eap->args[0];
}
if (eap->line2 < 0) { // failed
goto end;
}
}
// Execute the command // Execute the command
execute_cmd0(&retv, eap, &errormsg, preview); execute_cmd0(&retv, eap, &errormsg, preview);
@@ -2271,50 +2283,11 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter
goto doend; goto doend;
} }
if (ea.argt & EX_XFILE) {
if (expand_filename(&ea, cmdlinep, &errormsg) == FAIL) {
goto doend;
}
}
// Accept buffer name. Cannot be used at the same time with a buffer
// number. Don't do this for a user command.
if ((ea.argt & EX_BUFNAME) && *ea.arg != NUL && ea.addr_count == 0
&& !IS_USER_CMDIDX(ea.cmdidx)) {
// :bdelete, :bwipeout and :bunload take several arguments, separated
// by spaces: find next space (skipping over escaped characters).
// The others take one argument: ignore trailing spaces.
if (ea.cmdidx == CMD_bdelete || ea.cmdidx == CMD_bwipeout
|| ea.cmdidx == CMD_bunload) {
p = skiptowhite_esc(ea.arg);
} else {
p = ea.arg + STRLEN(ea.arg);
while (p > ea.arg && ascii_iswhite(p[-1])) {
p--;
}
}
ea.line2 = buflist_findpat(ea.arg, p, (ea.argt & EX_BUFUNL) != 0,
false, false);
if (ea.line2 < 0) { // failed
goto doend;
}
ea.addr_count = 1;
ea.arg = skipwhite(p);
}
// 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 && cmdmod.cmod_did_esilent > 0) {
emsg_silent -= cmdmod.cmod_did_esilent;
if (emsg_silent < 0) {
emsg_silent = 0;
}
cmdmod.cmod_did_esilent = 0;
}
// 7. Execute the command. // 7. Execute the command.
int retv = 0; int retv = 0;
execute_cmd0(&retv, &ea, &errormsg, false); if (execute_cmd0(&retv, &ea, &errormsg, false) == FAIL) {
goto doend;
}
// If the command just executed called do_cmdline(), any throw or ":return" // If the command just executed called do_cmdline(), any throw or ":return"
// or ":finish" encountered there must also check the cstack of the still // or ":finish" encountered there must also check the cstack of the still
@@ -2346,7 +2319,7 @@ doend:
STRCPY(IObuff, errormsg); STRCPY(IObuff, errormsg);
errormsg = (char *)IObuff; errormsg = (char *)IObuff;
} }
append_command(*cmdlinep); append_command(*ea.cmdlinep);
} }
emsg(errormsg); emsg(errormsg);
} }