mirror of
https://github.com/neovim/neovim.git
synced 2025-09-19 01:38:16 +00:00
refactor(cmd): hoist out some code into functions
This commit is contained in:
@@ -1563,6 +1563,28 @@ err:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void execute_cmd0(int *retv, exarg_T *eap, char **errormsg, bool preview)
|
||||||
|
{
|
||||||
|
// Execute the command
|
||||||
|
if (IS_USER_CMDIDX(eap->cmdidx)) {
|
||||||
|
// Execute a user-defined command.
|
||||||
|
*retv = do_ucmd(eap, preview);
|
||||||
|
} else {
|
||||||
|
// Call the function to execute the command or the preview callback.
|
||||||
|
eap->errmsg = NULL;
|
||||||
|
|
||||||
|
if (preview) {
|
||||||
|
*retv = (cmdnames[eap->cmdidx].cmd_preview_func)(eap, cmdpreview_get_ns(),
|
||||||
|
cmdpreview_get_bufnr());
|
||||||
|
} else {
|
||||||
|
(cmdnames[eap->cmdidx].cmd_func)(eap);
|
||||||
|
}
|
||||||
|
if (eap->errmsg != NULL) {
|
||||||
|
*errormsg = _(eap->errmsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Execute an Ex command using parsed command line information.
|
/// Execute an Ex command using parsed command line information.
|
||||||
/// Does not do any validation of the Ex command arguments.
|
/// Does not do any validation of the Ex command arguments.
|
||||||
///
|
///
|
||||||
@@ -1675,23 +1697,7 @@ int execute_cmd(exarg_T *eap, CmdParseInfo *cmdinfo, bool preview)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Execute the command
|
// Execute the command
|
||||||
if (IS_USER_CMDIDX(eap->cmdidx)) {
|
execute_cmd0(&retv, eap, &errormsg, preview);
|
||||||
// Execute a user-defined command.
|
|
||||||
retv = do_ucmd(eap, preview);
|
|
||||||
} else {
|
|
||||||
// Call the function to execute the command or the preview callback.
|
|
||||||
eap->errmsg = NULL;
|
|
||||||
|
|
||||||
if (preview) {
|
|
||||||
retv = (cmdnames[eap->cmdidx].cmd_preview_func)(eap, cmdpreview_get_ns(),
|
|
||||||
cmdpreview_get_bufnr());
|
|
||||||
} else {
|
|
||||||
(cmdnames[eap->cmdidx].cmd_func)(eap);
|
|
||||||
}
|
|
||||||
if (eap->errmsg != NULL) {
|
|
||||||
errormsg = _(eap->errmsg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (errormsg != NULL && *errormsg != NUL) {
|
if (errormsg != NULL && *errormsg != NUL) {
|
||||||
@@ -1704,6 +1710,142 @@ end:
|
|||||||
#undef ERROR
|
#undef ERROR
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void profile_cmd(const exarg_T *eap, cstack_T *cstack, LineGetter fgetline, void *cookie)
|
||||||
|
{
|
||||||
|
// Count this line for profiling if skip is TRUE.
|
||||||
|
if (do_profiling == PROF_YES
|
||||||
|
&& (!eap->skip || cstack->cs_idx == 0
|
||||||
|
|| (cstack->cs_idx > 0
|
||||||
|
&& (cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE)))) {
|
||||||
|
int skip = did_emsg || got_int || current_exception;
|
||||||
|
|
||||||
|
if (eap->cmdidx == CMD_catch) {
|
||||||
|
skip = !skip && !(cstack->cs_idx >= 0
|
||||||
|
&& (cstack->cs_flags[cstack->cs_idx] & CSF_THROWN)
|
||||||
|
&& !(cstack->cs_flags[cstack->cs_idx] & CSF_CAUGHT));
|
||||||
|
} else if (eap->cmdidx == CMD_else || eap->cmdidx == CMD_elseif) {
|
||||||
|
skip = skip || !(cstack->cs_idx >= 0
|
||||||
|
&& !(cstack->cs_flags[cstack->cs_idx]
|
||||||
|
& (CSF_ACTIVE | CSF_TRUE)));
|
||||||
|
} else if (eap->cmdidx == CMD_finally) {
|
||||||
|
skip = false;
|
||||||
|
} else if (eap->cmdidx != CMD_endif
|
||||||
|
&& eap->cmdidx != CMD_endfor
|
||||||
|
&& eap->cmdidx != CMD_endtry
|
||||||
|
&& eap->cmdidx != CMD_endwhile) {
|
||||||
|
skip = eap->skip;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!skip) {
|
||||||
|
if (getline_equal(fgetline, cookie, get_func_line)) {
|
||||||
|
func_line_exec(getline_cookie(fgetline, cookie));
|
||||||
|
} else if (getline_equal(fgetline, cookie, getsourceline)) {
|
||||||
|
script_line_exec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool skip_cmd(const exarg_T *eap)
|
||||||
|
{
|
||||||
|
// Skip the command when it's not going to be executed.
|
||||||
|
// The commands like :if, :endif, etc. always need to be executed.
|
||||||
|
// Also make an exception for commands that handle a trailing command
|
||||||
|
// themselves.
|
||||||
|
if (eap->skip) {
|
||||||
|
switch (eap->cmdidx) {
|
||||||
|
// commands that need evaluation
|
||||||
|
case CMD_while:
|
||||||
|
case CMD_endwhile:
|
||||||
|
case CMD_for:
|
||||||
|
case CMD_endfor:
|
||||||
|
case CMD_if:
|
||||||
|
case CMD_elseif:
|
||||||
|
case CMD_else:
|
||||||
|
case CMD_endif:
|
||||||
|
case CMD_try:
|
||||||
|
case CMD_catch:
|
||||||
|
case CMD_finally:
|
||||||
|
case CMD_endtry:
|
||||||
|
case CMD_function:
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Commands that handle '|' themselves. Check: A command should
|
||||||
|
// either have the EX_TRLBAR flag, appear in this list or appear in
|
||||||
|
// the list at ":help :bar".
|
||||||
|
case CMD_aboveleft:
|
||||||
|
case CMD_and:
|
||||||
|
case CMD_belowright:
|
||||||
|
case CMD_botright:
|
||||||
|
case CMD_browse:
|
||||||
|
case CMD_call:
|
||||||
|
case CMD_confirm:
|
||||||
|
case CMD_const:
|
||||||
|
case CMD_delfunction:
|
||||||
|
case CMD_djump:
|
||||||
|
case CMD_dlist:
|
||||||
|
case CMD_dsearch:
|
||||||
|
case CMD_dsplit:
|
||||||
|
case CMD_echo:
|
||||||
|
case CMD_echoerr:
|
||||||
|
case CMD_echomsg:
|
||||||
|
case CMD_echon:
|
||||||
|
case CMD_eval:
|
||||||
|
case CMD_execute:
|
||||||
|
case CMD_filter:
|
||||||
|
case CMD_help:
|
||||||
|
case CMD_hide:
|
||||||
|
case CMD_ijump:
|
||||||
|
case CMD_ilist:
|
||||||
|
case CMD_isearch:
|
||||||
|
case CMD_isplit:
|
||||||
|
case CMD_keepalt:
|
||||||
|
case CMD_keepjumps:
|
||||||
|
case CMD_keepmarks:
|
||||||
|
case CMD_keeppatterns:
|
||||||
|
case CMD_leftabove:
|
||||||
|
case CMD_let:
|
||||||
|
case CMD_lockmarks:
|
||||||
|
case CMD_lockvar:
|
||||||
|
case CMD_lua:
|
||||||
|
case CMD_match:
|
||||||
|
case CMD_mzscheme:
|
||||||
|
case CMD_noautocmd:
|
||||||
|
case CMD_noswapfile:
|
||||||
|
case CMD_perl:
|
||||||
|
case CMD_psearch:
|
||||||
|
case CMD_python:
|
||||||
|
case CMD_py3:
|
||||||
|
case CMD_python3:
|
||||||
|
case CMD_pythonx:
|
||||||
|
case CMD_pyx:
|
||||||
|
case CMD_return:
|
||||||
|
case CMD_rightbelow:
|
||||||
|
case CMD_ruby:
|
||||||
|
case CMD_silent:
|
||||||
|
case CMD_smagic:
|
||||||
|
case CMD_snomagic:
|
||||||
|
case CMD_substitute:
|
||||||
|
case CMD_syntax:
|
||||||
|
case CMD_tab:
|
||||||
|
case CMD_tcl:
|
||||||
|
case CMD_throw:
|
||||||
|
case CMD_tilde:
|
||||||
|
case CMD_topleft:
|
||||||
|
case CMD_unlet:
|
||||||
|
case CMD_unlockvar:
|
||||||
|
case CMD_verbose:
|
||||||
|
case CMD_vertical:
|
||||||
|
case CMD_wincmd:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// Execute one Ex command.
|
/// Execute one Ex command.
|
||||||
///
|
///
|
||||||
/// If 'sourcing' is TRUE, the command will be included in the error message.
|
/// If 'sourcing' is TRUE, the command will be included in the error message.
|
||||||
@@ -1786,38 +1928,7 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter
|
|||||||
}
|
}
|
||||||
char *p = find_ex_command(&ea, NULL);
|
char *p = find_ex_command(&ea, NULL);
|
||||||
|
|
||||||
// Count this line for profiling if skip is TRUE.
|
profile_cmd(&ea, cstack, fgetline, cookie);
|
||||||
if (do_profiling == PROF_YES
|
|
||||||
&& (!ea.skip || cstack->cs_idx == 0
|
|
||||||
|| (cstack->cs_idx > 0
|
|
||||||
&& (cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE)))) {
|
|
||||||
int skip = did_emsg || got_int || current_exception;
|
|
||||||
|
|
||||||
if (ea.cmdidx == CMD_catch) {
|
|
||||||
skip = !skip && !(cstack->cs_idx >= 0
|
|
||||||
&& (cstack->cs_flags[cstack->cs_idx] & CSF_THROWN)
|
|
||||||
&& !(cstack->cs_flags[cstack->cs_idx] & CSF_CAUGHT));
|
|
||||||
} else if (ea.cmdidx == CMD_else || ea.cmdidx == CMD_elseif) {
|
|
||||||
skip = skip || !(cstack->cs_idx >= 0
|
|
||||||
&& !(cstack->cs_flags[cstack->cs_idx]
|
|
||||||
& (CSF_ACTIVE | CSF_TRUE)));
|
|
||||||
} else if (ea.cmdidx == CMD_finally) {
|
|
||||||
skip = false;
|
|
||||||
} else if (ea.cmdidx != CMD_endif
|
|
||||||
&& ea.cmdidx != CMD_endfor
|
|
||||||
&& ea.cmdidx != CMD_endtry
|
|
||||||
&& ea.cmdidx != CMD_endwhile) {
|
|
||||||
skip = ea.skip;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!skip) {
|
|
||||||
if (getline_equal(fgetline, cookie, get_func_line)) {
|
|
||||||
func_line_exec(getline_cookie(fgetline, cookie));
|
|
||||||
} else if (getline_equal(fgetline, cookie, getsourceline)) {
|
|
||||||
script_line_exec();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// May go to debug mode. If this happens and the ">quit" debug command is
|
// May go to debug mode. If this happens and the ">quit" debug command is
|
||||||
// used, throw an interrupt exception and skip the next command.
|
// used, throw an interrupt exception and skip the next command.
|
||||||
@@ -1934,12 +2045,12 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter
|
|||||||
const int ni = is_cmd_ni(ea.cmdidx);
|
const int ni = is_cmd_ni(ea.cmdidx);
|
||||||
|
|
||||||
// Forced commands.
|
// Forced commands.
|
||||||
if (*p == '!' && ea.cmdidx != CMD_substitute
|
ea.forceit = *p == '!'
|
||||||
&& ea.cmdidx != CMD_smagic && ea.cmdidx != CMD_snomagic) {
|
&& ea.cmdidx != CMD_substitute
|
||||||
|
&& ea.cmdidx != CMD_smagic
|
||||||
|
&& ea.cmdidx != CMD_snomagic;
|
||||||
|
if (ea.forceit) {
|
||||||
p++;
|
p++;
|
||||||
ea.forceit = true;
|
|
||||||
} else {
|
|
||||||
ea.forceit = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Parse arguments. Then check for errors.
|
// 6. Parse arguments. Then check for errors.
|
||||||
@@ -2048,11 +2159,7 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter
|
|||||||
|
|
||||||
// Skip to start of argument.
|
// Skip to start of argument.
|
||||||
// Don't do this for the ":!" command, because ":!! -l" needs the space.
|
// Don't do this for the ":!" command, because ":!! -l" needs the space.
|
||||||
if (ea.cmdidx == CMD_bang) {
|
ea.arg = ea.cmdidx == CMD_bang ? p : skipwhite(p);
|
||||||
ea.arg = p;
|
|
||||||
} else {
|
|
||||||
ea.arg = skipwhite(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ":file" cannot be run with an argument when "curbuf->b_ro_locked" is set
|
// ":file" cannot be run with an argument when "curbuf->b_ro_locked" is set
|
||||||
if (ea.cmdidx == CMD_file && *ea.arg != NUL && curbuf_locked()) {
|
if (ea.cmdidx == CMD_file && *ea.arg != NUL && curbuf_locked()) {
|
||||||
@@ -2082,9 +2189,7 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter
|
|||||||
++ea.arg;
|
++ea.arg;
|
||||||
ea.usefilter = TRUE;
|
ea.usefilter = TRUE;
|
||||||
}
|
}
|
||||||
}
|
} else if (ea.cmdidx == CMD_read) {
|
||||||
|
|
||||||
if (ea.cmdidx == CMD_read) {
|
|
||||||
if (ea.forceit) {
|
if (ea.forceit) {
|
||||||
ea.usefilter = TRUE; // :r! filter if ea.forceit
|
ea.usefilter = TRUE; // :r! filter if ea.forceit
|
||||||
ea.forceit = FALSE;
|
ea.forceit = FALSE;
|
||||||
@@ -2092,9 +2197,7 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter
|
|||||||
++ea.arg;
|
++ea.arg;
|
||||||
ea.usefilter = TRUE;
|
ea.usefilter = TRUE;
|
||||||
}
|
}
|
||||||
}
|
} else if (ea.cmdidx == CMD_lshift || ea.cmdidx == CMD_rshift) {
|
||||||
|
|
||||||
if (ea.cmdidx == CMD_lshift || ea.cmdidx == CMD_rshift) {
|
|
||||||
ea.amount = 1;
|
ea.amount = 1;
|
||||||
while (*ea.arg == *ea.cmd) { // count number of '>' or '<'
|
while (*ea.arg == *ea.cmd) { // count number of '>' or '<'
|
||||||
ea.arg++;
|
ea.arg++;
|
||||||
@@ -2164,100 +2267,8 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter
|
|||||||
goto doend;
|
goto doend;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip the command when it's not going to be executed.
|
if (skip_cmd(&ea)) {
|
||||||
// The commands like :if, :endif, etc. always need to be executed.
|
goto doend;
|
||||||
// Also make an exception for commands that handle a trailing command
|
|
||||||
// themselves.
|
|
||||||
if (ea.skip) {
|
|
||||||
switch (ea.cmdidx) {
|
|
||||||
// commands that need evaluation
|
|
||||||
case CMD_while:
|
|
||||||
case CMD_endwhile:
|
|
||||||
case CMD_for:
|
|
||||||
case CMD_endfor:
|
|
||||||
case CMD_if:
|
|
||||||
case CMD_elseif:
|
|
||||||
case CMD_else:
|
|
||||||
case CMD_endif:
|
|
||||||
case CMD_try:
|
|
||||||
case CMD_catch:
|
|
||||||
case CMD_finally:
|
|
||||||
case CMD_endtry:
|
|
||||||
case CMD_function:
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Commands that handle '|' themselves. Check: A command should
|
|
||||||
// either have the EX_TRLBAR flag, appear in this list or appear in
|
|
||||||
// the list at ":help :bar".
|
|
||||||
case CMD_aboveleft:
|
|
||||||
case CMD_and:
|
|
||||||
case CMD_belowright:
|
|
||||||
case CMD_botright:
|
|
||||||
case CMD_browse:
|
|
||||||
case CMD_call:
|
|
||||||
case CMD_confirm:
|
|
||||||
case CMD_const:
|
|
||||||
case CMD_delfunction:
|
|
||||||
case CMD_djump:
|
|
||||||
case CMD_dlist:
|
|
||||||
case CMD_dsearch:
|
|
||||||
case CMD_dsplit:
|
|
||||||
case CMD_echo:
|
|
||||||
case CMD_echoerr:
|
|
||||||
case CMD_echomsg:
|
|
||||||
case CMD_echon:
|
|
||||||
case CMD_eval:
|
|
||||||
case CMD_execute:
|
|
||||||
case CMD_filter:
|
|
||||||
case CMD_help:
|
|
||||||
case CMD_hide:
|
|
||||||
case CMD_ijump:
|
|
||||||
case CMD_ilist:
|
|
||||||
case CMD_isearch:
|
|
||||||
case CMD_isplit:
|
|
||||||
case CMD_keepalt:
|
|
||||||
case CMD_keepjumps:
|
|
||||||
case CMD_keepmarks:
|
|
||||||
case CMD_keeppatterns:
|
|
||||||
case CMD_leftabove:
|
|
||||||
case CMD_let:
|
|
||||||
case CMD_lockmarks:
|
|
||||||
case CMD_lockvar:
|
|
||||||
case CMD_lua:
|
|
||||||
case CMD_match:
|
|
||||||
case CMD_mzscheme:
|
|
||||||
case CMD_noautocmd:
|
|
||||||
case CMD_noswapfile:
|
|
||||||
case CMD_perl:
|
|
||||||
case CMD_psearch:
|
|
||||||
case CMD_python:
|
|
||||||
case CMD_py3:
|
|
||||||
case CMD_python3:
|
|
||||||
case CMD_pythonx:
|
|
||||||
case CMD_pyx:
|
|
||||||
case CMD_return:
|
|
||||||
case CMD_rightbelow:
|
|
||||||
case CMD_ruby:
|
|
||||||
case CMD_silent:
|
|
||||||
case CMD_smagic:
|
|
||||||
case CMD_snomagic:
|
|
||||||
case CMD_substitute:
|
|
||||||
case CMD_syntax:
|
|
||||||
case CMD_tab:
|
|
||||||
case CMD_tcl:
|
|
||||||
case CMD_throw:
|
|
||||||
case CMD_tilde:
|
|
||||||
case CMD_topleft:
|
|
||||||
case CMD_unlet:
|
|
||||||
case CMD_unlockvar:
|
|
||||||
case CMD_verbose:
|
|
||||||
case CMD_vertical:
|
|
||||||
case CMD_wincmd:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
goto doend;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ea.argt & EX_XFILE) {
|
if (ea.argt & EX_XFILE) {
|
||||||
@@ -2302,17 +2313,8 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 7. Execute the command.
|
// 7. Execute the command.
|
||||||
if (IS_USER_CMDIDX(ea.cmdidx)) {
|
int retv = 0;
|
||||||
// Execute a user-defined command.
|
execute_cmd0(&retv, &ea, &errormsg, false);
|
||||||
do_ucmd(&ea, false);
|
|
||||||
} else {
|
|
||||||
// Call the function to execute the command.
|
|
||||||
ea.errmsg = NULL;
|
|
||||||
(cmdnames[ea.cmdidx].cmd_func)(&ea);
|
|
||||||
if (ea.errmsg != NULL) {
|
|
||||||
errormsg = _(ea.errmsg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
||||||
|
Reference in New Issue
Block a user