aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ex_docmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/ex_docmd.c')
-rw-r--r--src/nvim/ex_docmd.c841
1 files changed, 452 insertions, 389 deletions
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index bf518f3849..e11dd0a2f6 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -4,59 +4,57 @@
// ex_docmd.c: functions for executing an Ex command line.
#include <assert.h>
+#include <ctype.h>
#include <inttypes.h>
+#include <limits.h>
#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include "auto/config.h"
#include "nvim/arglist.h"
#include "nvim/ascii.h"
+#include "nvim/autocmd.h"
#include "nvim/buffer.h"
#include "nvim/change.h"
#include "nvim/charset.h"
#include "nvim/cmdexpand.h"
-#include "nvim/cmdhist.h"
#include "nvim/cursor.h"
#include "nvim/debugger.h"
-#include "nvim/diff.h"
#include "nvim/digraph.h"
#include "nvim/drawscreen.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
+#include "nvim/eval/typval.h"
+#include "nvim/eval/typval_defs.h"
#include "nvim/eval/userfunc.h"
-#include "nvim/eval/vars.h"
-#include "nvim/event/rstream.h"
-#include "nvim/event/wstream.h"
+#include "nvim/event/loop.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_eval.h"
#include "nvim/ex_getln.h"
-#include "nvim/ex_session.h"
#include "nvim/file_search.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
-#include "nvim/func_attr.h"
#include "nvim/garray.h"
#include "nvim/getchar.h"
+#include "nvim/gettext.h"
#include "nvim/globals.h"
-#include "nvim/hardcopy.h"
-#include "nvim/help.h"
+#include "nvim/highlight_defs.h"
#include "nvim/highlight_group.h"
-#include "nvim/if_cscope.h"
#include "nvim/input.h"
#include "nvim/keycodes.h"
-#include "nvim/locale.h"
-#include "nvim/lua/executor.h"
+#include "nvim/macros.h"
#include "nvim/main.h"
-#include "nvim/mapping.h"
#include "nvim/mark.h"
-#include "nvim/match.h"
#include "nvim/mbyte.h"
+#include "nvim/memfile_defs.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
-#include "nvim/menu.h"
#include "nvim/message.h"
#include "nvim/mouse.h"
#include "nvim/move.h"
@@ -66,28 +64,25 @@
#include "nvim/optionstr.h"
#include "nvim/os/input.h"
#include "nvim/os/os.h"
-#include "nvim/os/time.h"
-#include "nvim/os_unix.h"
+#include "nvim/os/shell.h"
#include "nvim/path.h"
#include "nvim/popupmenu.h"
+#include "nvim/pos.h"
#include "nvim/profile.h"
#include "nvim/quickfix.h"
#include "nvim/regexp.h"
+#include "nvim/runtime.h"
+#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/shada.h"
-#include "nvim/sign.h"
-#include "nvim/spell.h"
-#include "nvim/spellfile.h"
#include "nvim/state.h"
+#include "nvim/statusline.h"
#include "nvim/strings.h"
-#include "nvim/syntax.h"
#include "nvim/tag.h"
-#include "nvim/terminal.h"
+#include "nvim/types.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
-#include "nvim/undo_defs.h"
#include "nvim/usercmd.h"
-#include "nvim/version.h"
#include "nvim/vim.h"
#include "nvim/window.h"
@@ -254,7 +249,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;
}
@@ -535,7 +530,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
if (flags & DOCMD_KEEPLINE) {
xfree(repeat_cmdline);
if (count == 0) {
- repeat_cmdline = (char *)vim_strsave((char_u *)next_cmdline);
+ repeat_cmdline = xstrdup(next_cmdline);
} else {
repeat_cmdline = NULL;
}
@@ -642,7 +637,7 @@ 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) {
+ 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;
@@ -727,7 +722,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 && !did_throw
+ if (!got_int && !did_throw && !aborting()
&& ((getline_equal(fgetline, cookie, getsourceline)
&& !source_finished(fgetline, cookie))
|| (getline_equal(fgetline, cookie, get_func_line)
@@ -771,52 +766,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
// of interrupts or errors to exceptions, and ensure that no more
// commands are executed.
if (did_throw) {
- assert(current_exception != NULL);
- char *p = NULL;
- msglist_T *messages = NULL;
- msglist_T *next;
-
- // If the uncaught exception is a user exception, report it as an
- // error. If it is an error exception, display the saved error
- // message now. For an interrupt exception, do nothing; the
- // interrupt message is given elsewhere.
- switch (current_exception->type) {
- case ET_USER:
- vim_snprintf((char *)IObuff, IOSIZE,
- _("E605: Exception not caught: %s"),
- current_exception->value);
- p = (char *)vim_strsave(IObuff);
- break;
- case ET_ERROR:
- messages = current_exception->messages;
- current_exception->messages = NULL;
- break;
- case ET_INTERRUPT:
- break;
- }
-
- estack_push(ETYPE_EXCEPT, current_exception->throw_name, current_exception->throw_lnum);
- current_exception->throw_name = NULL;
-
- discard_current_exception(); // uses IObuff if 'verbose'
- suppress_errthrow = true;
- force_abort = true;
- msg_ext_set_kind("emsg"); // kind=emsg for :throw, exceptions. #9993
-
- if (messages != NULL) {
- do {
- next = messages->next;
- emsg(messages->msg);
- xfree(messages->msg);
- xfree(messages);
- messages = next;
- } while (messages != NULL);
- } else if (p != NULL) {
- emsg(p);
- xfree(p);
- }
- xfree(SOURCING_NAME);
- estack_pop();
+ handle_did_throw();
} else if (got_int || (did_emsg && force_abort)) {
// On an interrupt or an aborting error not converted to an exception,
// disable the conversion of errors to exceptions. (Interrupts are not
@@ -906,6 +856,57 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
return retval;
}
+/// Handle when "did_throw" is set after executing commands.
+void handle_did_throw(void)
+{
+ assert(current_exception != NULL);
+ char *p = NULL;
+ msglist_T *messages = NULL;
+
+ // If the uncaught exception is a user exception, report it as an
+ // error. If it is an error exception, display the saved error
+ // message now. For an interrupt exception, do nothing; the
+ // interrupt message is given elsewhere.
+ switch (current_exception->type) {
+ case ET_USER:
+ vim_snprintf(IObuff, IOSIZE,
+ _("E605: Exception not caught: %s"),
+ current_exception->value);
+ p = xstrdup(IObuff);
+ break;
+ case ET_ERROR:
+ messages = current_exception->messages;
+ current_exception->messages = NULL;
+ break;
+ case ET_INTERRUPT:
+ break;
+ }
+
+ estack_push(ETYPE_EXCEPT, current_exception->throw_name, current_exception->throw_lnum);
+ current_exception->throw_name = NULL;
+
+ discard_current_exception(); // uses IObuff if 'verbose'
+ suppress_errthrow = true;
+ force_abort = true;
+ msg_ext_set_kind("emsg"); // kind=emsg for :throw, exceptions. #9993
+
+ if (messages != NULL) {
+ do {
+ msglist_T *next = messages->next;
+ emsg(messages->msg);
+ xfree(messages->msg);
+ xfree(messages->sfile);
+ xfree(messages);
+ messages = next;
+ } while (messages != NULL);
+ } else if (p != NULL) {
+ emsg(p);
+ xfree(p);
+ }
+ xfree(SOURCING_NAME);
+ estack_pop();
+}
+
/// Obtain a line when inside a ":while" or ":for" loop.
static char *get_loop_line(int c, void *cookie, int indent, bool do_concat)
{
@@ -1060,7 +1061,7 @@ static int current_tab_nr(tabpage_T *tab)
#define LAST_TAB_NR current_tab_nr(NULL)
/// Figure out the address type for ":wincmd".
-static void get_wincmd_addr_type(char *arg, exarg_T *eap)
+static void get_wincmd_addr_type(const char *arg, exarg_T *eap)
{
switch (*arg) {
case 'S':
@@ -1300,9 +1301,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);
}
@@ -1339,6 +1340,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);
@@ -1430,7 +1445,7 @@ bool parse_cmdline(char *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo, char **er
// If the modifier was parsed OK the error must be in the following command
char *cmdname = after_modifier ? after_modifier : cmdline;
append_command(cmdname);
- *errormsg = (char *)IObuff;
+ *errormsg = IObuff;
goto end;
}
@@ -1512,6 +1527,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
@@ -1536,7 +1575,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--;
}
@@ -1551,15 +1590,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;
@@ -1608,6 +1639,7 @@ int execute_cmd(exarg_T *eap, CmdParseInfo *cmdinfo, bool preview)
char *errormsg = NULL;
int retv = 0;
+#undef ERROR
#define ERROR(msg) \
do { \
errormsg = msg; \
@@ -1658,6 +1690,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);
@@ -1757,6 +1794,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:
@@ -1794,6 +1832,7 @@ static bool skip_cmd(const exarg_T *eap)
case CMD_throw:
case CMD_tilde:
case CMD_topleft:
+ case CMD_trust:
case CMD_unlet:
case CMD_unlockvar:
case CMD_verbose:
@@ -1892,9 +1931,11 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter
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.
- dbg_check_breakpoint(&ea);
+ if (!exiting) {
+ // May go to debug mode. If this happens and the ">quit" debug command is
+ // used, throw an interrupt exception and skip the next command.
+ dbg_check_breakpoint(&ea);
+ }
if (!ea.skip && got_int) {
ea.skip = true;
(void)do_intthrow(cstack);
@@ -1929,7 +1970,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
@@ -1997,7 +2038,7 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter
if (!(flags & DOCMD_VERBOSE)) {
append_command(cmdname);
}
- errormsg = (char *)IObuff;
+ errormsg = IObuff;
did_emsg_syntax = true;
verify_command(cmdname);
}
@@ -2266,9 +2307,9 @@ doend:
if (errormsg != NULL && *errormsg != NUL && !did_emsg) {
if (flags & DOCMD_VERBOSE) {
- if (errormsg != (char *)IObuff) {
+ if (errormsg != IObuff) {
STRCPY(IObuff, errormsg);
- errormsg = (char *)IObuff;
+ errormsg = IObuff;
}
append_command(*ea.cmdlinep);
}
@@ -2438,8 +2479,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;
@@ -2798,7 +2843,7 @@ theend:
/// @param pp start of command
/// @param cmd name of command
/// @param len required length
-bool checkforcmd(char **pp, char *cmd, int len)
+bool checkforcmd(char **pp, const char *cmd, int len)
{
int i;
@@ -2819,24 +2864,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 = IObuff + IOSIZE - 100;
+ d -= utf_head_off(IObuff, d);
STRCPY(d, "...");
}
STRCAT(IObuff, ": ");
- d = (char *)IObuff + STRLEN(IObuff);
- while (*s != NUL && (char_u *)d - IObuff + 5 < IOSIZE) {
+ d = IObuff + strlen(IObuff);
+ 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);
@@ -2936,7 +2981,7 @@ char *find_ex_command(exarg_T *eap, int *full)
for (; (int)eap->cmdidx < CMD_SIZE;
eap->cmdidx = (cmdidx_T)((int)eap->cmdidx + 1)) {
- if (STRNCMP(cmdnames[(int)eap->cmdidx].cmd_name, eap->cmd,
+ if (strncmp(cmdnames[(int)eap->cmdidx].cmd_name, eap->cmd,
(size_t)len) == 0) {
if (full != NULL
&& cmdnames[(int)eap->cmdidx].cmd_name[len] == NUL) {
@@ -3081,10 +3126,9 @@ 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)
@@ -3313,7 +3357,7 @@ static linenr_T get_address(exarg_T *eap, char **ptr, cmd_addr_T addr_type, int
goto error;
}
if (skip) { // skip "/pat/"
- cmd = skip_regexp(cmd, c, p_magic, NULL);
+ cmd = skip_regexp(cmd, c, magic_isset());
if (*cmd == c) {
cmd++;
}
@@ -3342,7 +3386,7 @@ static linenr_T get_address(exarg_T *eap, char **ptr, cmd_addr_T addr_type, int
}
searchcmdlen = 0;
flags = silent ? 0 : SEARCH_HIS | SEARCH_MSG;
- if (!do_search(NULL, c, c, (char_u *)cmd, 1L, flags, NULL)) {
+ if (!do_search(NULL, c, c, cmd, 1L, flags, NULL)) {
curwin->w_cursor = pos;
cmd = NULL;
goto error;
@@ -3442,9 +3486,10 @@ static linenr_T get_address(exarg_T *eap, char **ptr, cmd_addr_T addr_type, int
} else {
i = (char_u)(*cmd++);
}
- if (!ascii_isdigit(*cmd)) { // '+' is '+1', but '+0' is not '+1'
+ if (!ascii_isdigit(*cmd)) { // '+' is '+1'
n = 1;
} else {
+ // "number", "+number" or "-number"
n = getdigits_int32(&cmd, false, MAXLNUM);
if (n == MAXLNUM) {
emsg(_(e_line_number_out_of_range));
@@ -3459,8 +3504,8 @@ static linenr_T get_address(exarg_T *eap, char **ptr, cmd_addr_T addr_type, int
} else if (addr_type == ADDR_LOADED_BUFFERS || addr_type == ADDR_BUFFERS) {
lnum = compute_buffer_local_count(addr_type, lnum, (i == '-') ? -1 * n : n);
} else {
- // Relative line addressing, need to adjust for folded lines
- // now, but only do it after the first address.
+ // Relative line addressing: need to adjust for lines in a
+ // closed fold after the first address.
if (addr_type == ADDR_LINES && (i == '-' || i == '+')
&& address_count >= 2) {
(void)hasFolding(lnum, NULL, &lnum);
@@ -3653,7 +3698,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);
@@ -3662,7 +3707,7 @@ 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);
@@ -3690,7 +3735,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] == '=') {
@@ -3739,7 +3784,6 @@ int expand_filename(exarg_T *eap, char **cmdlinep, char **errormsgp)
&& eap->cmdidx != CMD_bang
&& eap->cmdidx != CMD_grep
&& eap->cmdidx != CMD_grepadd
- && eap->cmdidx != CMD_hardcopy
&& eap->cmdidx != CMD_lgrep
&& eap->cmdidx != CMD_lgrepadd
&& eap->cmdidx != CMD_lmake
@@ -3758,7 +3802,7 @@ int expand_filename(exarg_T *eap, char **cmdlinep, char **errormsgp)
for (l = repl; *l; l++) {
if (vim_strchr((char *)ESCAPE_CHARS, *l) != NULL) {
- l = (char *)vim_strsave_escaped((char_u *)repl, ESCAPE_CHARS);
+ l = vim_strsave_escaped(repl, (char *)ESCAPE_CHARS);
xfree(repl);
repl = l;
break;
@@ -3773,7 +3817,7 @@ int expand_filename(exarg_T *eap, char **cmdlinep, char **errormsgp)
&& strpbrk(repl, "!") != NULL) {
char *l;
- l = (char *)vim_strsave_escaped((char_u *)repl, (char_u *)"!");
+ l = vim_strsave_escaped(repl, "!");
xfree(repl);
repl = l;
}
@@ -3794,14 +3838,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, (char_u *)NameBuff, MAXPATHL, true, true, NULL);
- has_wildcards = path_has_wildcard((char_u *)NameBuff);
- p = (char *)NameBuff;
+ expand_env_esc(eap->arg, NameBuff, MAXPATHL, true, true, NULL);
+ has_wildcards = path_has_wildcard(NameBuff);
+ p = 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);
}
}
@@ -3825,11 +3869,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);
}
}
@@ -3847,10 +3891,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);
@@ -3868,7 +3912,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;
}
@@ -3883,7 +3927,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));
}
}
@@ -3935,7 +3979,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;
}
@@ -3943,7 +3987,7 @@ void separate_nextcmd(exarg_T *eap)
}
if (!(eap->argt & EX_NOTRLCOM)) { // remove trailing spaces
- del_trailing_spaces((char_u *)eap->arg);
+ del_trailing_spaces(eap->arg);
}
}
@@ -4014,7 +4058,7 @@ static int getargopt(exarg_T *eap)
int bad_char_idx;
// ":edit ++[no]bin[ary] file"
- if (STRNCMP(arg, "bin", 3) == 0 || STRNCMP(arg, "nobin", 5) == 0) {
+ if (strncmp(arg, "bin", 3) == 0 || strncmp(arg, "nobin", 5) == 0) {
if (*arg == 'n') {
arg += 2;
eap->force_bin = FORCE_NOBIN;
@@ -4029,26 +4073,33 @@ static int getargopt(exarg_T *eap)
}
// ":read ++edit file"
- if (STRNCMP(arg, "edit", 4) == 0) {
+ if (strncmp(arg, "edit", 4) == 0) {
eap->read_edit = true;
eap->arg = skipwhite(arg + 4);
return OK;
}
- if (STRNCMP(arg, "ff", 2) == 0) {
+ // ":write ++p foo/bar/file
+ if (strncmp(arg, "p", 1) == 0) {
+ eap->mkdir_p = true;
+ eap->arg = skipwhite(arg + 1);
+ return OK;
+ }
+
+ if (strncmp(arg, "ff", 2) == 0) {
arg += 2;
pp = &eap->force_ff;
- } else if (STRNCMP(arg, "fileformat", 10) == 0) {
+ } else if (strncmp(arg, "fileformat", 10) == 0) {
arg += 10;
pp = &eap->force_ff;
- } else if (STRNCMP(arg, "enc", 3) == 0) {
- if (STRNCMP(arg, "encoding", 8) == 0) {
+ } else if (strncmp(arg, "enc", 3) == 0) {
+ if (strncmp(arg, "encoding", 8) == 0) {
arg += 8;
} else {
arg += 3;
}
pp = &eap->force_enc;
- } else if (STRNCMP(arg, "bad", 3) == 0) {
+ } else if (strncmp(arg, "bad", 3) == 0) {
arg += 3;
pp = &bad_char_idx;
}
@@ -4110,9 +4161,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 {
@@ -4179,13 +4230,12 @@ theend:
static void ex_autocmd(exarg_T *eap)
{
- // Disallow autocommands from .exrc and .vimrc in current
- // directory for security reasons.
+ // Disallow autocommands in secure mode.
if (secure) {
secure = 2;
eap->errmsg = _(e_curdir);
} else if (eap->cmdidx == CMD_autocmd) {
- do_autocmd(eap->arg, eap->forceit);
+ do_autocmd(eap, eap->arg, eap->forceit);
} else {
do_augroup(eap->arg, eap->forceit);
}
@@ -4312,15 +4362,14 @@ char *find_nextcmd(const char *p)
/// 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);
- } else {
- return NULL;
+ return s + 1;
}
+ return NULL;
}
/// - if there are more files to edit
@@ -4343,14 +4392,14 @@ 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) {
+ "%d more files to edit. Quit anyway?", n), n);
+ if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 1) == VIM_YES) {
return OK;
}
return FAIL;
}
semsg(NGETTEXT("E173: %" PRId64 " more file to edit",
- "E173: %" PRId64 " more files to edit", (unsigned long)n), (int64_t)n);
+ "E173: %" PRId64 " more files to edit", n), (int64_t)n);
quitmore = 2; // next try to quit is allowed
}
return FAIL;
@@ -4383,7 +4432,7 @@ static void ex_colorscheme(exarg_T *eap)
} else {
msg("default");
}
- } else if (load_colors((char_u *)eap->arg) == FAIL) {
+ } else if (load_colors(eap->arg) == FAIL) {
semsg(_("E185: Cannot find color scheme '%s'"), eap->arg);
}
}
@@ -4578,7 +4627,7 @@ static void ex_pclose(exarg_T *eap)
void ex_win_close(int forceit, win_T *win, tabpage_T *tp)
{
// Never close the autocommand window.
- if (win == aucmd_win) {
+ if (is_aucmd_win(win)) {
emsg(_(e_autocmd_close));
return;
}
@@ -4615,23 +4664,29 @@ static void ex_tabclose(exarg_T *eap)
{
if (cmdwin_type != 0) {
cmdwin_result = K_IGNORE;
- } else if (first_tabpage->tp_next == NULL) {
+ return;
+ }
+
+ if (first_tabpage->tp_next == NULL) {
emsg(_("E784: Cannot close last tab page"));
- } else {
- int tab_number = get_tabpage_arg(eap);
- if (eap->errmsg == NULL) {
- tabpage_T *tp = find_tabpage(tab_number);
- if (tp == NULL) {
- beep_flush();
- return;
- }
- if (tp != curtab) {
- tabpage_close_other(tp, eap->forceit);
- return;
- } else if (!text_locked() && !curbuf_locked()) {
- tabpage_close(eap->forceit);
- }
- }
+ return;
+ }
+
+ int tab_number = get_tabpage_arg(eap);
+ if (eap->errmsg != NULL) {
+ return;
+ }
+
+ tabpage_T *tp = find_tabpage(tab_number);
+ if (tp == NULL) {
+ beep_flush();
+ return;
+ }
+ if (tp != curtab) {
+ tabpage_close_other(tp, eap->forceit);
+ return;
+ } else if (!text_locked() && !curbuf_locked()) {
+ tabpage_close(eap->forceit);
}
}
@@ -4640,32 +4695,38 @@ static void ex_tabonly(exarg_T *eap)
{
if (cmdwin_type != 0) {
cmdwin_result = K_IGNORE;
- } else if (first_tabpage->tp_next == NULL) {
+ return;
+ }
+
+ if (first_tabpage->tp_next == NULL) {
msg(_("Already only one tab page"));
- } else {
- int tab_number = get_tabpage_arg(eap);
- if (eap->errmsg == NULL) {
- goto_tabpage(tab_number);
- // Repeat this up to a 1000 times, because autocommands may
- // mess up the lists.
- for (int done = 0; done < 1000; done++) {
- FOR_ALL_TABS(tp) {
- if (tp->tp_topframe != topframe) {
- tabpage_close_other(tp, eap->forceit);
- // if we failed to close it quit
- if (valid_tabpage(tp)) {
- done = 1000;
- }
- // start over, "tp" is now invalid
- break;
- }
- }
- assert(first_tabpage);
- if (first_tabpage->tp_next == NULL) {
- break;
+ return;
+ }
+
+ int tab_number = get_tabpage_arg(eap);
+ if (eap->errmsg != NULL) {
+ return;
+ }
+
+ goto_tabpage(tab_number);
+ // Repeat this up to a 1000 times, because autocommands may
+ // mess up the lists.
+ for (int done = 0; done < 1000; done++) {
+ FOR_ALL_TABS(tp) {
+ if (tp->tp_topframe != topframe) {
+ tabpage_close_other(tp, eap->forceit);
+ // if we failed to close it quit
+ if (valid_tabpage(tp)) {
+ done = 1000;
}
+ // start over, "tp" is now invalid
+ break;
}
}
+ assert(first_tabpage);
+ if (first_tabpage->tp_next == NULL) {
+ break;
+ }
}
}
@@ -4692,7 +4753,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
@@ -4708,11 +4768,6 @@ void tabpage_close_other(tabpage_T *tp, int forceit)
break;
}
}
-
- redraw_tabline = true;
- if (h != tabline_height()) {
- win_new_screen_rows();
- }
}
/// ":only".
@@ -4725,9 +4780,8 @@ static void ex_only(exarg_T *eap)
for (wp = firstwin; --wnr > 0;) {
if (wp->w_next == NULL) {
break;
- } else {
- wp = wp->w_next;
}
+ wp = wp->w_next;
}
} else {
wp = curwin;
@@ -4741,25 +4795,27 @@ static void ex_only(exarg_T *eap)
static void ex_hide(exarg_T *eap)
{
// ":hide" or ":hide | cmd": hide current window
- if (!eap->skip) {
- if (eap->addr_count == 0) {
- win_close(curwin, false, eap->forceit); // don't free buffer
- } else {
- int winnr = 0;
- win_T *win = NULL;
+ if (eap->skip) {
+ return;
+ }
- FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
- winnr++;
- if (winnr == eap->line2) {
- win = wp;
- break;
- }
- }
- if (win == NULL) {
- win = lastwin;
+ if (eap->addr_count == 0) {
+ win_close(curwin, false, eap->forceit); // don't free buffer
+ } else {
+ int winnr = 0;
+ win_T *win = NULL;
+
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ winnr++;
+ if (winnr == eap->line2) {
+ win = wp;
+ break;
}
- win_close(win, false, eap->forceit);
}
+ if (win == NULL) {
+ win = lastwin;
+ }
+ win_close(win, false, eap->forceit);
}
}
@@ -4834,7 +4890,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
@@ -4910,8 +4965,8 @@ 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_MESS, true, (char_u *)curbuf->b_ffname);
+ fname = (char *)find_file_in_path(eap->arg, strlen(eap->arg),
+ FNAME_MESS, true, curbuf->b_ffname);
if (fname == NULL) {
goto theend;
}
@@ -5034,9 +5089,8 @@ static void ex_tabs(exarg_T *eap)
}
msg_putchar('\n');
- vim_snprintf((char *)IObuff, IOSIZE, _("Tab page %d"), tabcount++);
- msg_outtrans_attr((char *)IObuff, HL_ATTR(HLF_T));
- ui_flush(); // output one line at a time
+ vim_snprintf(IObuff, IOSIZE, _("Tab page %d"), tabcount++);
+ msg_outtrans_attr(IObuff, HL_ATTR(HLF_T));
os_breakcheck();
FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
@@ -5050,12 +5104,11 @@ static void ex_tabs(exarg_T *eap)
msg_putchar(bufIsChanged(wp->w_buffer) ? '+' : ' ');
msg_putchar(' ');
if (buf_spname(wp->w_buffer) != NULL) {
- STRLCPY(IObuff, buf_spname(wp->w_buffer), IOSIZE);
+ xstrlcpy(IObuff, buf_spname(wp->w_buffer), IOSIZE);
} else {
- home_replace(wp->w_buffer, wp->w_buffer->b_fname, (char *)IObuff, IOSIZE, true);
+ home_replace(wp->w_buffer, wp->w_buffer->b_fname, IObuff, IOSIZE, true);
}
- msg_outtrans((char *)IObuff);
- ui_flush(); // output one line at a time
+ msg_outtrans(IObuff);
os_breakcheck();
}
}
@@ -5105,23 +5158,25 @@ 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),
- FNAME_MESS, true, (char_u *)curbuf->b_ffname);
+ char *fname = (char *)find_file_in_path(eap->arg, strlen(eap->arg),
+ FNAME_MESS, true, curbuf->b_ffname);
if (eap->addr_count > 0) {
// Repeat finding the file "count" times. This matters when it
// appears several times in the path.
linenr_T count = eap->line2;
while (fname != NULL && --count > 0) {
xfree(fname);
- fname = (char *)find_file_in_path(NULL, 0, FNAME_MESS, false, (char_u *)curbuf->b_ffname);
+ fname = (char *)find_file_in_path(NULL, 0, FNAME_MESS, false, curbuf->b_ffname);
}
}
- if (fname != NULL) {
- eap->arg = fname;
- do_exedit(eap, NULL);
- xfree(fname);
+ if (fname == NULL) {
+ return;
}
+
+ eap->arg = fname;
+ do_exedit(eap, NULL);
+ xfree(fname);
}
/// ":edit", ":badd", ":balt", ":visual".
@@ -5183,7 +5238,7 @@ void do_exedit(exarg_T *eap, win_T *old_curwin)
old_curwin == NULL ? curwin : NULL);
} else if ((eap->cmdidx != CMD_split && eap->cmdidx != CMD_vsplit)
|| *eap->arg != NUL) {
- // Can't edit another file when "curbuf->b_ro_lockec" is set. Only ":edit"
+ // Can't edit another file when "curbuf->b_ro_locked" is set. Only ":edit"
// can bring us here, others are stopped earlier.
if (*eap->arg != NUL && curbuf_locked()) {
return;
@@ -5273,7 +5328,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);
}
}
@@ -5346,50 +5401,51 @@ static void ex_read(exarg_T *eap)
if (eap->usefilter) { // :r!cmd
do_bang(1, eap, false, false, true);
- } else {
- if (u_save(eap->line2, (linenr_T)(eap->line2 + 1)) == FAIL) {
+ return;
+ }
+
+ if (u_save(eap->line2, (linenr_T)(eap->line2 + 1)) == FAIL) {
+ return;
+ }
+
+ int i;
+ if (*eap->arg == NUL) {
+ if (check_fname() == FAIL) { // check for no file name
return;
}
- int i;
-
- if (*eap->arg == NUL) {
- if (check_fname() == FAIL) { // check for no file name
- return;
- }
- i = readfile(curbuf->b_ffname, curbuf->b_fname,
- eap->line2, (linenr_T)0, (linenr_T)MAXLNUM, eap, 0, false);
- } else {
- if (vim_strchr(p_cpo, CPO_ALTREAD) != NULL) {
- (void)setaltfname(eap->arg, eap->arg, (linenr_T)1);
- }
- i = readfile(eap->arg, NULL,
- eap->line2, (linenr_T)0, (linenr_T)MAXLNUM, eap, 0, false);
+ i = readfile(curbuf->b_ffname, curbuf->b_fname,
+ eap->line2, (linenr_T)0, (linenr_T)MAXLNUM, eap, 0, false);
+ } else {
+ if (vim_strchr(p_cpo, CPO_ALTREAD) != NULL) {
+ (void)setaltfname(eap->arg, eap->arg, (linenr_T)1);
+ }
+ i = readfile(eap->arg, NULL,
+ eap->line2, (linenr_T)0, (linenr_T)MAXLNUM, eap, 0, false);
+ }
+ if (i != OK) {
+ if (!aborting()) {
+ semsg(_(e_notopen), eap->arg);
}
- if (i != OK) {
- if (!aborting()) {
- semsg(_(e_notopen), eap->arg);
+ } else {
+ if (empty && exmode_active) {
+ // Delete the empty line that remains. Historically ex does
+ // this but vi doesn't.
+ linenr_T lnum;
+ if (eap->line2 == 0) {
+ lnum = curbuf->b_ml.ml_line_count;
+ } else {
+ lnum = 1;
}
- } else {
- if (empty && exmode_active) {
- // Delete the empty line that remains. Historically ex does
- // this but vi doesn't.
- linenr_T lnum;
- if (eap->line2 == 0) {
- lnum = curbuf->b_ml.ml_line_count;
- } else {
- lnum = 1;
- }
- if (*ml_get(lnum) == NUL && u_savedel(lnum, 1L) == OK) {
- ml_delete(lnum, false);
- if (curwin->w_cursor.lnum > 1
- && curwin->w_cursor.lnum >= lnum) {
- curwin->w_cursor.lnum--;
- }
- deleted_lines_mark(lnum, 1L);
+ if (*ml_get(lnum) == NUL && u_savedel(lnum, 1L) == OK) {
+ ml_delete(lnum, false);
+ if (curwin->w_cursor.lnum > 1
+ && curwin->w_cursor.lnum >= lnum) {
+ curwin->w_cursor.lnum--;
}
+ deleted_lines_mark(lnum, 1L);
}
- redraw_curbuf_later(UPD_VALID);
}
+ redraw_curbuf_later(UPD_VALID);
}
}
@@ -5441,7 +5497,7 @@ static void post_chdir(CdScope scope, bool trigger_dirchanged)
}
char cwd[MAXPATHL];
- if (os_dirname((char_u *)cwd, MAXPATHL) != OK) {
+ if (os_dirname(cwd, MAXPATHL) != OK) {
return;
}
switch (scope) {
@@ -5479,7 +5535,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"));
@@ -5488,7 +5544,7 @@ bool changedir_func(char *new_dir, CdScope scope)
new_dir = pdir;
}
- if (os_dirname((char_u *)NameBuff, MAXPATHL) == OK) {
+ if (os_dirname(NameBuff, MAXPATHL) == OK) {
pdir = xstrdup(NameBuff);
} else {
pdir = NULL;
@@ -5503,13 +5559,13 @@ bool changedir_func(char *new_dir, CdScope scope)
#endif
// Use NameBuff for home directory name.
expand_env("$HOME", NameBuff, MAXPATHL);
- new_dir = (char *)NameBuff;
+ new_dir = NameBuff;
}
bool dir_differs = pdir == NULL || pathcmp(pdir, new_dir, -1) != 0;
if (dir_differs) {
do_autocmd_dirchanged(new_dir, scope, kCdCauseManual, true);
- if (vim_chdir((char_u *)new_dir) != 0) {
+ if (vim_chdir(new_dir) != 0) {
emsg(_(e_failed));
xfree(pdir);
return false;
@@ -5543,27 +5599,27 @@ 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);
}
}
}
@@ -5571,7 +5627,7 @@ void ex_cd(exarg_T *eap)
/// ":pwd".
static void ex_pwd(exarg_T *eap)
{
- if (os_dirname((char_u *)NameBuff, MAXPATHL) == OK) {
+ if (os_dirname(NameBuff, MAXPATHL) == OK) {
#ifdef BACKSLASH_IN_FILENAME
slash_adjust(NameBuff);
#endif
@@ -5584,9 +5640,9 @@ static void ex_pwd(exarg_T *eap)
} else if (curtab->tp_localdir != NULL) {
context = "tabpage";
}
- smsg("[%s] %s", context, (char *)NameBuff);
+ smsg("[%s] %s", context, NameBuff);
} else {
- msg((char *)NameBuff);
+ msg(NameBuff);
}
} else {
emsg(_("E187: Unknown"));
@@ -5621,15 +5677,11 @@ static void ex_sleep(exarg_T *eap)
do_sleep(len);
}
-/// Sleep for "msec" milliseconds, but keep checking for a CTRL-C every second.
+/// Sleep for "msec" milliseconds, but return early on CTRL-C.
void do_sleep(long msec)
{
ui_flush(); // flush before waiting
- for (long left = msec; !got_int && left > 0; left -= 1000L) {
- int next = left > 1000l ? 1000 : (int)left;
- LOOP_PROCESS_EVENTS_UNTIL(&main_loop, main_loop.events, (int)next, got_int);
- os_breakcheck();
- }
+ LOOP_PROCESS_EVENTS_UNTIL(&main_loop, main_loop.events, msec, got_int);
// If CTRL-C was typed to interrupt the sleep, drop the CTRL-C from the
// input buffer, otherwise a following call to input() fails.
@@ -5675,7 +5727,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));
@@ -5791,21 +5843,21 @@ void ex_may_print(exarg_T *eap)
/// ":smagic" and ":snomagic".
static void ex_submagic(exarg_T *eap)
{
- int magic_save = p_magic;
+ const optmagic_T saved = magic_overruled;
- p_magic = (eap->cmdidx == CMD_smagic);
+ magic_overruled = eap->cmdidx == CMD_smagic ? OPTION_MAGIC_ON : OPTION_MAGIC_OFF;
ex_substitute(eap);
- p_magic = magic_save;
+ magic_overruled = saved;
}
/// ":smagic" and ":snomagic" preview callback.
static int ex_submagic_preview(exarg_T *eap, long cmdpreview_ns, handle_T cmdpreview_bufnr)
{
- int magic_save = p_magic;
+ const optmagic_T saved = magic_overruled;
- p_magic = (eap->cmdidx == CMD_smagic);
+ magic_overruled = eap->cmdidx == CMD_smagic ? OPTION_MAGIC_ON : OPTION_MAGIC_OFF;
int retv = ex_substitute_preview(eap, cmdpreview_ns, cmdpreview_bufnr);
- p_magic = magic_save;
+ magic_overruled = saved;
return retv;
}
@@ -5846,20 +5898,21 @@ static void ex_at(exarg_T *eap)
// Put the register in the typeahead buffer with the "silent" flag.
if (do_execreg(c, true, vim_strchr(p_cpo, CPO_EXECBUF) != NULL, true) == FAIL) {
beep_flush();
- } else {
- bool save_efr = exec_from_reg;
+ return;
+ }
- exec_from_reg = true;
+ const bool save_efr = exec_from_reg;
- // Execute from the typeahead buffer.
- // Continue until the stuff buffer is empty and all added characters
- // have been consumed.
- while (!stuff_empty() || typebuf.tb_len > prev_len) {
- (void)do_cmdline(NULL, getexline, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE);
- }
+ exec_from_reg = true;
- exec_from_reg = save_efr;
+ // Execute from the typeahead buffer.
+ // Continue until the stuff buffer is empty and all added characters
+ // have been consumed.
+ while (!stuff_empty() || typebuf.tb_len > prev_len) {
+ (void)do_cmdline(NULL, getexline, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE);
}
+
+ exec_from_reg = save_efr;
}
/// ":!".
@@ -5873,7 +5926,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
}
@@ -5900,7 +5953,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);
}
@@ -5989,7 +6042,7 @@ static void ex_redir(exarg_T *eap)
return;
}
- redir_fd = open_exfile((char_u *)fname, eap->forceit, mode);
+ redir_fd = open_exfile(fname, eap->forceit, mode);
xfree(fname);
} else if (*arg == '@') {
// redirect to a register a-z (resp. A-Z for appending)
@@ -6007,7 +6060,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);
}
}
}
@@ -6061,9 +6114,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();
}
@@ -6089,14 +6143,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();
@@ -6153,11 +6215,11 @@ int vim_mkdir_emsg(const char *const name, const int prot)
/// @param mode "w" for create new file or "a" for append
///
/// @return file descriptor, or NULL on failure.
-FILE *open_exfile(char_u *fname, int forceit, char *mode)
+FILE *open_exfile(char *fname, int forceit, char *mode)
{
#ifdef UNIX
// with Unix it is possible to open a directory
- if (os_isdir((char *)fname)) {
+ if (os_isdir(fname)) {
semsg(_(e_isadir2), fname);
return NULL;
}
@@ -6168,7 +6230,7 @@ FILE *open_exfile(char_u *fname, int forceit, char *mode)
}
FILE *fd;
- if ((fd = os_fopen((char *)fname, mode)) == NULL) {
+ if ((fd = os_fopen(fname, mode)) == NULL) {
semsg(_("E190: Cannot open \"%s\" for writing"), fname);
}
@@ -6180,17 +6242,21 @@ static void ex_mark(exarg_T *eap)
{
if (*eap->arg == NUL) { // No argument?
emsg(_(e_argreq));
- } else if (eap->arg[1] != NUL) { // more than one character?
+ return;
+ }
+
+ if (eap->arg[1] != NUL) { // more than one character?
semsg(_(e_trailing_arg), eap->arg);
- } else {
- pos_T pos = curwin->w_cursor; // save curwin->w_cursor
- curwin->w_cursor.lnum = eap->line2;
- beginline(BL_WHITE | BL_FIX);
- if (setmark(*eap->arg) == FAIL) { // set mark
- emsg(_("E191: Argument must be a letter or forward/backward quote"));
- }
- curwin->w_cursor = pos; // restore curwin->w_cursor
+ return;
}
+
+ pos_T pos = curwin->w_cursor; // save curwin->w_cursor
+ curwin->w_cursor.lnum = eap->line2;
+ beginline(BL_WHITE | BL_FIX);
+ if (setmark(*eap->arg) == FAIL) { // set mark
+ emsg(_("E191: Argument must be a letter or forward/backward quote"));
+ }
+ curwin->w_cursor = pos; // restore curwin->w_cursor
}
/// Update w_topline, w_leftcol and the cursor position.
@@ -6292,7 +6358,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;
@@ -6321,7 +6387,7 @@ static void ex_normal(exarg_T *eap)
check_cursor_moved(curwin);
}
- exec_normal_cmd((char_u *)(arg != NULL ? arg : eap->arg),
+ exec_normal_cmd((arg != NULL ? arg : eap->arg),
eap->forceit ? REMAP_NONE : REMAP_YES, false);
} while (eap->addr_count > 0 && eap->line1 <= eap->line2 && !got_int);
}
@@ -6385,10 +6451,10 @@ static void ex_stopinsert(exarg_T *eap)
/// Execute normal mode command "cmd".
/// "remap" can be REMAP_NONE or REMAP_YES.
-void exec_normal_cmd(char_u *cmd, int remap, bool silent)
+void exec_normal_cmd(char *cmd, int remap, bool silent)
{
// Stuff the argument into the typeahead buffer.
- ins_typebuf((char *)cmd, remap, 0, true, silent);
+ ins_typebuf(cmd, remap, 0, true, silent);
exec_normal(false);
}
@@ -6457,7 +6523,7 @@ static void ex_findpat(exarg_T *eap)
if (*eap->arg == '/') { // Match regexp, not just whole words
whole = false;
eap->arg++;
- char *p = skip_regexp(eap->arg, '/', p_magic, NULL);
+ char *p = skip_regexp(eap->arg, '/', magic_isset());
if (*p) {
*p++ = NUL;
p = skipwhite(p);
@@ -6466,12 +6532,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(eap->arg, 0, strlen(eap->arg), whole, !eap->forceit,
*eap->cmd == 'd' ? FIND_DEFINE : FIND_ANY,
n, action, eap->line1, eap->line2);
}
@@ -6522,7 +6588,7 @@ static void ex_tag(exarg_T *eap)
ex_tag_cmd(eap, cmdnames[eap->cmdidx].cmd_name);
}
-static void ex_tag_cmd(exarg_T *eap, char *name)
+static void ex_tag_cmd(exarg_T *eap, const char *name)
{
int cmd;
@@ -6551,10 +6617,6 @@ static void ex_tag_cmd(exarg_T *eap, char *name)
cmd = DT_LAST; // ":tlast"
break;
default: // ":tag"
- if (p_cst && *eap->arg != NUL) {
- ex_cstag(eap);
- return;
- }
cmd = DT_TAG;
break;
}
@@ -6563,7 +6625,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);
}
@@ -6589,7 +6651,7 @@ enum {
/// Check "str" for starting with a special cmdline variable.
/// If found return one of the SPEC_ values and set "*usedlen" to the length of
/// the variable. Otherwise return -1 and "*usedlen" is unchanged.
-ssize_t find_cmdline_var(const char_u *src, size_t *usedlen)
+ssize_t find_cmdline_var(const char *src, size_t *usedlen)
FUNC_ATTR_NONNULL_ALL
{
static char *(spec_str[]) = {
@@ -6612,8 +6674,8 @@ 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]);
- if (STRNCMP(src, spec_str[i], len) == 0) {
+ size_t len = strlen(spec_str[i]);
+ if (strncmp(src, spec_str[i], len) == 0) {
*usedlen = len;
assert(i <= SSIZE_MAX);
return (ssize_t)i;
@@ -6652,8 +6714,8 @@ ssize_t find_cmdline_var(const char_u *src, size_t *usedlen)
/// @return an allocated string if a valid match was found.
/// Returns NULL if no match was found. "usedlen" then still contains the
/// number of characters to skip.
-char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnump, char **errormsg,
- int *escaped, bool empty_is_error)
+char_u *eval_vars(char_u *src, const char_u *srcstart, size_t *usedlen, linenr_T *lnump,
+ char **errormsg, int *escaped, bool empty_is_error)
{
char *result;
char *resultbuf = NULL;
@@ -6669,7 +6731,7 @@ char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnum
}
// Check if there is something to do.
- ssize_t spec_idx = find_cmdline_var(src, usedlen);
+ ssize_t spec_idx = find_cmdline_var((char *)src, usedlen);
if (spec_idx < 0) { // no match
*usedlen = 1;
return NULL;
@@ -6679,7 +6741,7 @@ char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnum
// Note: In "\\%" the % is also not recognized!
if (src > srcstart && src[-1] == '\\') {
*usedlen = 0;
- STRMOVE(src - 1, src); // remove backslash
+ STRMOVE(src - 1, (char *)src); // remove backslash
return NULL;
}
@@ -6712,7 +6774,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;
@@ -6766,7 +6828,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;
@@ -6789,7 +6851,7 @@ char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnum
// postponed to avoid a delay when <afile> is not used.
result = FullName_save(autocmd_fname, false);
// Copy into `autocmd_fname`, don't reassign it. #8165
- STRLCPY(autocmd_fname, result, MAXPATHL);
+ xstrlcpy(autocmd_fname, result, MAXPATHL);
xfree(result);
}
result = autocmd_fname;
@@ -6797,7 +6859,7 @@ char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnum
*errormsg = _("E495: no autocommand file name to substitute for \"<afile>\"");
return NULL;
}
- result = (char *)path_try_shorten_fname((char_u *)result);
+ result = path_try_shorten_fname(result);
break;
case SPEC_ABUF: // buffer number for autocommand
@@ -6879,7 +6941,7 @@ 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)++;
@@ -6923,7 +6985,7 @@ char *expand_sfile(char *arg)
char *result = xstrdup(arg);
for (char *p = result; *p;) {
- if (STRNCMP(p, "<sfile>", 7) != 0) {
+ if (strncmp(p, "<sfile>", 7) != 0) {
p++;
} else {
// replace "<sfile>" with the sourced file name, and do ":" stuff
@@ -6942,11 +7004,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);
@@ -6986,12 +7048,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);
@@ -7029,19 +7091,19 @@ static void ex_filetype(exarg_T *eap)
// Accept "plugin" and "indent" in any order.
for (;;) {
- if (STRNCMP(arg, "plugin", 6) == 0) {
+ if (strncmp(arg, "plugin", 6) == 0) {
plugin = true;
arg = skipwhite(arg + 6);
continue;
}
- if (STRNCMP(arg, "indent", 6) == 0) {
+ if (strncmp(arg, "indent", 6) == 0) {
indent = true;
arg = skipwhite(arg + 6);
continue;
}
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;
@@ -7058,7 +7120,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);
@@ -7108,17 +7170,18 @@ void filetype_maybe_enable(void)
/// ":setfiletype [FALLBACK] {name}"
static void ex_setfiletype(exarg_T *eap)
{
- if (!did_filetype) {
- char *arg = eap->arg;
+ if (did_filetype) {
+ return;
+ }
- if (STRNCMP(arg, "FALLBACK ", 9) == 0) {
- arg += 9;
- }
+ char *arg = eap->arg;
+ if (strncmp(arg, "FALLBACK ", 9) == 0) {
+ arg += 9;
+ }
- set_option_value_give_err("filetype", 0L, arg, OPT_LOCAL);
- if (arg != eap->arg) {
- did_filetype = false;
- }
+ set_option_value_give_err("filetype", 0L, arg, OPT_LOCAL);
+ if (arg != eap->arg) {
+ did_filetype = false;
}
}
@@ -7200,7 +7263,7 @@ static void ex_terminal(exarg_T *eap)
char ex_cmd[1024];
if (*eap->arg != NUL) { // Run {cmd} in 'shell'.
- char *name = (char *)vim_strsave_escaped((char_u *)eap->arg, (char_u *)"\"\\");
+ char *name = vim_strsave_escaped(eap->arg, "\"\\");
snprintf(ex_cmd, sizeof(ex_cmd),
":enew%s | call termopen(\"%s\")",
eap->forceit ? "!" : "", name);
@@ -7233,7 +7296,7 @@ static void ex_terminal(exarg_T *eap)
void verify_command(char *cmd)
{
- if (strcmp("smile", cmd)) {
+ if (strcmp("smile", cmd) != 0) {
return; // acceptable non-existing command
}
msg(" #xxn` #xnxx` ,+x@##@Mz;` .xxx"