diff options
Diffstat (limited to 'src/nvim/ex_docmd.c')
-rw-r--r-- | src/nvim/ex_docmd.c | 342 |
1 files changed, 172 insertions, 170 deletions
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 2343978ed8..bf8153637c 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -1563,6 +1563,28 @@ err: 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. /// 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 - 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_cmd0(&retv, eap, &errormsg, preview); end: if (errormsg != NULL && *errormsg != NUL) { @@ -1704,6 +1710,142 @@ end: #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. /// /// 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); - // Count this line for profiling if skip is TRUE. - 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(); - } - } - } + profile_cmd(&ea, cstack, fgetline, cookie); // May go to debug mode. If this happens and the ">quit" debug command is // 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); // Forced commands. - if (*p == '!' && ea.cmdidx != CMD_substitute - && ea.cmdidx != CMD_smagic && ea.cmdidx != CMD_snomagic) { + ea.forceit = *p == '!' + && ea.cmdidx != CMD_substitute + && ea.cmdidx != CMD_smagic + && ea.cmdidx != CMD_snomagic; + if (ea.forceit) { p++; - ea.forceit = true; - } else { - ea.forceit = false; } // 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. // Don't do this for the ":!" command, because ":!! -l" needs the space. - if (ea.cmdidx == CMD_bang) { - ea.arg = p; - } else { - ea.arg = skipwhite(p); - } + ea.arg = ea.cmdidx == CMD_bang ? p : skipwhite(p); // ":file" cannot be run with an argument when "curbuf->b_ro_locked" is set 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.usefilter = TRUE; } - } - - if (ea.cmdidx == CMD_read) { + } else if (ea.cmdidx == CMD_read) { if (ea.forceit) { ea.usefilter = TRUE; // :r! filter if ea.forceit ea.forceit = FALSE; @@ -2092,9 +2197,7 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter ++ea.arg; ea.usefilter = TRUE; } - } - - if (ea.cmdidx == CMD_lshift || ea.cmdidx == CMD_rshift) { + } else if (ea.cmdidx == CMD_lshift || ea.cmdidx == CMD_rshift) { ea.amount = 1; while (*ea.arg == *ea.cmd) { // count number of '>' or '<' ea.arg++; @@ -2164,100 +2267,8 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter goto doend; } - // 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 (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 (skip_cmd(&ea)) { + goto doend; } 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. - if (IS_USER_CMDIDX(ea.cmdidx)) { - // Execute a user-defined command. - 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); - } - } + int retv = 0; + execute_cmd0(&retv, &ea, &errormsg, false); // If the command just executed called do_cmdline(), any throw or ":return" // or ":finish" encountered there must also check the cstack of the still |