aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/autocmd.c18
-rw-r--r--src/nvim/buffer.c25
-rw-r--r--src/nvim/buffer_defs.h14
-rw-r--r--src/nvim/channel.c20
-rw-r--r--src/nvim/charset.c4
-rw-r--r--src/nvim/context.c2
-rw-r--r--src/nvim/diff.c2
-rw-r--r--src/nvim/edit.c5
-rw-r--r--src/nvim/eval.c47
-rw-r--r--src/nvim/eval.h4
-rw-r--r--src/nvim/eval/decode.c4
-rw-r--r--src/nvim/eval/encode.c4
-rw-r--r--src/nvim/eval/executor.c2
-rw-r--r--src/nvim/eval/funcs.c202
-rw-r--r--src/nvim/eval/typval.c37
-rw-r--r--src/nvim/event/libuv_process.c14
-rw-r--r--src/nvim/event/process.c3
-rw-r--r--src/nvim/event/process.h3
-rw-r--r--src/nvim/ex_cmds.c38
-rw-r--r--src/nvim/ex_cmds2.c8
-rw-r--r--src/nvim/ex_cmds_defs.h4
-rw-r--r--src/nvim/ex_docmd.c27
-rw-r--r--src/nvim/ex_getln.c4
-rw-r--r--src/nvim/file_search.c2
-rw-r--r--src/nvim/fileio.c5
-rw-r--r--src/nvim/fold.c7
-rw-r--r--src/nvim/globals.h2
-rw-r--r--src/nvim/lua/converter.c6
-rw-r--r--src/nvim/main.c6
-rw-r--r--src/nvim/memline_defs.h8
-rw-r--r--src/nvim/menu.c8
-rw-r--r--src/nvim/ops.c4
-rw-r--r--src/nvim/option.c24
-rw-r--r--src/nvim/option_defs.h13
-rw-r--r--src/nvim/options.lua8
-rw-r--r--src/nvim/os/pty_process_unix.c35
-rw-r--r--src/nvim/os/pty_process_unix.h1
-rw-r--r--src/nvim/os/pty_process_win.c78
-rw-r--r--src/nvim/os/pty_process_win.h1
-rw-r--r--src/nvim/os/time.c2
-rw-r--r--src/nvim/quickfix.c8
-rw-r--r--src/nvim/screen.c21
-rw-r--r--src/nvim/shada.c16
-rw-r--r--src/nvim/sign_defs.h4
-rw-r--r--src/nvim/spell.c2
-rw-r--r--src/nvim/spellfile.c3
-rw-r--r--src/nvim/syntax.c8
-rw-r--r--src/nvim/tag.c2
-rw-r--r--src/nvim/terminal.c57
-rw-r--r--src/nvim/testdir/test_autocmd.vim34
-rw-r--r--src/nvim/testdir/test_compiler.vim18
-rw-r--r--src/nvim/testdir/test_eval_stuff.vim11
-rw-r--r--src/nvim/testdir/test_excmd.vim8
-rw-r--r--src/nvim/testdir/test_mksession.vim26
-rw-r--r--src/nvim/testdir/test_options.vim4
-rw-r--r--src/nvim/testdir/test_quickfix.vim19
-rw-r--r--src/nvim/testdir/test_window_cmd.vim4
-rw-r--r--src/nvim/tui/input.c2
-rw-r--r--src/nvim/ui_compositor.c2
-rw-r--r--src/nvim/version.c6
-rw-r--r--src/nvim/viml/parser/expressions.c6
61 files changed, 658 insertions, 304 deletions
diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c
index 42224d0a4f..3de2e0f342 100644
--- a/src/nvim/autocmd.c
+++ b/src/nvim/autocmd.c
@@ -544,7 +544,7 @@ char_u *au_event_disable(char *what)
} else {
STRCAT(new_ei, what);
}
- set_string_option_direct((char_u *)"ei", -1, new_ei, OPT_FREE, SID_NONE);
+ set_string_option_direct("ei", -1, new_ei, OPT_FREE, SID_NONE);
xfree(new_ei);
return save_ei;
@@ -553,7 +553,7 @@ char_u *au_event_disable(char *what)
void au_event_restore(char_u *old_ei)
{
if (old_ei != NULL) {
- set_string_option_direct((char_u *)"ei", -1, old_ei, OPT_FREE, SID_NONE);
+ set_string_option_direct("ei", -1, old_ei, OPT_FREE, SID_NONE);
xfree(old_ei);
}
}
@@ -700,11 +700,15 @@ void do_autocmd(char_u *arg_in, int forceit)
last_event = (event_T)-1; // for listing the event name
last_group = AUGROUP_ERROR; // for listing the group name
if (*arg == '*' || *arg == NUL || *arg == '|') {
- for (event_T event = (event_T)0; event < (int)NUM_EVENTS;
- event = (event_T)(event + 1)) {
- if (do_autocmd_event(event, pat, once, nested, cmd, forceit, group)
- == FAIL) {
- break;
+ if (!forceit && *cmd != NUL) {
+ EMSG(_(e_cannot_define_autocommands_for_all_events));
+ } else {
+ for (event_T event = (event_T)0; event < (int)NUM_EVENTS;
+ event = (event_T)(event + 1)) {
+ if (do_autocmd_event(event, pat, once, nested, cmd, forceit, group)
+ == FAIL) {
+ break;
+ }
}
}
} else {
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 0134ee838d..19ce02700f 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -3236,7 +3236,7 @@ void maketitle(void)
0, maxlen, NULL, NULL);
title_str = (char_u *)buf;
if (called_emsg) {
- set_string_option_direct((char_u *)"titlestring", -1, (char_u *)"",
+ set_string_option_direct("titlestring", -1, (char_u *)"",
OPT_FREE, SID_ERROR);
}
called_emsg |= save_called_emsg;
@@ -3270,7 +3270,7 @@ void maketitle(void)
case 6: buf_p = strappend(buf_p, " -"); break;
case 5:
case 7: buf_p = strappend(buf_p, " -+"); break;
- default: assert(false);
+ default: abort();
}
if (curbuf->b_fname != NULL) {
@@ -3346,7 +3346,7 @@ void maketitle(void)
p_iconstring, use_sandbox,
0, 0, NULL, NULL);
if (called_emsg) {
- set_string_option_direct((char_u *)"iconstring", -1,
+ set_string_option_direct("iconstring", -1,
(char_u *)"", OPT_FREE, SID_ERROR);
}
called_emsg |= save_called_emsg;
@@ -3486,7 +3486,7 @@ int build_stl_str_hl(
stl_items = xmalloc(sizeof(stl_item_t) * stl_items_len);
stl_groupitems = xmalloc(sizeof(int) * stl_items_len);
stl_hltab = xmalloc(sizeof(stl_hlrec_t) * stl_items_len);
- stl_tabtab = xmalloc(sizeof(stl_hlrec_t) * stl_items_len);
+ stl_tabtab = xmalloc(sizeof(StlClickRecord) * stl_items_len);
stl_separator_locations = xmalloc(sizeof(int) * stl_items_len);
}
@@ -3940,9 +3940,9 @@ int build_stl_str_hl(
// Store the current buffer number as a string variable
vim_snprintf((char *)buf_tmp, sizeof(buf_tmp), "%d", curbuf->b_fnum);
- set_internal_string_var((char_u *)"g:actual_curbuf", buf_tmp);
+ set_internal_string_var("g:actual_curbuf", buf_tmp);
vim_snprintf((char *)win_tmp, sizeof(win_tmp), "%d", curwin->handle);
- set_internal_string_var((char_u *)"g:actual_curwin", win_tmp);
+ set_internal_string_var("g:actual_curwin", win_tmp);
buf_T *const save_curbuf = curbuf;
win_T *const save_curwin = curwin;
@@ -4482,22 +4482,15 @@ int build_stl_str_hl(
int num_separators = 0;
for (int i = 0; i < itemcnt; i++) {
if (stl_items[i].type == Separate) {
+ // Create an array of the start location for each
+ // separator mark.
+ stl_separator_locations[num_separators] = i;
num_separators++;
}
}
// If we have separated groups, then we deal with it now
if (num_separators) {
- // Create an array of the start location for each
- // separator mark.
- int index = 0;
- for (int i = 0; i < itemcnt; i++) {
- if (stl_items[i].type == Separate) {
- stl_separator_locations[index] = i;
- index++;
- }
- }
-
int standard_spaces = (maxwidth - width) / num_separators;
int final_spaces = (maxwidth - width) -
standard_spaces * (num_separators - 1);
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index cc09b7e989..360616609c 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -296,13 +296,11 @@ typedef struct arglist {
int id; ///< id of this arglist
} alist_T;
-/*
- * For each argument remember the file name as it was given, and the buffer
- * number that contains the expanded file name (required for when ":cd" is
- * used.
- *
- * TODO: move aentry_T to another header
- */
+// For each argument remember the file name as it was given, and the buffer
+// number that contains the expanded file name (required for when ":cd" is
+// used).
+//
+// TODO(Felipe): move aentry_T to another header
typedef struct argentry {
char_u *ae_fname; // file name as specified
int ae_fnum; // buffer number with expanded file name
@@ -1036,10 +1034,10 @@ struct matchitem {
int id; ///< match ID
int priority; ///< match priority
char_u *pattern; ///< pattern to highlight
- int hlg_id; ///< highlight group ID
regmmatch_T match; ///< regexp program for pattern
posmatch_T pos; ///< position matches
match_T hl; ///< struct for doing the actual highlighting
+ int hlg_id; ///< highlight group ID
int conceal_char; ///< cchar for Conceal highlighting
};
diff --git a/src/nvim/channel.c b/src/nvim/channel.c
index 37cbfb968b..09a34ca9fe 100644
--- a/src/nvim/channel.c
+++ b/src/nvim/channel.c
@@ -292,7 +292,6 @@ static void close_cb(Stream *stream, void *data)
/// directory if `cwd` is NULL
/// @param[in] pty_width Width of the pty, ignored if `pty` is false
/// @param[in] pty_height Height of the pty, ignored if `pty` is false
-/// @param[in] term_name `$TERM` for the pty
/// @param[in] env Nvim's configured environment is used if this is NULL,
/// otherwise defines all environment variables
/// @param[out] status_out 0 for invalid arguments, > 0 for the channel id,
@@ -304,7 +303,7 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout,
bool pty, bool rpc, bool overlapped, bool detach,
const char *cwd,
uint16_t pty_width, uint16_t pty_height,
- char *term_name, char **env, varnumber_T *status_out)
+ dict_T *env, varnumber_T *status_out)
{
assert(cwd == NULL || os_isdir_executable(cwd));
@@ -317,7 +316,9 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout,
if (detach) {
EMSG2(_(e_invarg2), "terminal/pty job cannot be detached");
shell_free_argv(argv);
- xfree(term_name);
+ if (env) {
+ tv_dict_free(env);
+ }
channel_destroy_early(chan);
*status_out = 0;
return NULL;
@@ -329,9 +330,6 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout,
if (pty_height > 0) {
chan->stream.pty.height = pty_height;
}
- if (term_name) {
- chan->stream.pty.term_name = term_name;
- }
} else {
chan->stream.uv = libuv_process_init(&main_loop, chan);
}
@@ -358,17 +356,17 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout,
if (status) {
EMSG3(_(e_jobspawn), os_strerror(status), cmd);
xfree(cmd);
- os_free_fullenv(proc->env);
- if (proc->type == kProcessTypePty) {
- xfree(chan->stream.pty.term_name);
+ if (proc->env) {
+ tv_dict_free(proc->env);
}
channel_destroy_early(chan);
*status_out = proc->status;
return NULL;
}
xfree(cmd);
- os_free_fullenv(proc->env);
-
+ if (proc->env) {
+ tv_dict_free(proc->env);
+ }
wstream_init(&proc->in, 0);
if (has_out) {
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index 3e52b3e3ce..be265e3f27 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -1747,7 +1747,7 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
goto vim_str2nr_dec;
}
default: {
- assert(false);
+ abort();
}
}
} else if ((what & (STR2NR_HEX|STR2NR_OCT|STR2NR_BIN))
@@ -1788,7 +1788,7 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
}
// Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
- assert(false); // Should’ve used goto earlier.
+ abort(); // Should’ve used goto earlier.
#define PARSE_NUMBER(base, cond, conv) \
do { \
while (!STRING_ENDED(ptr) && (cond)) { \
diff --git a/src/nvim/context.c b/src/nvim/context.c
index 1ae0510762..4162daa6ca 100644
--- a/src/nvim/context.c
+++ b/src/nvim/context.c
@@ -126,7 +126,7 @@ bool ctx_restore(Context *ctx, const int flags)
}
char_u *op_shada;
- get_option_value((char_u *)"shada", NULL, &op_shada, OPT_GLOBAL);
+ get_option_value("shada", NULL, &op_shada, OPT_GLOBAL);
set_option_value("shada", 0L, "!,'100,%", OPT_GLOBAL);
if (flags & kCtxRegs) {
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index 93bc34fa4b..358725239c 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -1375,7 +1375,7 @@ void diff_win_options(win_T *wp, int addbuf)
}
wp->w_p_fdm_save = vim_strsave(wp->w_p_fdm);
}
- set_string_option_direct((char_u *)"fdm", -1, (char_u *)"diff",
+ set_string_option_direct("fdm", -1, (char_u *)"diff",
OPT_LOCAL | OPT_FREE, 0);
curwin = old_curwin;
curbuf = curwin->w_buffer;
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index b2abb06075..100e88e261 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -313,6 +313,11 @@ static void insert_enter(InsertState *s)
set_vim_var_string(VV_CHAR, NULL, -1);
ins_apply_autocmds(EVENT_INSERTENTER);
+ // Check for changed highlighting, e.g. for ModeMsg.
+ if (need_highlight_changed) {
+ highlight_changed();
+ }
+
// Make sure the cursor didn't move. Do call check_cursor_col() in
// case the text was modified. Since Insert mode was not started yet
// a call to check_cursor_col() may move the cursor, especially with
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 8a1556320c..d07618d2c0 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -365,7 +365,7 @@ void eval_init(void)
eval_msgpack_type_lists[i] = type_list;
if (tv_dict_add(msgpack_types_dict, di) == FAIL) {
// There must not be duplicate items in this dictionary by definition.
- assert(false);
+ abort();
}
}
msgpack_types_dict->dv_lock = VAR_FIXED;
@@ -455,14 +455,15 @@ void eval_clear(void)
* Set an internal variable to a string value. Creates the variable if it does
* not already exist.
*/
-void set_internal_string_var(char_u *name, char_u *value)
+void set_internal_string_var(const char *name, char_u *value)
+ FUNC_ATTR_NONNULL_ARG(1)
{
- const typval_T tv = {
+ typval_T tv = {
.v_type = VAR_STRING,
.vval.v_string = value,
};
- set_var((const char *)name, STRLEN(name), (typval_T *)&tv, true);
+ set_var(name, strlen(name), &tv, true);
}
static lval_T *redir_lval = NULL;
@@ -522,9 +523,9 @@ var_redir_start(
tv.v_type = VAR_STRING;
tv.vval.v_string = (char_u *)"";
if (append) {
- set_var_lval(redir_lval, redir_endp, &tv, true, false, (char_u *)".");
+ set_var_lval(redir_lval, redir_endp, &tv, true, false, ".");
} else {
- set_var_lval(redir_lval, redir_endp, &tv, true, false, (char_u *)"=");
+ set_var_lval(redir_lval, redir_endp, &tv, true, false, "=");
}
clear_lval(redir_lval);
err = did_emsg;
@@ -584,7 +585,7 @@ void var_redir_stop(void)
redir_endp = (char_u *)get_lval(redir_varname, NULL, redir_lval,
false, false, 0, FNE_CHECK_START);
if (redir_endp != NULL && redir_lval->ll_name != NULL) {
- set_var_lval(redir_lval, redir_endp, &tv, false, false, (char_u *)".");
+ set_var_lval(redir_lval, redir_endp, &tv, false, false, ".");
}
clear_lval(redir_lval);
}
@@ -1847,7 +1848,7 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv,
s = tv_get_string_chk(tv); // != NULL if number or string.
}
if (s != NULL && op != NULL && *op != '=') {
- opt_type = get_option_value(arg, &numval, (char_u **)&stringval,
+ opt_type = get_option_value((char *)arg, &numval, (char_u **)&stringval,
opt_flags);
if ((opt_type == 1 && *op == '.')
|| (opt_type == 0 && *op != '.')) {
@@ -1924,7 +1925,7 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv,
if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) {
EMSG(_(e_letunexp));
} else {
- set_var_lval(&lv, p, tv, copy, is_const, op);
+ set_var_lval(&lv, p, tv, copy, is_const, (const char *)op);
arg_end = p;
}
}
@@ -2121,9 +2122,10 @@ char_u *get_lval(char_u *const name, typval_T *const rettv,
return NULL;
}
}
- lp->ll_range = TRUE;
- } else
- lp->ll_range = FALSE;
+ lp->ll_range = true;
+ } else {
+ lp->ll_range = false;
+ }
if (*p != ']') {
if (!quiet) {
@@ -2240,12 +2242,10 @@ char_u *get_lval(char_u *const name, typval_T *const rettv,
return NULL;
}
- /*
- * May need to find the item or absolute index for the second
- * index of a range.
- * When no index given: "lp->ll_empty2" is TRUE.
- * Otherwise "lp->ll_n2" is set to the second index.
- */
+ // May need to find the item or absolute index for the second
+ // index of a range.
+ // When no index given: "lp->ll_empty2" is true.
+ // Otherwise "lp->ll_n2" is set to the second index.
if (lp->ll_range && !lp->ll_empty2) {
lp->ll_n2 = (long)tv_get_number(&var2); // Is number or string.
tv_clear(&var2);
@@ -2299,7 +2299,7 @@ void clear_lval(lval_T *lp)
* "%" for "%=", "." for ".=" or "=" for "=".
*/
static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv,
- int copy, const bool is_const, const char_u *op)
+ int copy, const bool is_const, const char *op)
{
int cc;
listitem_T *ri;
@@ -2326,7 +2326,7 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv,
TV_CSTRING)
&& !tv_check_lock(di->di_tv.v_lock, (const char *)lp->ll_name,
TV_CSTRING)))
- && eexe_mod_op(&tv, rettv, (const char *)op) == OK) {
+ && eexe_mod_op(&tv, rettv, op) == OK) {
set_var(lp->ll_name, lp->ll_name_len, &tv, false);
}
tv_clear(&tv);
@@ -2369,8 +2369,7 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv,
*/
for (ri = tv_list_first(rettv->vval.v_list); ri != NULL; ) {
if (op != NULL && *op != '=') {
- eexe_mod_op(TV_LIST_ITEM_TV(lp->ll_li), TV_LIST_ITEM_TV(ri),
- (const char *)op);
+ eexe_mod_op(TV_LIST_ITEM_TV(lp->ll_li), TV_LIST_ITEM_TV(ri), op);
} else {
tv_clear(TV_LIST_ITEM_TV(lp->ll_li));
tv_copy(TV_LIST_ITEM_TV(ri), TV_LIST_ITEM_TV(lp->ll_li));
@@ -2428,7 +2427,7 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv,
}
if (op != NULL && *op != '=') {
- eexe_mod_op(lp->ll_tv, rettv, (const char *)op);
+ eexe_mod_op(lp->ll_tv, rettv, op);
goto notify;
} else {
tv_clear(lp->ll_tv);
@@ -4538,7 +4537,7 @@ int get_option_tv(const char **const arg, typval_T *const rettv,
c = *option_end;
*option_end = NUL;
- opt_type = get_option_value((char_u *)(*arg), &numval,
+ opt_type = get_option_value(*arg, &numval,
rettv == NULL ? NULL : &stringval, opt_flags);
if (opt_type == -3) { // invalid name
diff --git a/src/nvim/eval.h b/src/nvim/eval.h
index 06b7f9e21d..c1891758ea 100644
--- a/src/nvim/eval.h
+++ b/src/nvim/eval.h
@@ -56,10 +56,10 @@ typedef struct lval_S {
///< isn't NULL it's the Dict to which to add the item.
listitem_T *ll_li; ///< The list item or NULL.
list_T *ll_list; ///< The list or NULL.
- int ll_range; ///< TRUE when a [i:j] range was used.
+ bool ll_range; ///< true when a [i:j] range was used.
+ bool ll_empty2; ///< Second index is empty: [i:].
long ll_n1; ///< First index for list.
long ll_n2; ///< Second index for list range.
- int ll_empty2; ///< Second index is empty: [i:].
dict_T *ll_dict; ///< The Dictionary or NULL.
dictitem_T *ll_di; ///< The dictitem or NULL.
char_u *ll_newkey; ///< New key for Dict in allocated memory or NULL.
diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c
index 638fef331a..bd4dc87d31 100644
--- a/src/nvim/eval/decode.c
+++ b/src/nvim/eval/decode.c
@@ -147,7 +147,7 @@ static inline int json_decoder_pop(ValuesStackItem obj,
tv_clear(&key.val);
if (tv_dict_add(last_container.container.vval.v_dict, obj_di)
== FAIL) {
- assert(false);
+ abort();
}
obj_di->di_tv = obj.val;
} else {
@@ -480,7 +480,7 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
break;
}
default: {
- assert(false);
+ abort();
}
}
} else {
diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c
index 9a9f2e4287..a4d7af7971 100644
--- a/src/nvim/eval/encode.c
+++ b/src/nvim/eval/encode.c
@@ -174,7 +174,7 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack,
case kMPConvPartial: {
switch (v.data.p.stage) {
case kMPConvPartialArgs: {
- assert(false);
+ abort();
break;
}
case kMPConvPartialSelf: {
@@ -237,7 +237,7 @@ bool encode_vim_list_to_buf(const list_T *const list, size_t *const ret_len,
char *const buf = xmalloc(len);
size_t read_bytes;
if (encode_read_from_list(&lrstate, buf, len, &read_bytes) != OK) {
- assert(false);
+ abort();
}
assert(len == read_bytes);
*ret_buf = buf;
diff --git a/src/nvim/eval/executor.c b/src/nvim/eval/executor.c
index da05ecda43..bbba9d12f2 100644
--- a/src/nvim/eval/executor.c
+++ b/src/nvim/eval/executor.c
@@ -118,7 +118,7 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2,
return OK;
}
case VAR_UNKNOWN: {
- assert(false);
+ abort();
}
}
}
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 8235d74cbb..fae5711b9c 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -1798,7 +1798,7 @@ static void f_environ(typval_T *argvars, typval_T *rettv, FunPtr fptr)
os_copy_fullenv(env, env_size);
- for (size_t i = 0; i < env_size; i++) {
+ for (ssize_t i = env_size - 1; i >= 0; i--) {
const char * str = env[i];
const char * const end = strchr(str + (str[0] == '=' ? 1 : 0),
'=');
@@ -1806,6 +1806,12 @@ static void f_environ(typval_T *argvars, typval_T *rettv, FunPtr fptr)
ptrdiff_t len = end - str;
assert(len > 0);
const char * value = str + len + 1;
+ if (tv_dict_find(rettv->vval.v_dict, str, len) != NULL) {
+ // Since we're traversing from the end of the env block to the front, any
+ // duplicate names encountered should be ignored. This preserves the
+ // semantics of env vars defined later in the env block taking precedence.
+ continue;
+ }
tv_dict_add_str(rettv->vval.v_dict,
str, len,
value);
@@ -2143,7 +2149,7 @@ static void f_menu_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_list_alloc_ret(rettv, kListLenMayKnow);
int modes = MENU_ALL_MODES;
if (argvars[1].v_type == VAR_STRING) {
- const char_u *const strmodes = (char_u *)tv_get_string(&argvars[1]);
+ const char *const strmodes = tv_get_string(&argvars[1]);
modes = get_menu_cmd_modes(strmodes, false, NULL, NULL);
}
menu_get((char_u *)tv_get_string(&argvars[0]), modes, rettv->vval.v_list);
@@ -3164,7 +3170,7 @@ static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if (xpc.xp_context == EXPAND_MENUS) {
- set_context_in_menu_cmd(&xpc, (char_u *)"menu", xpc.xp_pattern, false);
+ set_context_in_menu_cmd(&xpc, "menu", xpc.xp_pattern, false);
xpc.xp_pattern_len = STRLEN(xpc.xp_pattern);
}
@@ -3301,7 +3307,7 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
break;
case kCdScopeInvalid: // We should never get here
- assert(false);
+ abort();
}
if (from) {
@@ -4354,7 +4360,7 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
break;
case kCdScopeInvalid:
// We should never get here
- assert(false);
+ abort();
}
}
@@ -4875,6 +4881,108 @@ static void f_jobresize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = 1;
}
+static const char *ignored_env_vars[] = {
+#ifndef WIN32
+ "COLUMNS",
+ "LINES",
+ "TERMCAP",
+ "COLORFGBG",
+#endif
+ NULL
+};
+
+/// According to comments in src/win/process.c of libuv, Windows has a few
+/// "essential" environment variables.
+static const char *required_env_vars[] = {
+#ifdef WIN32
+ "HOMEDRIVE",
+ "HOMEPATH",
+ "LOGONSERVER",
+ "PATH",
+ "SYSTEMDRIVE",
+ "SYSTEMROOT",
+ "TEMP",
+ "USERDOMAIN",
+ "USERNAME",
+ "USERPROFILE",
+ "WINDIR",
+#endif
+ NULL
+};
+
+static dict_T *create_environment(const dictitem_T *job_env,
+ const bool clear_env,
+ const bool pty,
+ const char * const pty_term_name)
+{
+ dict_T * env = tv_dict_alloc();
+
+ if (!clear_env) {
+ typval_T temp_env = TV_INITIAL_VALUE;
+ f_environ(NULL, &temp_env, NULL);
+ tv_dict_extend(env, temp_env.vval.v_dict, "force");
+ tv_dict_free(temp_env.vval.v_dict);
+
+ if (pty) {
+ // These environment variables generally shouldn't be propagated to the
+ // child process. We're removing them here so the user can still decide
+ // they want to explicitly set them.
+ for (size_t i = 0;
+ i < ARRAY_SIZE(ignored_env_vars) && ignored_env_vars[i];
+ i++) {
+ dictitem_T *dv = tv_dict_find(env, ignored_env_vars[i], -1);
+ if (dv) {
+ tv_dict_item_remove(env, dv);
+ }
+ }
+#ifndef WIN32
+ // Set COLORTERM to "truecolor" if termguicolors is set and 256
+ // otherwise, but only if it was set in the parent terminal at all
+ dictitem_T *dv = tv_dict_find(env, S_LEN("COLORTERM"));
+ if (dv) {
+ tv_dict_item_remove(env, dv);
+ tv_dict_add_str(env, S_LEN("COLORTERM"), p_tgc ? "truecolor" : "256");
+ }
+#endif
+ }
+ }
+
+ // For a pty, we need a sane $TERM set. We can't rely on nvim's environment,
+ // because the child process is going to be communicating with nvim, not the
+ // parent terminal. Set a sane default, but let the user override it in the
+ // job's environment if they want.
+ if (pty) {
+ dictitem_T *dv = tv_dict_find(env, S_LEN("TERM"));
+ if (dv) {
+ tv_dict_item_remove(env, dv);
+ }
+ tv_dict_add_str(env, S_LEN("TERM"), pty_term_name);
+ }
+
+ if (job_env) {
+ tv_dict_extend(env, job_env->di_tv.vval.v_dict, "force");
+ }
+
+ if (pty) {
+ // Now that the custom environment is configured, we need to ensure certain
+ // environment variables are present.
+ for (size_t i = 0;
+ i < ARRAY_SIZE(required_env_vars) && required_env_vars[i];
+ i++) {
+ size_t len = strlen(required_env_vars[i]);
+ dictitem_T *dv = tv_dict_find(env, required_env_vars[i], len);
+ if (!dv) {
+ const char *env_var = os_getenv(required_env_vars[i]);
+ if (env_var) {
+ tv_dict_add_str(env, required_env_vars[i], len, env_var);
+ }
+ }
+ }
+ }
+
+ return env;
+}
+
// "jobstart()" function
static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
@@ -4887,7 +4995,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
bool executable = true;
char **argv = tv_to_argv(&argvars[0], NULL, &executable);
- char **env = NULL;
+ dict_T *env = NULL;
if (!argv) {
rettv->vval.v_number = executable ? 0 : -1;
return; // Did error message in tv_to_argv.
@@ -4911,6 +5019,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
on_stderr = CALLBACK_READER_INIT;
Callback on_exit = CALLBACK_NONE;
char *cwd = NULL;
+ dictitem_T *job_env = NULL;
if (argvars[1].v_type == VAR_DICT) {
job_opts = argvars[1].vval.v_dict;
@@ -4936,7 +5045,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
#endif
char *new_cwd = tv_dict_get_string(job_opts, "cwd", false);
- if (new_cwd && strlen(new_cwd) > 0) {
+ if (new_cwd && *new_cwd != NUL) {
cwd = new_cwd;
// The new cwd must be a directory.
if (!os_isdir_executable((const char *)cwd)) {
@@ -4945,46 +5054,14 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
}
- dictitem_T *job_env = tv_dict_find(job_opts, S_LEN("env"));
- if (job_env) {
- if (job_env->di_tv.v_type != VAR_DICT) {
- EMSG2(_(e_invarg2), "env");
- shell_free_argv(argv);
- return;
- }
-
- size_t custom_env_size = (size_t)tv_dict_len(job_env->di_tv.vval.v_dict);
- size_t i = 0;
- size_t env_size = 0;
- if (clear_env) {
- // + 1 for last null entry
- env = xmalloc((custom_env_size + 1) * sizeof(*env));
- env_size = 0;
- } else {
- env_size = os_get_fullenv_size();
-
- env = xmalloc((custom_env_size + env_size + 1) * sizeof(*env));
-
- os_copy_fullenv(env, env_size);
- i = env_size;
- }
- assert(env); // env must be allocated at this point
-
- TV_DICT_ITER(job_env->di_tv.vval.v_dict, var, {
- const char *str = tv_get_string(&var->di_tv);
- assert(str);
- size_t len = STRLEN(var->di_key) + strlen(str) + strlen("=") + 1;
- env[i] = xmalloc(len);
- snprintf(env[i], len, "%s=%s", (char *)var->di_key, str);
- i++;
- });
-
- // must be null terminated
- env[env_size + custom_env_size] = NULL;
+ job_env = tv_dict_find(job_opts, S_LEN("env"));
+ if (job_env && job_env->di_tv.v_type != VAR_DICT) {
+ EMSG2(_(e_invarg2), "env");
+ shell_free_argv(argv);
+ return;
}
-
if (!common_job_callbacks(job_opts, &on_stdout, &on_stderr, &on_exit)) {
shell_free_argv(argv);
return;
@@ -4997,12 +5074,19 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (pty) {
width = (uint16_t)tv_dict_get_number(job_opts, "width");
height = (uint16_t)tv_dict_get_number(job_opts, "height");
- term_name = tv_dict_get_string(job_opts, "TERM", true);
+ // Legacy method, before env option existed, to specify $TERM. No longer
+ // documented, but still usable to avoid breaking scripts.
+ term_name = tv_dict_get_string(job_opts, "TERM", false);
+ if (!term_name) {
+ term_name = "ansi";
+ }
}
+ env = create_environment(job_env, clear_env, pty, term_name);
+
Channel *chan = channel_job_start(argv, on_stdout, on_stderr, on_exit, pty,
rpc, overlapped, detach, cwd, width, height,
- term_name, env, &rettv->vval.v_number);
+ env, &rettv->vval.v_number);
if (chan) {
channel_create_event(chan, NULL);
}
@@ -7445,7 +7529,7 @@ static void f_rpcstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
Channel *chan = channel_job_start(argv, CALLBACK_READER_INIT,
CALLBACK_READER_INIT, CALLBACK_NONE,
false, true, false, false, NULL, 0, 0,
- NULL, NULL, &rettv->vval.v_number);
+ NULL, &rettv->vval.v_number);
if (chan) {
channel_create_event(chan, NULL);
}
@@ -10518,6 +10602,11 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
Callback on_exit = CALLBACK_NONE;
dict_T *job_opts = NULL;
const char *cwd = ".";
+ dict_T *env = NULL;
+ const bool pty = true;
+ bool clear_env = false;
+ dictitem_T *job_env = NULL;
+
if (argvars[1].v_type == VAR_DICT) {
job_opts = argvars[1].vval.v_dict;
@@ -10532,18 +10621,31 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
+ job_env = tv_dict_find(job_opts, S_LEN("env"));
+ if (job_env && job_env->di_tv.v_type != VAR_DICT) {
+ EMSG2(_(e_invarg2), "env");
+ shell_free_argv(argv);
+ return;
+ }
+
+ clear_env = tv_dict_get_number(job_opts, "clear_env") != 0;
+
if (!common_job_callbacks(job_opts, &on_stdout, &on_stderr, &on_exit)) {
shell_free_argv(argv);
return;
}
}
+ env = create_environment(job_env, clear_env, pty, "xterm-256color");
+
+ const bool rpc = false;
+ const bool overlapped = false;
+ const bool detach = false;
uint16_t term_width = MAX(0, curwin->w_width_inner - win_col_off(curwin));
Channel *chan = channel_job_start(argv, on_stdout, on_stderr, on_exit,
- true, false, false, false, cwd,
+ pty, rpc, overlapped, detach, cwd,
term_width, curwin->w_height_inner,
- xstrdup("xterm-256color"), NULL,
- &rettv->vval.v_number);
+ env, &rettv->vval.v_number);
if (rettv->vval.v_number <= 0) {
return;
}
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
index 02d32a4f86..9be487f4fd 100644
--- a/src/nvim/eval/typval.c
+++ b/src/nvim/eval/typval.c
@@ -1523,6 +1523,33 @@ varnumber_T tv_dict_get_number(const dict_T *const d, const char *const key)
return tv_get_number(&di->di_tv);
}
+/// Converts a dict to an environment
+///
+///
+char **tv_dict_to_env(dict_T *denv)
+{
+ size_t env_size = (size_t)tv_dict_len(denv);
+
+ size_t i = 0;
+ char **env = NULL;
+
+ // + 1 for NULL
+ env = xmalloc((env_size + 1) * sizeof(*env));
+
+ TV_DICT_ITER(denv, var, {
+ const char *str = tv_get_string(&var->di_tv);
+ assert(str);
+ size_t len = STRLEN(var->di_key) + strlen(str) + strlen("=") + 1;
+ env[i] = xmalloc(len);
+ snprintf(env[i], len, "%s=%s", (char *)var->di_key, str);
+ i++;
+ });
+
+ // must be null terminated
+ env[env_size] = NULL;
+ return env;
+}
+
/// Get a string item from a dictionary
///
/// @param[in] d Dictionary to get item from.
@@ -2494,7 +2521,7 @@ void tv_item_lock(typval_T *const tv, const int deep, const bool lock)
break;
}
case VAR_UNKNOWN: {
- assert(false);
+ abort();
}
}
#undef CHANGE_LOCK
@@ -2666,7 +2693,7 @@ bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic,
}
}
- assert(false);
+ abort();
return false;
}
@@ -2719,7 +2746,7 @@ bool tv_check_str_or_nr(const typval_T *const tv)
return false;
}
}
- assert(false);
+ abort();
return false;
}
@@ -2764,7 +2791,7 @@ bool tv_check_num(const typval_T *const tv)
return false;
}
}
- assert(false);
+ abort();
return false;
}
@@ -2809,7 +2836,7 @@ bool tv_check_str(const typval_T *const tv)
return false;
}
}
- assert(false);
+ abort();
return false;
}
diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c
index 13517d3df1..0b1ecb12e2 100644
--- a/src/nvim/event/libuv_process.c
+++ b/src/nvim/event/libuv_process.c
@@ -41,7 +41,6 @@ int libuv_process_spawn(LibuvProcess *uvproc)
#endif
uvproc->uvopts.exit_cb = exit_cb;
uvproc->uvopts.cwd = proc->cwd;
- uvproc->uvopts.env = proc->env;
uvproc->uvopts.stdio = uvproc->uvstdio;
uvproc->uvopts.stdio_count = 3;
uvproc->uvstdio[0].flags = UV_IGNORE;
@@ -49,6 +48,12 @@ int libuv_process_spawn(LibuvProcess *uvproc)
uvproc->uvstdio[2].flags = UV_IGNORE;
uvproc->uv.data = proc;
+ if (proc->env) {
+ uvproc->uvopts.env = tv_dict_to_env(proc->env);
+ } else {
+ uvproc->uvopts.env = NULL;
+ }
+
if (!proc->in.closed) {
uvproc->uvstdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
#ifdef WIN32
@@ -78,6 +83,9 @@ int libuv_process_spawn(LibuvProcess *uvproc)
int status;
if ((status = uv_spawn(&proc->loop->uv, &uvproc->uv, &uvproc->uvopts))) {
ELOG("uv_spawn failed: %s", uv_strerror(status));
+ if (uvproc->uvopts.env) {
+ os_free_fullenv(uvproc->uvopts.env);
+ }
return status;
}
@@ -97,6 +105,10 @@ static void close_cb(uv_handle_t *handle)
if (proc->internal_close_cb) {
proc->internal_close_cb(proc);
}
+ LibuvProcess *uvproc = (LibuvProcess *)proc;
+ if (uvproc->uvopts.env) {
+ os_free_fullenv(uvproc->uvopts.env);
+ }
}
static void exit_cb(uv_process_t *handle, int64_t status, int term_signal)
diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c
index 8e9964bd37..b93d6cc0ab 100644
--- a/src/nvim/event/process.c
+++ b/src/nvim/event/process.c
@@ -270,9 +270,6 @@ static void process_close_event(void **argv)
{
Process *proc = argv[0];
shell_free_argv(proc->argv);
- if (proc->type == kProcessTypePty) {
- xfree(((PtyProcess *)proc)->term_name);
- }
if (proc->cb) { // "on_exit" for jobstart(). See channel_job_start().
proc->cb(proc, proc->status, proc->data);
}
diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h
index 84e81238e9..24debdb276 100644
--- a/src/nvim/event/process.h
+++ b/src/nvim/event/process.h
@@ -4,6 +4,7 @@
#include "nvim/event/loop.h"
#include "nvim/event/rstream.h"
#include "nvim/event/wstream.h"
+#include "nvim/eval/typval.h"
typedef enum {
kProcessTypeUv,
@@ -23,7 +24,7 @@ struct process {
uint64_t stopped_time; // process_stop() timestamp
const char *cwd;
char **argv;
- char **env;
+ dict_T *env;
Stream in, out, err;
process_exit_cb cb;
internal_process_cb internal_exit_cb, internal_close_cb;
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index a2487336f1..cd7ff9a00b 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -790,7 +790,10 @@ void ex_retab(exarg_T *eap)
for (col = 0; col < len; col++) {
ptr[col] = (col < num_tabs) ? '\t' : ' ';
}
- ml_replace(lnum, new_line, false);
+ if (ml_replace(lnum, new_line, false) == OK) {
+ // "new_line" may have been copied
+ new_line = curbuf->b_ml.ml_line_ptr;
+ }
if (first_line == 0) {
first_line = lnum;
}
@@ -2413,7 +2416,10 @@ int do_ecmd(
(flags & ECMD_HIDE) || curbuf->terminal ? 0 : DOBUF_UNLOAD,
false);
- the_curwin->w_closing = false;
+ // Autocommands may have closed the window.
+ if (win_valid(the_curwin)) {
+ the_curwin->w_closing = false;
+ }
buf->b_locked--;
// autocmds may abort script processing
@@ -3126,6 +3132,9 @@ static bool sub_joining_lines(exarg_T *eap, char_u *pat, char_u *sub,
|| *cmd == 'l'
|| *cmd == 'p'
|| *cmd == '#')))) {
+ if (eap->skip) {
+ return true;
+ }
curwin->w_cursor.lnum = eap->line1;
if (*cmd == 'l') {
eap->flags = EXFLAG_LIST;
@@ -3307,11 +3316,7 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
int save_b_changed = curbuf->b_changed;
bool preview = (State & CMDPREVIEW);
- // inccommand tests fail without this check
- if (!preview) {
- // Required for Undo to work for extmarks.
- u_save_cursor();
- }
+ bool did_save = false;
if (!global_busy) {
sub_nsubs = 0;
@@ -3988,6 +3993,11 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
int matchcols = end.col - ((end.lnum == start.lnum)
? start.col : 0);
int subcols = new_endcol - ((lnum == lnum_start) ? start_col : 0);
+ if (!did_save) {
+ // Required for Undo to work for extmarks.
+ u_save_cursor();
+ did_save = true;
+ }
extmark_splice(curbuf, lnum_start-1, start_col,
end.lnum-start.lnum, matchcols, replaced_bytes,
lnum-lnum_start, subcols, sublen-1, kExtmarkUndo);
@@ -4217,7 +4227,7 @@ skip:
size_t subsize = preview_lines.subresults.size;
if (preview && !aborting()) {
if (got_quit || profile_passed_limit(timeout)) { // Too slow, disable.
- set_string_option_direct((char_u *)"icm", -1, (char_u *)"", OPT_FREE,
+ set_string_option_direct("icm", -1, (char_u *)"", OPT_FREE,
SID_NONE);
} else if (*p_icm != NUL && pat != NULL) {
if (pre_src_id == 0) {
@@ -4518,7 +4528,7 @@ prepare_tagpreview (
RESET_BINDING(curwin); /* don't take over 'scrollbind'
and 'cursorbind' */
curwin->w_p_diff = false; // no 'diff'
- set_string_option_direct((char_u *)"fdc", -1, // no 'foldcolumn'
+ set_string_option_direct("fdc", -1, // no 'foldcolumn'
(char_u *)"0", OPT_FREE, SID_NONE);
return true;
}
@@ -5013,7 +5023,7 @@ int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches,
static void prepare_help_buffer(void)
{
curbuf->b_help = true;
- set_string_option_direct((char_u *)"buftype", -1, (char_u *)"help",
+ set_string_option_direct("buftype", -1, (char_u *)"help",
OPT_FREE|OPT_LOCAL, 0);
// Always set these options after jumping to a help tag, because the
@@ -5023,13 +5033,13 @@ static void prepare_help_buffer(void)
// Only set it when needed, buf_init_chartab() is some work.
char_u *p = (char_u *)"!-~,^*,^|,^\",192-255";
if (STRCMP(curbuf->b_p_isk, p) != 0) {
- set_string_option_direct((char_u *)"isk", -1, p, OPT_FREE|OPT_LOCAL, 0);
+ set_string_option_direct("isk", -1, p, OPT_FREE|OPT_LOCAL, 0);
check_buf_options(curbuf);
(void)buf_init_chartab(curbuf, FALSE);
}
// Don't use the global foldmethod.
- set_string_option_direct((char_u *)"fdm", -1, (char_u *)"manual",
+ set_string_option_direct("fdm", -1, (char_u *)"manual",
OPT_FREE|OPT_LOCAL, 0);
curbuf->b_p_ts = 8; // 'tabstop' is 8.
@@ -5649,7 +5659,7 @@ static buf_T *show_sub(exarg_T *eap, pos_T old_cusr,
cmdmod.tab = 0; // disable :tab modifier
cmdmod.noswapfile = true; // disable swap for preview buffer
// disable file info message
- set_string_option_direct((char_u *)"shm", -1, (char_u *)"F", OPT_FREE,
+ set_string_option_direct("shm", -1, (char_u *)"F", OPT_FREE,
SID_NONE);
bool outside_curline = (eap->line1 != old_cusr.lnum
@@ -5772,7 +5782,7 @@ static buf_T *show_sub(exarg_T *eap, pos_T old_cusr,
update_screen(SOME_VALID);
RedrawingDisabled = save_rd;
- set_string_option_direct((char_u *)"shm", -1, save_shm_p, OPT_FREE, SID_NONE);
+ set_string_option_direct("shm", -1, save_shm_p, OPT_FREE, SID_NONE);
xfree(save_shm_p);
cmdmod = save_cmdmod;
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index c400975108..2598b13079 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -1639,10 +1639,10 @@ int get_arglist_exp(char_u *str, int *fcountp, char_u ***fnamesp, bool wig)
if (wig) {
i = expand_wildcards(ga.ga_len, (char_u **)ga.ga_data,
- fcountp, fnamesp, EW_FILE|EW_NOTFOUND);
+ fcountp, fnamesp, EW_FILE|EW_NOTFOUND|EW_NOTWILD);
} else {
i = gen_expand_wildcards(ga.ga_len, (char_u **)ga.ga_data,
- fcountp, fnamesp, EW_FILE|EW_NOTFOUND);
+ fcountp, fnamesp, EW_FILE|EW_NOTFOUND|EW_NOTWILD);
}
ga_clear(&ga);
@@ -2375,13 +2375,13 @@ void ex_compiler(exarg_T *eap)
// Set "b:current_compiler" from "current_compiler".
p = get_var_value("g:current_compiler");
if (p != NULL) {
- set_internal_string_var((char_u *)"b:current_compiler", p);
+ set_internal_string_var("b:current_compiler", p);
}
// Restore "current_compiler" for ":compiler {name}".
if (!eap->forceit) {
if (old_cur_comp != NULL) {
- set_internal_string_var((char_u *)"g:current_compiler",
+ set_internal_string_var("g:current_compiler",
old_cur_comp);
xfree(old_cur_comp);
} else {
diff --git a/src/nvim/ex_cmds_defs.h b/src/nvim/ex_cmds_defs.h
index ca84d375ce..f928c61ea4 100644
--- a/src/nvim/ex_cmds_defs.h
+++ b/src/nvim/ex_cmds_defs.h
@@ -188,8 +188,8 @@ struct exarg {
// used for completion on the command line
struct expand {
- int xp_context; // type of expansion
char_u *xp_pattern; // start of item to expand
+ int xp_context; // type of expansion
size_t xp_pattern_len; // bytes in xp_pattern before cursor
char_u *xp_arg; // completion function
sctx_T xp_script_ctx; // SCTX for completion function
@@ -199,9 +199,9 @@ struct expand {
// characters need to be escaped
#endif
int xp_numfiles; // number of files found by file name completion
+ int xp_col; // cursor position in line
char_u **xp_files; // list of files
char_u *xp_line; // text being completed
- int xp_col; // cursor position in line
};
// values for xp_backslash
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 18683c54d3..6cc915c8c2 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -317,7 +317,9 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
int count = 0; /* line number count */
int did_inc = FALSE; /* incremented RedrawingDisabled */
int retval = OK;
- cstack_T cstack; // conditional stack
+ cstack_T cstack = { // conditional stack
+ .cs_idx = -1,
+ };
garray_T lines_ga; // keep lines for ":while"/":for"
int current_line = 0; // active line in lines_ga
char_u *fname = NULL; // function or script name
@@ -360,11 +362,6 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
call_depth++;
start_batch_changes();
- cstack.cs_idx = -1;
- cstack.cs_looplevel = 0;
- cstack.cs_trylevel = 0;
- cstack.cs_emsg_silent_list = NULL;
- cstack.cs_lflags = 0;
ga_init(&lines_ga, (int)sizeof(wcmd_T), 10);
real_cookie = getline_cookie(fgetline, cookie);
@@ -2182,7 +2179,7 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg, bool skip_only)
// Set 'eventignore' to "all". Restore the
// existing option value later.
cmdmod.save_ei = vim_strsave(p_ei);
- set_string_option_direct((char_u *)"ei", -1,
+ set_string_option_direct("ei", -1,
(char_u *)"all", OPT_FREE, SID_NONE);
}
continue;
@@ -2294,9 +2291,8 @@ static void undo_cmdmod(const exarg_T *eap, int save_msg_scroll)
}
if (cmdmod.save_ei != NULL) {
- /* Restore 'eventignore' to the value before ":noautocmd". */
- set_string_option_direct((char_u *)"ei", -1, cmdmod.save_ei,
- OPT_FREE, SID_NONE);
+ // Restore 'eventignore' to the value before ":noautocmd".
+ set_string_option_direct("ei", -1, cmdmod.save_ei, OPT_FREE, SID_NONE);
free_string_option(cmdmod.save_ei);
}
@@ -3522,7 +3518,7 @@ const char * set_one_cmd_context(
// EX_XFILE: file names are handled above.
if (!(ea.argt & EX_XFILE)) {
if (context == EXPAND_MENUS) {
- return (const char *)set_context_in_menu_cmd(xp, (char_u *)cmd,
+ return (const char *)set_context_in_menu_cmd(xp, cmd,
(char_u *)arg, forceit);
} else if (context == EXPAND_COMMANDS) {
return arg;
@@ -3602,7 +3598,7 @@ const char * set_one_cmd_context(
case CMD_tmenu: case CMD_tunmenu:
case CMD_popup: case CMD_emenu:
return (const char *)set_context_in_menu_cmd(
- xp, (char_u *)cmd, (char_u *)arg, forceit);
+ xp, cmd, (char_u *)arg, forceit);
case CMD_colorscheme:
xp->xp_context = EXPAND_COLORS;
@@ -7594,7 +7590,7 @@ void post_chdir(CdScope scope, bool trigger_dirchanged)
curwin->w_localdir = (char_u *)xstrdup(cwd);
break;
case kCdScopeInvalid:
- assert(false);
+ abort();
}
shorten_fnames(true);
@@ -7759,6 +7755,11 @@ static void do_exmap(exarg_T *eap, int isabbrev)
static void ex_winsize(exarg_T *eap)
{
char_u *arg = eap->arg;
+
+ if (!ascii_isdigit(*arg)) {
+ EMSG2(_(e_invarg2), arg);
+ return;
+ }
int w = getdigits_int(&arg, false, 10);
arg = skipwhite(arg);
char_u *p = arg;
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 8d10e98259..7776191869 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -886,7 +886,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
need_wait_return = false;
}
- set_string_option_direct((char_u *)"icm", -1, s->save_p_icm, OPT_FREE,
+ set_string_option_direct("icm", -1, s->save_p_icm, OPT_FREE,
SID_NONE);
State = s->save_State;
setmouse();
@@ -6383,7 +6383,7 @@ int hist_type2char(int type)
return '>';
}
default: {
- assert(false);
+ abort();
}
}
return NUL;
diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c
index b1fa0b6779..8beba38509 100644
--- a/src/nvim/file_search.c
+++ b/src/nvim/file_search.c
@@ -1595,7 +1595,7 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope, bool changed_window)
}
case kCdScopeInvalid: {
// Should never happen.
- assert(false);
+ abort();
}
}
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index a542bb19dd..b240e7b134 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -1644,8 +1644,7 @@ failed:
save_file_ff(curbuf);
// If editing a new file: set 'fenc' for the current buffer.
// Also for ":read ++edit file".
- set_string_option_direct((char_u *)"fenc", -1, fenc,
- OPT_FREE | OPT_LOCAL, 0);
+ set_string_option_direct("fenc", -1, fenc, OPT_FREE | OPT_LOCAL, 0);
}
if (fenc_alloced)
xfree(fenc);
@@ -2002,7 +2001,7 @@ void set_forced_fenc(exarg_T *eap)
{
if (eap->force_enc != 0) {
char_u *fenc = enc_canonize(eap->cmd + eap->force_enc);
- set_string_option_direct((char_u *)"fenc", -1, fenc, OPT_FREE|OPT_LOCAL, 0);
+ set_string_option_direct("fenc", -1, fenc, OPT_FREE|OPT_LOCAL, 0);
xfree(fenc);
}
}
diff --git a/src/nvim/fold.c b/src/nvim/fold.c
index 0593c16999..5032646d7e 100644
--- a/src/nvim/fold.c
+++ b/src/nvim/fold.c
@@ -2999,7 +2999,6 @@ static void foldlevelDiff(fline_T *flp)
static void foldlevelExpr(fline_T *flp)
{
win_T *win;
- int n;
int c;
linenr_T lnum = flp->lnum + flp->off;
@@ -3017,7 +3016,7 @@ static void foldlevelExpr(fline_T *flp)
/* KeyTyped may be reset to 0 when calling a function which invokes
* do_cmdline(). To make 'foldopen' work correctly restore KeyTyped. */
const bool save_keytyped = KeyTyped;
- n = (int)eval_foldexpr(flp->wp->w_p_fde, &c);
+ const int n = eval_foldexpr(flp->wp->w_p_fde, &c);
KeyTyped = save_keytyped;
switch (c) {
@@ -3202,8 +3201,10 @@ int put_folds(FILE *fd, win_T *wp)
{
if (foldmethodIsManual(wp)) {
if (put_line(fd, "silent! normal! zE") == FAIL
- || put_folds_recurse(fd, &wp->w_folds, (linenr_T)0) == FAIL)
+ || put_folds_recurse(fd, &wp->w_folds, (linenr_T)0) == FAIL
+ || put_line(fd, "let &fdl = &fdl") == FAIL) {
return FAIL;
+ }
}
/* If some folds are manually opened/closed, need to restore that. */
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 3b8f4116b7..22f06941aa 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -1009,6 +1009,8 @@ EXTERN char_u e_floatonly[] INIT(=N_(
EXTERN char_u e_floatexchange[] INIT(=N_(
"E5602: Cannot exchange or rotate float"));
+EXTERN char e_cannot_define_autocommands_for_all_events[] INIT(= N_(
+ "E1155: Cannot define autocommands for ALL events"));
EXTERN char top_bot_msg[] INIT(= N_("search hit TOP, continuing at BOTTOM"));
EXTERN char bot_top_msg[] INIT(= N_("search hit BOTTOM, continuing at TOP"));
diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c
index 030df69caa..83b3729ad3 100644
--- a/src/nvim/lua/converter.c
+++ b/src/nvim/lua/converter.c
@@ -245,7 +245,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
} else {
dictitem_T *const di = tv_dict_item_alloc_len(s, len);
if (tv_dict_add(cur.tv->vval.v_dict, di) == FAIL) {
- assert(false);
+ abort();
}
kv_push(stack, cur);
cur = (TVPopStackItem) { &di->di_tv, false, false, 0 };
@@ -391,7 +391,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
break;
}
default: {
- assert(false);
+ abort();
}
}
nlua_pop_typval_table_processing_end:
@@ -1200,7 +1200,7 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err)
break;
}
default: {
- assert(false);
+ abort();
}
}
break;
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 9f71df3a46..7064f2a068 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -1404,9 +1404,9 @@ static void load_plugins(void)
static void handle_quickfix(mparm_T *paramp)
{
if (paramp->edit_type == EDIT_QF) {
- if (paramp->use_ef != NULL)
- set_string_option_direct((char_u *)"ef", -1,
- paramp->use_ef, OPT_FREE, SID_CARG);
+ if (paramp->use_ef != NULL) {
+ set_string_option_direct("ef", -1, paramp->use_ef, OPT_FREE, SID_CARG);
+ }
vim_snprintf((char *)IObuff, IOSIZE, "cfile %s", p_ef);
if (qf_init(NULL, p_ef, p_efm, true, IObuff, p_menc) < 0) {
msg_putchar('\n');
diff --git a/src/nvim/memline_defs.h b/src/nvim/memline_defs.h
index 9a6f29a908..dc4755f83d 100644
--- a/src/nvim/memline_defs.h
+++ b/src/nvim/memline_defs.h
@@ -45,16 +45,16 @@ typedef struct memline {
memfile_T *ml_mfp; // pointer to associated memfile
+ infoptr_T *ml_stack; // stack of pointer blocks (array of IPTRs)
+ int ml_stack_top; // current top of ml_stack
+ int ml_stack_size; // total number of entries in ml_stack
+
#define ML_EMPTY 1 // empty buffer
#define ML_LINE_DIRTY 2 // cached line was changed and allocated
#define ML_LOCKED_DIRTY 4 // ml_locked was changed
#define ML_LOCKED_POS 8 // ml_locked needs positive block number
int ml_flags;
- infoptr_T *ml_stack; // stack of pointer blocks (array of IPTRs)
- int ml_stack_top; // current top of ml_stack
- int ml_stack_size; // total number of entries in ml_stack
-
linenr_T ml_line_lnum; // line number of cached line, 0 if not valid
char_u *ml_line_ptr; // pointer to cached line
size_t ml_line_offset; // cached byte offset of ml_line_lnum
diff --git a/src/nvim/menu.c b/src/nvim/menu.c
index 7094d3be90..ac3b7768e6 100644
--- a/src/nvim/menu.c
+++ b/src/nvim/menu.c
@@ -81,7 +81,7 @@ ex_menu(exarg_T *eap)
// kFalse for "menu disable
vimmenu_T menuarg;
- modes = get_menu_cmd_modes(eap->cmd, eap->forceit, &noremap, &unmenu);
+ modes = get_menu_cmd_modes((char *)eap->cmd, eap->forceit, &noremap, &unmenu);
arg = eap->arg;
for (;; ) {
@@ -912,7 +912,9 @@ static int expand_emenu; /* TRUE for ":emenu" command */
/*
* Work out what to complete when doing command line completion of menu names.
*/
-char_u *set_context_in_menu_cmd(expand_T *xp, char_u *cmd, char_u *arg, int forceit)
+char_u *set_context_in_menu_cmd(expand_T *xp, const char *cmd, char_u *arg,
+ bool forceit)
+ FUNC_ATTR_NONNULL_ALL
{
char_u *after_dot;
char_u *p;
@@ -1178,7 +1180,7 @@ static bool menu_namecmp(const char_u *const name, const char_u *const mname)
/// to whether the command is an "unmenu" command.
int
get_menu_cmd_modes(
- const char_u * cmd,
+ const char *cmd,
bool forceit,
int *noremap,
int *unmenu
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 052b07ed44..87d092281a 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -2623,7 +2623,7 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append)
}
// NOTREACHED
case kMTUnknown:
- assert(false);
+ abort();
}
}
@@ -6092,7 +6092,7 @@ static void set_clipboard(int name, yankreg_T *reg)
break;
}
case kMTUnknown: {
- assert(false);
+ abort();
}
}
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 74bf6f0590..ac25c86b5f 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -1942,6 +1942,7 @@ static void didset_options(void)
(void)opt_strings_flags(p_dy, p_dy_values, &dy_flags, true);
(void)opt_strings_flags(p_rdb, p_rdb_values, &rdb_flags, true);
(void)opt_strings_flags(p_tc, p_tc_values, &tc_flags, false);
+ (void)opt_strings_flags(p_tpf, p_tpf_values, &tpf_flags, true);
(void)opt_strings_flags(p_ve, p_ve_values, &ve_flags, true);
(void)opt_strings_flags(p_wop, p_wop_values, &wop_flags, true);
(void)opt_strings_flags(p_jop, p_jop_values, &jop_flags, true);
@@ -2119,9 +2120,9 @@ static int shada_idx = -1;
// "set_sid".
void
set_string_option_direct(
- char_u *name,
+ const char *name,
int opt_idx,
- char_u *val,
+ const char_u *val,
int opt_flags, // OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL
int set_sid
)
@@ -2132,7 +2133,7 @@ set_string_option_direct(
int idx = opt_idx;
if (idx == -1) { // Use name.
- idx = findoption((const char *)name);
+ idx = findoption(name);
if (idx < 0) { // Not found (should not happen).
internal_error("set_string_option_direct()");
IEMSG2(_("For option %s"), name);
@@ -3077,6 +3078,10 @@ ambw_end:
if (!parse_winhl_opt(curwin)) {
errmsg = e_invarg;
}
+ } else if (varp == &p_tpf) {
+ if (opt_strings_flags(p_tpf, p_tpf_values, &tpf_flags, true) != OK) {
+ errmsg = e_invarg;
+ }
} else {
// Options that are a list of flags.
p = NULL;
@@ -3786,7 +3791,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
if (p_terse && p == NULL) {
STRCPY(IObuff, p_shm);
STRCAT(IObuff, "s");
- set_string_option_direct((char_u *)"shm", -1, IObuff, OPT_FREE, 0);
+ set_string_option_direct("shm", -1, IObuff, OPT_FREE, 0);
} else if (!p_terse && p != NULL) { // remove 's' from p_shm
STRMOVE(p, p + 1);
}
@@ -4526,7 +4531,7 @@ bool is_tty_option(const char *name)
#define TCO_BUFFER_SIZE 8
/// @param name TUI-related option
/// @param[out,allocated] value option string value
-bool get_tty_option(char *name, char **value)
+bool get_tty_option(const char *name, char **value)
{
if (strequal(name, "t_Co")) {
if (value) {
@@ -4592,6 +4597,7 @@ bool set_tty_option(const char *name, char *value)
///
/// @return Option index or -1 if option was not found.
static int findoption(const char *const arg)
+ FUNC_ATTR_NONNULL_ALL
{
return findoption_len(arg, strlen(arg));
}
@@ -4605,17 +4611,17 @@ static int findoption(const char *const arg)
/// hidden String option: -2.
/// unknown option: -3.
int get_option_value(
- char_u *name,
+ const char *name,
long *numval,
char_u **stringval, ///< NULL when only checking existence
int opt_flags
)
{
- if (get_tty_option((char *)name, (char **)stringval)) {
+ if (get_tty_option(name, (char **)stringval)) {
return 0;
}
- int opt_idx = findoption((const char *)name);
+ int opt_idx = findoption(name);
if (opt_idx < 0) { // Unknown option.
return -3;
}
@@ -7049,7 +7055,7 @@ void set_fileformat(int eol_style, int opt_flags)
// p is NULL if "eol_style" is EOL_UNKNOWN.
if (p != NULL) {
- set_string_option_direct((char_u *)"ff",
+ set_string_option_direct("ff",
-1,
(char_u *)p,
OPT_FREE | opt_flags,
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index 683afc670e..43b0107800 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -621,6 +621,19 @@ EXTERN int p_sta; // 'smarttab'
EXTERN int p_sb; // 'splitbelow'
EXTERN long p_tpm; // 'tabpagemax'
EXTERN char_u *p_tal; // 'tabline'
+EXTERN char_u *p_tpf; // 'termpastefilter'
+EXTERN unsigned int tpf_flags; ///< flags from 'termpastefilter'
+#ifdef IN_OPTION_C
+static char *(p_tpf_values[]) =
+ { "BS", "HT", "FF", "ESC", "DEL", "C0", "C1", NULL };
+#endif
+# define TPF_BS 0x001
+# define TPF_HT 0x002
+# define TPF_FF 0x004
+# define TPF_ESC 0x008
+# define TPF_DEL 0x010
+# define TPF_C0 0x020
+# define TPF_C1 0x040
EXTERN char_u *p_sps; // 'spellsuggest'
EXTERN int p_spr; // 'splitright'
EXTERN int p_sol; // 'startofline'
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index df2bfbce34..fe108ef1cc 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -2821,6 +2821,14 @@ return {
defaults={if_true={vi=false}}
},
{
+ full_name='termpastefilter', abbreviation='tpf',
+ type='string', list='onecomma', scope={'global'},
+ deny_duplicates=true,
+ vim=true,
+ varname='p_tpf',
+ defaults={if_true={vi="", vim="BS,HT,ESC,DEL"}}
+ },
+ {
full_name='terse',
short_desc=N_("hides notification of search wrap"),
type='bool', scope={'global'},
diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c
index 4d7d9a45df..d794969ab5 100644
--- a/src/nvim/os/pty_process_unix.c
+++ b/src/nvim/os/pty_process_unix.c
@@ -20,6 +20,10 @@
# include <pty.h>
#endif
+#ifdef __APPLE__
+# include <crt_externs.h>
+#endif
+
#include <uv.h>
#include "nvim/lib/klist.h"
@@ -154,28 +158,14 @@ void pty_process_teardown(Loop *loop)
static void init_child(PtyProcess *ptyproc)
FUNC_ATTR_NONNULL_ALL
{
+#if defined(HAVE__NSGETENVIRON)
+#define environ (*_NSGetEnviron())
+#else
+ extern char **environ;
+#endif
// New session/process-group. #6530
setsid();
- os_unsetenv("COLUMNS");
- os_unsetenv("LINES");
- os_unsetenv("TERMCAP");
- os_unsetenv("COLORFGBG");
- // setting COLORTERM to "truecolor" if termguicolors is set and 256
- // otherwise, but only if it was set in the parent terminal at all
- if (os_env_exists("COLORTERM")) {
- const char *colorterm = os_getenv("COLORTERM");
- if (colorterm != NULL) {
- if (p_tgc) {
- os_setenv("COLORTERM", "truecolor", 1);
- } else {
- os_setenv("COLORTERM", "256", 1);
- }
- } else {
- os_unsetenv("COLORTERM");
- }
- }
-
signal(SIGCHLD, SIG_DFL);
signal(SIGHUP, SIG_DFL);
signal(SIGINT, SIG_DFL);
@@ -190,9 +180,12 @@ static void init_child(PtyProcess *ptyproc)
}
char *prog = ptyproc->process.argv[0];
- os_setenv("TERM", ptyproc->term_name ? ptyproc->term_name : "ansi", 1);
- execvp(prog, ptyproc->process.argv);
+
+ assert(proc->env);
+ environ = tv_dict_to_env(proc->env);
+ execvp(prog, proc->argv);
ELOG("execvp failed: %s: %s", strerror(errno), prog);
+
_exit(122); // 122 is EXEC_FAILED in the Vim source.
}
diff --git a/src/nvim/os/pty_process_unix.h b/src/nvim/os/pty_process_unix.h
index f7c57b3839..8c822eafad 100644
--- a/src/nvim/os/pty_process_unix.h
+++ b/src/nvim/os/pty_process_unix.h
@@ -17,7 +17,6 @@ static inline PtyProcess pty_process_init(Loop *loop, void *data)
{
PtyProcess rv;
rv.process = process_init(loop, kProcessTypePty, data);
- rv.term_name = NULL;
rv.width = 80;
rv.height = 24;
rv.tty_fd = -1;
diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c
index 6f7100e846..52d2f84ace 100644
--- a/src/nvim/os/pty_process_win.c
+++ b/src/nvim/os/pty_process_win.c
@@ -52,6 +52,7 @@ int pty_process_spawn(PtyProcess *ptyproc)
uv_connect_t *out_req = NULL;
wchar_t *cmd_line = NULL;
wchar_t *cwd = NULL;
+ wchar_t *env = NULL;
const char *emsg = NULL;
assert(proc->err.closed);
@@ -124,13 +125,22 @@ int pty_process_spawn(PtyProcess *ptyproc)
goto cleanup;
}
+ if (proc->env != NULL) {
+ status = build_env_block(proc->env, &env);
+ }
+
+ if (status != 0) {
+ emsg = "build_env_block failed";
+ goto cleanup;
+ }
+
if (ptyproc->type == kConpty) {
if (!os_conpty_spawn(conpty_object,
&process_handle,
NULL,
cmd_line,
cwd,
- NULL)) {
+ env)) {
emsg = "os_conpty_spawn failed";
status = (int)GetLastError();
goto cleanup;
@@ -141,7 +151,7 @@ int pty_process_spawn(PtyProcess *ptyproc)
NULL, // Optional application name
cmd_line,
cwd,
- NULL, // Optional environment variables
+ env,
&err);
if (spawncfg == NULL) {
emsg = "winpty_spawn_config_new failed";
@@ -213,6 +223,7 @@ cleanup:
xfree(in_req);
xfree(out_req);
xfree(cmd_line);
+ xfree(env);
xfree(cwd);
return status;
}
@@ -454,3 +465,66 @@ int translate_winpty_error(int winpty_errno)
default: return UV_UNKNOWN;
}
}
+
+typedef struct EnvNode {
+ wchar_t *str;
+ size_t len;
+ QUEUE node;
+} EnvNode;
+
+/// Build the environment block to pass to CreateProcessW.
+///
+/// @param[in] denv Dict of environment name/value pairs
+/// @param[out] env Allocated environment block
+///
+/// @returns zero on success or error code of MultiByteToWideChar function.
+static int build_env_block(dict_T *denv, wchar_t **env_block)
+{
+ const size_t denv_size = (size_t)tv_dict_len(denv);
+ size_t env_block_len = 0;
+ int rc;
+ char **env = tv_dict_to_env(denv);
+
+ QUEUE *q;
+ QUEUE env_q;
+ QUEUE_INIT(&env_q);
+ // Convert env vars to wchar_t and calculate how big the final env block
+ // needs to be
+ for (size_t i = 0; i < denv_size; i++) {
+ EnvNode *env_node = xmalloc(sizeof(*env_node));
+ rc = utf8_to_utf16(env[i], -1, &env_node->str);
+ if (rc != 0) {
+ goto cleanup;
+ }
+ env_node->len = wcslen(env_node->str) + 1;
+ env_block_len += env_node->len;
+ QUEUE_INSERT_TAIL(&env_q, &env_node->node);
+ }
+
+ // Additional '\0' after the final entry
+ env_block_len++;
+
+ *env_block = xmalloc(sizeof(**env_block) * env_block_len);
+ wchar_t *pos = *env_block;
+
+ QUEUE_FOREACH(q, &env_q) {
+ EnvNode *env_node = QUEUE_DATA(q, EnvNode, node);
+ memcpy(pos, env_node->str, env_node->len * sizeof(*pos));
+ pos += env_node->len;
+ }
+
+ *pos = L'\0';
+
+cleanup:
+ q = QUEUE_HEAD(&env_q);
+ while (q != &env_q) {
+ QUEUE *next = q->next;
+ EnvNode *env_node = QUEUE_DATA(q, EnvNode, node);
+ XFREE_CLEAR(env_node->str);
+ QUEUE_REMOVE(q);
+ xfree(env_node);
+ q = next;
+ }
+
+ return rc;
+}
diff --git a/src/nvim/os/pty_process_win.h b/src/nvim/os/pty_process_win.h
index 8ad5ba7286..f8ec79a3d6 100644
--- a/src/nvim/os/pty_process_win.h
+++ b/src/nvim/os/pty_process_win.h
@@ -37,7 +37,6 @@ static inline PtyProcess pty_process_init(Loop *loop, void *data)
{
PtyProcess rv;
rv.process = process_init(loop, kProcessTypePty, data);
- rv.term_name = NULL;
rv.width = 80;
rv.height = 24;
rv.object.winpty = NULL;
diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c
index 4b6533cd0c..5cf628935f 100644
--- a/src/nvim/os/time.c
+++ b/src/nvim/os/time.c
@@ -97,7 +97,7 @@ void os_microdelay(uint64_t us, bool ignoreinput)
const int rv = uv_cond_timedwait(&delay_cond, &delay_mutex, ns_delta);
if (0 != rv && UV_ETIMEDOUT != rv) {
- assert(false);
+ abort();
break;
} // Else: Timeout proceeded normally.
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index a625c09f78..dfd38a6eca 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -3665,7 +3665,7 @@ static int qf_open_new_cwindow(qf_info_T *qi, int height)
static void qf_set_title_var(qf_list_T *qfl)
{
if (qfl->qf_title != NULL) {
- set_internal_string_var((char_u *)"w:quickfix_title", qfl->qf_title);
+ set_internal_string_var("w:quickfix_title", qfl->qf_title);
}
}
@@ -4951,7 +4951,7 @@ void ex_cfile(exarg_T *eap)
}
}
if (*eap->arg != NUL) {
- set_string_option_direct((char_u *)"ef", -1, eap->arg, OPT_FREE, 0);
+ set_string_option_direct("ef", -1, eap->arg, OPT_FREE, 0);
}
char_u *enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc;
@@ -5264,7 +5264,7 @@ void ex_vimgrep(exarg_T *eap)
qf_new_list(qi, title);
}
- // parse the list of arguments
+ // Parse the list of arguments, wildcards have already been expanded.
if (get_arglist_exp(p, &fcount, &fnames, true) == FAIL) {
goto theend;
}
@@ -5648,7 +5648,7 @@ static int get_qfline_items(qfline_T *qfp, list_T *list)
== FAIL)) {
// tv_dict_add* fail only if key already exist, but this is a newly
// allocated dictionary which is thus guaranteed to have no existing keys.
- assert(false);
+ abort();
}
return OK;
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index a78f905a70..6b6c51d836 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -5092,9 +5092,9 @@ static void redraw_custom_statusline(win_T *wp)
// When there is an error disable the statusline, otherwise the
// display is messed up with errors and a redraw triggers the problem
// again and again.
- set_string_option_direct((char_u *)"statusline", -1,
- (char_u *)"", OPT_FREE | (*wp->w_p_stl != NUL
- ? OPT_LOCAL : OPT_GLOBAL), SID_ERROR);
+ set_string_option_direct("statusline", -1, (char_u *)"",
+ OPT_FREE | (*wp->w_p_stl != NUL
+ ? OPT_LOCAL : OPT_GLOBAL), SID_ERROR);
}
did_emsg |= saved_did_emsg;
entered = false;
@@ -5175,7 +5175,7 @@ get_keymap_str (
static void
win_redr_custom (
win_T *wp,
- int draw_ruler /* TRUE or FALSE */
+ bool draw_ruler
)
{
static int entered = FALSE;
@@ -6852,7 +6852,7 @@ void draw_tabline(void)
did_emsg = false;
win_redr_custom(NULL, false);
if (did_emsg) {
- set_string_option_direct((char_u *)"tabline", -1,
+ set_string_option_direct("tabline", -1,
(char_u *)"", OPT_FREE, SID_ERROR);
}
did_emsg |= saved_did_emsg;
@@ -7114,11 +7114,12 @@ static void win_redr_ruler(win_T *wp, int always)
if (*p_ruf) {
int save_called_emsg = called_emsg;
- called_emsg = FALSE;
- win_redr_custom(wp, TRUE);
- if (called_emsg)
- set_string_option_direct((char_u *)"rulerformat", -1,
- (char_u *)"", OPT_FREE, SID_ERROR);
+ called_emsg = false;
+ win_redr_custom(wp, true);
+ if (called_emsg) {
+ set_string_option_direct("rulerformat", -1, (char_u *)"",
+ OPT_FREE, SID_ERROR);
+ }
called_emsg |= save_called_emsg;
return;
}
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index 2444910bb3..c0e787380f 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -765,7 +765,7 @@ static ShaDaReadResult sd_reader_skip(ShaDaReadDef *const sd_reader,
(uint64_t) offset);
return kSDReadStatusNotShaDa;
}
- assert(false);
+ abort();
}
return kSDReadStatusSuccess;
}
@@ -1224,7 +1224,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
}
case kSDReadStatusFinished: {
// Should be handled by the while condition.
- assert(false);
+ abort();
}
case kSDReadStatusNotShaDa:
case kSDReadStatusReadError: {
@@ -1236,7 +1236,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
}
switch (cur_entry.type) {
case kSDItemMissing: {
- assert(false);
+ abort();
}
case kSDItemUnknown: {
break;
@@ -1628,7 +1628,7 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
((size_t) (!CHECK_DEFAULT(entry, attr)))
switch (entry.type) {
case kSDItemMissing: {
- assert(false);
+ abort();
}
case kSDItemUnknown: {
if (spacker->callback(spacker->data, entry.data.unknown_item.contents,
@@ -1850,7 +1850,7 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
break;
}
default: {
- assert(false);
+ abort();
}
}
}
@@ -2147,7 +2147,7 @@ static inline ShaDaWriteResult shada_read_when_writing(
}
case kSDReadStatusFinished: {
// Should be handled by the while condition.
- assert(false);
+ abort();
}
case kSDReadStatusNotShaDa: {
ret = kSDWriteReadNotShada;
@@ -2184,7 +2184,7 @@ static inline ShaDaWriteResult shada_read_when_writing(
}
case kSDItemHeader:
case kSDItemBufferList: {
- assert(false);
+ abort();
}
case kSDItemUnknown: {
ret = shada_pack_entry(packer, entry, 0);
@@ -4044,7 +4044,7 @@ shada_read_next_item_start:
}
case kSDItemMissing:
case kSDItemUnknown: {
- assert(false);
+ abort();
}
}
entry->type = (ShadaEntryType) type_u64;
diff --git a/src/nvim/sign_defs.h b/src/nvim/sign_defs.h
index c898dba890..19c0263cf1 100644
--- a/src/nvim/sign_defs.h
+++ b/src/nvim/sign_defs.h
@@ -24,11 +24,11 @@ typedef struct signlist signlist_T;
struct signlist
{
int id; // unique identifier for each placed sign
- linenr_T lnum; // line number which has this sign
int typenr; // typenr of sign
+ int priority; // priority for highlighting
bool has_text_or_icon; // has text or icon
+ linenr_T lnum; // line number which has this sign
signgroup_T *group; // sign group
- int priority; // priority for highlighting
signlist_T *next; // next signlist entry
signlist_T *prev; // previous entry -- for easy reordering
};
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 6425c9fed5..fd1e01395a 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -6624,7 +6624,7 @@ void ex_spelldump(exarg_T *eap)
if (no_spell_checking(curwin)) {
return;
}
- get_option_value((char_u *)"spl", &dummy, &spl, OPT_LOCAL);
+ get_option_value("spl", &dummy, &spl, OPT_LOCAL);
// Create a new empty buffer in a new window.
do_cmdline_cmd("new");
diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c
index 90af010164..3c125959a9 100644
--- a/src/nvim/spellfile.c
+++ b/src/nvim/spellfile.c
@@ -5387,7 +5387,8 @@ spell_add_word (
len, word, NameBuff);
}
}
- if (fseek(fd, fpos_next, SEEK_SET) <= 0) {
+ if (fseek(fd, fpos_next, SEEK_SET) != 0) {
+ PERROR(_("Seek error in spellfile"));
break;
}
}
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index f99eca7953..547d953be9 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -3419,7 +3419,7 @@ static void syn_cmd_on(exarg_T *eap, int syncing)
*/
static void syn_cmd_enable(exarg_T *eap, int syncing)
{
- set_internal_string_var((char_u *)"syntax_cmd", (char_u *)"enable");
+ set_internal_string_var("syntax_cmd", (char_u *)"enable");
syn_cmd_onoff(eap, "syntax");
do_unlet(S_LEN("g:syntax_cmd"), true);
}
@@ -3432,7 +3432,7 @@ static void syn_cmd_reset(exarg_T *eap, int syncing)
{
eap->nextcmd = check_nextcmd(eap->arg);
if (!eap->skip) {
- set_internal_string_var((char_u *)"syntax_cmd", (char_u *)"reset");
+ set_internal_string_var("syntax_cmd", (char_u *)"reset");
do_cmdline_cmd("runtime! syntax/syncolor.vim");
do_unlet(S_LEN("g:syntax_cmd"), true);
}
@@ -5614,14 +5614,14 @@ void ex_ownsyntax(exarg_T *eap)
// Move value of b:current_syntax to w:current_syntax.
new_value = get_var_value("b:current_syntax");
if (new_value != NULL) {
- set_internal_string_var((char_u *)"w:current_syntax", new_value);
+ set_internal_string_var("w:current_syntax", new_value);
}
// Restore value of b:current_syntax.
if (old_value == NULL) {
do_unlet(S_LEN("b:current_syntax"), true);
} else {
- set_internal_string_var((char_u *)"b:current_syntax", old_value);
+ set_internal_string_var("b:current_syntax", old_value);
xfree(old_value);
}
}
diff --git a/src/nvim/tag.c b/src/nvim/tag.c
index c6b1a0d04c..84ca240734 100644
--- a/src/nvim/tag.c
+++ b/src/nvim/tag.c
@@ -1461,7 +1461,7 @@ find_tags(
p_ic = ignorecase_opt(pat, true, true);
break;
default:
- assert(false);
+ abort();
}
help_save = curbuf->b_help;
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index 39e2ca6171..642c443318 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -535,8 +535,44 @@ void terminal_send(Terminal *term, char *data, size_t size)
term->opts.write_cb(data, size, term->opts.data);
}
+static bool is_filter_char(int c)
+{
+ unsigned int flag = 0;
+ switch (c) {
+ case 0x08:
+ flag = TPF_BS;
+ break;
+ case 0x09:
+ flag = TPF_HT;
+ break;
+ case 0x0A:
+ case 0x0D:
+ break;
+ case 0x0C:
+ flag = TPF_FF;
+ break;
+ case 0x1b:
+ flag = TPF_ESC;
+ break;
+ case 0x7F:
+ flag = TPF_DEL;
+ break;
+ default:
+ if (c < ' ') {
+ flag = TPF_C0;
+ } else if (c >= 0x80 && c <= 0x9F) {
+ flag = TPF_C1;
+ }
+ }
+ return !!(tpf_flags & flag);
+}
+
void terminal_paste(long count, char_u **y_array, size_t y_size)
{
+ vterm_keyboard_start_paste(curbuf->terminal->vt);
+ terminal_flush_output(curbuf->terminal);
+ size_t buff_len = STRLEN(y_array[0]);
+ char_u *buff = xmalloc(buff_len);
for (int i = 0; i < count; i++) { // -V756
// feed the lines to the terminal
for (size_t j = 0; j < y_size; j++) {
@@ -544,9 +580,28 @@ void terminal_paste(long count, char_u **y_array, size_t y_size)
// terminate the previous line
terminal_send(curbuf->terminal, "\n", 1);
}
- terminal_send(curbuf->terminal, (char *)y_array[j], STRLEN(y_array[j]));
+ size_t len = STRLEN(y_array[j]);
+ if (len > buff_len) {
+ buff = xrealloc(buff, len);
+ buff_len = len;
+ }
+ char_u *dst = buff;
+ char_u *src = y_array[j];
+ while (*src != '\0') {
+ len = (size_t)utf_ptr2len(src);
+ int c = utf_ptr2char(src);
+ if (!is_filter_char(c)) {
+ memcpy(dst, src, len);
+ dst += len;
+ }
+ src += len;
+ }
+ terminal_send(curbuf->terminal, (char *)buff, (size_t)(dst - buff));
}
}
+ xfree(buff);
+ vterm_keyboard_end_paste(curbuf->terminal->vt);
+ terminal_flush_output(curbuf->terminal);
}
void terminal_flush_output(Terminal *term)
diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim
index c571e37ac3..1f3a45a9ab 100644
--- a/src/nvim/testdir/test_autocmd.vim
+++ b/src/nvim/testdir/test_autocmd.vim
@@ -1279,26 +1279,9 @@ func Test_TextYankPost()
bwipe!
endfunc
-func Test_nocatch_wipe_all_buffers()
- " Real nasty autocommand: wipe all buffers on any event.
- au * * bwipe *
- call assert_fails('next x', 'E93')
- bwipe
- au!
-endfunc
-
-func Test_nocatch_wipe_dummy_buffer()
- " Nasty autocommand: wipe buffer on any event.
- au * x bwipe
- call assert_fails('lv½ /x', 'E480')
- au!
-endfunc
-
-func Test_wipe_cbuffer()
- sv x
- au * * bw
- lb
- au!
+func Test_autocommand_all_events()
+ call assert_fails('au * * bwipe', 'E1155:')
+ call assert_fails('au * x bwipe', 'E1155:')
endfunc
" Test TextChangedI and TextChangedP
@@ -1956,4 +1939,15 @@ func Test_autocmd_window()
%bw!
endfunc
+func Test_autocmd_closes_window()
+ au BufNew,BufWinLeave * e %e
+ file yyy
+ au BufNew,BufWinLeave * ball
+ call assert_fails('n xxx', 'E143:')
+
+ bwipe %
+ au! BufNew
+ au! BufWinLeave
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_compiler.vim b/src/nvim/testdir/test_compiler.vim
index 9101f8cfa0..d361205baa 100644
--- a/src/nvim/testdir/test_compiler.vim
+++ b/src/nvim/testdir/test_compiler.vim
@@ -37,17 +37,27 @@ func Test_compiler()
bw!
endfunc
+func GetCompilerNames()
+ " return glob('$VIMRUNTIME/compiler/*.vim', 0, 1)
+ " \ ->map({i, v -> substitute(v, '.*[\\/]\([a-zA-Z0-9_\-]*\).vim', '\1', '')})
+ " \ ->sort()
+ return sort(map(glob('$VIMRUNTIME/compiler/*.vim', 0, 1), {i, v -> substitute(v, '.*[\\/]\([a-zA-Z0-9_\-]*\).vim', '\1', '')}))
+endfunc
+
func Test_compiler_without_arg()
let runtime = substitute($VIMRUNTIME, '\\', '/', 'g')
let a = split(execute('compiler'))
- call assert_match(runtime .. '/compiler/ant.vim$', a[0])
- call assert_match(runtime .. '/compiler/bcc.vim$', a[1])
- call assert_match(runtime .. '/compiler/xo.vim$', a[-1])
+ let exp = GetCompilerNames()
+ call assert_match(runtime .. '/compiler/' .. exp[0] .. '.vim$', a[0])
+ call assert_match(runtime .. '/compiler/' .. exp[1] .. '.vim$', a[1])
+ call assert_match(runtime .. '/compiler/' .. exp[-1] .. '.vim$', a[-1])
endfunc
func Test_compiler_completion()
+ " let clist = GetCompilerNames()->join(' ')
+ let clist = join(GetCompilerNames(), ' ')
call feedkeys(":compiler \<C-A>\<C-B>\"\<CR>", 'tx')
- call assert_match('^"compiler ant bcc .* xmlwf xo$', @:)
+ call assert_match('^"compiler ' .. clist .. '$', @:)
call feedkeys(":compiler p\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"compiler pbx perl php pylint pyunit', @:)
diff --git a/src/nvim/testdir/test_eval_stuff.vim b/src/nvim/testdir/test_eval_stuff.vim
index 061364fb73..ff50d53d86 100644
--- a/src/nvim/testdir/test_eval_stuff.vim
+++ b/src/nvim/testdir/test_eval_stuff.vim
@@ -22,6 +22,17 @@ func Test_E963()
call assert_equal(v_o, v:oldfiles)
endfunc
+func Test_for_invalid()
+ call assert_fails("for x in 99", 'E714:')
+ call assert_fails("for x in 'asdf'", 'E714:')
+ call assert_fails("for x in {'a': 9}", 'E714:')
+
+ if 0
+ /1/5/2/s/\n
+ endif
+ redraw
+endfunc
+
func Test_mkdir_p()
call mkdir('Xmkdir/nested', 'p')
call assert_true(isdirectory('Xmkdir/nested'))
diff --git a/src/nvim/testdir/test_excmd.vim b/src/nvim/testdir/test_excmd.vim
index 20508b12d3..98a3e60368 100644
--- a/src/nvim/testdir/test_excmd.vim
+++ b/src/nvim/testdir/test_excmd.vim
@@ -131,3 +131,11 @@ func Test_confirm_cmd_cancel()
\ term_getline(buf, 20))}, 1000)
call StopVimInTerminal(buf)
endfunc
+
+" Test for the :winsize command
+func Test_winsize_cmd()
+ call assert_fails('winsize 1', 'E465:')
+ call assert_fails('winsize 1 x', 'E465:')
+ call assert_fails('win_getid(1)', 'E475: Invalid argument: _getid(1)')
+ " Actually changing the window size would be flaky.
+endfunc
diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim
index f71da92bf8..88320e0c22 100644
--- a/src/nvim/testdir/test_mksession.vim
+++ b/src/nvim/testdir/test_mksession.vim
@@ -291,6 +291,32 @@ endfunc
endif
+func Test_mkview_open_folds()
+ enew!
+
+ call append(0, ['a', 'b', 'c'])
+ 1,3fold
+ " zR affects 'foldlevel', make sure the option is applied after the folds
+ " have been recreated.
+ normal zR
+ write! Xtestfile
+
+ call assert_equal(-1, foldclosed(1))
+ call assert_equal(-1, foldclosed(2))
+ call assert_equal(-1, foldclosed(3))
+
+ mkview! Xtestview
+ source Xtestview
+
+ call assert_equal(-1, foldclosed(1))
+ call assert_equal(-1, foldclosed(2))
+ call assert_equal(-1, foldclosed(3))
+
+ call delete('Xtestview')
+ call delete('Xtestfile')
+ %bwipe
+endfunc
+
" Test :mkview with a file argument.
func Test_mkview_file()
" Create a view with line number and a fold.
diff --git a/src/nvim/testdir/test_options.vim b/src/nvim/testdir/test_options.vim
index 84d99ebb74..5a10c9baa6 100644
--- a/src/nvim/testdir/test_options.vim
+++ b/src/nvim/testdir/test_options.vim
@@ -330,12 +330,10 @@ func Test_set_ttytype()
set ttytype=xterm
call assert_equal('xterm', &ttytype)
call assert_equal(&ttytype, &term)
- " "set ttytype=" gives E522 instead of E529
- " in travis on some builds. Why? Catch both for now
try
set ttytype=
call assert_report('set ttytype= did not fail')
- catch /E529\|E522/
+ catch /E529/
endtry
" Some systems accept any terminal name and return dumb settings,
diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim
index 48c0a83053..704fdacdcd 100644
--- a/src/nvim/testdir/test_quickfix.vim
+++ b/src/nvim/testdir/test_quickfix.vim
@@ -2650,6 +2650,13 @@ func Test_vimgrep()
call XvimgrepTests('l')
endfunc
+func Test_vimgrep_wildcards_expanded_once()
+ new X[id-01] file.txt
+ call setline(1, 'some text to search for')
+ vimgrep text %
+ bwipe!
+endfunc
+
" Test for incsearch highlighting of the :vimgrep pattern
" This test used to cause "E315: ml_get: invalid lnum" errors.
func Test_vimgrep_incsearch()
@@ -3540,7 +3547,7 @@ func Test_lbuffer_crash()
sv Xtest
augroup QF_Test
au!
- au * * bw
+ au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bw
augroup END
lbuffer
augroup QF_Test
@@ -3552,7 +3559,7 @@ endfunc
func Test_lexpr_crash()
augroup QF_Test
au!
- au * * call setloclist(0, [], 'f')
+ au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
augroup END
lexpr ""
augroup QF_Test
@@ -3587,7 +3594,7 @@ func Test_lvimgrep_crash()
sv Xtest
augroup QF_Test
au!
- au * * call setloclist(0, [], 'f')
+ au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
augroup END
lvimgrep quickfix test_quickfix.vim
augroup QF_Test
@@ -3889,7 +3896,7 @@ func Test_lbuffer_with_bwipe()
new
new
augroup nasty
- au * * bwipe
+ au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bwipe
augroup END
lbuffer
augroup nasty
@@ -3902,9 +3909,9 @@ endfunc
func Xexpr_acmd_freelist(cchar)
call s:setup_commands(a:cchar)
- " This was using freed memory.
+ " This was using freed memory (but with what events?)
augroup nasty
- au * * call g:Xsetlist([], 'f')
+ au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call g:Xsetlist([], 'f')
augroup END
Xexpr "x"
augroup nasty
diff --git a/src/nvim/testdir/test_window_cmd.vim b/src/nvim/testdir/test_window_cmd.vim
index 687b1cb989..969b75d424 100644
--- a/src/nvim/testdir/test_window_cmd.vim
+++ b/src/nvim/testdir/test_window_cmd.vim
@@ -513,8 +513,8 @@ func Test_window_colon_command()
endfunc
func Test_access_freed_mem()
- " This was accessing freed memory
- au * 0 vs xxx
+ " This was accessing freed memory (but with what events?)
+ au BufEnter,BufLeave,WinEnter,WinLeave 0 vs xxx
arg 0
argadd
all
diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c
index 124f96e039..3e683a4926 100644
--- a/src/nvim/tui/input.c
+++ b/src/nvim/tui/input.c
@@ -297,7 +297,7 @@ static void forward_mouse_event(TermInput *input, TermKeyKey *key)
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Release");
break;
case TERMKEY_MOUSE_UNKNOWN:
- assert(false);
+ abort();
}
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "><%d,%d>", col, row);
diff --git a/src/nvim/ui_compositor.c b/src/nvim/ui_compositor.c
index 9d3ec21949..06efc9fa99 100644
--- a/src/nvim/ui_compositor.c
+++ b/src/nvim/ui_compositor.c
@@ -157,7 +157,7 @@ bool ui_comp_put_grid(ScreenGrid *grid, int row, int col, int height, int width,
#ifndef NDEBUG
for (size_t i = 0; i < kv_size(layers); i++) {
if (kv_A(layers, i) == grid) {
- assert(false);
+ abort();
}
}
#endif
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 834d27cc84..deba3f6e49 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -300,7 +300,7 @@ static const int included_patches[] = {
1620,
1619,
1618,
- // 1617,
+ 1617,
// 1616,
1615,
1614,
@@ -392,7 +392,7 @@ static const int included_patches[] = {
1528,
1527,
1526,
- // 1525,
+ 1525,
1524,
1523,
1522,
@@ -462,7 +462,7 @@ static const int included_patches[] = {
1458,
1457,
1456,
- // 1455,
+ 1455,
1454,
1453,
1452,
diff --git a/src/nvim/viml/parser/expressions.c b/src/nvim/viml/parser/expressions.c
index 44b6ab5f5a..e9d82ca87d 100644
--- a/src/nvim/viml/parser/expressions.c
+++ b/src/nvim/viml/parser/expressions.c
@@ -2078,7 +2078,7 @@ viml_pexpr_parse_process_token:
case kExprLexMissing:
case kExprLexSpacing:
case kExprLexEOC: {
- assert(false);
+ abort();
}
case kExprLexInvalid: {
ERROR_FROM_TOKEN(cur_token);
@@ -3028,7 +3028,7 @@ viml_pexpr_parse_end:
// Until trailing "}" it is impossible to distinguish curly braces
// identifier and dictionary, so it must not appear in the stack like
// this.
- assert(false);
+ abort();
}
case kExprNodeInteger:
case kExprNodeFloat:
@@ -3042,7 +3042,7 @@ viml_pexpr_parse_end:
// These are plain values and not containers, for them it should only
// be possible to show up in the topmost stack element, but it was
// unconditionally popped at the start.
- assert(false);
+ abort();
}
case kExprNodeComma:
case kExprNodeColon: