aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.git-blame-ignore-revs13
-rw-r--r--.github/workflows/labeler.yml2
-rw-r--r--README.md4
-rw-r--r--runtime/doc/api.txt2
-rw-r--r--runtime/doc/autocmd.txt6
-rw-r--r--runtime/doc/options.txt3
-rw-r--r--runtime/doc/repeat.txt3
-rw-r--r--runtime/doc/vim_diff.txt1
-rw-r--r--runtime/lua/vim/diagnostic.lua23
-rw-r--r--src/nvim/api/autocmd.c2
-rw-r--r--src/nvim/api/keysets.lua2
-rw-r--r--src/nvim/buffer.c4
-rw-r--r--src/nvim/diff.c2
-rw-r--r--src/nvim/eval.c3
-rw-r--r--src/nvim/ex_docmd.c2
-rw-r--r--src/nvim/testdir/test_autocmd.vim17
-rw-r--r--src/nvim/window.c126
-rw-r--r--test/functional/api/autocmd_spec.lua30
-rw-r--r--test/functional/api/command_spec.lua7
-rw-r--r--test/functional/editor/tabpage_spec.lua17
-rw-r--r--test/functional/ex_cmds/cmd_map_spec.lua58
-rw-r--r--test/functional/ex_cmds/echo_spec.lua14
-rw-r--r--test/functional/ex_cmds/script_spec.lua14
-rw-r--r--test/functional/helpers.lua26
-rw-r--r--test/functional/legacy/assert_spec.lua12
-rw-r--r--test/functional/legacy/memory_usage_spec.lua17
-rw-r--r--test/functional/vimscript/lang_spec.lua1
27 files changed, 239 insertions, 172 deletions
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index bbca6b3339..737a9a249e 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -36,3 +36,16 @@ d90fb1c0bfc1e64c783c385a79e7de87013dadba
9c268263b1792d00b3ffdfd7495af2575862656e
8c74c895b300bcee5fa937a2329d1d4756567b42
40be47e0faef7aa015eb4ba44ceb1ee1a03e97cf
+4472c56d54f447040f6e8610b261b7efa0d04eb6
+a68faed02dc8e37b8f10da14dc02e33e6ed93947
+725cbe7d414f609e769081276f2a034e32a4337b
+7e3bdc75e44b9139d8afaea4381b53ae78b15746
+4ba12b3dda34472c193c9fa8ffd7d3bd5b6c04d6
+849f104c2789c884428fd45501912c6591a78e12
+38dd53c525054daf83dba27d7d46e90e8b41fa50
+6059784770c4c88fb6fe528b9f7634192fa1164e
+ee031eb5256bb83e0d6add2bae6fd943a4186ffe
+
+# typos
+d238b8f6003d34cae7f65ff7585b48a2cd9449fb
+4547137aaff32b20172870a549d3a28a3c7adf1c
diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml
index d50e0c1f92..7845ae92a3 100644
--- a/.github/workflows/labeler.yml
+++ b/.github/workflows/labeler.yml
@@ -30,6 +30,8 @@ jobs:
run: gh pr edit "$PR_NUMBER" --add-label "$(echo "$PR_TITLE" | sed -E 's|([[:alpha:]]+)(\(.*\))?!?:.*|\1|')" || true
- name: "Extract commit scope and add as label"
run: gh pr edit "$PR_NUMBER" --add-label "$(echo "$PR_TITLE" | sed -E 's|[[:alpha:]]+\((.+)\)!?:.*|\1|')" || true
+ - name: "Extract if the PR is a breaking change and add it as label"
+ run: gh pr edit "$PR_NUMBER" --add-label "$(echo "$PR_TITLE" | sed -E 's|[[:alpha:]]+(\(.*\))?!:.*|breaking-change|')" || true
request-reviewer:
if: github.event.pull_request.state == 'open' && github.event.pull_request.draft == false
diff --git a/README.md b/README.md
index 4ec5cf2be3..b5a469b32d 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,6 @@
-[![Neovim](https://raw.githubusercontent.com/neovim/neovim.github.io/master/logos/neovim-logo-300x87.png)](https://neovim.io)
+<h1 align="center">
+ <img src="https://raw.githubusercontent.com/neovim/neovim.github.io/master/logos/neovim-logo-300x87.png" alt="Neovim">
+</h1>
[Documentation](https://neovim.io/doc/general/) |
[Chat](https://app.element.io/#/room/#neovim:matrix.org) |
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt
index 02a27e15f8..0a8a3e9a2c 100644
--- a/runtime/doc/api.txt
+++ b/runtime/doc/api.txt
@@ -3282,7 +3282,7 @@ nvim_del_autocmd({id}) *nvim_del_autocmd()*
See also: ~
|nvim_create_autocmd()|
-nvim_do_autocmd({event}, {*opts}) *nvim_do_autocmd()*
+nvim_exec_autocmd({event}, {*opts}) *nvim_exec_autocmd()*
Execute an autocommand |autocmd-execute|.
Parameters: ~
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index ab0b0cd07c..54fb4c14a0 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -500,9 +500,9 @@ CursorMoved After the cursor was moved in Normal or Visual
of the cursor line has been changed, e.g. with
"x", "rx" or "p".
Not triggered when there is typeahead, while
- executing a script file, when an operator is
- pending, or when moving to another window while
- remaining at the same cursor position.
+ executing a script file, or when an operator
+ is pending. Always triggered when moving to
+ another window.
For an example see |match-parens|.
Note: Cannot be skipped with |:noautocmd|.
Careful: This is triggered very often, don't
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 8323ec3e9d..c0a7b73438 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -3670,8 +3670,7 @@ A jump table for the options with a short description can be found at |Q_op|.
0: never
1: only if there are at least two windows
2: always
- 3: have a global statusline at the bottom instead of one for
- each window
+ 3: always and ONLY the last window
The screen looks nicer with a status line if you have several
windows, but it takes another screen line. |status-line|
diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt
index 994f97bba0..508565dea4 100644
--- a/runtime/doc/repeat.txt
+++ b/runtime/doc/repeat.txt
@@ -182,8 +182,7 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|.
*:so* *:source* *load-vim-script*
:[range]so[urce] [file] Runs |Ex| commands or Lua code (".lua" files) from
- [file], or from the current buffer if no [file] is
- given.
+ [file], or current buffer if no [file].
Triggers the |SourcePre| autocommand.
*:source!*
:[range]so[urce]! {file}
diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt
index 9ca5faf112..59f085977b 100644
--- a/runtime/doc/vim_diff.txt
+++ b/runtime/doc/vim_diff.txt
@@ -180,6 +180,7 @@ Commands:
|:Man| is available by default, with many improvements such as completion
|:sign-define| accepts a `numhl` argument, to highlight the line number
|:match| can be invoked before highlight group is defined
+ |:source| works with Lua and anonymous (no file) scripts
Events:
|RecordingEnter|
diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua
index fcb1e61764..1ec66d7c55 100644
--- a/runtime/lua/vim/diagnostic.lua
+++ b/runtime/lua/vim/diagnostic.lua
@@ -1224,6 +1224,18 @@ function M.open_float(opts, ...)
opts = opts or {}
bufnr = get_bufnr(bufnr or opts.bufnr)
+
+ do
+ -- Resolve options with user settings from vim.diagnostic.config
+ -- Unlike the other decoration functions (e.g. set_virtual_text, set_signs, etc.) `open_float`
+ -- does not have a dedicated table for configuration options; instead, the options are mixed in
+ -- with its `opts` table which also includes "keyword" parameters. So we create a dedicated
+ -- options table that inherits missing keys from the global configuration before resolving.
+ local t = global_diagnostic_options.float
+ local float_opts = vim.tbl_extend("keep", opts, type(t) == "table" and t or {})
+ opts = get_resolved_options({ float = float_opts }, nil, bufnr).float
+ end
+
local scope = ({l = "line", c = "cursor", b = "buffer"})[opts.scope] or opts.scope or "line"
local lnum, col
if scope == "line" or scope == "cursor" then
@@ -1242,17 +1254,6 @@ function M.open_float(opts, ...)
error("Invalid value for option 'scope'")
end
- do
- -- Resolve options with user settings from vim.diagnostic.config
- -- Unlike the other decoration functions (e.g. set_virtual_text, set_signs, etc.) `open_float`
- -- does not have a dedicated table for configuration options; instead, the options are mixed in
- -- with its `opts` table which also includes "keyword" parameters. So we create a dedicated
- -- options table that inherits missing keys from the global configuration before resolving.
- local t = global_diagnostic_options.float
- local float_opts = vim.tbl_extend("keep", opts, type(t) == "table" and t or {})
- opts = get_resolved_options({ float = float_opts }, nil, bufnr).float
- end
-
local diagnostics = get_diagnostics(bufnr, opts, true)
if scope == "line" then
diff --git a/src/nvim/api/autocmd.c b/src/nvim/api/autocmd.c
index 9aaa0418dc..49f6f98ba4 100644
--- a/src/nvim/api/autocmd.c
+++ b/src/nvim/api/autocmd.c
@@ -695,7 +695,7 @@ void nvim_del_augroup_by_name(String name)
/// - modeline (bool) optional: defaults to true. Process the
/// modeline after the autocommands |<nomodeline>|.
/// @see |:doautocmd|
-void nvim_do_autocmd(Object event, Dict(do_autocmd) *opts, Error *err)
+void nvim_exec_autocmd(Object event, Dict(exec_autocmd) *opts, Error *err)
FUNC_API_SINCE(9)
{
int au_group = AUGROUP_ALL;
diff --git a/src/nvim/api/keysets.lua b/src/nvim/api/keysets.lua
index b6264cdfab..6a29b0fb59 100644
--- a/src/nvim/api/keysets.lua
+++ b/src/nvim/api/keysets.lua
@@ -133,7 +133,7 @@ return {
"nested";
"pattern";
};
- do_autocmd = {
+ exec_autocmd = {
"buffer";
"group";
"modeline";
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 4ca752e747..bf592a626d 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -590,6 +590,10 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last)
// Remove the buffer from the list.
if (wipe_buf) {
+ // Do not wipe out the buffer if it is used in a window.
+ if (buf->b_nwindows > 0) {
+ return false;
+ }
if (buf->b_sfname != buf->b_ffname) {
XFREE_CLEAR(buf->b_sfname);
} else {
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index 1b8a9f41e9..a6bbe40999 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -1536,7 +1536,7 @@ static void diff_read(int idx_orig, int idx_new, diffio_T *dio)
long off;
int i;
int notset = true; // block "*dp" not set yet
- diffhunk_T *hunk;
+ diffhunk_T *hunk = NULL; // init to avoid gcc warning
enum {
DIFF_ED,
DIFF_UNIFIED,
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index fbbc543893..6c72c2866e 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -9217,6 +9217,8 @@ dictitem_T *find_var_in_ht(hashtab_T *const ht, int htname, const char *const va
/// Finds the dict (g:, l:, s:, …) and hashtable used for a variable.
///
+/// Assigns SID if s: scope is accessed from Lua or anonymous Vimscript. #15994
+///
/// @param[in] name Variable name, possibly with scope prefix.
/// @param[in] name_len Variable name length.
/// @param[out] varname Will be set to the start of the name without scope
@@ -9304,6 +9306,7 @@ static hashtab_T *find_var_ht_dict(const char *name, const size_t name_len, cons
}
}
if (current_sctx.sc_sid == SID_STR || current_sctx.sc_sid == SID_LUA) {
+ // Create SID if s: scope is accessed from Lua or anon Vimscript. #15994
new_script_item(NULL, &current_sctx.sc_sid);
}
*d = &SCRIPT_SV(current_sctx.sc_sid)->sv_dict;
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 0dbc9d6b14..20325509c4 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -6839,7 +6839,7 @@ void tabpage_close_other(tabpage_T *tp, int forceit)
// Autocommands may delete the tab page under our fingers and we may
// fail to close a window with a modified buffer.
- if (!valid_tabpage(tp) || tp->tp_firstwin == wp) {
+ if (!valid_tabpage(tp) || tp->tp_lastwin == wp) {
break;
}
}
diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim
index d4005e41e8..76c69ad10b 100644
--- a/src/nvim/testdir/test_autocmd.vim
+++ b/src/nvim/testdir/test_autocmd.vim
@@ -2611,4 +2611,21 @@ func Test_autocmd_closing_cmdwin()
only
endfunc
+func Test_bufwipeout_changes_window()
+ " This should not crash, but we don't have any expectations about what
+ " happens, changing window in BufWipeout has unpredictable results.
+ tabedit
+ let g:window_id = win_getid()
+ topleft new
+ setlocal bufhidden=wipe
+ autocmd BufWipeout <buffer> call win_gotoid(g:window_id)
+ tabprevious
+ +tabclose
+
+ unlet g:window_id
+ au! BufWipeout
+ %bwipe!
+endfunc
+
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/window.c b/src/nvim/window.c
index fa71a08b94..6bd2ef3ef6 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -971,7 +971,6 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
int before;
int minheight;
int wmh1;
- int hsep_height;
bool did_set_fraction = false;
// aucmd_win should always remain floating
@@ -1084,7 +1083,6 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
}
}
} else {
- hsep_height = STATUS_HEIGHT;
layout = FR_COL;
/*
@@ -1093,7 +1091,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
*/
// Current window requires at least 1 space.
wmh1 = p_wmh == 0 ? 1 : p_wmh;
- needed = wmh1 + hsep_height;
+ needed = wmh1 + STATUS_HEIGHT;
if (flags & WSP_ROOM) {
needed += p_wh - wmh1;
}
@@ -1135,15 +1133,15 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
new_size = oldwin_height / 2;
}
- if (new_size > available - minheight - hsep_height) {
- new_size = available - minheight - hsep_height;
+ if (new_size > available - minheight - STATUS_HEIGHT) {
+ new_size = available - minheight - STATUS_HEIGHT;
}
if (new_size < wmh1) {
new_size = wmh1;
}
// if it doesn't fit in the current window, need win_equal()
- if (oldwin_height - new_size - hsep_height < p_wmh) {
+ if (oldwin_height - new_size - STATUS_HEIGHT < p_wmh) {
do_equal = true;
}
@@ -1156,7 +1154,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
set_fraction(oldwin);
did_set_fraction = true;
- win_setheight_win(oldwin->w_height + new_size + hsep_height,
+ win_setheight_win(oldwin->w_height + new_size + STATUS_HEIGHT,
oldwin);
oldwin_height = oldwin->w_height;
if (need_status) {
@@ -1173,7 +1171,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
while (frp != NULL) {
if (frp->fr_win != oldwin && frp->fr_win != NULL
&& (frp->fr_win->w_height > new_size
- || frp->fr_win->w_height > oldwin_height - new_size - hsep_height)) {
+ || frp->fr_win->w_height > oldwin_height - new_size - STATUS_HEIGHT)) {
do_equal = true;
break;
}
@@ -2021,7 +2019,6 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int
int room = 0;
int new_size;
int has_next_curwin = 0;
- int hsep_height;
bool hnc;
if (topfr->fr_layout == FR_LEAF) {
@@ -2167,7 +2164,6 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int
totwincount -= wincount;
}
} else { // topfr->fr_layout == FR_COL
- hsep_height = STATUS_HEIGHT;
topfr->fr_width = width;
topfr->fr_height = height;
@@ -2182,7 +2178,7 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int
} else {
extra_sep = 0;
}
- totwincount = (n + extra_sep) / (p_wmh + hsep_height);
+ totwincount = (n + extra_sep) / (p_wmh + STATUS_HEIGHT);
has_next_curwin = frame_has_win(topfr, next_curwin);
/*
@@ -2217,7 +2213,7 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int
} else {
// These windows don't use up room.
totwincount -= (n + (fr->fr_next == NULL
- ? extra_sep : 0)) / (p_wmh + hsep_height);
+ ? extra_sep : 0)) / (p_wmh + STATUS_HEIGHT);
}
room -= new_size - n;
if (room < 0) {
@@ -2263,7 +2259,7 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int
// Compute the maximum number of windows vert. in "fr".
n = frame_minheight(fr, NOWIN);
wincount = (n + (fr->fr_next == NULL ? extra_sep : 0))
- / (p_wmh + hsep_height);
+ / (p_wmh + STATUS_HEIGHT);
m = frame_minheight(fr, next_curwin);
if (has_next_curwin) {
hnc = frame_has_win(fr, next_curwin);
@@ -2350,6 +2346,30 @@ void entering_window(win_T *const win)
}
}
+void win_init_empty(win_T *wp)
+{
+ redraw_later(wp, NOT_VALID);
+ wp->w_lines_valid = 0;
+ wp->w_cursor.lnum = 1;
+ wp->w_curswant = wp->w_cursor.col = 0;
+ wp->w_cursor.coladd = 0;
+ wp->w_pcmark.lnum = 1; // pcmark not cleared but set to line 1
+ wp->w_pcmark.col = 0;
+ wp->w_prev_pcmark.lnum = 0;
+ wp->w_prev_pcmark.col = 0;
+ wp->w_topline = 1;
+ wp->w_topfill = 0;
+ wp->w_botline = 2;
+ wp->w_s = &wp->w_buffer->b_s;
+}
+
+/// Init the current window "curwin".
+/// Called when a new file is being edited.
+void curwin_init(void)
+{
+ win_init_empty(curwin);
+}
+
/// Closes all windows for buffer `buf` unless there is only one non-floating window.
///
/// @param keep_curwin don't close `curwin`
@@ -2867,6 +2887,13 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
for (ptp = first_tabpage; ptp != NULL && ptp != tp; ptp = ptp->tp_next) {
}
if (ptp == NULL || tp == curtab) {
+ // If the buffer was removed from the window we have to give it any
+ // buffer.
+ if (win_valid_any_tab(win) && win->w_buffer == NULL) {
+ win->w_buffer = firstbuf;
+ firstbuf->b_nwindows++;
+ win_init_empty(win);
+ }
return;
}
@@ -3793,33 +3820,6 @@ void close_others(int message, int forceit)
}
}
-
-/*
- * Init the current window "curwin".
- * Called when a new file is being edited.
- */
-void curwin_init(void)
-{
- win_init_empty(curwin);
-}
-
-void win_init_empty(win_T *wp)
-{
- redraw_later(wp, NOT_VALID);
- wp->w_lines_valid = 0;
- wp->w_cursor.lnum = 1;
- wp->w_curswant = wp->w_cursor.col = 0;
- wp->w_cursor.coladd = 0;
- wp->w_pcmark.lnum = 1; // pcmark not cleared but set to line 1
- wp->w_pcmark.col = 0;
- wp->w_prev_pcmark.lnum = 0;
- wp->w_prev_pcmark.col = 0;
- wp->w_topline = 1;
- wp->w_topfill = 0;
- wp->w_botline = 2;
- wp->w_s = &wp->w_buffer->b_s;
-}
-
/*
* Allocate the first window and put an empty buffer in it.
* Called from main().
@@ -6510,38 +6510,32 @@ void last_status(bool morewin)
}
// Look for resizable frames and take lines from them to make room for the statusline
-static void resize_frame_for_status(frame_T *fr, int resize_amount)
+static void resize_frame_for_status(frame_T *fr)
{
// Find a frame to take a line from.
frame_T *fp = fr;
win_T *wp = fr->fr_win;
- int n;
- while (resize_amount > 0) {
- while (fp->fr_height <= frame_minheight(fp, NULL)) {
- if (fp == topframe) {
- emsg(_(e_noroom));
- return;
- }
- // In a column of frames: go to frame above. If already at
- // the top or in a row of frames: go to parent.
- if (fp->fr_parent->fr_layout == FR_COL && fp->fr_prev != NULL) {
- fp = fp->fr_prev;
- } else {
- fp = fp->fr_parent;
- }
+ while (fp->fr_height <= frame_minheight(fp, NULL)) {
+ if (fp == topframe) {
+ emsg(_(e_noroom));
+ return;
}
- n = MIN(fp->fr_height - frame_minheight(fp, NULL), resize_amount);
- resize_amount -= n;
-
- if (fp != fr) {
- frame_new_height(fp, fp->fr_height - n, false, false);
- frame_fix_height(wp);
- (void)win_comp_pos();
+ // In a column of frames: go to frame above. If already at
+ // the top or in a row of frames: go to parent.
+ if (fp->fr_parent->fr_layout == FR_COL && fp->fr_prev != NULL) {
+ fp = fp->fr_prev;
} else {
- win_new_height(wp, wp->w_height - n);
+ fp = fp->fr_parent;
}
}
+ if (fp != fr) {
+ frame_new_height(fp, fp->fr_height - 1, false, false);
+ frame_fix_height(wp);
+ (void)win_comp_pos();
+ } else {
+ win_new_height(wp, wp->w_height - 1);
+ }
}
static void last_status_rec(frame_T *fr, bool statusline, bool is_stl_global)
@@ -6562,15 +6556,12 @@ static void last_status_rec(frame_T *fr, bool statusline, bool is_stl_global)
} else if (wp->w_status_height == 0 && !is_stl_global && statusline) {
// Add statusline to window if needed
wp->w_status_height = STATUS_HEIGHT;
- resize_frame_for_status(fr, STATUS_HEIGHT);
+ resize_frame_for_status(fr);
comp_col();
}
} else if (wp->w_status_height != 0 && is_stl_global) {
// If statusline is global and the window has a statusline, replace it with a horizontal
// separator
- if (STATUS_HEIGHT - 1 != 0) {
- win_new_height(wp, wp->w_height + STATUS_HEIGHT - 1);
- }
wp->w_status_height = 0;
wp->w_hsep_height = 1;
comp_col();
@@ -6578,7 +6569,6 @@ static void last_status_rec(frame_T *fr, bool statusline, bool is_stl_global)
// If statusline isn't global and the window doesn't have a statusline, re-add it
wp->w_status_height = STATUS_HEIGHT;
wp->w_hsep_height = 0;
- resize_frame_for_status(fr, STATUS_HEIGHT - 1);
comp_col();
}
redraw_all_later(SOME_VALID);
diff --git a/test/functional/api/autocmd_spec.lua b/test/functional/api/autocmd_spec.lua
index a58ca00a75..3b14ae9bf7 100644
--- a/test/functional/api/autocmd_spec.lua
+++ b/test/functional/api/autocmd_spec.lua
@@ -168,7 +168,7 @@ describe('autocmd api', function()
})
]]
- meths.do_autocmd("User", {pattern = "Test"})
+ meths.exec_autocmd("User", {pattern = "Test"})
eq({{
buflocal = false,
command = 'A test autocommand',
@@ -179,7 +179,7 @@ describe('autocmd api', function()
pattern = 'Test',
}}, meths.get_autocmds({event = "User", pattern = "Test"}))
meths.set_var("some_condition", true)
- meths.do_autocmd("User", {pattern = "Test"})
+ meths.exec_autocmd("User", {pattern = "Test"})
eq({}, meths.get_autocmds({event = "User", pattern = "Test"}))
end)
end)
@@ -490,7 +490,7 @@ describe('autocmd api', function()
end)
end)
- describe('nvim_do_autocmd', function()
+ describe('nvim_exec_autocmd', function()
it("can trigger builtin autocmds", function()
meths.set_var("autocmd_executed", false)
@@ -500,7 +500,7 @@ describe('autocmd api', function()
})
eq(false, meths.get_var("autocmd_executed"))
- meths.do_autocmd("BufReadPost", {})
+ meths.exec_autocmd("BufReadPost", {})
eq(true, meths.get_var("autocmd_executed"))
end)
@@ -514,10 +514,10 @@ describe('autocmd api', function()
})
-- Doesn't execute for other non-matching events
- meths.do_autocmd("CursorHold", { buffer = 1 })
+ meths.exec_autocmd("CursorHold", { buffer = 1 })
eq(-1, meths.get_var("buffer_executed"))
- meths.do_autocmd("BufLeave", { buffer = 1 })
+ meths.exec_autocmd("BufLeave", { buffer = 1 })
eq(1, meths.get_var("buffer_executed"))
end)
@@ -531,7 +531,7 @@ describe('autocmd api', function()
})
-- Doesn't execute for other non-matching events
- meths.do_autocmd("CursorHold", { buffer = 1 })
+ meths.exec_autocmd("CursorHold", { buffer = 1 })
eq('none', meths.get_var("filename_executed"))
meths.command('edit __init__.py')
@@ -539,7 +539,7 @@ describe('autocmd api', function()
end)
it('cannot pass buf and fname', function()
- local ok = pcall(meths.do_autocmd, "BufReadPre", { pattern = "literally_cannot_error.rs", buffer = 1 })
+ local ok = pcall(meths.exec_autocmd, "BufReadPre", { pattern = "literally_cannot_error.rs", buffer = 1 })
eq(false, ok)
end)
@@ -557,16 +557,16 @@ describe('autocmd api', function()
})
-- Doesn't execute for other non-matching events
- meths.do_autocmd("CursorHoldI", { buffer = 1 })
+ meths.exec_autocmd("CursorHoldI", { buffer = 1 })
eq('none', meths.get_var("filename_executed"))
- meths.do_autocmd("CursorHoldI", { buffer = tonumber(meths.get_current_buf()) })
+ meths.exec_autocmd("CursorHoldI", { buffer = tonumber(meths.get_current_buf()) })
eq('__init__.py', meths.get_var("filename_executed"))
-- Reset filename
meths.set_var("filename_executed", 'none')
- meths.do_autocmd("CursorHoldI", { pattern = '__init__.py' })
+ meths.exec_autocmd("CursorHoldI", { pattern = '__init__.py' })
eq('__init__.py', meths.get_var("filename_executed"))
end)
@@ -578,9 +578,9 @@ describe('autocmd api', function()
command = 'let g:matched = "matched"'
})
- meths.do_autocmd("User", { pattern = "OtherCommand" })
+ meths.exec_autocmd("User", { pattern = "OtherCommand" })
eq('none', meths.get_var('matched'))
- meths.do_autocmd("User", { pattern = "TestCommand" })
+ meths.exec_autocmd("User", { pattern = "TestCommand" })
eq('matched', meths.get_var('matched'))
end)
@@ -594,7 +594,7 @@ describe('autocmd api', function()
})
eq(false, meths.get_var("group_executed"))
- meths.do_autocmd("FileType", { group = auid })
+ meths.exec_autocmd("FileType", { group = auid })
eq(true, meths.get_var("group_executed"))
end)
@@ -609,7 +609,7 @@ describe('autocmd api', function()
})
eq(false, meths.get_var("group_executed"))
- meths.do_autocmd("FileType", { group = auname })
+ meths.exec_autocmd("FileType", { group = auname })
eq(true, meths.get_var("group_executed"))
end)
end)
diff --git a/test/functional/api/command_spec.lua b/test/functional/api/command_spec.lua
index b80004f67c..94176fc2ce 100644
--- a/test/functional/api/command_spec.lua
+++ b/test/functional/api/command_spec.lua
@@ -65,6 +65,7 @@ describe('nvim_get_commands', function()
local cmd3 = { addr=NIL, bang=false, bar=true, complete=NIL, complete_arg=NIL, count=NIL, definition='call \128\253R3_ohyeah()', name='Cmd3', nargs='0', range=NIL, register=false, keepscript=false, script_id=3, }
local cmd4 = { addr=NIL, bang=false, bar=false, complete=NIL, complete_arg=NIL, count=NIL, definition='call \128\253R4_just_great()', name='Cmd4', nargs='0', range=NIL, register=true, keepscript=false, script_id=4, }
source([[
+ let s:foo = 1
command -complete=custom,ListUsers -nargs=+ Finger !finger <args>
]])
eq({Finger=cmd1}, meths.get_commands({builtin=false}))
@@ -72,12 +73,18 @@ describe('nvim_get_commands', function()
eq({Finger=cmd1, TestCmd=cmd0}, meths.get_commands({builtin=false}))
source([[
+ function! s:foo() abort
+ endfunction
command -bang -nargs=* Cmd2 call <SID>foo(<q-args>)
]])
source([[
+ function! s:ohyeah() abort
+ endfunction
command -bar -nargs=0 Cmd3 call <SID>ohyeah()
]])
source([[
+ function! s:just_great() abort
+ endfunction
command -register Cmd4 call <SID>just_great()
]])
-- TODO(justinmk): Order is stable but undefined. Sort before return?
diff --git a/test/functional/editor/tabpage_spec.lua b/test/functional/editor/tabpage_spec.lua
index d1d6854b07..2494daf99b 100644
--- a/test/functional/editor/tabpage_spec.lua
+++ b/test/functional/editor/tabpage_spec.lua
@@ -3,8 +3,10 @@ local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local command = helpers.command
local eq = helpers.eq
+local neq = helpers.neq
local feed = helpers.feed
local eval = helpers.eval
+local exec = helpers.exec
describe('tabpage', function()
before_each(clear)
@@ -34,5 +36,20 @@ describe('tabpage', function()
eq(3, eval('tabpagenr()'))
end)
+
+ it('does not crash or loop 999 times if BufWipeout autocommand switches window #17868', function()
+ exec([[
+ tabedit
+ let s:window_id = win_getid()
+ botright new
+ setlocal bufhidden=wipe
+ let g:win_closed = 0
+ autocmd WinClosed * let g:win_closed += 1
+ autocmd BufWipeout <buffer> call win_gotoid(s:window_id)
+ tabprevious
+ +tabclose
+ ]])
+ neq(999, eval('g:win_closed'))
+ end)
end)
diff --git a/test/functional/ex_cmds/cmd_map_spec.lua b/test/functional/ex_cmds/cmd_map_spec.lua
index 0b2190bbcf..64cf53dfa9 100644
--- a/test/functional/ex_cmds/cmd_map_spec.lua
+++ b/test/functional/ex_cmds/cmd_map_spec.lua
@@ -1,21 +1,23 @@
local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
-local feed_command = helpers.feed_command
local feed = helpers.feed
local eq = helpers.eq
local expect = helpers.expect
local eval = helpers.eval
local funcs = helpers.funcs
local insert = helpers.insert
+local write_file = helpers.write_file
local exc_exec = helpers.exc_exec
-local source = helpers.source
+local command = helpers.command
local Screen = require('test.functional.ui.screen')
describe('mappings with <Cmd>', function()
local screen
+ local tmpfile = 'X_ex_cmds_cmd_map'
+
local function cmdmap(lhs, rhs)
- feed_command('noremap '..lhs..' <Cmd>'..rhs..'<cr>')
- feed_command('noremap! '..lhs..' <Cmd>'..rhs..'<cr>')
+ command('noremap '..lhs..' <Cmd>'..rhs..'<cr>')
+ command('noremap! '..lhs..' <Cmd>'..rhs..'<cr>')
end
before_each(function()
@@ -39,7 +41,7 @@ describe('mappings with <Cmd>', function()
cmdmap('<F4>', 'normal! ww')
cmdmap('<F5>', 'normal! "ay')
cmdmap('<F6>', 'throw "very error"')
- feed_command([[
+ command([[
function! TextObj()
if mode() !=# "v"
normal! v
@@ -55,11 +57,15 @@ describe('mappings with <Cmd>', function()
feed('gg')
cmdmap('<F8>', 'startinsert')
cmdmap('<F9>', 'stopinsert')
- feed_command("abbr foo <Cmd>let g:y = 17<cr>bar")
+ command("abbr foo <Cmd>let g:y = 17<cr>bar")
+ end)
+
+ after_each(function()
+ os.remove(tmpfile)
end)
it('can be displayed', function()
- feed_command('map <F3>')
+ command('map <F3>')
screen:expect([[
^some short lines |
of test text |
@@ -73,8 +79,8 @@ describe('mappings with <Cmd>', function()
end)
it('handles invalid mappings', function()
- feed_command('let x = 0')
- feed_command('noremap <F3> <Cmd><Cmd>let x = 1<cr>')
+ command('let x = 0')
+ command('noremap <F3> <Cmd><Cmd>let x = 1<cr>')
feed('<F3>')
screen:expect([[
^some short lines |
@@ -87,7 +93,7 @@ describe('mappings with <Cmd>', function()
{2:E5521: <Cmd> mapping must end with <CR> before second <Cmd>} |
]])
- feed_command('noremap <F3> <Cmd><F3>let x = 2<cr>')
+ command('noremap <F3> <Cmd><F3>let x = 2<cr>')
feed('<F3>')
screen:expect([[
^some short lines |
@@ -100,7 +106,7 @@ describe('mappings with <Cmd>', function()
{2:E5522: <Cmd> mapping must not include <F3> key} |
]])
- feed_command('noremap <F3> <Cmd>let x = 3')
+ command('noremap <F3> <Cmd>let x = 3')
feed('<F3>')
screen:expect([[
^some short lines |
@@ -137,7 +143,7 @@ describe('mappings with <Cmd>', function()
eq('n', eval('mode(1)'))
-- select mode mapping
- feed_command('snoremap <F3> <Cmd>let m = mode(1)<cr>')
+ command('snoremap <F3> <Cmd>let m = mode(1)<cr>')
feed('gh<F3>')
eq('s', eval('m'))
-- didn't leave select mode
@@ -184,8 +190,8 @@ describe('mappings with <Cmd>', function()
eq('n', eval('mode(1)'))
-- terminal mode
- feed_command('tnoremap <F3> <Cmd>let m = mode(1)<cr>')
- feed_command('split | terminal')
+ command('tnoremap <F3> <Cmd>let m = mode(1)<cr>')
+ command('split | terminal')
feed('i')
eq('t', eval('mode(1)'))
feed('<F3>')
@@ -264,11 +270,11 @@ describe('mappings with <Cmd>', function()
end)
it('works in :normal command', function()
- feed_command('noremap ,x <Cmd>call append(1, "xx")\\| call append(1, "aa")<cr>')
- feed_command('noremap ,f <Cmd>nosuchcommand<cr>')
- feed_command('noremap ,e <Cmd>throw "very error"\\| call append(1, "yy")<cr>')
- feed_command('noremap ,m <Cmd>echoerr "The message."\\| call append(1, "zz")<cr>')
- feed_command('noremap ,w <Cmd>for i in range(5)\\|if i==1\\|echoerr "Err"\\|endif\\|call append(1, i)\\|endfor<cr>')
+ command('noremap ,x <Cmd>call append(1, "xx")\\| call append(1, "aa")<cr>')
+ command('noremap ,f <Cmd>nosuchcommand<cr>')
+ command('noremap ,e <Cmd>throw "very error"\\| call append(1, "yy")<cr>')
+ command('noremap ,m <Cmd>echoerr "The message."\\| call append(1, "zz")<cr>')
+ command('noremap ,w <Cmd>for i in range(5)\\|if i==1\\|echoerr "Err"\\|endif\\|call append(1, i)\\|endfor<cr>')
feed(":normal ,x<cr>")
screen:expect([[
@@ -297,7 +303,7 @@ describe('mappings with <Cmd>', function()
:normal ,x |
]])
- feed_command(':%d')
+ command(':%d')
eq('Vim(echoerr):Err', exc_exec("normal ,w"))
screen:expect([[
^ |
@@ -310,8 +316,8 @@ describe('mappings with <Cmd>', function()
--No lines in buffer-- |
]])
- feed_command(':%d')
- feed_command(':normal ,w')
+ command(':%d')
+ feed(':normal ,w<cr>')
screen:expect([[
^ |
4 |
@@ -401,8 +407,8 @@ describe('mappings with <Cmd>', function()
end)
it('works in select mode', function()
- feed_command('snoremap <F1> <cmd>throw "very error"<cr>')
- feed_command('snoremap <F2> <cmd>normal! <c-g>"by<cr>')
+ command('snoremap <F1> <cmd>throw "very error"<cr>')
+ command('snoremap <F2> <cmd>normal! <c-g>"by<cr>')
-- can extend select mode
feed('gh<F4>')
screen:expect([[
@@ -830,12 +836,14 @@ describe('mappings with <Cmd>', function()
end)
it("works with <SID> mappings", function()
- source([[
+ command('new!')
+ write_file(tmpfile, [[
map <f2> <Cmd>call <SID>do_it()<Cr>
function! s:do_it()
let g:x = 10
endfunction
]])
+ command('source '..tmpfile)
feed('<f2>')
eq('', eval('v:errmsg'))
eq(10, eval('g:x'))
diff --git a/test/functional/ex_cmds/echo_spec.lua b/test/functional/ex_cmds/echo_spec.lua
index d320425de1..a6be04138b 100644
--- a/test/functional/ex_cmds/echo_spec.lua
+++ b/test/functional/ex_cmds/echo_spec.lua
@@ -181,9 +181,9 @@ describe(':echo :echon :echomsg :echoerr', function()
end)
it('dumps references to script functions', function()
- eq('<SNR>2_Test2', eval('String(Test2_f)'))
- eq("function('<SNR>2_Test2')", eval('StringMsg(Test2_f)'))
- eq("function('<SNR>2_Test2')", eval('StringErr(Test2_f)'))
+ eq('<SNR>1_Test2', eval('String(Test2_f)'))
+ eq("function('<SNR>1_Test2')", eval('StringMsg(Test2_f)'))
+ eq("function('<SNR>1_Test2')", eval('StringErr(Test2_f)'))
end)
it('dump references to lambdas', function()
@@ -205,11 +205,11 @@ describe(':echo :echon :echomsg :echoerr', function()
it('dumps automatically created partials', function()
assert_same_echo_dump(
- "function('<SNR>2_Test2', {'f': function('<SNR>2_Test2')})",
+ "function('<SNR>1_Test2', {'f': function('<SNR>1_Test2')})",
'{"f": Test2_f}.f',
true)
assert_same_echo_dump(
- "function('<SNR>2_Test2', [1], {'f': function('<SNR>2_Test2', [1])})",
+ "function('<SNR>1_Test2', [1], {'f': function('<SNR>1_Test2', [1])})",
'{"f": function(Test2_f, [1])}.f',
true)
end)
@@ -227,7 +227,7 @@ describe(':echo :echon :echomsg :echoerr', function()
function()
meths.set_var('d', {v=true})
eq(dedent([[
- {'p': function('<SNR>2_Test2', {...@0}), 'f': function('<SNR>2_Test2'), 'v': v:true}]]),
+ {'p': function('<SNR>1_Test2', {...@0}), 'f': function('<SNR>1_Test2'), 'v': v:true}]]),
exec_capture('echo String(extend(extend(g:d, {"f": g:Test2_f}), {"p": g:d.f}))'))
end)
@@ -264,7 +264,7 @@ describe(':echo :echon :echomsg :echoerr', function()
eval('add(l, function("Test1", l))')
eval('add(l, function("Test1", d))')
eq(dedent([=[
- {'p': function('<SNR>2_Test2', [[[...@3], function('Test1', [[...@3]]), function('Test1', {...@0})], function('Test1', [[[...@5], function('Test1', [[...@5]]), function('Test1', {...@0})]]), function('Test1', {...@0})], {...@0}), 'f': function('<SNR>2_Test2'), 'v': v:true}]=]),
+ {'p': function('<SNR>1_Test2', [[[...@3], function('Test1', [[...@3]]), function('Test1', {...@0})], function('Test1', [[[...@5], function('Test1', [[...@5]]), function('Test1', {...@0})]]), function('Test1', {...@0})], {...@0}), 'f': function('<SNR>1_Test2'), 'v': v:true}]=]),
exec_capture('echo String(extend(extend(g:d, {"f": g:Test2_f}), {"p": function(g:d.f, l)}))'))
end)
end)
diff --git a/test/functional/ex_cmds/script_spec.lua b/test/functional/ex_cmds/script_spec.lua
index f249b9ba7c..bf69ada820 100644
--- a/test/functional/ex_cmds/script_spec.lua
+++ b/test/functional/ex_cmds/script_spec.lua
@@ -2,18 +2,30 @@ local helpers = require('test.functional.helpers')(after_each)
local eq = helpers.eq
local neq = helpers.neq
+local command = helpers.command
+local write_file = helpers.write_file
local meths = helpers.meths
local clear = helpers.clear
local dedent = helpers.dedent
-local source = helpers.source
local exc_exec = helpers.exc_exec
local missing_provider = helpers.missing_provider
+local tmpfile = 'X_ex_cmds_script'
+
before_each(clear)
+local function source(code)
+ write_file(tmpfile, code)
+ command('source '..tmpfile)
+end
+
describe('script_get-based command', function()
local garbage = ')}{+*({}]*[;(+}{&[]}{*])('
+ after_each(function()
+ os.remove(tmpfile)
+ end)
+
local function test_garbage_exec(cmd, check_neq)
describe(cmd, function()
it('works correctly when skipping oneline variant', function()
diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua
index 1845786c4b..173fc54af5 100644
--- a/test/functional/helpers.lua
+++ b/test/functional/helpers.lua
@@ -21,7 +21,6 @@ local map = global_helpers.tbl_map
local ok = global_helpers.ok
local sleep = global_helpers.sleep
local tbl_contains = global_helpers.tbl_contains
-local write_file = global_helpers.write_file
local fail = global_helpers.fail
local module = {
@@ -54,7 +53,6 @@ if module.nvim_dir == module.nvim_prog then
module.nvim_dir = "."
end
-local tmpname = global_helpers.tmpname
local iswin = global_helpers.iswin
local prepend_argv
@@ -494,24 +492,9 @@ function module.feed_command(...)
end
end
-local sourced_fnames = {}
+-- @deprecated use nvim_exec()
function module.source(code)
- local fname = tmpname()
- write_file(fname, code)
- module.command('source '..fname)
- -- DO NOT REMOVE FILE HERE.
- -- do_source() has a habit of checking whether files are “same” by using inode
- -- and device IDs. If you run two source() calls in quick succession there is
- -- a good chance that underlying filesystem will reuse the inode, making files
- -- appear as “symlinks” to do_source when it checks FileIDs. With current
- -- setup linux machines (both QB, travis and mine(ZyX-I) with XFS) do reuse
- -- inodes, Mac OS machines (again, both QB and travis) do not.
- --
- -- Files appearing as “symlinks” mean that both the first and the second
- -- source() calls will use same SID, which may fail some tests which check for
- -- exact numbers after `<SNR>` in e.g. function names.
- sourced_fnames[#sourced_fnames + 1] = fname
- return fname
+ module.exec(dedent(code))
end
function module.has_powershell()
@@ -525,7 +508,7 @@ function module.set_shell_powershell()
local cmd = set_encoding..'Remove-Item -Force '..table.concat(iswin()
and {'alias:cat', 'alias:echo', 'alias:sleep'}
or {'alias:echo'}, ',')..';'
- module.source([[
+ module.exec([[
let &shell = ']]..shell..[['
set shellquote= shellxquote=
let &shellpipe = '2>&1 | Out-File -Encoding UTF8 %s; exit $LastExitCode'
@@ -887,9 +870,6 @@ module = global_helpers.tbl_extend('error', module, global_helpers)
return function(after_each)
if after_each then
after_each(function()
- for _, fname in ipairs(sourced_fnames) do
- os.remove(fname)
- end
check_logs()
check_cores('build/bin/nvim')
if session then
diff --git a/test/functional/legacy/assert_spec.lua b/test/functional/legacy/assert_spec.lua
index dd6a9d0bde..4829a0bbe1 100644
--- a/test/functional/legacy/assert_spec.lua
+++ b/test/functional/legacy/assert_spec.lua
@@ -136,19 +136,19 @@ describe('assert function:', function()
end)
it('should have file names and passed messages', function()
- local tmpname_one = source([[
+ source([[
call assert_equal(1, 100, 'equal assertion failed')
call assert_false('true', 'true assertion failed')
call assert_true('false', 'false assertion failed')
]])
- local tmpname_two = source([[
+ source([[
call assert_true('', 'file two')
]])
expected_errors({
- tmpname_one .. " line 1: equal assertion failed: Expected 1 but got 100",
- tmpname_one .. " line 2: true assertion failed: Expected False but got 'true'",
- tmpname_one .. " line 3: false assertion failed: Expected True but got 'false'",
- tmpname_two .. " line 1: file two: Expected True but got ''",
+ "nvim_exec(): equal assertion failed: Expected 1 but got 100",
+ "nvim_exec(): true assertion failed: Expected False but got 'true'",
+ "nvim_exec(): false assertion failed: Expected True but got 'false'",
+ "nvim_exec(): file two: Expected True but got ''",
})
end)
end)
diff --git a/test/functional/legacy/memory_usage_spec.lua b/test/functional/legacy/memory_usage_spec.lua
index 8d25b9d927..eec89aa919 100644
--- a/test/functional/legacy/memory_usage_spec.lua
+++ b/test/functional/legacy/memory_usage_spec.lua
@@ -10,6 +10,7 @@ local source = helpers.source
local poke_eventloop = helpers.poke_eventloop
local uname = helpers.uname
local load_adjust = helpers.load_adjust
+local write_file = helpers.write_file
local isCI = helpers.isCI
local function isasan()
@@ -84,6 +85,12 @@ setmetatable(monitor_memory_usage,
end})
describe('memory usage', function()
+ local tmpfile = 'X_memory_usage'
+
+ after_each(function()
+ os.remove(tmpfile)
+ end)
+
local function check_result(tbl, status, result)
if not status then
print('')
@@ -103,7 +110,7 @@ describe('memory usage', function()
it('function capture vargs', function()
local pid = eval('getpid()')
local before = monitor_memory_usage(pid)
- source([[
+ write_file(tmpfile, [[
func s:f(...)
let x = a:000
endfunc
@@ -111,6 +118,8 @@ describe('memory usage', function()
call s:f(0)
endfor
]])
+ -- TODO: check_result fails if command() is used here. Why? #16064
+ feed_command('source '..tmpfile)
poke_eventloop()
local after = monitor_memory_usage(pid)
-- Estimate the limit of max usage as 2x initial usage.
@@ -136,7 +145,7 @@ describe('memory usage', function()
it('function capture lvars', function()
local pid = eval('getpid()')
local before = monitor_memory_usage(pid)
- local fname = source([[
+ write_file(tmpfile, [[
if !exists('s:defined_func')
func s:f()
let x = l:
@@ -147,10 +156,12 @@ describe('memory usage', function()
call s:f()
endfor
]])
+ feed_command('source '..tmpfile)
poke_eventloop()
local after = monitor_memory_usage(pid)
for _ = 1, 3 do
- feed_command('so '..fname)
+ -- TODO: check_result fails if command() is used here. Why? #16064
+ feed_command('source '..tmpfile)
poke_eventloop()
end
local last = monitor_memory_usage(pid)
diff --git a/test/functional/vimscript/lang_spec.lua b/test/functional/vimscript/lang_spec.lua
index d5254986ab..90437f2ee1 100644
--- a/test/functional/vimscript/lang_spec.lua
+++ b/test/functional/vimscript/lang_spec.lua
@@ -11,6 +11,7 @@ describe('vimscript', function()
return
end
source([[
+ let s:foo = 1
func! <sid>_dummy_function()
echo 1
endfunc