diff options
Diffstat (limited to 'src/nvim/ex_docmd.c')
-rw-r--r-- | src/nvim/ex_docmd.c | 321 |
1 files changed, 181 insertions, 140 deletions
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 8cf5d56dd7..5591b5f55d 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -134,6 +134,7 @@ struct dbg_stuff { char *vv_throwpoint; int did_emsg; int got_int; + bool did_throw; int need_rethrow; int check_cstack; except_T *current_exception; @@ -165,6 +166,7 @@ static void save_dbg_stuff(struct dbg_stuff *dsp) // Necessary for debugging an inactive ":catch", ":finally", ":endtry". dsp->did_emsg = did_emsg; did_emsg = false; dsp->got_int = got_int; got_int = false; + dsp->did_throw = did_throw; did_throw = false; dsp->need_rethrow = need_rethrow; need_rethrow = false; dsp->check_cstack = check_cstack; check_cstack = false; dsp->current_exception = current_exception; current_exception = NULL; @@ -180,6 +182,7 @@ static void restore_dbg_stuff(struct dbg_stuff *dsp) (void)v_throwpoint(dsp->vv_throwpoint); did_emsg = dsp->did_emsg; got_int = dsp->got_int; + did_throw = dsp->did_throw; need_rethrow = dsp->need_rethrow; check_cstack = dsp->check_cstack; current_exception = dsp->current_exception; @@ -251,7 +254,7 @@ void do_exmode(void) RedrawingDisabled--; no_wait_return--; redraw_all_later(UPD_NOT_VALID); - update_screen(UPD_NOT_VALID); + update_screen(); need_wait_return = false; msg_scroll = save_msg_scroll; } @@ -397,7 +400,8 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) initial_trylevel = trylevel; - current_exception = NULL; + // "did_throw" will be set to true when an exception is being thrown. + did_throw = false; // "did_emsg" will be set to true when emsg() is used, in which case we // cancel the whole command line, and any if/endif or loop. // If force_abort is set, we cancel everything. @@ -462,7 +466,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) if (breakpoint != NULL && dbg_tick != NULL && *dbg_tick != debug_tick) { *breakpoint = dbg_find_breakpoint(getline_equal(fgetline, cookie, getsourceline), - (char_u *)fname, SOURCING_LNUM); + fname, SOURCING_LNUM); *dbg_tick = debug_tick; } @@ -471,10 +475,10 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) // Did we encounter a breakpoint? if (breakpoint != NULL && *breakpoint != 0 && *breakpoint <= SOURCING_LNUM) { - dbg_breakpoint((char_u *)fname, SOURCING_LNUM); + dbg_breakpoint(fname, SOURCING_LNUM); // Find next breakpoint. *breakpoint = dbg_find_breakpoint(getline_equal(fgetline, cookie, getsourceline), - (char_u *)fname, SOURCING_LNUM); + fname, SOURCING_LNUM); *dbg_tick = debug_tick; } if (do_profiling == PROF_YES) { @@ -516,7 +520,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) cstack.cs_idx < 0 ? 0 : (cstack.cs_idx + 1) * 2, true)) == NULL) { - // Don't call wait_return for aborted command line. The NULL + // Don't call wait_return() for aborted command line. The NULL // returned for the end of a sourced file or executed function // doesn't do this. if (KeyTyped && !(flags & DOCMD_REPEAT)) { @@ -531,7 +535,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) if (flags & DOCMD_KEEPLINE) { xfree(repeat_cmdline); if (count == 0) { - repeat_cmdline = vim_strsave((char_u *)next_cmdline); + repeat_cmdline = xstrdup(next_cmdline); } else { repeat_cmdline = NULL; } @@ -625,7 +629,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) // not to use a cs_line[] from an entry that isn't a ":while" // or ":for": It would make "current_line" invalid and can // cause a crash. - if (!did_emsg && !got_int && !current_exception + if (!did_emsg && !got_int && !did_throw && cstack.cs_idx >= 0 && (cstack.cs_flags[cstack.cs_idx] & (CSF_WHILE | CSF_FOR)) @@ -638,9 +642,8 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) // Check for the next breakpoint at or after the ":while" // or ":for". - if (breakpoint != NULL) { - *breakpoint = dbg_find_breakpoint(getline_equal(fgetline, cookie, getsourceline), - (char_u *)fname, + if (breakpoint != NULL && lines_ga.ga_len > current_line) { + *breakpoint = dbg_find_breakpoint(getline_equal(fgetline, cookie, getsourceline), fname, ((wcmd_T *)lines_ga.ga_data)[current_line].lnum - 1); *dbg_tick = debug_tick; } @@ -667,7 +670,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) current_line = 0; } - // A ":finally" makes did_emsg, got_int and current_exception pending for + // A ":finally" makes did_emsg, got_int and did_throw pending for // being restored at the ":endtry". Reset them here and set the // ACTIVE and FINALLY flags, so that the finally clause gets executed. // This includes the case where a missing ":endif", ":endwhile" or @@ -676,9 +679,8 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) cstack.cs_lflags &= ~CSL_HAD_FINA; report_make_pending((cstack.cs_pending[cstack.cs_idx] & (CSTP_ERROR | CSTP_INTERRUPT | CSTP_THROW)), - current_exception); - did_emsg = got_int = false; - current_exception = NULL; + did_throw ? current_exception : NULL); + did_emsg = got_int = did_throw = false; cstack.cs_flags[cstack.cs_idx] |= CSF_ACTIVE | CSF_FINALLY; } @@ -691,7 +693,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) // exception, cancel everything. If it is left normally, reset // force_abort to get the non-EH compatible abortion behavior for // the rest of the script. - if (trylevel == 0 && !did_emsg && !got_int && !current_exception) { + if (trylevel == 0 && !did_emsg && !got_int && !did_throw) { force_abort = false; } @@ -705,7 +707,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) // - didn't get an error message or lines are not typed // - there is a command after '|', inside a :if, :while, :for or :try, or // looping for ":source" command or function call. - } while (!((got_int || (did_emsg && force_abort) || current_exception) + } while (!((got_int || (did_emsg && force_abort) || did_throw) && cstack.cs_trylevel == 0) && !(did_emsg // Keep going when inside try/catch, so that the error can be @@ -725,7 +727,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) if (cstack.cs_idx >= 0) { // If a sourced file or executed function ran to its end, report the // unclosed conditional. - if (!got_int && !current_exception + if (!got_int && !did_throw && ((getline_equal(fgetline, cookie, getsourceline) && !source_finished(fgetline, cookie)) || (getline_equal(fgetline, cookie, get_func_line) @@ -768,7 +770,8 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) // conditional, discard the uncaught exception, disable the conversion // of interrupts or errors to exceptions, and ensure that no more // commands are executed. - if (current_exception) { + if (did_throw) { + assert(current_exception != NULL); char *p = NULL; msglist_T *messages = NULL; msglist_T *next; @@ -782,7 +785,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) vim_snprintf((char *)IObuff, IOSIZE, _("E605: Exception not caught: %s"), current_exception->value); - p = (char *)vim_strsave(IObuff); + p = xstrdup((char *)IObuff); break; case ET_ERROR: messages = current_exception->messages; @@ -830,14 +833,14 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) // cstack belongs to the same function or, respectively, script file, it // will have to be checked for finally clauses to be executed due to the // ":return" or ":finish". This is done in do_one_cmd(). - if (current_exception) { + if (did_throw) { need_rethrow = true; } if ((getline_equal(fgetline, cookie, getsourceline) && ex_nesting_level > source_level(real_cookie)) || (getline_equal(fgetline, cookie, get_func_line) && ex_nesting_level > func_level(real_cookie) + 1)) { - if (!current_exception) { + if (!did_throw) { check_cstack = true; } } else { @@ -851,8 +854,8 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) || getline_equal(fgetline, cookie, get_func_line)) && ex_nesting_level + 1 <= debug_break_level) { do_debug(getline_equal(fgetline, cookie, getsourceline) - ? (char_u *)_("End of sourced file") - : (char_u *)_("End of function")); + ? _("End of sourced file") + : _("End of function")); } } @@ -888,7 +891,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) need_wait_return = false; msg_didany = false; // don't wait when restarting edit } else if (need_wait_return) { - // The msg_start() above clears msg_didout. The wait_return we do + // The msg_start() above clears msg_didout. The wait_return() we do // here should not overwrite the command that may be shown before // doing that. msg_didout |= msg_didout_before_start; @@ -1297,9 +1300,9 @@ static void parse_register(exarg_T *eap) // for '=' register: accept the rest of the line as an expression if (eap->arg[-1] == '=' && eap->arg[0] != NUL) { if (!eap->skip) { - set_expr_line(vim_strsave((char_u *)eap->arg)); + set_expr_line(xstrdup(eap->arg)); } - eap->arg += STRLEN(eap->arg); + eap->arg += strlen(eap->arg); } eap->arg = skipwhite(eap->arg); } @@ -1336,6 +1339,20 @@ static int parse_count(exarg_T *eap, char **errormsg, bool validate) || ascii_iswhite(*p))) { long n = getdigits_long(&eap->arg, false, -1); eap->arg = skipwhite(eap->arg); + + if (eap->args != NULL) { + assert(eap->argc > 0 && eap->arg >= eap->args[0]); + // If eap->arg is still pointing to the first argument, just make eap->args[0] point to the + // same location. This is needed for usecases like vim.cmd.sleep('10m'). If eap->arg is + // pointing outside the first argument, shift arguments by 1. + if (eap->arg < eap->args[0] + eap->arglens[0]) { + eap->arglens[0] -= (size_t)(eap->arg - eap->args[0]); + eap->args[0] = eap->arg; + } else { + shift_cmd_args(eap); + } + } + if (n <= 0 && (eap->argt & EX_ZEROR) == 0) { if (errormsg != NULL) { *errormsg = _(e_zerocount); @@ -1509,6 +1526,30 @@ end: return retval; } +// Shift Ex-command arguments to the right. +static void shift_cmd_args(exarg_T *eap) +{ + assert(eap->args != NULL && eap->argc > 0); + + char **oldargs = eap->args; + size_t *oldarglens = eap->arglens; + + eap->argc--; + eap->args = eap->argc > 0 ? xcalloc(eap->argc, sizeof(char *)) : NULL; + eap->arglens = eap->argc > 0 ? xcalloc(eap->argc, sizeof(size_t)) : NULL; + + for (size_t i = 0; i < eap->argc; i++) { + eap->args[i] = oldargs[i + 1]; + eap->arglens[i] = oldarglens[i + 1]; + } + + // If there are no arguments, make eap->arg point to the end of string. + eap->arg = (eap->argc > 0 ? eap->args[0] : (oldargs[0] + oldarglens[0])); + + xfree(oldargs); + xfree(oldarglens); +} + static int execute_cmd0(int *retv, exarg_T *eap, char **errormsg, bool preview) { // If filename expansion is enabled, expand filenames @@ -1533,7 +1574,7 @@ static int execute_cmd0(int *retv, exarg_T *eap, char **errormsg, bool preview) || eap->cmdidx == CMD_bunload) { p = skiptowhite_esc(eap->arg); } else { - p = eap->arg + STRLEN(eap->arg); + p = eap->arg + strlen(eap->arg); while (p > eap->arg && ascii_iswhite(p[-1])) { p--; } @@ -1548,15 +1589,7 @@ static int execute_cmd0(int *retv, exarg_T *eap, char **errormsg, bool preview) 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]; + shift_cmd_args(eap); } if (eap->line2 < 0) { // failed return FAIL; @@ -1655,6 +1688,11 @@ int execute_cmd(exarg_T *eap, CmdParseInfo *cmdinfo, bool preview) (void)hasFolding(eap->line2, NULL, &eap->line2); } + // Use first argument as count when possible + if (parse_count(eap, &errormsg, true) == FAIL) { + goto end; + } + // Execute the command execute_cmd0(&retv, eap, &errormsg, preview); @@ -1676,7 +1714,7 @@ static void profile_cmd(const exarg_T *eap, cstack_T *cstack, LineGetter fgetlin && (!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; + bool skip = did_emsg || got_int || did_throw; if (eap->cmdidx == CMD_catch) { skip = !skip && !(cstack->cs_idx >= 0 @@ -1754,6 +1792,7 @@ static bool skip_cmd(const exarg_T *eap) case CMD_filter: case CMD_help: case CMD_hide: + case CMD_horizontal: case CMD_ijump: case CMD_ilist: case CMD_isearch: @@ -1873,7 +1912,7 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter ea.skip = (did_emsg || got_int - || current_exception + || did_throw || (cstack->cs_idx >= 0 && !(cstack->cs_flags[cstack->cs_idx] & CSF_ACTIVE))); @@ -1926,7 +1965,7 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter // If we got a line, but no command, then go to the line. // If we find a '|' or '\n' we set ea.nextcmd. if (*ea.cmd == NUL || *ea.cmd == '"' - || (ea.nextcmd = (char *)check_nextcmd((char_u *)ea.cmd)) != NULL) { + || (ea.nextcmd = check_nextcmd(ea.cmd)) != NULL) { // strange vi behaviour: // ":3" jumps to line 3 // ":3|..." prints line 3 @@ -2435,8 +2474,12 @@ int parse_command_modifiers(exarg_T *eap, char **errormsg, cmdmod_T *cmod, bool continue; } - // ":hide" and ":hide | cmd" are not modifiers case 'h': + if (checkforcmd(&eap->cmd, "horizontal", 3)) { + cmod->cmod_split |= WSP_HOR; + continue; + } + // ":hide" and ":hide | cmd" are not modifiers if (p != eap->cmd || !checkforcmd(&p, "hide", 3) || *p == NUL || ends_excmd(*p)) { break; @@ -2816,24 +2859,24 @@ bool checkforcmd(char **pp, char *cmd, int len) /// invisible otherwise. static void append_command(char *cmd) { - size_t len = STRLEN(IObuff); + size_t len = strlen(IObuff); char *s = cmd; char *d; if (len > IOSIZE - 100) { // Not enough space, truncate and put in "...". d = (char *)IObuff + IOSIZE - 100; - d -= utf_head_off(IObuff, (const char_u *)d); + d -= utf_head_off((char *)IObuff, d); STRCPY(d, "..."); } STRCAT(IObuff, ": "); d = (char *)IObuff + STRLEN(IObuff); - while (*s != NUL && (char_u *)d - IObuff + 5 < IOSIZE) { + while (*s != NUL && d - IObuff + 5 < IOSIZE) { if ((char_u)s[0] == 0xc2 && (char_u)s[1] == 0xa0) { s += 2; STRCPY(d, "<a0>"); d += 4; - } else if ((char_u *)d - IObuff + utfc_ptr2len(s) + 1 >= IOSIZE) { + } else if (d - IObuff + utfc_ptr2len(s) + 1 >= IOSIZE) { break; } else { mb_copy_char((const char **)&s, &d); @@ -3078,17 +3121,16 @@ void f_fullcommand(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) return; } - rettv->vval.v_string = (char *)vim_strsave(IS_USER_CMDIDX(ea.cmdidx) - ? (char_u *)get_user_command_name(ea.useridx, - ea.cmdidx) - : (char_u *)cmdnames[ea.cmdidx].cmd_name); + rettv->vval.v_string = xstrdup(IS_USER_CMDIDX(ea.cmdidx) + ? get_user_command_name(ea.useridx, ea.cmdidx) + : cmdnames[ea.cmdidx].cmd_name); } cmdidx_T excmd_get_cmdidx(const char *cmd, size_t len) { cmdidx_T idx; - for (idx = (cmdidx_T)0; (int)idx < (int)CMD_SIZE; idx = (cmdidx_T)((int)idx + 1)) { + for (idx = (cmdidx_T)0; (int)idx < CMD_SIZE; idx = (cmdidx_T)((int)idx + 1)) { if (strncmp(cmdnames[(int)idx].cmd_name, cmd, len) == 0) { break; } @@ -3310,7 +3352,7 @@ static linenr_T get_address(exarg_T *eap, char **ptr, cmd_addr_T addr_type, int goto error; } if (skip) { // skip "/pat/" - cmd = (char *)skip_regexp((char_u *)cmd, c, p_magic, NULL); + cmd = skip_regexp(cmd, c, p_magic, NULL); if (*cmd == c) { cmd++; } @@ -3650,7 +3692,7 @@ char *replace_makeprg(exarg_T *eap, char *arg, char **cmdlinep) // Don't do it when ":vimgrep" is used for ":grep". if ((eap->cmdidx == CMD_make || eap->cmdidx == CMD_lmake || isgrep) && !grep_internal(eap->cmdidx)) { - const char *program = isgrep ? (*curbuf->b_p_gp == NUL ? (char *)p_gp : curbuf->b_p_gp) + const char *program = isgrep ? (*curbuf->b_p_gp == NUL ? p_gp : curbuf->b_p_gp) : (*curbuf->b_p_mp == NUL ? (char *)p_mp : curbuf->b_p_mp); arg = skipwhite(arg); @@ -3659,13 +3701,13 @@ char *replace_makeprg(exarg_T *eap, char *arg, char **cmdlinep) // Replace $* by given arguments if ((new_cmdline = strrep(program, "$*", arg)) == NULL) { // No $* in arg, build "<makeprg> <arg>" instead - new_cmdline = xmalloc(STRLEN(program) + STRLEN(arg) + 2); + new_cmdline = xmalloc(strlen(program) + strlen(arg) + 2); STRCPY(new_cmdline, program); STRCAT(new_cmdline, " "); STRCAT(new_cmdline, arg); } - msg_make((char_u *)arg); + msg_make(arg); // 'eap->cmd' is not set here, because it is not used at CMD_make xfree(*cmdlinep); @@ -3687,7 +3729,7 @@ int expand_filename(exarg_T *eap, char **cmdlinep, char **errormsgp) // Decide to expand wildcards *before* replacing '%', '#', etc. If // the file name contains a wildcard it should not cause expanding. // (it will be expanded anyway if there is a wildcard before replacing). - int has_wildcards = path_has_wildcard((char_u *)p); + int has_wildcards = path_has_wildcard(p); while (*p != NUL) { // Skip over `=expr`, wildcards in it are not expanded. if (p[0] == '`' && p[1] == '=') { @@ -3791,14 +3833,14 @@ int expand_filename(exarg_T *eap, char **cmdlinep, char **errormsgp) // if there are still wildcards present. if (vim_strchr(eap->arg, '$') != NULL || vim_strchr(eap->arg, '~') != NULL) { - expand_env_esc((char_u *)eap->arg, NameBuff, MAXPATHL, true, true, NULL); + expand_env_esc((char_u *)eap->arg, (char_u *)NameBuff, MAXPATHL, true, true, NULL); has_wildcards = path_has_wildcard(NameBuff); p = (char *)NameBuff; } else { p = NULL; } if (p != NULL) { - (void)repl_cmdline(eap, eap->arg, STRLEN(eap->arg), p, cmdlinep); + (void)repl_cmdline(eap, eap->arg, strlen(eap->arg), p, cmdlinep); } } @@ -3807,7 +3849,7 @@ int expand_filename(exarg_T *eap, char **cmdlinep, char **errormsgp) // done by ExpandOne() below. #ifdef UNIX if (!has_wildcards) { - backslash_halve((char_u *)eap->arg); + backslash_halve(eap->arg); } #else backslash_halve((char_u *)eap->arg); @@ -3822,11 +3864,11 @@ int expand_filename(exarg_T *eap, char **cmdlinep, char **errormsgp) if (p_wic) { options += WILD_ICASE; } - p = (char *)ExpandOne(&xpc, (char_u *)eap->arg, NULL, options, WILD_EXPAND_FREE); + p = ExpandOne(&xpc, eap->arg, NULL, options, WILD_EXPAND_FREE); if (p == NULL) { return FAIL; } - (void)repl_cmdline(eap, eap->arg, STRLEN(eap->arg), p, cmdlinep); + (void)repl_cmdline(eap, eap->arg, strlen(eap->arg), p, cmdlinep); xfree(p); } } @@ -3844,10 +3886,10 @@ static char *repl_cmdline(exarg_T *eap, char *src, size_t srclen, char *repl, ch // The new command line is build in new_cmdline[]. // First allocate it. // Careful: a "+cmd" argument may have been NUL terminated. - size_t len = STRLEN(repl); - size_t i = (size_t)(src - *cmdlinep) + STRLEN(src + srclen) + len + 3; + size_t len = strlen(repl); + size_t i = (size_t)(src - *cmdlinep) + strlen(src + srclen) + len + 3; if (eap->nextcmd != NULL) { - i += STRLEN(eap->nextcmd); // add space for next command + i += strlen(eap->nextcmd); // add space for next command } char *new_cmdline = xmalloc(i); size_t offset = (size_t)(src - *cmdlinep); @@ -3865,7 +3907,7 @@ static char *repl_cmdline(exarg_T *eap, char *src, size_t srclen, char *repl, ch src = new_cmdline + i; // remember where to continue if (eap->nextcmd != NULL) { // append next command - i = STRLEN(new_cmdline) + 1; + i = strlen(new_cmdline) + 1; STRCPY(new_cmdline + i, eap->nextcmd); eap->nextcmd = new_cmdline + i; } @@ -3880,7 +3922,7 @@ static char *repl_cmdline(exarg_T *eap, char *src, size_t srclen, char *repl, ch } else { // Otherwise, argument gets shifted alongside the replaced text. // The amount of the shift is equal to the difference of the old and new string length. - eap->args[j] = new_cmdline + (eap->args[j] - *cmdlinep) + (len - srclen); + eap->args[j] = new_cmdline + ((eap->args[j] - *cmdlinep) + (ptrdiff_t)(len - srclen)); } } @@ -3932,7 +3974,7 @@ void separate_nextcmd(exarg_T *eap) STRMOVE(p - 1, p); // remove the '\' p--; } else { - eap->nextcmd = (char *)check_nextcmd((char_u *)p); + eap->nextcmd = check_nextcmd(p); *p = NUL; break; } @@ -4061,7 +4103,7 @@ static int getargopt(exarg_T *eap) *arg = NUL; if (pp == &eap->force_ff) { - if (check_ff_value((char_u *)eap->cmd + eap->force_ff) == FAIL) { + if (check_ff_value(eap->cmd + eap->force_ff) == FAIL) { return FAIL; } eap->force_ff = (char_u)eap->cmd[eap->force_ff]; @@ -4107,9 +4149,9 @@ static int get_tabpage_arg(exarg_T *eap) tab_number = (int)getdigits(&p, false, tab_number); if (relative == 0) { - if (STRCMP(p, "$") == 0) { + if (strcmp(p, "$") == 0) { tab_number = LAST_TAB_NR; - } else if (STRCMP(p, "#") == 0) { + } else if (strcmp(p, "#") == 0) { if (valid_tabpage(lastused_tabpage)) { tab_number = tabpage_index(lastused_tabpage); } else { @@ -4295,7 +4337,7 @@ int ends_excmd(int c) FUNC_ATTR_CONST /// @return the next command, after the first '|' or '\n' or, /// NULL if not found. -char_u *find_nextcmd(const char_u *p) +char *find_nextcmd(const char *p) { while (*p != '|' && *p != '\n') { if (*p == NUL) { @@ -4303,18 +4345,18 @@ char_u *find_nextcmd(const char_u *p) } p++; } - return (char_u *)p + 1; + return (char *)p + 1; } /// Check if *p is a separator between Ex commands, skipping over white space. /// /// @return NULL if it isn't, the following character if it is. -char_u *check_nextcmd(char_u *p) +char *check_nextcmd(char *p) { - char *s = skipwhite((char *)p); + char *s = skipwhite(p); if (*s == '|' || *s == '\n') { - return (char_u *)(s + 1); + return s + 1; } else { return NULL; } @@ -4341,7 +4383,7 @@ static int check_more(int message, bool forceit) vim_snprintf((char *)buff, DIALOG_MSG_SIZE, NGETTEXT("%d more file to edit. Quit anyway?", "%d more files to edit. Quit anyway?", (unsigned long)n), n); - if (vim_dialog_yesno(VIM_QUESTION, NULL, (char_u *)buff, 1) == VIM_YES) { + if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 1) == VIM_YES) { return OK; } return FAIL; @@ -4689,7 +4731,6 @@ void tabpage_close(int forceit) void tabpage_close_other(tabpage_T *tp, int forceit) { int done = 0; - int h = tabline_height(); char prev_idx[NUMBUFLEN]; // Limit to 1000 windows, autocommands may add a window while we close @@ -4705,11 +4746,6 @@ void tabpage_close_other(tabpage_T *tp, int forceit) break; } } - - redraw_tabline = true; - if (h != tabline_height()) { - win_new_screen_rows(); - } } /// ":only". @@ -4831,7 +4867,6 @@ static void ex_print(exarg_T *eap) if (++eap->line1 > eap->line2) { break; } - ui_flush(); // show one line at a time } setpcmark(); // put cursor at last line @@ -4907,7 +4942,7 @@ void ex_splitview(exarg_T *eap) } if (eap->cmdidx == CMD_sfind || eap->cmdidx == CMD_tabfind) { - fname = (char *)find_file_in_path((char_u *)eap->arg, STRLEN(eap->arg), + fname = (char *)find_file_in_path((char_u *)eap->arg, strlen(eap->arg), FNAME_MESS, true, (char_u *)curbuf->b_ffname); if (fname == NULL) { goto theend; @@ -5032,8 +5067,7 @@ static void ex_tabs(exarg_T *eap) msg_putchar('\n'); vim_snprintf((char *)IObuff, IOSIZE, _("Tab page %d"), tabcount++); - msg_outtrans_attr(IObuff, HL_ATTR(HLF_T)); - ui_flush(); // output one line at a time + msg_outtrans_attr((char *)IObuff, HL_ATTR(HLF_T)); os_breakcheck(); FOR_ALL_WINDOWS_IN_TAB(wp, tp) { @@ -5052,7 +5086,6 @@ static void ex_tabs(exarg_T *eap) home_replace(wp->w_buffer, wp->w_buffer->b_fname, (char *)IObuff, IOSIZE, true); } msg_outtrans((char *)IObuff); - ui_flush(); // output one line at a time os_breakcheck(); } } @@ -5102,7 +5135,7 @@ static void ex_resize(exarg_T *eap) /// ":find [+command] <file>" command. static void ex_find(exarg_T *eap) { - char *fname = (char *)find_file_in_path((char_u *)eap->arg, STRLEN(eap->arg), + char *fname = (char *)find_file_in_path((char_u *)eap->arg, strlen(eap->arg), FNAME_MESS, true, (char_u *)curbuf->b_ffname); if (eap->addr_count > 0) { // Repeat finding the file "count" times. This matters when it @@ -5270,7 +5303,7 @@ static void ex_swapname(exarg_T *eap) if (curbuf->b_ml.ml_mfp == NULL || curbuf->b_ml.ml_mfp->mf_fname == NULL) { msg(_("No swap file")); } else { - msg((char *)curbuf->b_ml.ml_mfp->mf_fname); + msg(curbuf->b_ml.ml_mfp->mf_fname); } } @@ -5476,7 +5509,7 @@ bool changedir_func(char *new_dir, CdScope scope) char *pdir = NULL; // ":cd -": Change to previous directory - if (STRCMP(new_dir, "-") == 0) { + if (strcmp(new_dir, "-") == 0) { pdir = get_prevdir(scope); if (pdir == NULL) { emsg(_("E186: No previous directory")); @@ -5485,8 +5518,8 @@ bool changedir_func(char *new_dir, CdScope scope) new_dir = pdir; } - if (os_dirname(NameBuff, MAXPATHL) == OK) { - pdir = (char *)vim_strsave(NameBuff); + if (os_dirname((char_u *)NameBuff, MAXPATHL) == OK) { + pdir = xstrdup(NameBuff); } else { pdir = NULL; } @@ -5499,7 +5532,7 @@ bool changedir_func(char *new_dir, CdScope scope) if (*new_dir == NUL && p_cdh) { #endif // Use NameBuff for home directory name. - expand_env((char_u *)"$HOME", NameBuff, MAXPATHL); + expand_env("$HOME", NameBuff, MAXPATHL); new_dir = (char *)NameBuff; } @@ -5540,27 +5573,26 @@ void ex_cd(exarg_T *eap) // for non-UNIX ":cd" means: print current directory unless 'cdhome' is set if (*new_dir == NUL && !p_cdh) { ex_pwd(NULL); - } else + return; + } #endif - { - CdScope scope = kCdScopeGlobal; - switch (eap->cmdidx) { - case CMD_tcd: - case CMD_tchdir: - scope = kCdScopeTabpage; - break; - case CMD_lcd: - case CMD_lchdir: - scope = kCdScopeWindow; - break; - default: - break; - } - if (changedir_func(new_dir, scope)) { - // Echo the new current directory if the command was typed. - if (KeyTyped || p_verbose >= 5) { - ex_pwd(eap); - } + CdScope scope = kCdScopeGlobal; + switch (eap->cmdidx) { + case CMD_tcd: + case CMD_tchdir: + scope = kCdScopeTabpage; + break; + case CMD_lcd: + case CMD_lchdir: + scope = kCdScopeWindow; + break; + default: + break; + } + if (changedir_func(new_dir, scope)) { + // Echo the new current directory if the command was typed. + if (KeyTyped || p_verbose >= 5) { + ex_pwd(eap); } } } @@ -5568,7 +5600,7 @@ void ex_cd(exarg_T *eap) /// ":pwd". static void ex_pwd(exarg_T *eap) { - if (os_dirname(NameBuff, MAXPATHL) == OK) { + if (os_dirname((char_u *)NameBuff, MAXPATHL) == OK) { #ifdef BACKSLASH_IN_FILENAME slash_adjust(NameBuff); #endif @@ -5672,7 +5704,7 @@ static void ex_wincmd(exarg_T *eap) p = eap->arg + 1; } - eap->nextcmd = (char *)check_nextcmd((char_u *)p); + eap->nextcmd = check_nextcmd(p); p = skipwhite(p); if (*p != NUL && *p != '"' && eap->nextcmd == NULL) { emsg(_(e_invarg)); @@ -5870,7 +5902,7 @@ static void ex_undo(exarg_T *eap) { if (eap->addr_count != 1) { if (eap->forceit) { - u_undo_and_forget(1); // :undo! + u_undo_and_forget(1, true); // :undo! } else { u_undo(1); // :undo } @@ -5897,7 +5929,7 @@ static void ex_undo(exarg_T *eap) emsg(_(e_undobang_cannot_redo_or_move_branch)); return; } - u_undo_and_forget(count); + u_undo_and_forget(count, true); } else { // :undo 123 undo_time(step, false, false, true); } @@ -6004,7 +6036,7 @@ static void ex_redir(exarg_T *eap) // Make register empty when not using @A-@Z and the // command is valid. if (*arg == NUL && !isupper(redir_reg)) { - write_reg_contents(redir_reg, (char_u *)"", 0, false); + write_reg_contents(redir_reg, "", 0, false); } } } @@ -6058,9 +6090,10 @@ static void ex_redraw(exarg_T *eap) if (eap->forceit) { redraw_all_later(UPD_NOT_VALID); redraw_cmdline = true; + } else if (VIsual_active) { + redraw_curbuf_later(UPD_INVERTED); } - update_screen(eap->forceit ? UPD_NOT_VALID - : VIsual_active ? UPD_INVERTED : 0); + update_screen(); if (need_maketitle) { maketitle(); } @@ -6086,14 +6119,22 @@ static void ex_redrawstatus(exarg_T *eap) int r = RedrawingDisabled; int p = p_lz; - RedrawingDisabled = 0; - p_lz = false; if (eap->forceit) { status_redraw_all(); } else { status_redraw_curbuf(); } - update_screen(VIsual_active ? UPD_INVERTED : 0); + + RedrawingDisabled = 0; + p_lz = false; + if (State & MODE_CMDLINE) { + redraw_statuslines(); + } else { + if (VIsual_active) { + redraw_curbuf_later(UPD_INVERTED); + } + update_screen(); + } RedrawingDisabled = r; p_lz = p; ui_flush(); @@ -6154,12 +6195,12 @@ FILE *open_exfile(char_u *fname, int forceit, char *mode) { #ifdef UNIX // with Unix it is possible to open a directory - if (os_isdir(fname)) { + if (os_isdir((char *)fname)) { semsg(_(e_isadir2), fname); return NULL; } #endif - if (!forceit && *mode != 'a' && os_path_exists(fname)) { + if (!forceit && *mode != 'a' && os_path_exists((char *)fname)) { semsg(_("E189: \"%s\" exists (add ! to override)"), fname); return NULL; } @@ -6289,7 +6330,7 @@ static void ex_normal(exarg_T *eap) } } if (len > 0) { - arg = xmalloc(STRLEN(eap->arg) + (size_t)len + 1); + arg = xmalloc(strlen(eap->arg) + (size_t)len + 1); len = 0; for (p = eap->arg; *p != NUL; p++) { arg[len++] = *p; @@ -6454,7 +6495,7 @@ static void ex_findpat(exarg_T *eap) if (*eap->arg == '/') { // Match regexp, not just whole words whole = false; eap->arg++; - char *p = (char *)skip_regexp((char_u *)eap->arg, '/', p_magic, NULL); + char *p = skip_regexp(eap->arg, '/', p_magic, NULL); if (*p) { *p++ = NUL; p = skipwhite(p); @@ -6463,12 +6504,12 @@ static void ex_findpat(exarg_T *eap) if (!ends_excmd(*p)) { eap->errmsg = ex_errmsg(e_trailing_arg, p); } else { - eap->nextcmd = (char *)check_nextcmd((char_u *)p); + eap->nextcmd = check_nextcmd(p); } } } if (!eap->skip) { - find_pattern_in_path((char_u *)eap->arg, 0, STRLEN(eap->arg), whole, !eap->forceit, + find_pattern_in_path((char_u *)eap->arg, 0, strlen(eap->arg), whole, !eap->forceit, *eap->cmd == 'd' ? FIND_DEFINE : FIND_ANY, n, action, eap->line1, eap->line2); } @@ -6560,7 +6601,7 @@ static void ex_tag_cmd(exarg_T *eap, char *name) cmd = DT_LTAG; } - do_tag((char_u *)eap->arg, cmd, eap->addr_count > 0 ? (int)eap->line2 : 1, + do_tag(eap->arg, cmd, eap->addr_count > 0 ? (int)eap->line2 : 1, eap->forceit, true); } @@ -6609,7 +6650,7 @@ ssize_t find_cmdline_var(const char_u *src, size_t *usedlen) }; for (size_t i = 0; i < ARRAY_SIZE(spec_str); i++) { - size_t len = STRLEN(spec_str[i]); + size_t len = strlen(spec_str[i]); if (STRNCMP(src, spec_str[i], len) == 0) { *usedlen = len; assert(i <= SSIZE_MAX); @@ -6709,7 +6750,7 @@ char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnum valid = 0; // Must have ":p:h" to be valid } else { result = curbuf->b_fname; - tilde_file = STRCMP(result, "~") == 0; + tilde_file = strcmp(result, "~") == 0; } break; @@ -6763,7 +6804,7 @@ char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnum valid = 0; // Must have ":p:h" to be valid } else { result = buf->b_fname; - tilde_file = STRCMP(result, "~") == 0; + tilde_file = strcmp(result, "~") == 0; } } break; @@ -6876,12 +6917,12 @@ char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnum } // Length of new string. - resultlen = STRLEN(result); + resultlen = strlen(result); // Remove the file name extension. if (src[*usedlen] == '<') { (*usedlen)++; char *s; - if ((s = (char *)STRRCHR(result, '.')) != NULL + if ((s = strrchr(result, '.')) != NULL && s >= path_tail(result)) { resultlen = (size_t)(s - result); } @@ -6939,11 +6980,11 @@ char *expand_sfile(char *arg) p += srclen; continue; } - size_t len = STRLEN(result) - srclen + STRLEN(repl) + 1; + size_t len = strlen(result) - srclen + strlen(repl) + 1; char *newres = xmalloc(len); memmove(newres, result, (size_t)(p - result)); STRCPY(newres + (p - result), repl); - len = STRLEN(newres); + len = strlen(newres); STRCAT(newres, p + srclen); xfree(repl); xfree(result); @@ -6983,12 +7024,12 @@ void dialog_msg(char *buff, char *format, char *fname) /// ":behave {mswin,xterm}" static void ex_behave(exarg_T *eap) { - if (STRCMP(eap->arg, "mswin") == 0) { + if (strcmp(eap->arg, "mswin") == 0) { set_option_value_give_err("selection", 0L, "exclusive", 0); set_option_value_give_err("selectmode", 0L, "mouse,key", 0); set_option_value_give_err("mousemodel", 0L, "popup", 0); set_option_value_give_err("keymodel", 0L, "startsel,stopsel", 0); - } else if (STRCMP(eap->arg, "xterm") == 0) { + } else if (strcmp(eap->arg, "xterm") == 0) { set_option_value_give_err("selection", 0L, "inclusive", 0); set_option_value_give_err("selectmode", 0L, "", 0); set_option_value_give_err("mousemodel", 0L, "extend", 0); @@ -7038,7 +7079,7 @@ static void ex_filetype(exarg_T *eap) } break; } - if (STRCMP(arg, "on") == 0 || STRCMP(arg, "detect") == 0) { + if (strcmp(arg, "on") == 0 || strcmp(arg, "detect") == 0) { if (*arg == 'o' || !filetype_detect) { source_runtime(FILETYPE_FILE, DIP_ALL); filetype_detect = kTrue; @@ -7055,7 +7096,7 @@ static void ex_filetype(exarg_T *eap) (void)do_doautocmd("filetypedetect BufRead", true, NULL); do_modelines(0); } - } else if (STRCMP(arg, "off") == 0) { + } else if (strcmp(arg, "off") == 0) { if (plugin || indent) { if (plugin) { source_runtime(FTPLUGOF_FILE, DIP_ALL); |