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.c160
1 files changed, 85 insertions, 75 deletions
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index e11dd0a2f6..a24e8458a6 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -369,7 +369,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
// Get the function or script name and the address where the next breakpoint
// line and the debug tick for a function or script are stored.
if (getline_is_func) {
- fname = (char *)func_name(real_cookie);
+ fname = func_name(real_cookie);
breakpoint = func_breakpoint(real_cookie);
dbg_tick = func_dbg_tick(real_cookie);
} else if (getline_equal(fgetline, cookie, getsourceline)) {
@@ -919,7 +919,7 @@ static char *get_loop_line(int c, void *cookie, int indent, bool do_concat)
char *line;
// First time inside the ":while"/":for": get line normally.
if (cp->getline == NULL) {
- line = (char *)getcmdline(c, 0L, indent, do_concat);
+ line = getcmdline(c, 0L, indent, do_concat);
} else {
line = cp->getline(c, cp->cookie, indent, do_concat);
}
@@ -2852,7 +2852,7 @@ bool checkforcmd(char **pp, const char *cmd, int len)
break;
}
}
- if (i >= len && !isalpha((*pp)[i])) {
+ if (i >= len && !ASCII_ISALPHA((*pp)[i])) {
*pp = skipwhite(*pp + i);
return true;
}
@@ -2877,7 +2877,7 @@ static void append_command(char *cmd)
STRCAT(IObuff, ": ");
d = IObuff + strlen(IObuff);
while (*s != NUL && d - IObuff + 5 < IOSIZE) {
- if ((char_u)s[0] == 0xc2 && (char_u)s[1] == 0xa0) {
+ if ((uint8_t)s[0] == 0xc2 && (uint8_t)s[1] == 0xa0) {
s += 2;
STRCPY(d, "<a0>");
d += 4;
@@ -2890,6 +2890,33 @@ static void append_command(char *cmd)
*d = NUL;
}
+/// Return true and set "*idx" if "p" points to a one letter command.
+/// - The 'k' command can directly be followed by any character.
+/// - The 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
+/// but :sre[wind] is another command, as are :scr[iptnames],
+/// :scs[cope], :sim[alt], :sig[ns] and :sil[ent].
+static int one_letter_cmd(const char *p, cmdidx_T *idx)
+{
+ if (*p == 'k') {
+ *idx = CMD_k;
+ return true;
+ }
+ if (p[0] == 's'
+ && ((p[1] == 'c'
+ && (p[2] == NUL
+ || (p[2] != 's' && p[2] != 'r'
+ && (p[3] == NUL
+ || (p[3] != 'i' && p[4] != 'p')))))
+ || p[1] == 'g'
+ || (p[1] == 'i' && p[2] != 'm' && p[2] != 'l' && p[2] != 'g')
+ || p[1] == 'I'
+ || (p[1] == 'r' && p[2] != 'e'))) {
+ *idx = CMD_substitute;
+ return true;
+ }
+ return false;
+}
+
/// Find an Ex command by its name, either built-in or user.
/// Start of the name can be found at eap->cmd.
/// Sets eap->cmdidx and returns a pointer to char after the command name.
@@ -2900,27 +2927,8 @@ char *find_ex_command(exarg_T *eap, int *full)
FUNC_ATTR_NONNULL_ARG(1)
{
// Isolate the command and search for it in the command table.
- // Exceptions:
- // - the 'k' command can directly be followed by any character.
- // - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
- // but :sre[wind] is another command, as are :scr[iptnames],
- // :scs[cope], :sim[alt], :sig[ns] and :sil[ent].
- // - the "d" command can directly be followed by 'l' or 'p' flag.
char *p = eap->cmd;
- if (*p == 'k') {
- eap->cmdidx = CMD_k;
- p++;
- } else if (p[0] == 's'
- && ((p[1] == 'c'
- && (p[2] == NUL
- || (p[2] != 's' && p[2] != 'r'
- && (p[3] == NUL
- || (p[3] != 'i' && p[4] != 'p')))))
- || p[1] == 'g'
- || (p[1] == 'i' && p[2] != 'm' && p[2] != 'l' && p[2] != 'g')
- || p[1] == 'I'
- || (p[1] == 'r' && p[2] != 'e'))) {
- eap->cmdidx = CMD_substitute;
+ if (one_letter_cmd(p, &eap->cmdidx)) {
p++;
} else {
while (ASCII_ISALPHA(*p)) {
@@ -2934,10 +2942,11 @@ char *find_ex_command(exarg_T *eap, int *full)
}
// check for non-alpha command
- if (p == eap->cmd && vim_strchr("@!=><&~#", *p) != NULL) {
+ if (p == eap->cmd && vim_strchr("@!=><&~#", (uint8_t)(*p)) != NULL) {
p++;
}
int len = (int)(p - eap->cmd);
+ // The "d" command can directly be followed by 'l' or 'p' flag.
if (*eap->cmd == 'd' && (p[-1] == 'l' || p[-1] == 'p')) {
// Check for ":dl", ":dell", etc. to ":deletel": that's
// :delete with the 'l' flag. Same for 'p'.
@@ -2958,7 +2967,7 @@ char *find_ex_command(exarg_T *eap, int *full)
}
if (ASCII_ISLOWER(eap->cmd[0])) {
- const int c1 = (char_u)eap->cmd[0];
+ const int c1 = (uint8_t)eap->cmd[0];
const int c2 = len == 1 ? NUL : eap->cmd[1];
if (command_count != CMD_SIZE) {
@@ -3135,9 +3144,11 @@ cmdidx_T excmd_get_cmdidx(const char *cmd, size_t len)
{
cmdidx_T idx;
- for (idx = (cmdidx_T)0; (int)idx < CMD_SIZE; idx = (cmdidx_T)((int)idx + 1)) {
- if (strncmp(cmdnames[(int)idx].cmd_name, cmd, len) == 0) {
- break;
+ if (!one_letter_cmd(cmd, &idx)) {
+ for (idx = (cmdidx_T)0; (int)idx < CMD_SIZE; idx = (cmdidx_T)((int)idx + 1)) {
+ if (strncmp(cmdnames[(int)idx].cmd_name, cmd, len) == 0) {
+ break;
+ }
}
}
@@ -3161,7 +3172,7 @@ uint32_t excmd_get_argt(cmdidx_T idx)
/// @return the "cmd" pointer advanced to beyond the range.
char *skip_range(const char *cmd, int *ctx)
{
- while (vim_strchr(" \t0123456789.$%'/?-+,;\\", *cmd) != NULL) {
+ while (vim_strchr(" \t0123456789.$%'/?-+,;\\", (uint8_t)(*cmd)) != NULL) {
if (*cmd == '\\') {
if (cmd[1] == '?' || cmd[1] == '/' || cmd[1] == '&') {
cmd++;
@@ -3350,7 +3361,7 @@ static linenr_T get_address(exarg_T *eap, char **ptr, cmd_addr_T addr_type, int
case '/':
case '?': // '/' or '?' - search
- c = (char_u)(*cmd++);
+ c = (uint8_t)(*cmd++);
if (addr_type != ADDR_LINES) {
addr_error(addr_type);
cmd = NULL;
@@ -3423,7 +3434,7 @@ static linenr_T get_address(exarg_T *eap, char **ptr, cmd_addr_T addr_type, int
pos.coladd = 0;
if (searchit(curwin, curbuf, &pos, NULL,
*cmd == '?' ? BACKWARD : FORWARD,
- (char_u *)"", 1L, SEARCH_MSG, i, NULL) != FAIL) {
+ "", 1L, SEARCH_MSG, i, NULL) != FAIL) {
lnum = pos.lnum;
} else {
cmd = NULL;
@@ -3484,7 +3495,7 @@ static linenr_T get_address(exarg_T *eap, char **ptr, cmd_addr_T addr_type, int
if (ascii_isdigit(*cmd)) {
i = '+'; // "number" is same as "+number"
} else {
- i = (char_u)(*cmd++);
+ i = (uint8_t)(*cmd++);
}
if (!ascii_isdigit(*cmd)) { // '+' is '+1'
n = 1;
@@ -3531,7 +3542,7 @@ error:
/// Get flags from an Ex command argument.
static void get_flags(exarg_T *eap)
{
- while (vim_strchr("lp#", *eap->arg) != NULL) {
+ while (vim_strchr("lp#", (uint8_t)(*eap->arg)) != NULL) {
if (*eap->arg == 'l') {
eap->flags |= EXFLAG_LIST;
} else if (*eap->arg == 'p') {
@@ -3699,7 +3710,7 @@ char *replace_makeprg(exarg_T *eap, char *arg, char **cmdlinep)
if ((eap->cmdidx == CMD_make || eap->cmdidx == CMD_lmake || isgrep)
&& !grep_internal(eap->cmdidx)) {
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);
+ : (*curbuf->b_p_mp == NUL ? p_mp : curbuf->b_p_mp);
arg = skipwhite(arg);
@@ -3748,7 +3759,7 @@ int expand_filename(exarg_T *eap, char **cmdlinep, char **errormsgp)
}
// Quick check if this cannot be the start of a special string.
// Also removes backslash before '%', '#' and '<'.
- if (vim_strchr("%#<", *p) == NULL) {
+ if (vim_strchr("%#<", (uint8_t)(*p)) == NULL) {
p++;
continue;
}
@@ -3756,8 +3767,8 @@ int expand_filename(exarg_T *eap, char **cmdlinep, char **errormsgp)
// Try to find a match at this position.
size_t srclen;
int escaped;
- char *repl = (char *)eval_vars((char_u *)p, (char_u *)eap->arg, &srclen, &(eap->do_ecmd_lnum),
- errormsgp, &escaped, true);
+ char *repl = eval_vars(p, eap->arg, &srclen, &(eap->do_ecmd_lnum),
+ errormsgp, &escaped, true);
if (*errormsgp != NULL) { // error detected
return FAIL;
}
@@ -3801,8 +3812,8 @@ int expand_filename(exarg_T *eap, char **cmdlinep, char **errormsgp)
#endif
for (l = repl; *l; l++) {
- if (vim_strchr((char *)ESCAPE_CHARS, *l) != NULL) {
- l = vim_strsave_escaped(repl, (char *)ESCAPE_CHARS);
+ if (vim_strchr(ESCAPE_CHARS, (uint8_t)(*l)) != NULL) {
+ l = vim_strsave_escaped(repl, ESCAPE_CHARS);
xfree(repl);
repl = l;
break;
@@ -3857,7 +3868,7 @@ int expand_filename(exarg_T *eap, char **cmdlinep, char **errormsgp)
backslash_halve(eap->arg);
}
#else
- backslash_halve((char_u *)eap->arg);
+ backslash_halve(eap->arg);
#endif
if (has_wildcards) {
@@ -4033,15 +4044,15 @@ char *skip_cmd_arg(char *p, int rembs)
return p;
}
-int get_bad_opt(const char_u *p, exarg_T *eap)
+int get_bad_opt(const char *p, exarg_T *eap)
FUNC_ATTR_NONNULL_ALL
{
if (STRICMP(p, "keep") == 0) {
eap->bad_char = BAD_KEEP;
} else if (STRICMP(p, "drop") == 0) {
eap->bad_char = BAD_DROP;
- } else if (MB_BYTE2LEN(*p) == 1 && p[1] == NUL) {
- eap->bad_char = *p;
+ } else if (MB_BYTE2LEN((uint8_t)(*p)) == 1 && p[1] == NUL) {
+ eap->bad_char = (uint8_t)(*p);
} else {
return FAIL;
}
@@ -4118,7 +4129,7 @@ static int getargopt(exarg_T *eap)
if (check_ff_value(eap->cmd + eap->force_ff) == FAIL) {
return FAIL;
}
- eap->force_ff = (char_u)eap->cmd[eap->force_ff];
+ eap->force_ff = (uint8_t)eap->cmd[eap->force_ff];
} else if (pp == &eap->force_enc) {
// Make 'fileencoding' lower case.
for (char *p = eap->cmd + eap->force_enc; *p != NUL; p++) {
@@ -4127,7 +4138,7 @@ static int getargopt(exarg_T *eap)
} else {
// Check ++bad= argument. Must be a single-byte character, "keep" or
// "drop".
- if (get_bad_opt((char_u *)eap->cmd + bad_char_idx, eap) == FAIL) {
+ if (get_bad_opt(eap->cmd + bad_char_idx, eap) == FAIL) {
return FAIL;
}
}
@@ -4965,8 +4976,8 @@ void ex_splitview(exarg_T *eap)
}
if (eap->cmdidx == CMD_sfind || eap->cmdidx == CMD_tabfind) {
- fname = (char *)find_file_in_path(eap->arg, strlen(eap->arg),
- FNAME_MESS, true, curbuf->b_ffname);
+ fname = find_file_in_path(eap->arg, strlen(eap->arg),
+ FNAME_MESS, true, curbuf->b_ffname);
if (fname == NULL) {
goto theend;
}
@@ -4976,7 +4987,7 @@ void ex_splitview(exarg_T *eap)
// Either open new tab page or split the window.
if (use_tab) {
if (win_new_tabpage(cmdmod.cmod_tab != 0 ? cmdmod.cmod_tab : eap->addr_count == 0
- ? 0 : (int)eap->line2 + 1, (char_u *)eap->arg) != FAIL) {
+ ? 0 : (int)eap->line2 + 1, eap->arg) != FAIL) {
do_exedit(eap, old_curwin);
apply_autocmds(EVENT_TABNEWENTERED, NULL, NULL, false, curbuf);
@@ -5158,15 +5169,15 @@ 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(eap->arg, strlen(eap->arg),
- FNAME_MESS, true, curbuf->b_ffname);
+ char *fname = 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, curbuf->b_ffname);
+ fname = find_file_in_path(NULL, 0, FNAME_MESS, false, curbuf->b_ffname);
}
}
@@ -5238,9 +5249,9 @@ 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_locked" is set. Only ":edit"
- // can bring us here, others are stopped earlier.
- if (*eap->arg != NUL && curbuf_locked()) {
+ // Can't edit another file when "textlock" or "curbuf->b_ro_locked" is set.
+ // Only ":edit" or ":script" can bring us here, others are stopped earlier.
+ if (*eap->arg != NUL && text_or_buf_locked()) {
return;
}
n = readonlymode;
@@ -5961,18 +5972,18 @@ static void ex_undo(exarg_T *eap)
static void ex_wundo(exarg_T *eap)
{
- char hash[UNDO_HASH_SIZE];
+ uint8_t hash[UNDO_HASH_SIZE];
- u_compute_hash(curbuf, (char_u *)hash);
- u_write_undo(eap->arg, eap->forceit, curbuf, (char_u *)hash);
+ u_compute_hash(curbuf, hash);
+ u_write_undo(eap->arg, eap->forceit, curbuf, hash);
}
static void ex_rundo(exarg_T *eap)
{
- char hash[UNDO_HASH_SIZE];
+ uint8_t hash[UNDO_HASH_SIZE];
- u_compute_hash(curbuf, (char_u *)hash);
- u_read_undo(eap->arg, (char_u *)hash, NULL);
+ u_compute_hash(curbuf, hash);
+ u_read_undo(eap->arg, hash, NULL);
}
/// ":redo".
@@ -5991,7 +6002,7 @@ static void ex_later(exarg_T *eap)
if (*p == NUL) {
count = 1;
- } else if (isdigit(*p)) {
+ } else if (isdigit((uint8_t)(*p))) {
count = getdigits_long(&p, false, 0);
switch (*p) {
case 's':
@@ -6049,7 +6060,7 @@ static void ex_redir(exarg_T *eap)
close_redir();
arg++;
if (valid_yank_reg(*arg, true) && *arg != '_') {
- redir_reg = (char_u)(*arg++);
+ redir_reg = (uint8_t)(*arg++);
if (*arg == '>' && arg[1] == '>') { // append
arg += 2;
} else {
@@ -6714,8 +6725,8 @@ ssize_t find_cmdline_var(const char *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, const char_u *srcstart, size_t *usedlen, linenr_T *lnump,
- char **errormsg, int *escaped, bool empty_is_error)
+char *eval_vars(char *src, const char *srcstart, size_t *usedlen, linenr_T *lnump, char **errormsg,
+ int *escaped, bool empty_is_error)
{
char *result;
char *resultbuf = NULL;
@@ -6731,7 +6742,7 @@ char_u *eval_vars(char_u *src, const char_u *srcstart, size_t *usedlen, linenr_T
}
// Check if there is something to do.
- ssize_t spec_idx = find_cmdline_var((char *)src, usedlen);
+ ssize_t spec_idx = find_cmdline_var(src, usedlen);
if (spec_idx < 0) { // no match
*usedlen = 1;
return NULL;
@@ -6789,16 +6800,16 @@ char_u *eval_vars(char_u *src, const char_u *srcstart, size_t *usedlen, linenr_T
skip_mod = true;
break;
}
- char *s = (char *)src + 1;
+ char *s = src + 1;
if (*s == '<') { // "#<99" uses v:oldfiles.
s++;
}
int i = getdigits_int(&s, false, 0);
- if ((char_u *)s == src + 2 && src[1] == '-') {
+ if (s == src + 2 && src[1] == '-') {
// just a minus sign, don't skip over it
s--;
}
- *usedlen = (size_t)((char_u *)s - src); // length of what we expand
+ *usedlen = (size_t)(s - src); // length of what we expand
if (src[1] == '<' && i != 0) {
if (*usedlen < 2) {
@@ -6834,7 +6845,7 @@ char_u *eval_vars(char_u *src, const char_u *srcstart, size_t *usedlen, linenr_T
break;
case SPEC_CFILE: // file name under cursor
- result = (char *)file_name_at_cursor(FNAME_MESS|FNAME_HYP, 1L, NULL);
+ result = file_name_at_cursor(FNAME_MESS|FNAME_HYP, 1L, NULL);
if (result == NULL) {
*errormsg = "";
return NULL;
@@ -6844,7 +6855,7 @@ char_u *eval_vars(char_u *src, const char_u *srcstart, size_t *usedlen, linenr_T
case SPEC_AFILE: // file name for autocommand
if (autocmd_fname != NULL
- && !path_is_absolute((char_u *)autocmd_fname)
+ && !path_is_absolute(autocmd_fname)
// For CmdlineEnter and related events, <afile> is not a path! #9348
&& !strequal("/", autocmd_fname)) {
// Still need to turn the fname into a full path. It was
@@ -6951,7 +6962,7 @@ char_u *eval_vars(char_u *src, const char_u *srcstart, size_t *usedlen, linenr_T
resultlen = (size_t)(s - result);
}
} else if (!skip_mod) {
- valid |= modify_fname((char *)src, tilde_file, usedlen, &result,
+ valid |= modify_fname(src, tilde_file, usedlen, &result,
&resultbuf, &resultlen);
if (result == NULL) {
*errormsg = "";
@@ -6974,7 +6985,7 @@ char_u *eval_vars(char_u *src, const char_u *srcstart, size_t *usedlen, linenr_T
result = xstrnsave(result, resultlen);
}
xfree(resultbuf);
- return (char_u *)result;
+ return result;
}
/// Expand the <sfile> string in "arg".
@@ -6991,8 +7002,7 @@ char *expand_sfile(char *arg)
// replace "<sfile>" with the sourced file name, and do ":" stuff
size_t srclen;
char *errormsg;
- char *repl = (char *)eval_vars((char_u *)p, (char_u *)result, &srclen, NULL, &errormsg, NULL,
- true);
+ char *repl = eval_vars(p, result, &srclen, NULL, &errormsg, NULL, true);
if (errormsg != NULL) {
if (*errormsg) {
emsg(errormsg);