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.c640
1 files changed, 430 insertions, 210 deletions
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 316006befd..7506c353dd 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -41,7 +41,7 @@
#include "nvim/highlight_group.h"
#include "nvim/if_cscope.h"
#include "nvim/input.h"
-#include "nvim/keymap.h"
+#include "nvim/keycodes.h"
#include "nvim/lua/executor.h"
#include "nvim/main.h"
#include "nvim/mark.h"
@@ -111,7 +111,7 @@ struct loop_cookie {
int current_line; // last read line from growarray
int repeating; // TRUE when looping a second time
// When "repeating" is FALSE use "getline" and "cookie" to get lines
- char_u *(*getline)(int, void *, int, bool);
+ char *(*getline)(int, void *, int, bool);
void *cookie;
};
@@ -187,7 +187,7 @@ void do_exmode(void)
varnumber_T changedtick;
exmode_active = true;
- State = NORMAL;
+ State = MODE_NORMAL;
may_trigger_modechanged();
// When using ":global /pat/ visual" and then "Q" we return to continue
@@ -324,7 +324,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
struct msglist *private_msg_list;
// "fgetline" and "cookie" passed to do_one_cmd()
- char_u *(*cmd_getline)(int, void *, int, bool);
+ char *(*cmd_getline)(int, void *, int, bool);
void *cmd_cookie;
struct loop_cookie cmd_loop_cookie;
void *real_cookie;
@@ -345,7 +345,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
// here. The value of 200 allows nested function calls, ":source", etc.
// Allow 200 or 'maxfuncdepth', whatever is larger.
if (call_depth >= 200 && call_depth >= p_mfd) {
- emsg(_("E169: Command too recursive"));
+ emsg(_(e_command_too_recursive));
// When converting to an exception, we do not include the command name
// since this is not an error of the specific command.
do_errthrow((cstack_T *)NULL, NULL);
@@ -372,7 +372,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
breakpoint = func_breakpoint(real_cookie);
dbg_tick = func_dbg_tick(real_cookie);
} else if (getline_equal(fgetline, cookie, getsourceline)) {
- fname = (char *)sourcing_name;
+ fname = sourcing_name;
breakpoint = source_breakpoint(real_cookie);
dbg_tick = source_dbg_tick(real_cookie);
}
@@ -518,10 +518,10 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
msg_didout = true;
}
if (fgetline == NULL
- || (next_cmdline = (char *)fgetline(':', cookie,
- cstack.cs_idx <
- 0 ? 0 : (cstack.cs_idx + 1) * 2,
- true)) == NULL) {
+ || (next_cmdline = fgetline(':', cookie,
+ cstack.cs_idx <
+ 0 ? 0 : (cstack.cs_idx + 1) * 2,
+ true)) == 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.
@@ -595,7 +595,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
recursive--;
// Ignore trailing '|'-separated commands in preview-mode ('inccommand').
- if ((State & CMDPREVIEW) && (flags & DOCMD_PREVIEW)) {
+ if ((State & MODE_CMDPREVIEW) && (flags & DOCMD_PREVIEW)) {
next_cmdline = NULL;
}
@@ -832,9 +832,9 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
break;
}
- saved_sourcing_name = (char *)sourcing_name;
+ saved_sourcing_name = sourcing_name;
saved_sourcing_lnum = sourcing_lnum;
- sourcing_name = (char_u *)current_exception->throw_name;
+ sourcing_name = current_exception->throw_name;
sourcing_lnum = current_exception->throw_lnum;
current_exception->throw_name = NULL;
@@ -856,7 +856,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
xfree(p);
}
xfree(sourcing_name);
- sourcing_name = (char_u *)saved_sourcing_name;
+ sourcing_name = saved_sourcing_name;
sourcing_lnum = saved_sourcing_lnum;
} else if (got_int || (did_emsg && force_abort)) {
// On an interrupt or an aborting error not converted to an exception,
@@ -949,7 +949,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
}
/// Obtain a line when inside a ":while" or ":for" loop.
-static char_u *get_loop_line(int c, void *cookie, int indent, bool do_concat)
+static char *get_loop_line(int c, void *cookie, int indent, bool do_concat)
{
struct loop_cookie *cp = (struct loop_cookie *)cookie;
wcmd_T *wp;
@@ -963,21 +963,21 @@ static char_u *get_loop_line(int c, void *cookie, int indent, bool do_concat)
if (cp->getline == NULL) {
line = (char *)getcmdline(c, 0L, indent, do_concat);
} else {
- line = (char *)cp->getline(c, cp->cookie, indent, do_concat);
+ line = cp->getline(c, cp->cookie, indent, do_concat);
}
if (line != NULL) {
store_loop_line(cp->lines_gap, line);
++cp->current_line;
}
- return (char_u *)line;
+ return line;
}
KeyTyped = false;
cp->current_line++;
wp = (wcmd_T *)(cp->lines_gap->ga_data) + cp->current_line;
sourcing_lnum = wp->lnum;
- return vim_strsave((char_u *)wp->line);
+ return xstrdup(wp->line);
}
/// Store a line in "gap" so that a ":while" loop can execute it again.
@@ -1218,7 +1218,7 @@ static char *skip_colon_white(const char *p, bool skipleadingwhite)
/// Set the addr type for command
///
/// @param p pointer to character after command name in cmdline
-static void set_cmd_addr_type(exarg_T *eap, char_u *p)
+void set_cmd_addr_type(exarg_T *eap, char_u *p)
{
// ea.addr_type for user commands is set by find_ucmd
if (IS_USER_CMDIDX(eap->cmdidx)) {
@@ -1239,8 +1239,48 @@ static void set_cmd_addr_type(exarg_T *eap, char_u *p)
}
}
+/// Get default range number for command based on its address type
+linenr_T get_cmd_default_range(exarg_T *eap)
+{
+ switch (eap->addr_type) {
+ case ADDR_LINES:
+ case ADDR_OTHER:
+ // Default is the cursor line number. Avoid using an invalid
+ // line number though.
+ return MIN(curwin->w_cursor.lnum, curbuf->b_ml.ml_line_count);
+ break;
+ case ADDR_WINDOWS:
+ return CURRENT_WIN_NR;
+ break;
+ case ADDR_ARGUMENTS:
+ return MIN(curwin->w_arg_idx + 1, ARGCOUNT);
+ break;
+ case ADDR_LOADED_BUFFERS:
+ case ADDR_BUFFERS:
+ return curbuf->b_fnum;
+ break;
+ case ADDR_TABS:
+ return CURRENT_TAB_NR;
+ break;
+ case ADDR_TABS_RELATIVE:
+ case ADDR_UNSIGNED:
+ return 1;
+ break;
+ case ADDR_QUICKFIX:
+ return (linenr_T)qf_get_cur_idx(eap);
+ break;
+ case ADDR_QUICKFIX_VALID:
+ return qf_get_cur_valid_idx(eap);
+ break;
+ default:
+ return 0;
+ // Will give an error later if a range is found.
+ break;
+ }
+}
+
/// Set default command range for -range=% based on the addr type of the command
-static void set_cmd_default_range(exarg_T *eap)
+void set_cmd_dflall_range(exarg_T *eap)
{
buf_T *buf;
@@ -1320,6 +1360,25 @@ static void parse_register(exarg_T *eap)
}
}
+// Change line1 and line2 of Ex command to use count
+void set_cmd_count(exarg_T *eap, long count, bool validate)
+{
+ if (eap->addr_type != ADDR_LINES) { // e.g. :buffer 2, :sleep 3
+ eap->line2 = count;
+ if (eap->addr_count == 0) {
+ eap->addr_count = 1;
+ }
+ } else {
+ eap->line1 = eap->line2;
+ eap->line2 += count - 1;
+ eap->addr_count++;
+ // Be vi compatible: no error message for out of range.
+ if (validate && eap->line2 > curbuf->b_ml.ml_line_count) {
+ eap->line2 = curbuf->b_ml.ml_line_count;
+ }
+ }
+}
+
static int parse_count(exarg_T *eap, char **errormsg, bool validate)
{
// Check for a count. When accepting a EX_BUFNAME, don't use "123foo" as a
@@ -1328,7 +1387,7 @@ static int parse_count(exarg_T *eap, char **errormsg, bool validate)
long n;
if ((eap->argt & EX_COUNT) && ascii_isdigit(*eap->arg)
- && (!(eap->argt & EX_BUFNAME) || *(p = (char *)skipdigits((char_u *)eap->arg + 1)) == NUL
+ && (!(eap->argt & EX_BUFNAME) || *(p = skipdigits(eap->arg + 1)) == NUL
|| ascii_iswhite(*p))) {
n = getdigits_long((char_u **)&eap->arg, false, -1);
eap->arg = skipwhite(eap->arg);
@@ -1338,25 +1397,19 @@ static int parse_count(exarg_T *eap, char **errormsg, bool validate)
}
return FAIL;
}
- if (eap->addr_type != ADDR_LINES) { // e.g. :buffer 2, :sleep 3
- eap->line2 = n;
- if (eap->addr_count == 0) {
- eap->addr_count = 1;
- }
- } else {
- eap->line1 = eap->line2;
- eap->line2 += n - 1;
- eap->addr_count++;
- // Be vi compatible: no error message for out of range.
- if (validate && eap->line2 > curbuf->b_ml.ml_line_count) {
- eap->line2 = curbuf->b_ml.ml_line_count;
- }
- }
+ set_cmd_count(eap, n, validate);
}
return OK;
}
+/// Check if command is not implemented
+bool is_cmd_ni(cmdidx_T cmdidx)
+{
+ return !IS_USER_CMDIDX(cmdidx) && (cmdnames[cmdidx].cmd_func == ex_ni
+ || cmdnames[cmdidx].cmd_func == ex_script_ni);
+}
+
/// Parse command line and return information about the first command.
///
/// @param cmdline Command line string
@@ -1394,14 +1447,17 @@ bool parse_cmdline(char *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo, char **er
if (eap->save_msg_silent != -1) {
cmdinfo->silent = !!msg_silent;
msg_silent = eap->save_msg_silent;
+ eap->save_msg_silent = -1;
}
if (eap->did_esilent) {
cmdinfo->emsg_silent = true;
emsg_silent--;
+ eap->did_esilent = false;
}
if (eap->did_sandbox) {
cmdinfo->sandbox = true;
sandbox--;
+ eap->did_sandbox = false;
}
if (cmdmod.save_ei != NULL) {
cmdinfo->noautocmd = true;
@@ -1411,6 +1467,7 @@ bool parse_cmdline(char *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo, char **er
if (eap->verbose_save != -1) {
cmdinfo->verbose = p_verbose;
p_verbose = eap->verbose_save;
+ eap->verbose_save = -1;
} else {
cmdinfo->verbose = -1;
}
@@ -1424,7 +1481,7 @@ bool parse_cmdline(char *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo, char **er
if (*eap->cmd == '*') {
eap->cmd = skipwhite(eap->cmd + 1);
}
- p = find_command(eap, NULL);
+ p = find_ex_command(eap, NULL);
// Set command address type and parse command range
set_cmd_addr_type(eap, (char_u *)p);
@@ -1494,7 +1551,7 @@ bool parse_cmdline(char *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo, char **er
}
// Set default range for command if required
if ((eap->argt & EX_DFLALL) && eap->addr_count == 0) {
- set_cmd_default_range(eap);
+ set_cmd_dflall_range(eap);
}
// Parse register and count
@@ -1519,6 +1576,147 @@ bool parse_cmdline(char *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo, char **er
return true;
}
+/// Execute an Ex command using parsed command line information.
+/// Does not do any validation of the Ex command arguments.
+///
+/// @param eap Ex-command arguments
+/// @param cmdinfo Command parse information
+void execute_cmd(exarg_T *eap, CmdParseInfo *cmdinfo)
+{
+#define ERROR(msg) \
+ do { \
+ emsg(msg); \
+ goto end; \
+ } while (0)
+
+ char *errormsg = NULL;
+ cmdmod_T save_cmdmod = cmdmod;
+ cmdmod = cmdinfo->cmdmod;
+
+ // Apply command modifiers
+ if (cmdinfo->silent) {
+ eap->save_msg_silent = msg_silent;
+ msg_silent++;
+ }
+ if (cmdinfo->emsg_silent) {
+ eap->did_esilent = true;
+ emsg_silent++;
+ }
+ if (cmdinfo->sandbox) {
+ eap->did_sandbox = true;
+ sandbox++;
+ }
+ if (cmdinfo->noautocmd) {
+ cmdmod.save_ei = (char *)vim_strsave(p_ei);
+ set_string_option_direct("ei", -1, (char_u *)"all", OPT_FREE, SID_NONE);
+ }
+ if (cmdinfo->verbose != -1) {
+ eap->verbose_save = p_verbose;
+ p_verbose = cmdinfo->verbose;
+ }
+
+ if (!MODIFIABLE(curbuf) && (eap->argt & EX_MODIFY)
+ // allow :put in terminals
+ && !(curbuf->terminal && eap->cmdidx == CMD_put)) {
+ ERROR(_(e_modifiable));
+ }
+ if (text_locked() && !(eap->argt & EX_CMDWIN)
+ && !IS_USER_CMDIDX(eap->cmdidx)) {
+ ERROR(_(get_text_locked_msg()));
+ }
+ // Disallow editing another buffer when "curbuf->b_ro_locked" is set.
+ // Do allow ":checktime" (it is postponed).
+ // Do allow ":edit" (check for an argument later).
+ // Do allow ":file" with no arguments
+ if (!(eap->argt & EX_CMDWIN)
+ && eap->cmdidx != CMD_checktime
+ && eap->cmdidx != CMD_edit
+ && !(eap->cmdidx == CMD_file && *eap->arg == NUL)
+ && !IS_USER_CMDIDX(eap->cmdidx)
+ && curbuf_locked()) {
+ ERROR(_(e_cannot_edit_other_buf));
+ }
+
+ if (((eap->argt & EX_WHOLEFOLD) || eap->addr_count >= 2) && !global_busy
+ && eap->addr_type == ADDR_LINES) {
+ // Put the first line at the start of a closed fold, put the last line
+ // at the end of a closed fold.
+ (void)hasFolding(eap->line1, &eap->line1, NULL);
+ (void)hasFolding(eap->line2, NULL, &eap->line2);
+ }
+
+ // If filename expansion is enabled, expand filenames
+ if (cmdinfo->magic.file) {
+ if (expand_filename(eap, (char_u **)eap->cmdlinep, &errormsg) == FAIL) {
+ ERROR(errormsg);
+ }
+ }
+
+ // Accept buffer name. Cannot be used at the same time with a buffer
+ // number. Don't do this for a user command.
+ if ((eap->argt & EX_BUFNAME) && *eap->arg != NUL && eap->addr_count == 0
+ && !IS_USER_CMDIDX(eap->cmdidx)) {
+ if (eap->args == NULL) {
+ // If argument positions are not specified, search the argument for the buffer name.
+ // :bdelete, :bwipeout and :bunload take several arguments, separated by spaces:
+ // find next space (skipping over escaped characters).
+ // The others take one argument: ignore trailing spaces.
+ char *p;
+
+ if (eap->cmdidx == CMD_bdelete || eap->cmdidx == CMD_bwipeout
+ || eap->cmdidx == CMD_bunload) {
+ p = (char *)skiptowhite_esc((char_u *)eap->arg);
+ } else {
+ p = eap->arg + STRLEN(eap->arg);
+ while (p > eap->arg && ascii_iswhite(p[-1])) {
+ p--;
+ }
+ }
+ eap->line2 = buflist_findpat((char_u *)eap->arg, (char_u *)p, (eap->argt & EX_BUFUNL) != 0,
+ false, false);
+ eap->addr_count = 1;
+ eap->arg = skipwhite(p);
+ } else {
+ // If argument positions are specified, just use the first argument
+ eap->line2 = buflist_findpat((char_u *)eap->args[0],
+ (char_u *)(eap->args[0] + eap->arglens[0]),
+ (eap->argt & EX_BUFUNL) != 0, false, false);
+ eap->addr_count = 1;
+ // Shift each argument by 1
+ for (size_t i = 0; i < eap->argc - 1; i++) {
+ eap->args[i] = eap->args[i + 1];
+ }
+ // Make the last argument point to the NUL terminator at the end of string
+ eap->args[eap->argc - 1] = eap->args[eap->argc - 1] + eap->arglens[eap->argc - 1];
+ eap->argc -= 1;
+
+ eap->arg = eap->args[0];
+ }
+ if (eap->line2 < 0) { // failed
+ goto end;
+ }
+ }
+
+ // Execute the command
+ if (IS_USER_CMDIDX(eap->cmdidx)) {
+ // Execute a user-defined command.
+ do_ucmd(eap);
+ } else {
+ // Call the function to execute the command.
+ eap->errmsg = NULL;
+ (cmdnames[eap->cmdidx].cmd_func)(eap);
+ if (eap->errmsg != NULL) {
+ ERROR(_(eap->errmsg));
+ }
+ }
+end:
+ // Undo command modifiers
+ undo_cmdmod(eap, msg_scroll);
+ cmdmod = save_cmdmod;
+
+#undef ERROR
+}
+
/// Execute one Ex command.
///
/// If 'sourcing' is TRUE, the command will be included in the error message.
@@ -1606,7 +1804,7 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter
if (*ea.cmd == '*') {
ea.cmd = skipwhite(ea.cmd + 1);
}
- p = find_command(&ea, NULL);
+ p = find_ex_command(&ea, NULL);
// Count this line for profiling if skip is TRUE.
if (do_profiling == PROF_YES
@@ -1728,11 +1926,11 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter
++p;
}
p = xstrnsave(ea.cmd, (size_t)(p - ea.cmd));
- int ret = apply_autocmds(EVENT_CMDUNDEFINED, (char_u *)p, (char_u *)p, true, NULL);
+ int ret = apply_autocmds(EVENT_CMDUNDEFINED, p, p, true, NULL);
xfree(p);
// If the autocommands did something and didn't cause an error, try
// finding the command again.
- p = (ret && !aborting()) ? find_command(&ea, NULL) : ea.cmd;
+ p = (ret && !aborting()) ? find_ex_command(&ea, NULL) : ea.cmd;
}
if (p == NULL) {
@@ -1759,10 +1957,7 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter
}
// set when Not Implemented
- const int ni = !IS_USER_CMDIDX(ea.cmdidx)
- && (cmdnames[ea.cmdidx].cmd_func == ex_ni
- || cmdnames[ea.cmdidx].cmd_func == ex_script_ni);
-
+ const int ni = is_cmd_ni(ea.cmdidx);
// Forced commands.
if (*p == '!' && ea.cmdidx != CMD_substitute
@@ -1976,7 +2171,7 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter
}
if ((ea.argt & EX_DFLALL) && ea.addr_count == 0) {
- set_cmd_default_range(&ea);
+ set_cmd_dflall_range(&ea);
}
// Parse register and count
@@ -2358,7 +2553,7 @@ int parse_command_modifiers(exarg_T *eap, char **errormsg, bool skip_only)
break;
}
if (!skip_only) {
- cmdmod.filter_regmatch.regprog = vim_regcomp((char_u *)reg_pat, RE_MAGIC);
+ cmdmod.filter_regmatch.regprog = vim_regcomp(reg_pat, RE_MAGIC);
if (cmdmod.filter_regmatch.regprog == NULL) {
break;
}
@@ -2543,7 +2738,6 @@ static void undo_cmdmod(const exarg_T *eap, int save_msg_scroll)
}
}
-
/// Parse the address range, if any, in "eap".
/// May set the last search pattern, unless "silent" is true.
///
@@ -2557,47 +2751,7 @@ int parse_cmd_address(exarg_T *eap, char **errormsg, bool silent)
// Repeat for all ',' or ';' separated addresses.
for (;;) {
eap->line1 = eap->line2;
- switch (eap->addr_type) {
- case ADDR_LINES:
- case ADDR_OTHER:
- // Default is the cursor line number. Avoid using an invalid
- // line number though.
- if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) {
- eap->line2 = curbuf->b_ml.ml_line_count;
- } else {
- eap->line2 = curwin->w_cursor.lnum;
- }
- break;
- case ADDR_WINDOWS:
- eap->line2 = CURRENT_WIN_NR;
- break;
- case ADDR_ARGUMENTS:
- eap->line2 = curwin->w_arg_idx + 1;
- if (eap->line2 > ARGCOUNT) {
- eap->line2 = ARGCOUNT;
- }
- break;
- case ADDR_LOADED_BUFFERS:
- case ADDR_BUFFERS:
- eap->line2 = curbuf->b_fnum;
- break;
- case ADDR_TABS:
- eap->line2 = CURRENT_TAB_NR;
- break;
- case ADDR_TABS_RELATIVE:
- case ADDR_UNSIGNED:
- eap->line2 = 1;
- break;
- case ADDR_QUICKFIX:
- eap->line2 = (linenr_T)qf_get_cur_idx(eap);
- break;
- case ADDR_QUICKFIX_VALID:
- eap->line2 = qf_get_cur_valid_idx(eap);
- break;
- case ADDR_NONE:
- // Will give an error later if a range is found.
- break;
- }
+ eap->line2 = get_cmd_default_range(eap);
eap->cmd = skipwhite(eap->cmd);
lnum = get_address(eap, &eap->cmd, eap->addr_type, eap->skip, silent,
eap->addr_count == 0, address_count++);
@@ -2772,7 +2926,7 @@ static void append_command(char *cmd)
/// "full" is set to TRUE if the whole command name matched.
///
/// @return NULL for an ambiguous user command.
-static char *find_command(exarg_T *eap, int *full)
+char *find_ex_command(exarg_T *eap, int *full)
FUNC_ATTR_NONNULL_ARG(1)
{
int len;
@@ -2816,7 +2970,7 @@ static char *find_command(exarg_T *eap, int *full)
}
// check for non-alpha command
- if (p == eap->cmd && vim_strchr((char_u *)"@!=><&~#", *p) != NULL) {
+ if (p == eap->cmd && vim_strchr("@!=><&~#", *p) != NULL) {
p++;
}
len = (int)(p - eap->cmd);
@@ -2859,7 +3013,7 @@ static char *find_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, (char *)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) {
@@ -3032,7 +3186,7 @@ int modifier_len(char *cmd)
char *p = cmd;
if (ascii_isdigit(*cmd)) {
- p = skipwhite((char *)skipdigits((char_u *)cmd + 1));
+ p = skipwhite(skipdigits(cmd + 1));
}
for (int i = 0; i < (int)ARRAY_SIZE(cmdmods); i++) {
int j;
@@ -3076,7 +3230,7 @@ int cmd_exists(const char *const name)
ea.cmd = (char *)((*name == '2' || *name == '3') ? name + 1 : name);
ea.cmdidx = (cmdidx_T)0;
int full = false;
- p = find_command(&ea, &full);
+ p = find_ex_command(&ea, &full);
if (p == NULL) {
return 3;
}
@@ -3108,7 +3262,7 @@ void f_fullcommand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
ea.cmd = (*name == '2' || *name == '3') ? name + 1 : name;
ea.cmdidx = (cmdidx_T)0;
- char *p = find_command(&ea, NULL);
+ char *p = find_ex_command(&ea, NULL);
if (p == NULL || ea.cmdidx == CMD_SIZE) {
return;
}
@@ -3142,7 +3296,7 @@ const char *set_one_cmd_context(expand_T *xp, const char *buff)
// 2. skip comment lines and leading space, colons or bars
const char *cmd;
- for (cmd = buff; vim_strchr((const char_u *)" \t:|", *cmd) != NULL; cmd++) {}
+ for (cmd = buff; vim_strchr(" \t:|", *cmd) != NULL; cmd++) {}
xp->xp_pattern = (char *)cmd;
if (*cmd == NUL) {
@@ -3203,7 +3357,7 @@ const char *set_one_cmd_context(expand_T *xp, const char *buff)
}
}
// check for non-alpha command
- if (p == cmd && vim_strchr((const char_u *)"@*!=><&~#", *p) != NULL) {
+ if (p == cmd && vim_strchr("@*!=><&~#", *p) != NULL) {
p++;
}
len = (size_t)(p - cmd);
@@ -3235,7 +3389,7 @@ const char *set_one_cmd_context(expand_T *xp, const char *buff)
}
if (ea.cmdidx == CMD_SIZE) {
- if (*cmd == 's' && vim_strchr((const char_u *)"cgriI", cmd[1]) != NULL) {
+ if (*cmd == 's' && vim_strchr("cgriI", cmd[1]) != NULL) {
ea.cmdidx = CMD_substitute;
p = cmd + 1;
} else if (cmd[0] >= 'A' && cmd[0] <= 'Z') {
@@ -3431,7 +3585,7 @@ const char *set_one_cmd_context(expand_T *xp, const char *buff)
xp->xp_shell = TRUE;
#endif
// When still after the command name expand executables.
- if ((char_u *)xp->xp_pattern == (char_u *)skipwhite(arg)) {
+ if (xp->xp_pattern == skipwhite(arg)) {
xp->xp_context = EXPAND_SHELLCMD;
}
}
@@ -3660,7 +3814,7 @@ const char *set_one_cmd_context(expand_T *xp, const char *buff)
case CMD_isplit:
case CMD_dsplit:
// Skip count.
- arg = (const char *)skipwhite((char *)skipdigits((const char_u *)arg));
+ arg = (const char *)skipwhite(skipdigits(arg));
if (*arg == '/') { // Match regexp, not just whole words.
for (++arg; *arg && *arg != '/'; arg++) {
if (*arg == '\\' && arg[1] != NUL) {
@@ -3980,7 +4134,7 @@ const char *set_one_cmd_context(expand_T *xp, const char *buff)
break;
case CMD_argdelete:
- while ((xp->xp_pattern = (char *)vim_strchr((const char_u *)arg, ' ')) != NULL) {
+ while ((xp->xp_pattern = vim_strchr(arg, ' ')) != NULL) {
arg = (const char *)(xp->xp_pattern + 1);
}
xp->xp_context = EXPAND_ARGLIST;
@@ -4011,7 +4165,7 @@ char *skip_range(const char *cmd, int *ctx)
{
unsigned delim;
- while (vim_strchr((char_u *)" \t0123456789.$%'/?-+,;\\", *cmd) != NULL) {
+ while (vim_strchr(" \t0123456789.$%'/?-+,;\\", *cmd) != NULL) {
if (*cmd == '\\') {
if (cmd[1] == '?' || cmd[1] == '/' || cmd[1] == '&') {
cmd++;
@@ -4381,7 +4535,7 @@ error:
/// Get flags from an Ex command argument.
static void get_flags(exarg_T *eap)
{
- while (vim_strchr((char_u *)"lp#", *eap->arg) != NULL) {
+ while (vim_strchr("lp#", *eap->arg) != NULL) {
if (*eap->arg == 'l') {
eap->flags |= EXFLAG_LIST;
} else if (*eap->arg == 'p') {
@@ -4416,7 +4570,7 @@ static void ex_script_ni(exarg_T *eap)
/// Check range in Ex command for validity.
///
/// @return NULL when valid, error message when invalid.
-static char *invalid_range(exarg_T *eap)
+char *invalid_range(exarg_T *eap)
{
buf_T *buf;
if (eap->line1 < 0 || eap->line2 < 0 || eap->line1 > eap->line2) {
@@ -4535,7 +4689,7 @@ static char *skip_grep_pat(exarg_T *eap)
/// For the ":make" and ":grep" commands insert the 'makeprg'/'grepprg' option
/// in the command line, so that things like % get expanded.
-static char *replace_makeprg(exarg_T *eap, char *p, char **cmdlinep)
+char *replace_makeprg(exarg_T *eap, char *p, char **cmdlinep)
{
char *new_cmdline;
char *program;
@@ -4637,8 +4791,8 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char **errormsgp)
* Quick check if this cannot be the start of a special string.
* Also removes backslash before '%', '#' and '<'.
*/
- if (vim_strchr((char_u *)"%#<", *p) == NULL) {
- ++p;
+ if (vim_strchr("%#<", *p) == NULL) {
+ p++;
continue;
}
@@ -4657,10 +4811,10 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char **errormsgp)
// Wildcards won't be expanded below, the replacement is taken
// literally. But do expand "~/file", "~user/file" and "$HOME/file".
- if (vim_strchr((char_u *)repl, '$') != NULL || vim_strchr((char_u *)repl, '~') != NULL) {
+ if (vim_strchr(repl, '$') != NULL || vim_strchr(repl, '~') != NULL) {
char *l = repl;
- repl = (char *)expand_env_save((char_u *)repl);
+ repl = expand_env_save(repl);
xfree(l);
}
@@ -4690,8 +4844,8 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char **errormsgp)
# define ESCAPE_CHARS escape_chars
#endif
- for (l = repl; *l; ++l) {
- if (vim_strchr(ESCAPE_CHARS, *l) != NULL) {
+ for (l = repl; *l; l++) {
+ if (vim_strchr((char *)ESCAPE_CHARS, *l) != NULL) {
l = (char *)vim_strsave_escaped((char_u *)repl, ESCAPE_CHARS);
xfree(repl);
repl = l;
@@ -4730,8 +4884,8 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char **errormsgp)
* After expanding environment variables, check again
* if there are still wildcards present.
*/
- if (vim_strchr((char_u *)eap->arg, '$') != NULL
- || vim_strchr((char_u *)eap->arg, '~') != NULL) {
+ if (vim_strchr(eap->arg, '$') != NULL
+ || vim_strchr(eap->arg, '~') != NULL) {
expand_env_esc((char_u *)eap->arg, NameBuff, MAXPATHL, true, true, NULL);
has_wildcards = path_has_wildcard(NameBuff);
p = (char *)NameBuff;
@@ -4773,7 +4927,7 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char **errormsgp)
return OK;
}
-/// Replace part of the command line, keeping eap->cmd, eap->arg and
+/// Replace part of the command line, keeping eap->cmd, eap->arg, eap->args and
/// eap->nextcmd correct.
/// "src" points to the part that is to be replaced, of length "srclen".
/// "repl" is the replacement string.
@@ -4792,6 +4946,7 @@ static char *repl_cmdline(exarg_T *eap, char *src, size_t srclen, char *repl, ch
i += STRLEN(eap->nextcmd); // add space for next command
}
char *new_cmdline = xmalloc(i);
+ size_t offset = (size_t)(src - *cmdlinep);
/*
* Copy the stuff before the expanded part.
@@ -4799,7 +4954,7 @@ static char *repl_cmdline(exarg_T *eap, char *src, size_t srclen, char *repl, ch
* Copy what came after the expanded part.
* Copy the next commands, if there are any.
*/
- i = (size_t)(src - *cmdlinep); // length of part before match
+ i = offset; // length of part before match
memmove(new_cmdline, *cmdlinep, i);
memmove(new_cmdline + i, repl, len);
@@ -4814,6 +4969,19 @@ static char *repl_cmdline(exarg_T *eap, char *src, size_t srclen, char *repl, ch
}
eap->cmd = new_cmdline + (eap->cmd - *cmdlinep);
eap->arg = new_cmdline + (eap->arg - *cmdlinep);
+
+ for (size_t j = 0; j < eap->argc; j++) {
+ if (offset >= (size_t)(eap->args[j] - *cmdlinep)) {
+ // If replaced text is after or in the same position as the argument,
+ // the argument's position relative to the beginning of the cmdline stays the same.
+ eap->args[j] = new_cmdline + (eap->args[j] - *cmdlinep);
+ } 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);
+ }
+ }
+
if (eap->do_ecmd_cmd != NULL && eap->do_ecmd_cmd != dollar_command) {
eap->do_ecmd_cmd = new_cmdline + (eap->do_ecmd_cmd - *cmdlinep);
}
@@ -5077,7 +5245,9 @@ static int get_tabpage_arg(exarg_T *eap)
tab_number = 0;
} else {
tab_number = (int)eap->line2;
- if (!unaccept_arg0 && *skipwhite(*eap->cmdlinep) == '-') {
+ char *cmdp = eap->cmd;
+ while (--cmdp > *eap->cmdlinep && (*cmdp == ' ' || ascii_isdigit(*cmdp))) {}
+ if (!unaccept_arg0 && *cmdp == '-') {
tab_number--;
if (tab_number < unaccept_arg0) {
eap->errmsg = e_invarg;
@@ -5325,12 +5495,12 @@ static int check_more(int message, bool forceit)
}
/// Function given to ExpandGeneric() to obtain the list of command names.
-char_u *get_command_name(expand_T *xp, int idx)
+char *get_command_name(expand_T *xp, int idx)
{
if (idx >= CMD_SIZE) {
- return (char_u *)expand_user_command_name(idx);
+ return expand_user_command_name(idx);
}
- return (char_u *)cmdnames[idx].cmd_name;
+ return cmdnames[idx].cmd_name;
}
/// Check for a valid user command name
@@ -6002,7 +6172,7 @@ bool uc_split_args_iter(const char *arg, size_t arglen, size_t *end, char *buf,
}
/// split and quote args for <f-args>
-static char *uc_split_args(char *arg, size_t *lenp)
+static char *uc_split_args(char *arg, char **args, size_t *arglens, size_t argc, size_t *lenp)
{
char *buf;
char *p;
@@ -6010,61 +6180,107 @@ static char *uc_split_args(char *arg, size_t *lenp)
int len;
// Precalculate length
- p = arg;
len = 2; // Initial and final quotes
+ if (args == NULL) {
+ p = arg;
- while (*p) {
- if (p[0] == '\\' && p[1] == '\\') {
- len += 2;
- p += 2;
- } else if (p[0] == '\\' && ascii_iswhite(p[1])) {
- len += 1;
- p += 2;
- } else if (*p == '\\' || *p == '"') {
- len += 2;
- p += 1;
- } else if (ascii_iswhite(*p)) {
- p = skipwhite(p);
- if (*p == NUL) {
- break;
+ while (*p) {
+ if (p[0] == '\\' && p[1] == '\\') {
+ len += 2;
+ p += 2;
+ } else if (p[0] == '\\' && ascii_iswhite(p[1])) {
+ len += 1;
+ p += 2;
+ } else if (*p == '\\' || *p == '"') {
+ len += 2;
+ p += 1;
+ } else if (ascii_iswhite(*p)) {
+ p = skipwhite(p);
+ if (*p == NUL) {
+ break;
+ }
+ len += 3; // ","
+ } else {
+ const int charlen = utfc_ptr2len(p);
+
+ len += charlen;
+ p += charlen;
}
- len += 3; // ","
- } else {
- const int charlen = utfc_ptr2len(p);
+ }
+ } else {
+ for (size_t i = 0; i < argc; i++) {
+ p = args[i];
+ const char *arg_end = args[i] + arglens[i];
+
+ while (p < arg_end) {
+ if (*p == '\\' || *p == '"') {
+ len += 2;
+ p += 1;
+ } else {
+ const int charlen = utfc_ptr2len(p);
- len += charlen;
- p += charlen;
+ len += charlen;
+ p += charlen;
+ }
+ }
+
+ if (i != argc - 1) {
+ len += 3; // ","
+ }
}
}
buf = xmalloc((size_t)len + 1);
- p = arg;
q = buf;
*q++ = '"';
- while (*p) {
- if (p[0] == '\\' && p[1] == '\\') {
- *q++ = '\\';
- *q++ = '\\';
- p += 2;
- } else if (p[0] == '\\' && ascii_iswhite(p[1])) {
- *q++ = p[1];
- p += 2;
- } else if (*p == '\\' || *p == '"') {
- *q++ = '\\';
- *q++ = *p++;
- } else if (ascii_iswhite(*p)) {
- p = skipwhite(p);
- if (*p == NUL) {
- break;
+
+ if (args == NULL) {
+ p = arg;
+ while (*p) {
+ if (p[0] == '\\' && p[1] == '\\') {
+ *q++ = '\\';
+ *q++ = '\\';
+ p += 2;
+ } else if (p[0] == '\\' && ascii_iswhite(p[1])) {
+ *q++ = p[1];
+ p += 2;
+ } else if (*p == '\\' || *p == '"') {
+ *q++ = '\\';
+ *q++ = *p++;
+ } else if (ascii_iswhite(*p)) {
+ p = skipwhite(p);
+ if (*p == NUL) {
+ break;
+ }
+ *q++ = '"';
+ *q++ = ',';
+ *q++ = '"';
+ } else {
+ mb_copy_char((const char_u **)&p, (char_u **)&q);
+ }
+ }
+ } else {
+ for (size_t i = 0; i < argc; i++) {
+ p = args[i];
+ const char *arg_end = args[i] + arglens[i];
+
+ while (p < arg_end) {
+ if (*p == '\\' || *p == '"') {
+ *q++ = '\\';
+ *q++ = *p++;
+ } else {
+ mb_copy_char((const char_u **)&p, (char_u **)&q);
+ }
+ }
+ if (i != argc - 1) {
+ *q++ = '"';
+ *q++ = ',';
+ *q++ = '"';
}
- *q++ = '"';
- *q++ = ',';
- *q++ = '"';
- } else {
- mb_copy_char((const char_u **)&p, (char_u **)&q);
}
}
+
*q++ = '"';
*q = 0;
@@ -6121,7 +6337,7 @@ static size_t uc_check_code(char *code, size_t len, char *buf, ucmd_T *cmd, exar
ct_NONE,
} type = ct_NONE;
- if ((vim_strchr((char_u *)"qQfF", *p) != NULL) && p[1] == '-') {
+ if ((vim_strchr("qQfF", *p) != NULL) && p[1] == '-') {
quote = (*p == 'q' || *p == 'Q') ? 1 : 2;
p += 2;
l -= 2;
@@ -6201,7 +6417,7 @@ static size_t uc_check_code(char *code, size_t len, char *buf, ucmd_T *cmd, exar
case 2: // Quote and split (<f-args>)
// This is hard, so only do it once, and cache the result
if (*split_buf == NULL) {
- *split_buf = uc_split_args(eap->arg, split_len);
+ *split_buf = uc_split_args(eap->arg, eap->args, eap->arglens, eap->argc, split_len);
}
result = *split_len;
@@ -6426,9 +6642,9 @@ static void do_ucmd(exarg_T *eap)
totlen = 0;
for (;;) {
- start = (char *)vim_strchr((char_u *)p, '<');
+ start = vim_strchr(p, '<');
if (start != NULL) {
- end = (char *)vim_strchr((char_u *)start + 1, '>');
+ end = vim_strchr(start + 1, '>');
}
if (buf != NULL) {
for (ksp = p; *ksp != NUL && (char_u)(*ksp) != K_SPECIAL; ksp++) {}
@@ -6510,28 +6726,28 @@ static void do_ucmd(exarg_T *eap)
static char *expand_user_command_name(int idx)
{
- return (char *)get_user_commands(NULL, idx - CMD_SIZE);
+ return get_user_commands(NULL, idx - CMD_SIZE);
}
/// Function given to ExpandGeneric() to obtain the list of user address type names.
-char_u *get_user_cmd_addr_type(expand_T *xp, int idx)
+char *get_user_cmd_addr_type(expand_T *xp, int idx)
{
- return (char_u *)addr_type_complete[idx].name;
+ return addr_type_complete[idx].name;
}
/// Function given to ExpandGeneric() to obtain the list of user command names.
-char_u *get_user_commands(expand_T *xp FUNC_ATTR_UNUSED, int idx)
+char *get_user_commands(expand_T *xp FUNC_ATTR_UNUSED, int idx)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
// In cmdwin, the alternative buffer should be used.
const buf_T *const buf = prevwin_curwin()->w_buffer;
if (idx < buf->b_ucmds.ga_len) {
- return USER_CMD_GA(&buf->b_ucmds, idx)->uc_name;
+ return (char *)USER_CMD_GA(&buf->b_ucmds, idx)->uc_name;
}
idx -= buf->b_ucmds.ga_len;
if (idx < ucmds.ga_len) {
- return USER_CMD(idx)->uc_name;
+ return (char *)USER_CMD(idx)->uc_name;
}
return NULL;
}
@@ -6558,7 +6774,7 @@ static char *get_user_command_name(int idx, int cmdidx)
/// Function given to ExpandGeneric() to obtain the list of user command
/// attributes.
-char_u *get_user_cmd_flags(expand_T *xp, int idx)
+char *get_user_cmd_flags(expand_T *xp, int idx)
{
static char *user_cmd_flags[] = { "addr", "bang", "bar",
"buffer", "complete", "count",
@@ -6567,31 +6783,31 @@ char_u *get_user_cmd_flags(expand_T *xp, int idx)
if (idx >= (int)ARRAY_SIZE(user_cmd_flags)) {
return NULL;
}
- return (char_u *)user_cmd_flags[idx];
+ return user_cmd_flags[idx];
}
/// Function given to ExpandGeneric() to obtain the list of values for -nargs.
-char_u *get_user_cmd_nargs(expand_T *xp, int idx)
+char *get_user_cmd_nargs(expand_T *xp, int idx)
{
static char *user_cmd_nargs[] = { "0", "1", "*", "?", "+" };
if (idx >= (int)ARRAY_SIZE(user_cmd_nargs)) {
return NULL;
}
- return (char_u *)user_cmd_nargs[idx];
+ return user_cmd_nargs[idx];
}
/// Function given to ExpandGeneric() to obtain the list of values for -complete.
-char_u *get_user_cmd_complete(expand_T *xp, int idx)
+char *get_user_cmd_complete(expand_T *xp, int idx)
{
if (idx >= (int)ARRAY_SIZE(command_complete)) {
return NULL;
}
char *cmd_compl = get_command_complete(idx);
if (cmd_compl == NULL) {
- return (char_u *)"";
+ return "";
} else {
- return (char_u *)cmd_compl;
+ return cmd_compl;
}
}
@@ -7564,7 +7780,7 @@ static void ex_tabs(exarg_T *eap)
if (buf_spname(wp->w_buffer) != NULL) {
STRLCPY(IObuff, buf_spname(wp->w_buffer), IOSIZE);
} else {
- home_replace(wp->w_buffer, wp->w_buffer->b_fname, IObuff, IOSIZE, true);
+ home_replace(wp->w_buffer, (char_u *)wp->w_buffer->b_fname, IObuff, IOSIZE, true);
}
msg_outtrans(IObuff);
ui_flush(); // output one line at a time
@@ -7879,13 +8095,13 @@ static void ex_read(exarg_T *eap)
if (check_fname() == FAIL) { // check for no file name
return;
}
- i = readfile(curbuf->b_ffname, curbuf->b_fname,
+ i = readfile((char *)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((char_u *)eap->arg, (char_u *)eap->arg, (linenr_T)1);
}
- i = readfile((char_u *)eap->arg, NULL,
+ i = readfile(eap->arg, NULL,
eap->line2, (linenr_T)0, (linenr_T)MAXLNUM, eap, 0, false);
}
if (i != OK) {
@@ -7958,7 +8174,7 @@ static void post_chdir(CdScope scope, bool trigger_dirchanged)
char *pdir = get_prevdir(scope);
// If still in global directory, set CWD as the global directory.
if (globaldir == NULL && pdir != NULL) {
- globaldir = vim_strsave((char_u *)pdir);
+ globaldir = xstrdup(pdir);
}
}
@@ -8376,8 +8592,7 @@ 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) {
+ if (do_execreg(c, true, vim_strchr(p_cpo, CPO_EXECBUF) != NULL, true) == FAIL) {
beep_flush();
} else {
bool save_efr = exec_from_reg;
@@ -8520,7 +8735,7 @@ static void ex_redir(exarg_T *eap)
close_redir();
// Expand environment variables and "~/".
- fname = (char *)expand_env_save((char_u *)arg);
+ fname = expand_env_save(arg);
if (fname == NULL) {
return;
}
@@ -8584,7 +8799,7 @@ static void ex_redir(exarg_T *eap)
/// ":redraw": force redraw
static void ex_redraw(exarg_T *eap)
{
- if (State & CMDPREVIEW) {
+ if (State & MODE_CMDPREVIEW) {
return; // Ignore :redraw during 'inccommand' preview. #9777
}
int r = RedrawingDisabled;
@@ -8615,10 +8830,10 @@ static void ex_redraw(exarg_T *eap)
ui_flush();
}
-/// ":redrawstatus": force redraw of status line(s)
+/// ":redrawstatus": force redraw of status line(s) and window bar(s)
static void ex_redrawstatus(exarg_T *eap)
{
- if (State & CMDPREVIEW) {
+ if (State & MODE_CMDPREVIEW) {
return; // Ignore :redrawstatus during 'inccommand' preview. #9777
}
int r = RedrawingDisabled;
@@ -8631,8 +8846,7 @@ static void ex_redrawstatus(exarg_T *eap)
} else {
status_redraw_curbuf();
}
- update_screen(VIsual_active ? INVERTED :
- 0);
+ update_screen(VIsual_active ? INVERTED : 0);
RedrawingDisabled = r;
p_lz = p;
ui_flush();
@@ -8802,7 +9016,7 @@ void restore_current_state(save_state_T *sst)
/// ":normal[!] {commands}": Execute normal mode commands.
static void ex_normal(exarg_T *eap)
{
- if (curbuf->terminal && State & TERM_FOCUS) {
+ if (curbuf->terminal && State & MODE_TERMINAL) {
emsg("Can't re-enter normal mode from terminal mode");
return;
}
@@ -8893,7 +9107,7 @@ static void ex_startinsert(exarg_T *eap)
// Ignore the command when already in Insert mode. Inserting an
// expression register that invokes a function can do this.
- if (State & INSERT) {
+ if (State & MODE_INSERT) {
return;
}
@@ -9261,7 +9475,7 @@ char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnum
result = "";
valid = 0; // Must have ":p:h" to be valid
} else {
- result = (char *)curbuf->b_fname;
+ result = curbuf->b_fname;
tilde_file = STRCMP(result, "~") == 0;
}
break;
@@ -9315,7 +9529,7 @@ char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnum
result = "";
valid = 0; // Must have ":p:h" to be valid
} else {
- result = (char *)buf->b_fname;
+ result = buf->b_fname;
tilde_file = STRCMP(result, "~") == 0;
}
}
@@ -9332,17 +9546,17 @@ char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnum
case SPEC_AFILE: // file name for autocommand
if (autocmd_fname != NULL
- && !path_is_absolute(autocmd_fname)
+ && !path_is_absolute((char_u *)autocmd_fname)
// For CmdlineEnter and related events, <afile> is not a path! #9348
- && !strequal("/", (char *)autocmd_fname)) {
+ && !strequal("/", autocmd_fname)) {
// Still need to turn the fname into a full path. It was
// postponed to avoid a delay when <afile> is not used.
- result = FullName_save((char *)autocmd_fname, false);
+ result = FullName_save(autocmd_fname, false);
// Copy into `autocmd_fname`, don't reassign it. #8165
STRLCPY(autocmd_fname, result, MAXPATHL);
xfree(result);
}
- result = (char *)autocmd_fname;
+ result = autocmd_fname;
if (result == NULL) {
*errormsg = _("E495: no autocommand file name to substitute for \"<afile>\"");
return NULL;
@@ -9360,7 +9574,7 @@ char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnum
break;
case SPEC_AMATCH: // match name for autocommand
- result = (char *)autocmd_match;
+ result = autocmd_match;
if (result == NULL) {
*errormsg = _("E497: no autocommand match name to substitute for \"<amatch>\"");
return NULL;
@@ -9368,7 +9582,7 @@ char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnum
break;
case SPEC_SFILE: // file name for ":so" command
- result = (char *)sourcing_name;
+ result = sourcing_name;
if (result == NULL) {
*errormsg = _("E498: no :source file name to substitute for \"<sfile>\"");
return NULL;
@@ -9417,7 +9631,7 @@ char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnum
if (src[*usedlen] == '<') {
(*usedlen)++;
if ((s = (char *)STRRCHR(result, '.')) != NULL
- && (char_u *)s >= path_tail((char_u *)result)) {
+ && s >= path_tail(result)) {
resultlen = (size_t)(s - result);
}
} else if (!skip_mod) {
@@ -9601,31 +9815,31 @@ static void ex_behave(exarg_T *eap)
/// Function given to ExpandGeneric() to obtain the possible arguments of the
/// ":behave {mswin,xterm}" command.
-char_u *get_behave_arg(expand_T *xp, int idx)
+char *get_behave_arg(expand_T *xp, int idx)
{
if (idx == 0) {
- return (char_u *)"mswin";
+ return "mswin";
}
if (idx == 1) {
- return (char_u *)"xterm";
+ return "xterm";
}
return NULL;
}
/// Function given to ExpandGeneric() to obtain the possible arguments of the
/// ":messages {clear}" command.
-char_u *get_messages_arg(expand_T *xp FUNC_ATTR_UNUSED, int idx)
+char *get_messages_arg(expand_T *xp FUNC_ATTR_UNUSED, int idx)
{
if (idx == 0) {
- return (char_u *)"clear";
+ return "clear";
}
return NULL;
}
-char_u *get_mapclear_arg(expand_T *xp FUNC_ATTR_UNUSED, int idx)
+char *get_mapclear_arg(expand_T *xp FUNC_ATTR_UNUSED, int idx)
{
if (idx == 0) {
- return (char_u *)"<buffer>";
+ return "<buffer>";
}
return NULL;
}
@@ -9651,8 +9865,8 @@ static void ex_filetype(exarg_T *eap)
// Print current status.
smsg("filetype detection:%s plugin:%s indent:%s",
filetype_detect == kTrue ? "ON" : "OFF",
- filetype_plugin == kTrue ? (filetype_detect == kTrue ? "ON" : "(on)") : "OFF", // NOLINT(whitespace/line_length)
- filetype_indent == kTrue ? (filetype_detect == kTrue ? "ON" : "(on)") : "OFF"); // NOLINT(whitespace/line_length)
+ filetype_plugin == kTrue ? (filetype_detect == kTrue ? "ON" : "(on)") : "OFF",
+ filetype_indent == kTrue ? (filetype_detect == kTrue ? "ON" : "(on)") : "OFF");
return;
}
@@ -9887,7 +10101,7 @@ bool cmd_can_preview(char *cmd)
if (*ea.cmd == '*') {
ea.cmd = skipwhite(ea.cmd + 1);
}
- char *end = find_command(&ea, NULL);
+ char *end = find_ex_command(&ea, NULL);
switch (ea.cmdidx) {
case CMD_substitute:
@@ -10278,3 +10492,9 @@ void verify_command(char *cmd)
msg("` `.:.`.,:iii;;;;;;;;iii;;;:` `.`` "
" `nW");
}
+
+/// Get argt of command with id
+uint32_t get_cmd_argt(cmdidx_T cmdidx)
+{
+ return cmdnames[(int)cmdidx].cmd_argt;
+}