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.c274
1 files changed, 158 insertions, 116 deletions
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 7bf272fbba..bf518f3849 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -47,6 +47,7 @@
#include "nvim/if_cscope.h"
#include "nvim/input.h"
#include "nvim/keycodes.h"
+#include "nvim/locale.h"
#include "nvim/lua/executor.h"
#include "nvim/main.h"
#include "nvim/mapping.h"
@@ -94,6 +95,12 @@ static char e_ambiguous_use_of_user_defined_command[]
= N_("E464: Ambiguous use of user-defined command");
static char e_not_an_editor_command[]
= N_("E492: Not an editor command");
+static char e_no_source_file_name_to_substitute_for_sfile[]
+ = N_("E498: no :source file name to substitute for \"<sfile>\"");
+static char e_no_call_stack_to_substitute_for_stack[]
+ = N_("E489: no call stack to substitute for \"<stack>\"");
+static char e_no_script_file_name_to_substitute_for_script[]
+ = N_("E1274: No script file name to substitute for \"<script>\"");
static int quitmore = 0;
static bool ex_pressedreturn = false;
@@ -127,6 +134,7 @@ struct dbg_stuff {
char *vv_throwpoint;
int did_emsg;
int got_int;
+ bool did_throw;
int need_rethrow;
int check_cstack;
except_T *current_exception;
@@ -158,6 +166,7 @@ static void save_dbg_stuff(struct dbg_stuff *dsp)
// Necessary for debugging an inactive ":catch", ":finally", ":endtry".
dsp->did_emsg = did_emsg; did_emsg = false;
dsp->got_int = got_int; got_int = false;
+ dsp->did_throw = did_throw; did_throw = false;
dsp->need_rethrow = need_rethrow; need_rethrow = false;
dsp->check_cstack = check_cstack; check_cstack = false;
dsp->current_exception = current_exception; current_exception = NULL;
@@ -173,6 +182,7 @@ static void restore_dbg_stuff(struct dbg_stuff *dsp)
(void)v_throwpoint(dsp->vv_throwpoint);
did_emsg = dsp->did_emsg;
got_int = dsp->got_int;
+ did_throw = dsp->did_throw;
need_rethrow = dsp->need_rethrow;
check_cstack = dsp->check_cstack;
current_exception = dsp->current_exception;
@@ -243,8 +253,8 @@ void do_exmode(void)
RedrawingDisabled--;
no_wait_return--;
- redraw_all_later(NOT_VALID);
- update_screen(NOT_VALID);
+ redraw_all_later(UPD_NOT_VALID);
+ update_screen(UPD_NOT_VALID);
need_wait_return = false;
msg_scroll = save_msg_scroll;
}
@@ -390,7 +400,8 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
initial_trylevel = trylevel;
- current_exception = NULL;
+ // "did_throw" will be set to true when an exception is being thrown.
+ did_throw = false;
// "did_emsg" will be set to true when emsg() is used, in which case we
// cancel the whole command line, and any if/endif or loop.
// If force_abort is set, we cancel everything.
@@ -455,7 +466,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
if (breakpoint != NULL && dbg_tick != NULL
&& *dbg_tick != debug_tick) {
*breakpoint = dbg_find_breakpoint(getline_equal(fgetline, cookie, getsourceline),
- (char_u *)fname, SOURCING_LNUM);
+ fname, SOURCING_LNUM);
*dbg_tick = debug_tick;
}
@@ -464,10 +475,10 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
// Did we encounter a breakpoint?
if (breakpoint != NULL && *breakpoint != 0 && *breakpoint <= SOURCING_LNUM) {
- dbg_breakpoint((char_u *)fname, SOURCING_LNUM);
+ dbg_breakpoint(fname, SOURCING_LNUM);
// Find next breakpoint.
*breakpoint = dbg_find_breakpoint(getline_equal(fgetline, cookie, getsourceline),
- (char_u *)fname, SOURCING_LNUM);
+ fname, SOURCING_LNUM);
*dbg_tick = debug_tick;
}
if (do_profiling == PROF_YES) {
@@ -509,7 +520,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
cstack.cs_idx <
0 ? 0 : (cstack.cs_idx + 1) * 2,
true)) == NULL) {
- // Don't call wait_return for aborted command line. The NULL
+ // Don't call wait_return() for aborted command line. The NULL
// returned for the end of a sourced file or executed function
// doesn't do this.
if (KeyTyped && !(flags & DOCMD_REPEAT)) {
@@ -524,7 +535,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
if (flags & DOCMD_KEEPLINE) {
xfree(repeat_cmdline);
if (count == 0) {
- repeat_cmdline = vim_strsave((char_u *)next_cmdline);
+ repeat_cmdline = (char *)vim_strsave((char_u *)next_cmdline);
} else {
repeat_cmdline = NULL;
}
@@ -618,7 +629,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
// not to use a cs_line[] from an entry that isn't a ":while"
// or ":for": It would make "current_line" invalid and can
// cause a crash.
- if (!did_emsg && !got_int && !current_exception
+ if (!did_emsg && !got_int && !did_throw
&& cstack.cs_idx >= 0
&& (cstack.cs_flags[cstack.cs_idx]
& (CSF_WHILE | CSF_FOR))
@@ -632,8 +643,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) {
- *breakpoint = dbg_find_breakpoint(getline_equal(fgetline, cookie, getsourceline),
- (char_u *)fname,
+ *breakpoint = dbg_find_breakpoint(getline_equal(fgetline, cookie, getsourceline), fname,
((wcmd_T *)lines_ga.ga_data)[current_line].lnum - 1);
*dbg_tick = debug_tick;
}
@@ -660,7 +670,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
current_line = 0;
}
- // A ":finally" makes did_emsg, got_int and current_exception pending for
+ // A ":finally" makes did_emsg, got_int and did_throw pending for
// being restored at the ":endtry". Reset them here and set the
// ACTIVE and FINALLY flags, so that the finally clause gets executed.
// This includes the case where a missing ":endif", ":endwhile" or
@@ -669,9 +679,8 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
cstack.cs_lflags &= ~CSL_HAD_FINA;
report_make_pending((cstack.cs_pending[cstack.cs_idx]
& (CSTP_ERROR | CSTP_INTERRUPT | CSTP_THROW)),
- current_exception);
- did_emsg = got_int = false;
- current_exception = NULL;
+ did_throw ? current_exception : NULL);
+ did_emsg = got_int = did_throw = false;
cstack.cs_flags[cstack.cs_idx] |= CSF_ACTIVE | CSF_FINALLY;
}
@@ -684,7 +693,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
// exception, cancel everything. If it is left normally, reset
// force_abort to get the non-EH compatible abortion behavior for
// the rest of the script.
- if (trylevel == 0 && !did_emsg && !got_int && !current_exception) {
+ if (trylevel == 0 && !did_emsg && !got_int && !did_throw) {
force_abort = false;
}
@@ -698,7 +707,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
// - didn't get an error message or lines are not typed
// - there is a command after '|', inside a :if, :while, :for or :try, or
// looping for ":source" command or function call.
- } while (!((got_int || (did_emsg && force_abort) || current_exception)
+ } while (!((got_int || (did_emsg && force_abort) || did_throw)
&& cstack.cs_trylevel == 0)
&& !(did_emsg
// Keep going when inside try/catch, so that the error can be
@@ -718,7 +727,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
if (cstack.cs_idx >= 0) {
// If a sourced file or executed function ran to its end, report the
// unclosed conditional.
- if (!got_int && !current_exception
+ if (!got_int && !did_throw
&& ((getline_equal(fgetline, cookie, getsourceline)
&& !source_finished(fgetline, cookie))
|| (getline_equal(fgetline, cookie, get_func_line)
@@ -761,7 +770,8 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
// conditional, discard the uncaught exception, disable the conversion
// of interrupts or errors to exceptions, and ensure that no more
// commands are executed.
- if (current_exception) {
+ if (did_throw) {
+ assert(current_exception != NULL);
char *p = NULL;
msglist_T *messages = NULL;
msglist_T *next;
@@ -823,14 +833,14 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
// cstack belongs to the same function or, respectively, script file, it
// will have to be checked for finally clauses to be executed due to the
// ":return" or ":finish". This is done in do_one_cmd().
- if (current_exception) {
+ if (did_throw) {
need_rethrow = true;
}
if ((getline_equal(fgetline, cookie, getsourceline)
&& ex_nesting_level > source_level(real_cookie))
|| (getline_equal(fgetline, cookie, get_func_line)
&& ex_nesting_level > func_level(real_cookie) + 1)) {
- if (!current_exception) {
+ if (!did_throw) {
check_cstack = true;
}
} else {
@@ -844,8 +854,8 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
|| getline_equal(fgetline, cookie, get_func_line))
&& ex_nesting_level + 1 <= debug_break_level) {
do_debug(getline_equal(fgetline, cookie, getsourceline)
- ? (char_u *)_("End of sourced file")
- : (char_u *)_("End of function"));
+ ? _("End of sourced file")
+ : _("End of function"));
}
}
@@ -881,7 +891,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
need_wait_return = false;
msg_didany = false; // don't wait when restarting edit
} else if (need_wait_return) {
- // The msg_start() above clears msg_didout. The wait_return we do
+ // The msg_start() above clears msg_didout. The wait_return() we do
// here should not overwrite the command that may be shown before
// doing that.
msg_didout |= msg_didout_before_start;
@@ -1361,6 +1371,13 @@ bool is_cmd_ni(cmdidx_T cmdidx)
bool parse_cmdline(char *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo, char **errormsg)
{
char *after_modifier = NULL;
+ bool retval = false;
+ // parsing the command modifiers may set ex_pressedreturn
+ const bool save_ex_pressedreturn = ex_pressedreturn;
+ // parsing the command range may require moving the cursor
+ const pos_T save_cursor = curwin->w_cursor;
+ // parsing the command range may set the last search pattern
+ save_last_search_pattern();
// Initialize cmdinfo
CLEAR_POINTER(cmdinfo);
@@ -1375,13 +1392,10 @@ bool parse_cmdline(char *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo, char **er
.cookie = NULL,
};
- const bool save_ex_pressedreturn = ex_pressedreturn;
// Parse command modifiers
if (parse_command_modifiers(eap, errormsg, &cmdinfo->cmdmod, false) == FAIL) {
- ex_pressedreturn = save_ex_pressedreturn;
- goto err;
+ goto end;
}
- ex_pressedreturn = save_ex_pressedreturn;
after_modifier = eap->cmd;
// Save location after command modifiers
@@ -1394,21 +1408,21 @@ bool parse_cmdline(char *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo, char **er
char *p = find_ex_command(eap, NULL);
if (p == NULL) {
*errormsg = _(e_ambiguous_use_of_user_defined_command);
- goto err;
+ goto end;
}
// Set command address type and parse command range
set_cmd_addr_type(eap, p);
eap->cmd = cmd;
- if (parse_cmd_address(eap, errormsg, false) == FAIL) {
- goto err;
+ if (parse_cmd_address(eap, errormsg, true) == FAIL) {
+ goto end;
}
// Skip colon and whitespace
eap->cmd = skip_colon_white(eap->cmd, true);
// Fail if command is a comment or if command doesn't exist
if (*eap->cmd == NUL || *eap->cmd == '"') {
- goto err;
+ goto end;
}
// Fail if command is invalid
if (eap->cmdidx == CMD_SIZE) {
@@ -1417,7 +1431,7 @@ bool parse_cmdline(char *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo, char **er
char *cmdname = after_modifier ? after_modifier : cmdline;
append_command(cmdname);
*errormsg = (char *)IObuff;
- goto err;
+ goto end;
}
// Correctly set 'forceit' for commands
@@ -1456,12 +1470,12 @@ bool parse_cmdline(char *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo, char **er
// Fail if command doesn't support bang but is used with a bang
if (!(eap->argt & EX_BANG) && eap->forceit) {
*errormsg = _(e_nobang);
- goto err;
+ goto end;
}
// Fail if command doesn't support a range but it is given a range
if (!(eap->argt & EX_RANGE) && eap->addr_count > 0) {
*errormsg = _(e_norange);
- goto err;
+ goto end;
}
// Set default range for command if required
if ((eap->argt & EX_DFLALL) && eap->addr_count == 0) {
@@ -1471,7 +1485,7 @@ bool parse_cmdline(char *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo, char **er
// Parse register and count
parse_register(eap);
if (parse_count(eap, errormsg, false) == FAIL) {
- goto err;
+ goto end;
}
// Remove leading whitespace and colon from next command
@@ -1487,10 +1501,15 @@ bool parse_cmdline(char *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo, char **er
cmdinfo->magic.bar = true;
}
- return true;
-err:
- undo_cmdmod(&cmdinfo->cmdmod);
- return false;
+ retval = true;
+end:
+ if (!retval) {
+ undo_cmdmod(&cmdinfo->cmdmod);
+ }
+ ex_pressedreturn = save_ex_pressedreturn;
+ curwin->w_cursor = save_cursor;
+ restore_last_search_pattern();
+ return retval;
}
static int execute_cmd0(int *retv, exarg_T *eap, char **errormsg, bool preview)
@@ -1660,7 +1679,7 @@ static void profile_cmd(const exarg_T *eap, cstack_T *cstack, LineGetter fgetlin
&& (!eap->skip || cstack->cs_idx == 0
|| (cstack->cs_idx > 0
&& (cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE)))) {
- int skip = did_emsg || got_int || current_exception;
+ bool skip = did_emsg || got_int || did_throw;
if (eap->cmdidx == CMD_catch) {
skip = !skip && !(cstack->cs_idx >= 0
@@ -1857,7 +1876,7 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter
ea.skip = (did_emsg
|| got_int
- || current_exception
+ || did_throw
|| (cstack->cs_idx >= 0
&& !(cstack->cs_flags[cstack->cs_idx] & CSF_ACTIVE)));
@@ -2565,7 +2584,7 @@ static void apply_cmdmod(cmdmod_T *cmod)
if ((cmod->cmod_flags & CMOD_NOAUTOCMD) && cmod->cmod_save_ei == NULL) {
// Set 'eventignore' to "all".
// First save the existing option value for restoring it later.
- cmod->cmod_save_ei = (char *)vim_strsave(p_ei);
+ cmod->cmod_save_ei = xstrdup(p_ei);
set_string_option_direct("ei", -1, "all", OPT_FREE, SID_NONE);
}
}
@@ -2587,7 +2606,7 @@ void undo_cmdmod(cmdmod_T *cmod)
if (cmod->cmod_save_ei != NULL) {
// Restore 'eventignore' to the value before ":noautocmd".
set_string_option_direct("ei", -1, cmod->cmod_save_ei, OPT_FREE, SID_NONE);
- free_string_option((char_u *)cmod->cmod_save_ei);
+ free_string_option(cmod->cmod_save_ei);
cmod->cmod_save_ei = NULL;
}
@@ -3038,7 +3057,7 @@ int cmd_exists(const char *const name)
}
/// "fullcommand" function
-void f_fullcommand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+void f_fullcommand(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
char *name = argvars[0].vval.v_string;
@@ -3072,7 +3091,7 @@ cmdidx_T excmd_get_cmdidx(const char *cmd, size_t len)
{
cmdidx_T idx;
- for (idx = (cmdidx_T)0; (int)idx < (int)CMD_SIZE; idx = (cmdidx_T)((int)idx + 1)) {
+ for (idx = (cmdidx_T)0; (int)idx < CMD_SIZE; idx = (cmdidx_T)((int)idx + 1)) {
if (strncmp(cmdnames[(int)idx].cmd_name, cmd, len) == 0) {
break;
}
@@ -3294,7 +3313,7 @@ static linenr_T get_address(exarg_T *eap, char **ptr, cmd_addr_T addr_type, int
goto error;
}
if (skip) { // skip "/pat/"
- cmd = (char *)skip_regexp((char_u *)cmd, c, p_magic, NULL);
+ cmd = skip_regexp(cmd, c, p_magic, NULL);
if (*cmd == c) {
cmd++;
}
@@ -3570,6 +3589,9 @@ char *invalid_range(exarg_T *eap)
assert(eap->line2 >= 0);
// No error for value that is too big, will use the last entry.
if (eap->line2 <= 0) {
+ if (eap->addr_count == 0) {
+ return _(e_no_errors);
+ }
return _(e_invrange);
}
break;
@@ -3631,8 +3653,8 @@ 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 : (char *)curbuf->b_p_gp)
- : (*curbuf->b_p_mp == NUL ? (char *)p_mp : (char *)curbuf->b_p_mp);
+ const char *program = isgrep ? (*curbuf->b_p_gp == NUL ? (char *)p_gp : curbuf->b_p_gp)
+ : (*curbuf->b_p_mp == NUL ? (char *)p_mp : curbuf->b_p_mp);
arg = skipwhite(arg);
@@ -3646,7 +3668,7 @@ char *replace_makeprg(exarg_T *eap, char *arg, char **cmdlinep)
STRCAT(new_cmdline, arg);
}
- msg_make((char_u *)arg);
+ msg_make(arg);
// 'eap->cmd' is not set here, because it is not used at CMD_make
xfree(*cmdlinep);
@@ -3690,7 +3712,7 @@ int expand_filename(exarg_T *eap, char **cmdlinep, char **errormsgp)
size_t srclen;
int escaped;
char *repl = (char *)eval_vars((char_u *)p, (char_u *)eap->arg, &srclen, &(eap->do_ecmd_lnum),
- errormsgp, &escaped);
+ errormsgp, &escaped, true);
if (*errormsgp != NULL) { // error detected
return FAIL;
}
@@ -3772,8 +3794,8 @@ int expand_filename(exarg_T *eap, char **cmdlinep, char **errormsgp)
// if there are still wildcards present.
if (vim_strchr(eap->arg, '$') != NULL
|| vim_strchr(eap->arg, '~') != NULL) {
- expand_env_esc((char_u *)eap->arg, NameBuff, MAXPATHL, true, true, NULL);
- has_wildcards = path_has_wildcard(NameBuff);
+ 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;
} else {
p = NULL;
@@ -3788,7 +3810,7 @@ int expand_filename(exarg_T *eap, char **cmdlinep, char **errormsgp)
// done by ExpandOne() below.
#ifdef UNIX
if (!has_wildcards) {
- backslash_halve((char_u *)eap->arg);
+ backslash_halve(eap->arg);
}
#else
backslash_halve((char_u *)eap->arg);
@@ -4042,7 +4064,7 @@ static int getargopt(exarg_T *eap)
*arg = NUL;
if (pp == &eap->force_ff) {
- if (check_ff_value((char_u *)eap->cmd + eap->force_ff) == FAIL) {
+ if (check_ff_value(eap->cmd + eap->force_ff) == FAIL) {
return FAIL;
}
eap->force_ff = (char_u)eap->cmd[eap->force_ff];
@@ -4276,7 +4298,7 @@ int ends_excmd(int c) FUNC_ATTR_CONST
/// @return the next command, after the first '|' or '\n' or,
/// NULL if not found.
-char_u *find_nextcmd(const char_u *p)
+char *find_nextcmd(const char *p)
{
while (*p != '|' && *p != '\n') {
if (*p == NUL) {
@@ -4284,7 +4306,7 @@ char_u *find_nextcmd(const char_u *p)
}
p++;
}
- return (char_u *)p + 1;
+ return (char *)p + 1;
}
/// Check if *p is a separator between Ex commands, skipping over white space.
@@ -5013,7 +5035,7 @@ static void ex_tabs(exarg_T *eap)
msg_putchar('\n');
vim_snprintf((char *)IObuff, IOSIZE, _("Tab page %d"), tabcount++);
- msg_outtrans_attr(IObuff, HL_ATTR(HLF_T));
+ msg_outtrans_attr((char *)IObuff, HL_ATTR(HLF_T));
ui_flush(); // output one line at a time
os_breakcheck();
@@ -5044,7 +5066,7 @@ static void ex_tabs(exarg_T *eap)
static void ex_mode(exarg_T *eap)
{
if (*eap->arg == NUL) {
- must_redraw = CLEAR;
+ must_redraw = UPD_CLEAR;
ex_redraw(eap);
} else {
emsg(_(e_screenmode));
@@ -5136,7 +5158,7 @@ void do_exedit(exarg_T *eap, win_T *old_curwin)
no_wait_return = 0;
need_wait_return = false;
msg_scroll = 0;
- redraw_all_later(NOT_VALID);
+ redraw_all_later(UPD_NOT_VALID);
pending_exmode_active = true;
normal_enter(false, true);
@@ -5298,7 +5320,7 @@ static void ex_syncbind(exarg_T *eap)
scrolldown(-y, true);
}
curwin->w_scbind_pos = topline;
- redraw_later(curwin, VALID);
+ redraw_later(curwin, UPD_VALID);
cursor_correct();
curwin->w_redr_status = true;
}
@@ -5366,7 +5388,7 @@ static void ex_read(exarg_T *eap)
deleted_lines_mark(lnum, 1L);
}
}
- redraw_curbuf_later(VALID);
+ redraw_curbuf_later(UPD_VALID);
}
}
}
@@ -5466,8 +5488,8 @@ bool changedir_func(char *new_dir, CdScope scope)
new_dir = pdir;
}
- if (os_dirname(NameBuff, MAXPATHL) == OK) {
- pdir = (char *)vim_strsave(NameBuff);
+ if (os_dirname((char_u *)NameBuff, MAXPATHL) == OK) {
+ pdir = xstrdup(NameBuff);
} else {
pdir = NULL;
}
@@ -5480,7 +5502,7 @@ bool changedir_func(char *new_dir, CdScope scope)
if (*new_dir == NUL && p_cdh) {
#endif
// Use NameBuff for home directory name.
- expand_env((char_u *)"$HOME", NameBuff, MAXPATHL);
+ expand_env("$HOME", NameBuff, MAXPATHL);
new_dir = (char *)NameBuff;
}
@@ -5549,7 +5571,7 @@ void ex_cd(exarg_T *eap)
/// ":pwd".
static void ex_pwd(exarg_T *eap)
{
- if (os_dirname(NameBuff, MAXPATHL) == OK) {
+ if (os_dirname((char_u *)NameBuff, MAXPATHL) == OK) {
#ifdef BACKSLASH_IN_FILENAME
slash_adjust(NameBuff);
#endif
@@ -6037,11 +6059,11 @@ static void ex_redraw(exarg_T *eap)
validate_cursor();
update_topline(curwin);
if (eap->forceit) {
- redraw_all_later(NOT_VALID);
+ redraw_all_later(UPD_NOT_VALID);
redraw_cmdline = true;
}
- update_screen(eap->forceit ? NOT_VALID
- : VIsual_active ? INVERTED : 0);
+ update_screen(eap->forceit ? UPD_NOT_VALID
+ : VIsual_active ? UPD_INVERTED : 0);
if (need_maketitle) {
maketitle();
}
@@ -6074,7 +6096,7 @@ static void ex_redrawstatus(exarg_T *eap)
} else {
status_redraw_curbuf();
}
- update_screen(VIsual_active ? INVERTED : 0);
+ update_screen(VIsual_active ? UPD_INVERTED : 0);
RedrawingDisabled = r;
p_lz = p;
ui_flush();
@@ -6135,7 +6157,7 @@ FILE *open_exfile(char_u *fname, int forceit, char *mode)
{
#ifdef UNIX
// with Unix it is possible to open a directory
- if (os_isdir(fname)) {
+ if (os_isdir((char *)fname)) {
semsg(_(e_isadir2), fname);
return NULL;
}
@@ -6435,7 +6457,7 @@ static void ex_findpat(exarg_T *eap)
if (*eap->arg == '/') { // Match regexp, not just whole words
whole = false;
eap->arg++;
- char *p = (char *)skip_regexp((char_u *)eap->arg, '/', p_magic, NULL);
+ char *p = skip_regexp(eap->arg, '/', p_magic, NULL);
if (*p) {
*p++ = NUL;
p = skipwhite(p);
@@ -6477,7 +6499,7 @@ static void ex_pedit(exarg_T *eap)
if (curwin != curwin_save && win_valid(curwin_save)) {
// Return cursor to where we were
validate_cursor();
- redraw_later(curwin, VALID);
+ redraw_later(curwin, UPD_VALID);
win_enter(curwin_save, true);
}
g_do_tagpreview = 0;
@@ -6555,6 +6577,7 @@ enum {
SPEC_SFILE,
SPEC_SLNUM,
SPEC_STACK,
+ SPEC_SCRIPT,
SPEC_AFILE,
SPEC_ABUF,
SPEC_AMATCH,
@@ -6579,6 +6602,7 @@ ssize_t find_cmdline_var(const char_u *src, size_t *usedlen)
[SPEC_SFILE] = "<sfile>", // ":so" file name
[SPEC_SLNUM] = "<slnum>", // ":so" file line number
[SPEC_STACK] = "<stack>", // call stack
+ [SPEC_SCRIPT] = "<script>", // script file name
[SPEC_AFILE] = "<afile>", // autocommand file name
[SPEC_ABUF] = "<abuf>", // autocommand buffer number
[SPEC_AMATCH] = "<amatch>", // autocommand match name
@@ -6600,34 +6624,36 @@ ssize_t find_cmdline_var(const char_u *src, size_t *usedlen)
/// Evaluate cmdline variables.
///
-/// change '%' to curbuf->b_ffname
-/// '#' to curwin->w_alt_fnum
-/// '<cword>' to word under the cursor
-/// '<cWORD>' to WORD under the cursor
-/// '<cexpr>' to C-expression under the cursor
-/// '<cfile>' to path name under the cursor
-/// '<sfile>' to sourced file name
-/// '<stack>' to call stack
-/// '<slnum>' to sourced file line number
-/// '<afile>' to file name for autocommand
-/// '<abuf>' to buffer number for autocommand
-/// '<amatch>' to matching name for autocommand
+/// change "%" to curbuf->b_ffname
+/// "#" to curwin->w_alt_fnum
+/// "<cword>" to word under the cursor
+/// "<cWORD>" to WORD under the cursor
+/// "<cexpr>" to C-expression under the cursor
+/// "<cfile>" to path name under the cursor
+/// "<sfile>" to sourced file name
+/// "<stack>" to call stack
+/// "<script>" to current script name
+/// "<slnum>" to sourced file line number
+/// "<afile>" to file name for autocommand
+/// "<abuf>" to buffer number for autocommand
+/// "<amatch>" to matching name for autocommand
///
/// When an error is detected, "errormsg" is set to a non-NULL pointer (may be
/// "" for error without a message) and NULL is returned.
///
-/// @param src pointer into commandline
-/// @param srcstart beginning of valid memory for src
-/// @param usedlen characters after src that are used
-/// @param lnump line number for :e command, or NULL
-/// @param errormsg pointer to error message
-/// @param escaped return value has escaped white space (can be NULL)
+/// @param src pointer into commandline
+/// @param srcstart beginning of valid memory for src
+/// @param usedlen characters after src that are used
+/// @param lnump line number for :e command, or NULL
+/// @param errormsg pointer to error message
+/// @param escaped return value has escaped white space (can be NULL)
+/// @param empty_is_error empty result is considered an error
///
/// @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)
+ int *escaped, bool empty_is_error)
{
char *result;
char *resultbuf = NULL;
@@ -6792,12 +6818,25 @@ 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 = estack_sfile(ESTACK_SFILE);
+ if (result == NULL) {
+ *errormsg = _(e_no_source_file_name_to_substitute_for_sfile);
+ return NULL;
+ }
+ resultbuf = result; // remember allocated string
+ break;
case SPEC_STACK: // call stack
- result = estack_sfile(spec_idx == SPEC_SFILE ? ESTACK_SFILE : ESTACK_STACK);
+ result = estack_sfile(ESTACK_STACK);
if (result == NULL) {
- *errormsg = spec_idx == SPEC_SFILE
- ? _("E498: no :source file name to substitute for \"<sfile>\"")
- : _("E489: no call stack to substitute for \"<stack>\"");
+ *errormsg = _(e_no_call_stack_to_substitute_for_stack);
+ return NULL;
+ }
+ resultbuf = result; // remember allocated string
+ break;
+ case SPEC_SCRIPT: // script file name
+ result = estack_sfile(ESTACK_SCRIPT);
+ if (result == NULL) {
+ *errormsg = _(e_no_script_file_name_to_substitute_for_script);
return NULL;
}
resultbuf = result; // remember allocated string
@@ -6845,7 +6884,7 @@ char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnum
if (src[*usedlen] == '<') {
(*usedlen)++;
char *s;
- if ((s = (char *)STRRCHR(result, '.')) != NULL
+ if ((s = strrchr(result, '.')) != NULL
&& s >= path_tail(result)) {
resultlen = (size_t)(s - result);
}
@@ -6860,11 +6899,13 @@ char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnum
}
if (resultlen == 0 || valid != VALID_HEAD + VALID_PATH) {
- if (valid != VALID_HEAD + VALID_PATH) {
- // xgettext:no-c-format
- *errormsg = _("E499: Empty file name for '%' or '#', only works with \":p:h\"");
- } else {
- *errormsg = _("E500: Evaluates to an empty string");
+ if (empty_is_error) {
+ if (valid != VALID_HEAD + VALID_PATH) {
+ // xgettext:no-c-format
+ *errormsg = _("E499: Empty file name for '%' or '#', only works with \":p:h\"");
+ } else {
+ *errormsg = _("E500: Evaluates to an empty string");
+ }
}
result = NULL;
} else {
@@ -6888,7 +6929,8 @@ 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);
+ char *repl = (char *)eval_vars((char_u *)p, (char_u *)result, &srclen, NULL, &errormsg, NULL,
+ true);
if (errormsg != NULL) {
if (*errormsg) {
emsg(errormsg);
@@ -6919,16 +6961,16 @@ char *expand_sfile(char *arg)
/// ":rshada" and ":wshada".
static void ex_shada(exarg_T *eap)
{
- char *save_shada = (char *)p_shada;
+ char *save_shada = p_shada;
if (*p_shada == NUL) {
- p_shada = (char_u *)"'100";
+ p_shada = "'100";
}
if (eap->cmdidx == CMD_rviminfo || eap->cmdidx == CMD_rshada) {
(void)shada_read_everything(eap->arg, eap->forceit, false);
} else {
shada_write_file(eap->arg, eap->forceit);
}
- p_shada = (char_u *)save_shada;
+ p_shada = save_shada;
}
/// Make a dialog message in "buff[DIALOG_MSG_SIZE]".
@@ -6945,15 +6987,15 @@ void dialog_msg(char *buff, char *format, char *fname)
static void ex_behave(exarg_T *eap)
{
if (STRCMP(eap->arg, "mswin") == 0) {
- set_option_value("selection", 0L, "exclusive", 0);
- set_option_value("selectmode", 0L, "mouse,key", 0);
- set_option_value("mousemodel", 0L, "popup", 0);
- set_option_value("keymodel", 0L, "startsel,stopsel", 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) {
- set_option_value("selection", 0L, "inclusive", 0);
- set_option_value("selectmode", 0L, "", 0);
- set_option_value("mousemodel", 0L, "extend", 0);
- set_option_value("keymodel", 0L, "", 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);
+ set_option_value_give_err("keymodel", 0L, "", 0);
} else {
semsg(_(e_invarg2), eap->arg);
}
@@ -7073,7 +7115,7 @@ static void ex_setfiletype(exarg_T *eap)
arg += 9;
}
- set_option_value("filetype", 0L, arg, OPT_LOCAL);
+ set_option_value_give_err("filetype", 0L, arg, OPT_LOCAL);
if (arg != eap->arg) {
did_filetype = false;
}
@@ -7099,7 +7141,7 @@ void set_no_hlsearch(bool flag)
static void ex_nohlsearch(exarg_T *eap)
{
set_no_hlsearch(true);
- redraw_all_later(SOME_VALID);
+ redraw_all_later(UPD_SOME_VALID);
}
static void ex_fold(exarg_T *eap)