summaryrefslogtreecommitdiffstats
path: root/src/ex_docmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ex_docmd.c')
-rw-r--r--src/ex_docmd.c125
1 files changed, 48 insertions, 77 deletions
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 71bfa93..2a59301 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -19,10 +19,6 @@ static int ex_pressedreturn = FALSE;
# define ex_hardcopy ex_ni
#endif
-#if defined(FEAT_EVAL) || defined(PROTO)
-static int cmp_cmdmod_info(const void *a, const void *b);
-#endif
-
#ifdef FEAT_EVAL
static char_u *do_one_cmd(char_u **, int, cstack_T *, char_u *(*fgetline)(int, void *, int, getline_opt_T), void *cookie);
#else
@@ -1460,8 +1456,13 @@ handle_did_throw(void)
current_exception->throw_name = NULL;
discard_current_exception(); // uses IObuff if 'verbose'
- suppress_errthrow = TRUE;
- force_abort = TRUE;
+
+ // If "silent!" is active the uncaught exception is not fatal.
+ if (emsg_silent == 0)
+ {
+ suppress_errthrow = TRUE;
+ force_abort = TRUE;
+ }
if (messages != NULL)
{
@@ -2336,12 +2337,7 @@ do_one_cmd(
{
for (p = ea.arg; *p; ++p)
{
- // Remove one backslash before a newline, so that it's possible to
- // pass a newline to the shell and also a newline that is preceded
- // with a backslash. This makes it impossible to end a shell
- // command in a backslash, but that doesn't appear useful.
- // Halving the number of backslashes is incompatible with previous
- // versions.
+ // Remove one backslash before a newline
if (*p == '\\' && p[1] == '\n')
STRMOVE(p, p + 1);
else if (*p == '\n' && !(ea.argt & EX_EXPR_ARG))
@@ -2722,6 +2718,12 @@ ex_errmsg(char *msg, char_u *arg)
}
/*
+ * The "+" string used in place of an empty command in Ex mode.
+ * This string is used in pointer comparison.
+ */
+static char exmode_plus[] = "+";
+
+/*
* Handle a range without a command.
* Returns an error message on failure.
*/
@@ -2730,7 +2732,8 @@ ex_range_without_command(exarg_T *eap)
{
char *errormsg = NULL;
- if ((*eap->cmd == '|' || (exmode_active && eap->line1 != eap->line2))
+ if ((*eap->cmd == '|' ||
+ (exmode_active && eap->cmd != (char_u *)exmode_plus + 1))
#ifdef FEAT_EVAL
&& !in_vim9script()
#endif
@@ -2860,9 +2863,8 @@ parse_command_modifiers(
{
// The automatically inserted Visual area range is skipped, so that
// typing ":cmdmod cmd" in Visual mode works without having to move the
- // range to after the modififiers. The command will be
- // "'<,'>cmdmod cmd", parse "cmdmod cmd" and then put back "'<,'>"
- // before "cmd" below.
+ // range to after the modifiers. The command will be "'<,'>cmdmod cmd",
+ // parse "cmdmod cmd" and then put back "'<,'>" before "cmd" below.
eap->cmd += 5;
cmd_start = eap->cmd;
has_visual_range = TRUE;
@@ -3213,7 +3215,7 @@ parse_command_modifiers(
eap->cmd = orig_cmd;
}
else if (use_plus_cmd)
- eap->cmd = (char_u *)"+";
+ eap->cmd = (char_u *)exmode_plus;
return OK;
}
@@ -4044,16 +4046,6 @@ static cmdmod_info_T cmdmod_info_tab[] = {
{"vim9cmd", 4, FALSE}
}; // cmdmod_info_tab
-// compare two cmdmod_info_T structs by case sensitive name with length
- static int
-cmp_cmdmod_info(const void *a, const void *b)
-{
- cmdmod_info_T *cm1 = (cmdmod_info_T *)a;
- cmdmod_info_T *cm2 = (cmdmod_info_T *)b;
-
- return STRNCMP(cm1->name, cm2->name, cm2->minlen);
-}
-
/*
* Return length of a command modifier (including optional count).
* Return zero when it's not a modifier.
@@ -4061,36 +4053,20 @@ cmp_cmdmod_info(const void *a, const void *b)
int
modifier_len(char_u *cmd)
{
+ int i, j;
char_u *p = cmd;
- cmdmod_info_T target;
- cmdmod_info_T *entry;
if (VIM_ISDIGIT(*cmd))
p = skipwhite(skipdigits(cmd + 1));
-
- // only lowercase characters can match
- if (!ASCII_ISLOWER(*p))
- return 0;
-
- target.name = (char *)p;
- target.minlen = 0; // not used, see cmp_cmdmod_info()
- target.has_count = FALSE;
-
- entry = (cmdmod_info_T *)bsearch(&target, &cmdmod_info_tab, ARRAY_LENGTH(cmdmod_info_tab), sizeof(cmdmod_info_tab[0]), cmp_cmdmod_info);
- if (entry != NULL)
+ for (i = 0; i < (int)ARRAY_LENGTH(cmdmod_info_tab); ++i)
{
- int i;
-
- for (i = entry->minlen; p[i] != NUL; ++i)
- {
- if (p[i] != entry->name[i])
+ for (j = 0; p[j] != NUL; ++j)
+ if (p[j] != cmdmod_info_tab[i].name[j])
break;
- }
-
- if (!ASCII_ISALPHA(p[i]) && i >= entry->minlen && (p == cmd || entry->has_count))
- return i + (int)(p - cmd);
+ if (!ASCII_ISALPHA(p[j]) && j >= cmdmod_info_tab[i].minlen
+ && (p == cmd || cmdmod_info_tab[i].has_count))
+ return j + (int)(p - cmd);
}
-
return 0;
}
@@ -4104,33 +4080,18 @@ cmd_exists(char_u *name)
{
exarg_T ea;
int full = FALSE;
+ int i;
+ int j;
char_u *p;
- // only lowercase characters can match
- if (ASCII_ISLOWER(*name))
+ // Check command modifiers.
+ for (i = 0; i < (int)ARRAY_LENGTH(cmdmod_info_tab); ++i)
{
- cmdmod_info_T target;
- cmdmod_info_T *entry;
-
- target.name = (char *)name;
- target.minlen = 0; // not used, see cmp_cmdmod_info()
- target.has_count = FALSE;
-
- // Check command modifiers.
- entry = (cmdmod_info_T *)bsearch(&target, &cmdmod_info_tab, ARRAY_LENGTH(cmdmod_info_tab), sizeof(cmdmod_info_tab[0]), cmp_cmdmod_info);
- if (entry != NULL)
- {
- int i;
-
- for (i = entry->minlen; name[i] != NUL; ++i)
- {
- if (name[i] != entry->name[i])
- break;
- }
-
- if (name[i] == NUL && i >= entry->minlen)
- return (entry->name[i] == NUL ? 2 : 1);
- }
+ for (j = 0; name[j] != NUL; ++j)
+ if (name[j] != cmdmod_info_tab[i].name[j])
+ break;
+ if (name[j] == NUL && j >= cmdmod_info_tab[i].minlen)
+ return (cmdmod_info_tab[i].name[j] == NUL ? 2 : 1);
}
// Check built-in commands and user defined commands.
@@ -4698,6 +4659,7 @@ get_address(
if (n == MAXLNUM)
{
emsg(_(e_line_number_out_of_range));
+ cmd = NULL;
goto error;
}
}
@@ -4728,6 +4690,7 @@ get_address(
if (lnum >= 0 && n >= LONG_MAX - lnum)
{
emsg(_(e_line_number_out_of_range));
+ cmd = NULL;
goto error;
}
lnum += n;
@@ -5401,7 +5364,11 @@ separate_nextcmd(exarg_T *eap, int keep_backslash)
&& in_vim9script()
&& !(eap->argt & EX_NOTRLCOM)
&& p > eap->cmd && VIM_ISWHITE(p[-1]))
- || *p == '|' || *p == '\n')
+ || (*p == '|'
+ && eap->cmdidx != CMD_append
+ && eap->cmdidx != CMD_change
+ && eap->cmdidx != CMD_insert)
+ || *p == '\n')
{
/*
* We remove the '\' before the '|', unless EX_CTRLV is used
@@ -5981,6 +5948,10 @@ get_command_name(expand_T *xp UNUSED, int idx)
{
if (idx >= (int)CMD_SIZE)
return expand_user_command_name(idx);
+ // the following are no real commands
+ if (STRNCMP(cmdnames[idx].cmd_name, "{", 1) == 0 ||
+ STRNCMP(cmdnames[idx].cmd_name, "}", 1) == 0)
+ return (char_u *)"";
return cmdnames[idx].cmd_name;
}
@@ -7261,7 +7232,7 @@ ex_resize(exarg_T *eap)
ex_find(exarg_T *eap)
{
if (!check_can_set_curbuf_forceit(eap->forceit))
- return;
+ return;
char_u *fname;
int count;
@@ -7353,7 +7324,7 @@ ex_edit(exarg_T *eap)
// All other commands must obey 'winfixbuf' / ! rules
&& (is_other_file(0, ffname) && !check_can_set_curbuf_forceit(eap->forceit))
)
- return;
+ return;
do_exedit(eap, NULL);
}