mirror of
https://github.com/neovim/neovim.git
synced 2025-09-19 17:58:18 +00:00
refactor(cmd): unify execute_cmd with do_one_cmd
This commit is contained in:
@@ -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;
|
||||||
|
@@ -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
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user