aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml2
-rw-r--r--.github/workflows/release.yml31
-rw-r--r--README.md1
-rw-r--r--contrib/flake.nix2
-rw-r--r--runtime/doc/lsp.txt4
-rw-r--r--runtime/doc/ui.txt8
-rw-r--r--runtime/lua/vim/lsp/handlers.lua36
-rw-r--r--runtime/lua/vim/lsp/protocol.lua10
-rw-r--r--src/nvim/edit.c5
-rw-r--r--src/nvim/eval.c3
-rw-r--r--src/nvim/ex_cmds.c9
-rw-r--r--src/nvim/ex_docmd.c10
-rw-r--r--src/nvim/ex_getln.c11
-rw-r--r--src/nvim/ex_session.c34
-rw-r--r--src/nvim/getchar.c6
-rw-r--r--src/nvim/globals.h7
-rw-r--r--src/nvim/main.c2
-rw-r--r--src/nvim/message.c40
-rw-r--r--src/nvim/mouse.c46
-rw-r--r--src/nvim/normal.c15
-rw-r--r--src/nvim/option.c12
-rw-r--r--src/nvim/options.lua1
-rw-r--r--src/nvim/screen.c39
-rw-r--r--src/nvim/spellfile.c2
-rw-r--r--src/nvim/testdir/test_bufline.vim2
-rw-r--r--src/nvim/testdir/test_messages.vim59
-rw-r--r--src/nvim/testdir/test_mksession.vim169
-rw-r--r--src/nvim/testdir/test_window_cmd.vim8
-rw-r--r--src/nvim/ui.c63
-rw-r--r--src/nvim/window.c2
-rw-r--r--test/functional/eval/null_spec.lua2
-rw-r--r--test/functional/eval/timer_spec.lua4
-rw-r--r--test/functional/ui/float_spec.lua43
-rw-r--r--test/functional/ui/mouse_spec.lua22
-rw-r--r--test/functional/ui/screen.lua17
-rw-r--r--test/functional/ui/searchhl_spec.lua24
36 files changed, 454 insertions, 297 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 97e1ed8742..3653f04d5d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -9,6 +9,7 @@ jobs:
unixish:
name: ${{ matrix.os }} ${{ matrix.flavor }} (cc=${{ matrix.cc }})
strategy:
+ fail-fast: false
matrix:
include:
- flavor: asan
@@ -90,6 +91,7 @@ jobs:
DEPS_PREFIX: "C:/projects/nvim-deps/usr"
strategy:
+ fail-fast: false
matrix:
config: [ MINGW_64-gcov, MINGW_32, MSVC_64, MSVC_32 ]
name: windows (${{ matrix.config }})
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 6905f8dd35..7587f62e59 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -105,8 +105,35 @@ jobs:
path: build/release/nvim-macos.tar.gz
retention-days: 1
+ windows:
+ runs-on: windows-2016
+ env:
+ DEPS_BUILD_DIR: "C:/projects/nvim-deps"
+ DEPS_PREFIX: "C:/projects/nvim-deps/usr"
+ strategy:
+ matrix:
+ include:
+ - config: MSVC_64
+ archive: nvim-win64
+ - config: MSVC_32
+ archive: nvim-win32
+ name: windows (${{ matrix.config }})
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+ - run: powershell ci\build.ps1 -NoTests
+ env:
+ CONFIGURATION: ${{ matrix.config }}
+ - run: move build\Neovim.zip build\${{ matrix.archive }}.zip
+ - uses: actions/upload-artifact@v2
+ with:
+ name: ${{ matrix.archive }}
+ path: build/${{ matrix.archive }}.zip
+ retention-days: 1
+
publish:
- needs: [linux, appimage, macOS]
+ needs: [linux, appimage, macOS, windows]
runs-on: ubuntu-20.04
steps:
- uses: actions/download-artifact@v2
@@ -143,6 +170,8 @@ jobs:
nvim-linux64.tar.gz:./nvim-linux64/nvim-linux64.tar.gz
nvim.appimage:./appimage/nvim.appimage
nvim.appimage.zsync:./appimage/nvim.appimage.zsync
+ nvim-win32.zip:./nvim-win32/nvim-win32.zip
+ nvim-win64.zip:./nvim-win64/nvim-win64.zip
body: |
${{ env.SUBJECT }}
```
diff --git a/README.md b/README.md
index e2c82fa6e7..180fc1df14 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,6 @@
[Twitter](https://twitter.com/Neovim)
[![GitHub CI](https://github.com/neovim/neovim/workflows/CI/badge.svg)](https://github.com/neovim/neovim/actions?query=workflow%3A%22CI%22)
-[![AppVeyor build status](https://ci.appveyor.com/api/projects/status/urdqjrik5u521fac/branch/master?svg=true)](https://ci.appveyor.com/project/neovim/neovim/branch/master)
[![Codecov coverage](https://img.shields.io/codecov/c/github/neovim/neovim.svg)](https://codecov.io/gh/neovim/neovim)
[![Coverity Scan analysis](https://scan.coverity.com/projects/2227/badge.svg)](https://scan.coverity.com/projects/2227)
[![Clang analysis](https://neovim.io/doc/reports/clang/badge.svg)](https://neovim.io/doc/reports/clang)
diff --git a/contrib/flake.nix b/contrib/flake.nix
index a75e584075..86e4b37cfa 100644
--- a/contrib/flake.nix
+++ b/contrib/flake.nix
@@ -44,7 +44,7 @@
pythonEnv = legacyPkgs.python3;
luacheck = legacyPkgs.luaPackages.luacheck;
in
- neovim-debug.overrideAttrs(oa: {
+ (neovim-debug.override({doCheck = true;})).overrideAttrs(oa: {
cmakeFlags = oa.cmakeFlags ++ [
"-DLUACHECK_PRG=${luacheck}/bin/luacheck"
"-DMIN_LOG_LEVEL=0"
diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt
index 67e2815715..8e93b188e9 100644
--- a/runtime/doc/lsp.txt
+++ b/runtime/doc/lsp.txt
@@ -118,7 +118,7 @@ FAQ *lsp-faq*
<
*vim.lsp.callbacks*
- Q: What happened to `vim.lsp.callbacks`?
- A: After better defining the interface of |lsp-hander|s, we thought it best
+ A: After better defining the interface of |lsp-handler|s, we thought it best
to remove the generic usage of `callbacks` and transform to `handlers`.
Due to this, `vim.lsp.callbacks` was renamed to |vim.lsp.handlers|.
@@ -257,7 +257,7 @@ For |lsp-notification|, each |lsp-handler| has this signature: >
*lsp-handler-configuration*
-To configure the behavior of a builtin |lsp-handler|, the conenvience method
+To configure the behavior of a builtin |lsp-handler|, the convenient method
|vim.lsp.with()| is provided for users.
To configure the behavior of |vim.lsp.diagnostic.on_publish_diagnostics()|,
diff --git a/runtime/doc/ui.txt b/runtime/doc/ui.txt
index e5c6b9b1b7..0a8584927e 100644
--- a/runtime/doc/ui.txt
+++ b/runtime/doc/ui.txt
@@ -213,11 +213,9 @@ the editor.
["mouse_on"]
["mouse_off"]
- |'mouse'| was enabled/disabled in the current editor mode. Useful for
- a terminal UI, or other situations where Nvim mouse would conflict
- with other usages of the mouse. UIs may ignore this and always send
- mouse input, because 'mouse' decides the behavior of |nvim_input()|
- implicitly.
+ 'mouse' was enabled/disabled in the current editor mode. Useful for
+ a terminal UI, or embedding into an application where Nvim mouse would
+ conflict with other usages of the mouse. Other UI:s may ignore this event.
["busy_start"]
["busy_stop"]
diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua
index 359573beb1..fd23a6a547 100644
--- a/runtime/lua/vim/lsp/handlers.lua
+++ b/runtime/lua/vim/lsp/handlers.lua
@@ -63,8 +63,44 @@ local function progress_callback(_, _, params, client_id)
vim.api.nvim_command("doautocmd <nomodeline> User LspProgressUpdate")
end
+--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#progress
M['$/progress'] = progress_callback
+--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window_workDoneProgress_create
+M['window/workDoneProgress/create'] = function(_, _, params, client_id)
+ local client = vim.lsp.get_client_by_id(client_id)
+ local token = params.token -- string or number
+ if not client then
+ err_message("LSP[", client_id, "] client has shut down after sending the message")
+ end
+ client.messages.progress[token] = {}
+ return vim.NIL
+end
+
+--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window_showMessageRequest
+M['window/showMessageRequest'] = function(_, _, params)
+
+ local actions = params.actions
+ print(params.message)
+ local option_strings = {params.message, "\nRequest Actions:"}
+ for i, action in ipairs(actions) do
+ local title = action.title:gsub('\r\n', '\\r\\n')
+ title = title:gsub('\n', '\\n')
+ table.insert(option_strings, string.format("%d. %s", i, title))
+ end
+
+ -- window/showMessageRequest can return either MessageActionItem[] or null.
+ local choice = vim.fn.inputlist(option_strings)
+ if choice < 1 or choice > #actions then
+ return vim.NIL
+ else
+ local action_chosen = actions[choice]
+ return {
+ title = action_chosen;
+ }
+ end
+end
+
--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction
M['textDocument/codeAction'] = function(_, _, actions)
if actions == nil or vim.tbl_isempty(actions) then
diff --git a/runtime/lua/vim/lsp/protocol.lua b/runtime/lua/vim/lsp/protocol.lua
index b785d2f586..b2d3d0641c 100644
--- a/runtime/lua/vim/lsp/protocol.lua
+++ b/runtime/lua/vim/lsp/protocol.lua
@@ -730,7 +730,15 @@ function protocol.make_client_capabilities()
experimental = nil;
window = {
workDoneProgress = true;
- }
+ showMessage = {
+ messageActionItem = {
+ additionalPropertiesSupport = false;
+ };
+ };
+ showDocument = {
+ support = false;
+ };
+ };
}
end
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 962ef9b245..876e53e3cd 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -7803,7 +7803,7 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
// Otherwise remove the mode message.
if (reg_recording != 0 || restart_edit != NUL) {
showmode();
- } else if (p_smd && (got_int || !skip_showmode())) {
+ } else if (p_smd) {
MSG("");
}
// Exit Insert mode
@@ -8329,9 +8329,6 @@ static void ins_mouse(int c)
pos_T tpos;
win_T *old_curwin = curwin;
- if (!mouse_has(MOUSE_INSERT))
- return;
-
undisplay_dollar();
tpos = curwin->w_cursor;
if (do_mouse(NULL, c, BACKWARD, 1, 0)) {
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 7916e3a66a..f60504de5e 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -76,9 +76,6 @@ static char_u * const namespace_char = (char_u *)"abglstvw";
/// Variable used for g:
static ScopeDictDictItem globvars_var;
-/// g: value
-#define globvarht globvardict.dv_hashtab
-
/*
* Old Vim variables such as "v:version" are also available without the "v:".
* Also in functions. We need a special hashtable for them.
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index a7d97c904b..ae389a6727 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -3713,9 +3713,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
redraw_later(curwin, SOME_VALID);
curwin->w_p_fen = save_p_fen;
- if (msg_row == Rows - 1) {
- msg_didout = false; // avoid a scroll-up
- }
+ if (msg_row == Rows - 1)
+ msg_didout = FALSE; /* avoid a scroll-up */
msg_starthere();
i = msg_scroll;
msg_scroll = 0; /* truncate msg when
@@ -3734,8 +3733,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
typed = plain_vgetc();
no_mapping--;
- // clear the question
- msg_didout = false; // don't scroll up
+ /* clear the question */
+ msg_didout = FALSE; /* don't scroll up */
msg_col = 0;
gotocmdline(TRUE);
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 3fc02e0693..003c78b241 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -4769,10 +4769,8 @@ static void ex_abclear(exarg_T *eap)
static void ex_autocmd(exarg_T *eap)
{
- /*
- * Disallow auto commands from .exrc and .vimrc in current
- * directory for security reasons.
- */
+ // Disallow autocommands from .exrc and .vimrc in current
+ // directory for security reasons.
if (secure) {
secure = 2;
eap->errmsg = e_curdir;
@@ -8071,8 +8069,8 @@ static void ex_redraw(exarg_T *eap)
RedrawingDisabled = r;
p_lz = p;
- // Reset msg_didout, so that a message that's there is overwritten.
- msg_didout = false;
+ /* Reset msg_didout, so that a message that's there is overwritten. */
+ msg_didout = FALSE;
msg_col = 0;
/* No need to wait after an intentional redraw. */
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 0bc52f1e97..0f50d5153d 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -1884,9 +1884,6 @@ static int command_line_handle_key(CommandLineState *s)
return command_line_not_changed(s); // Ignore mouse
case K_MIDDLEMOUSE:
- if (!mouse_has(MOUSE_COMMAND)) {
- return command_line_not_changed(s); // Ignore mouse
- }
cmdline_paste(eval_has_provider("clipboard") ? '*' : 0, true, true);
redrawcmd();
return command_line_changed(s);
@@ -1910,10 +1907,6 @@ static int command_line_handle_key(CommandLineState *s)
s->ignore_drag_release = false;
}
- if (!mouse_has(MOUSE_COMMAND)) {
- return command_line_not_changed(s); // Ignore mouse
- }
-
ccline.cmdspos = cmd_startcol();
for (ccline.cmdpos = 0; ccline.cmdpos < ccline.cmdlen;
ccline.cmdpos++) {
@@ -2746,8 +2739,8 @@ redraw:
no_mapping--;
- // make following messages go to the next line
- msg_didout = false;
+ /* make following messages go to the next line */
+ msg_didout = FALSE;
msg_col = 0;
if (msg_row < Rows - 1) {
msg_row++;
diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c
index d831ffc050..14dac9a126 100644
--- a/src/nvim/ex_session.c
+++ b/src/nvim/ex_session.c
@@ -526,8 +526,12 @@ static int makeopens(FILE *fd, char_u *dirnow)
}
}
- // Close all windows but one.
+ // Close all windows and tabs but one.
PUTLINE_FAIL("silent only");
+ if ((ssop_flags & SSOP_TABPAGES)
+ && put_line(fd, "silent tabonly") == FAIL) {
+ return FAIL;
+ }
//
// Now a :cd command to the session directory or the current directory
@@ -606,13 +610,26 @@ static int makeopens(FILE *fd, char_u *dirnow)
//
tab_firstwin = firstwin; // First window in tab page "tabnr".
tab_topframe = topframe;
+ if ((ssop_flags & SSOP_TABPAGES)) {
+ // Similar to ses_win_rec() below, populate the tab pages first so
+ // later local options won't be copied to the new tabs.
+ FOR_ALL_TABS(tp) {
+ if (tp->tp_next != NULL && put_line(fd, "tabnew") == FAIL) {
+ return FAIL;
+ }
+ }
+
+ if (first_tabpage->tp_next != NULL && put_line(fd, "tabrewind") == FAIL) {
+ return FAIL;
+ }
+ }
for (tabnr = 1;; tabnr++) {
tabpage_T *tp = find_tabpage(tabnr);
if (tp == NULL) {
break; // done all tab pages
}
- int need_tabnew = false;
+ bool need_tabnext = false;
int cnr = 1;
if ((ssop_flags & SSOP_TABPAGES)) {
@@ -624,7 +641,7 @@ static int makeopens(FILE *fd, char_u *dirnow)
tab_topframe = tp->tp_topframe;
}
if (tabnr > 1) {
- need_tabnew = true;
+ need_tabnext = true;
}
}
@@ -639,11 +656,15 @@ static int makeopens(FILE *fd, char_u *dirnow)
&& !bt_help(wp->w_buffer)
&& !bt_nofile(wp->w_buffer)
) {
- if (fputs(need_tabnew ? "tabedit " : "edit ", fd) < 0
+ if (need_tabnext && put_line(fd, "tabnext") == FAIL) {
+ return FAIL;
+ }
+ need_tabnext = false;
+
+ if (fputs("edit ", fd) < 0
|| ses_fname(fd, wp->w_buffer, &ssop_flags, true) == FAIL) {
return FAIL;
}
- need_tabnew = false;
if (!wp->w_arg_idx_invalid) {
edited_win = wp;
}
@@ -652,7 +673,7 @@ static int makeopens(FILE *fd, char_u *dirnow)
}
// If no file got edited create an empty tab page.
- if (need_tabnew && put_line(fd, "tabnew") == FAIL) {
+ if (need_tabnext && put_line(fd, "tabnext") == FAIL) {
return FAIL;
}
@@ -775,6 +796,7 @@ static int makeopens(FILE *fd, char_u *dirnow)
//
if (fprintf(fd, "%s",
"if exists('s:wipebuf') "
+ "&& len(win_findbuf(s:wipebuf)) == 0"
"&& getbufvar(s:wipebuf, '&buftype') isnot# 'terminal'\n"
" silent exe 'bwipe ' . s:wipebuf\n"
"endif\n"
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index eddbdef739..2e2993ed26 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -2490,10 +2490,8 @@ int inchar(
}
// Always flush the output characters when getting input characters
- // from the user and not just peeking.
- if (wait_time == -1L || wait_time > 10L) {
- ui_flush();
- }
+ // from the user.
+ ui_flush();
// Fill up to a third of the buffer, because each character may be
// tripled below.
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 6b962dc1f6..31b905e858 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -139,9 +139,8 @@ EXTERN int mod_mask INIT(= 0x0); // current key modifiers
EXTERN int cmdline_row;
EXTERN int redraw_cmdline INIT(= false); // cmdline must be redrawn
-EXTERN bool redraw_mode INIT(= false); // mode must be redrawn
EXTERN int clear_cmdline INIT(= false); // cmdline must be cleared
-EXTERN bool mode_displayed INIT(= false); // mode is being displayed
+EXTERN int mode_displayed INIT(= false); // mode is being displayed
EXTERN int cmdline_star INIT(= false); // cmdline is crypted
EXTERN int redrawing_cmdline INIT(= false); // cmdline is being redrawn
EXTERN int cmdline_was_last_drawn INIT(= false); // cmdline was last drawn
@@ -200,7 +199,7 @@ EXTERN int keep_msg_attr INIT(= 0); // highlight attr for keep_msg
EXTERN int keep_msg_more INIT(= false); // keep_msg was set by msgmore()
EXTERN int need_fileinfo INIT(= false); // do fileinfo() after redraw
EXTERN int msg_scroll INIT(= false); // msg_start() will scroll
-EXTERN bool msg_didout INIT(= false); // msg_outstr() was used in line
+EXTERN int msg_didout INIT(= false); // msg_outstr() was used in line
EXTERN int msg_didany INIT(= false); // msg_outstr() was used at all
EXTERN int msg_nowait INIT(= false); // don't wait for this msg
EXTERN int emsg_off INIT(= 0); // don't display errors for now,
@@ -216,6 +215,8 @@ EXTERN bool emsg_severe INIT(= false); // use message of next of several
EXTERN int did_endif INIT(= false); // just had ":endif"
EXTERN dict_T vimvardict; // Dictionary with v: variables
EXTERN dict_T globvardict; // Dictionary with g: variables
+/// g: value
+#define globvarht globvardict.dv_hashtab
EXTERN int did_emsg; // set by emsg() when the message
// is displayed or thrown
EXTERN bool called_vim_beep; // set if vim_beep() is called
diff --git a/src/nvim/main.c b/src/nvim/main.c
index e068b2361c..8bf745966e 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -2006,7 +2006,7 @@ static void version(void)
info_message = TRUE; // use mch_msg(), not mch_errmsg()
list_version();
msg_putchar('\n');
- msg_didout = false;
+ msg_didout = FALSE;
}
/// Prints help message for "nvim -h" or "nvim --help".
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 530b930fed..f94529c687 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -1128,11 +1128,11 @@ void wait_return(int redraw)
if (p_more) {
if (c == 'b' || c == 'k' || c == 'u' || c == 'g'
|| c == K_UP || c == K_PAGEUP) {
- if (msg_scrolled > Rows) {
- // scroll back to show older messages
+ if (msg_scrolled > Rows)
+ /* scroll back to show older messages */
do_more_prompt(c);
- } else {
- msg_didout = false;
+ else {
+ msg_didout = FALSE;
c = K_IGNORE;
msg_col =
cmdmsg_rl ? Columns - 1 :
@@ -1157,15 +1157,7 @@ void wait_return(int redraw)
|| c == K_MIDDLEDRAG || c == K_MIDDLERELEASE
|| c == K_RIGHTDRAG || c == K_RIGHTRELEASE
|| c == K_MOUSELEFT || c == K_MOUSERIGHT
- || c == K_MOUSEDOWN || c == K_MOUSEUP
- || (!mouse_has(MOUSE_RETURN)
- && mouse_row < msg_row
- && (c == K_LEFTMOUSE
- || c == K_MIDDLEMOUSE
- || c == K_RIGHTMOUSE
- || c == K_X1MOUSE
- || c == K_X2MOUSE))
- );
+ || c == K_MOUSEDOWN || c == K_MOUSEUP);
os_breakcheck();
/*
* Avoid that the mouse-up event causes visual mode to start.
@@ -2097,17 +2089,15 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr,
store_sb_text((char_u **)&sb_str, (char_u *)s, attr, &sb_col, true);
}
- if (*s == '\n') { // go to next line
- msg_didout = false; // remember that line is empty
- if (cmdmsg_rl) {
+ if (*s == '\n') { /* go to next line */
+ msg_didout = FALSE; /* remember that line is empty */
+ if (cmdmsg_rl)
msg_col = Columns - 1;
- } else {
+ else
msg_col = 0;
- }
- if (++msg_row >= Rows) { // safety check
+ if (++msg_row >= Rows) /* safety check */
msg_row = Rows - 1;
- }
- } else if (*s == '\r') { // go to column 0
+ } else if (*s == '\r') { /* go to column 0 */
msg_col = 0;
} else if (*s == '\b') { /* go to previous char */
if (msg_col)
@@ -2880,10 +2870,10 @@ void repeat_message(void)
ui_cursor_goto(msg_row, msg_col); /* put cursor back */
} else if (State == HITRETURN || State == SETWSIZE) {
if (msg_row == Rows - 1) {
- // Avoid drawing the "hit-enter" prompt below the previous one,
- // overwrite it. Esp. useful when regaining focus and a
- // FocusGained autocmd exists but didn't draw anything.
- msg_didout = false;
+ /* Avoid drawing the "hit-enter" prompt below the previous one,
+ * overwrite it. Esp. useful when regaining focus and a
+ * FocusGained autocmd exists but didn't draw anything. */
+ msg_didout = FALSE;
msg_col = 0;
msg_clr_eos();
}
diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c
index f05dade73f..ff471ea978 100644
--- a/src/nvim/mouse.c
+++ b/src/nvim/mouse.c
@@ -526,53 +526,9 @@ static win_T *mouse_find_grid_win(int *gridp, int *rowp, int *colp)
void setmouse(void)
{
ui_cursor_shape();
-
- // Be quick when mouse is off.
- if (*p_mouse == NUL) {
- return;
- }
-
- int checkfor = MOUSE_NORMAL; // assume normal mode
- if (VIsual_active) {
- checkfor = MOUSE_VISUAL;
- } else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE) {
- checkfor = MOUSE_RETURN;
- } else if (State & INSERT) {
- checkfor = MOUSE_INSERT;
- } else if (State & CMDLINE) {
- checkfor = MOUSE_COMMAND;
- } else if (State == CONFIRM || State == EXTERNCMD) {
- checkfor = ' '; // don't use mouse for ":confirm" or ":!cmd"
- }
-
- if (mouse_has(checkfor)) {
- ui_call_mouse_on();
- } else {
- ui_call_mouse_off();
- }
+ ui_check_mouse();
}
-/*
- * Return true if
- * - "c" is in 'mouse', or
- * - 'a' is in 'mouse' and "c" is in MOUSE_A, or
- * - the current buffer is a help file and 'h' is in 'mouse' and we are in a
- * normal editing mode (not at hit-return message).
- */
-int mouse_has(int c)
-{
- for (char_u *p = p_mouse; *p; ++p)
- switch (*p) {
- case 'a': if (vim_strchr((char_u *)MOUSE_A, c) != NULL)
- return true;
- break;
- case MOUSE_HELP: if (c != MOUSE_RETURN && curbuf->b_help)
- return true;
- break;
- default: if (c == *p) return true; break;
- }
- return false;
-}
// Set orig_topline. Used when jumping to another window, so that a double
// click still works.
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index f93d772068..4e955667dc 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -2375,10 +2375,10 @@ do_mouse (
* Also paste at the cursor if the current mode isn't in 'mouse' (only
* happens for the GUI).
*/
- if ((State & INSERT) || !mouse_has(MOUSE_NORMAL)) {
- if (regname == '.')
+ if ((State & INSERT)) {
+ if (regname == '.') {
insert_reg(regname, true);
- else {
+ } else {
if (regname == 0 && eval_has_provider("clipboard")) {
regname = '*';
}
@@ -2558,8 +2558,9 @@ do_mouse (
* on a status line */
if (VIsual_active)
jump_flags |= MOUSE_MAY_STOP_VIS;
- } else if (mouse_has(MOUSE_VISUAL))
+ } else {
jump_flags |= MOUSE_MAY_VIS;
+ }
} else if (which_button == MOUSE_RIGHT) {
if (is_click && VIsual_active) {
/*
@@ -2575,8 +2576,7 @@ do_mouse (
}
}
jump_flags |= MOUSE_FOCUS;
- if (mouse_has(MOUSE_VISUAL))
- jump_flags |= MOUSE_MAY_VIS;
+ jump_flags |= MOUSE_MAY_VIS;
}
}
@@ -2790,8 +2790,7 @@ do_mouse (
/* Handle double clicks, unless on status line */
else if (in_status_line) {
} else if (in_sep_line) {
- } else if ((mod_mask & MOD_MASK_MULTI_CLICK) && (State & (NORMAL | INSERT))
- && mouse_has(MOUSE_VISUAL)) {
+ } else if ((mod_mask & MOD_MASK_MULTI_CLICK) && (State & (NORMAL | INSERT))) {
if (is_click || !VIsual_active) {
if (VIsual_active) {
orig_cursor = VIsual;
diff --git a/src/nvim/option.c b/src/nvim/option.c
index d60c8bc01c..d43dd9ba15 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -3210,11 +3210,7 @@ ambw_end:
}
if (varp == &p_mouse) {
- if (*p_mouse == NUL) {
- ui_call_mouse_off();
- } else {
- setmouse(); // in case 'mouse' changed
- }
+ setmouse(); // in case 'mouse' changed
}
if (curwin->w_curswant != MAXCOL
@@ -4984,11 +4980,7 @@ void ui_refresh_options(void)
ui_call_option_set(name, value);
}
if (p_mouse != NULL) {
- if (*p_mouse == NUL) {
- ui_call_mouse_off();
- } else {
- setmouse();
- }
+ setmouse();
}
}
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index 64a09dc2b4..df2bfbce34 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -2313,6 +2313,7 @@ return {
deny_duplicates=true,
vi_def=true,
secure=true,
+ expand=true,
varname='p_shadafile',
defaults={if_true={vi=""}}
},
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index dc028f0ed7..a7fd2bfcc6 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -620,7 +620,7 @@ int update_screen(int type)
/* Clear or redraw the command line. Done last, because scrolling may
* mess up the command line. */
- if (clear_cmdline || redraw_cmdline || redraw_mode) {
+ if (clear_cmdline || redraw_cmdline) {
showmode();
}
@@ -2013,7 +2013,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
// end-of-line
int lcs_eol_one = wp->w_p_lcs_chars.eol; // 'eol' until it's been used
int lcs_prec_todo = wp->w_p_lcs_chars.prec; // 'prec' until it's been used
- bool has_fold = foldinfo.fi_level != 0 && foldinfo.fi_lines >= 0;
+ bool has_fold = foldinfo.fi_level != 0 && foldinfo.fi_lines > 0;
// saved "extra" items for when draw_state becomes WL_LINE (again)
int saved_n_extra = 0;
@@ -6559,28 +6559,12 @@ void grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
return;
}
-// Return true when postponing displaying the mode message: when not redrawing
-// or inside a mapping.
-bool skip_showmode(void)
-{
- // Call char_avail() only when we are going to show something, because it
- // takes a bit of time. redrawing() may also call char_avail_avail().
- if (global_busy
- || msg_silent != 0
- || !redrawing()
- || (char_avail() && !KeyTyped)) {
- redraw_mode = true; // show mode later
- return true;
- }
- return false;
-}
// Show the current mode and ruler.
//
// If clear_cmdline is TRUE, clear the rest of the cmdline.
// If clear_cmdline is FALSE there may be a message there that needs to be
// cleared only if a mode is shown.
-// If redraw_mode is true show or clear the mode.
// Return the length of the message (0 if no message).
int showmode(void)
{
@@ -6606,8 +6590,12 @@ int showmode(void)
|| restart_edit
|| VIsual_active));
if (do_mode || reg_recording != 0) {
- if (skip_showmode()) {
- return 0; // show mode later
+ // Don't show mode right now, when not redrawing or inside a mapping.
+ // Call char_avail() only when we are going to show something, because
+ // it takes a bit of time.
+ if (!redrawing() || (char_avail() && !KeyTyped) || msg_silent != 0) {
+ redraw_cmdline = TRUE; /* show mode later */
+ return 0;
}
nwr_save = need_wait_return;
@@ -6727,11 +6715,10 @@ int showmode(void)
need_clear = true;
}
- mode_displayed = true;
- if (need_clear || clear_cmdline || redraw_mode) {
+ mode_displayed = TRUE;
+ if (need_clear || clear_cmdline)
msg_clr_eos();
- }
- msg_didout = false; // overwrite this message
+ msg_didout = FALSE; /* overwrite this message */
length = msg_col;
msg_col = 0;
msg_no_more = false;
@@ -6740,9 +6727,6 @@ int showmode(void)
} else if (clear_cmdline && msg_silent == 0) {
// Clear the whole command line. Will reset "clear_cmdline".
msg_clr_cmdline();
- } else if (redraw_mode) {
- msg_pos_mode();
- msg_clr_eos();
}
// NB: also handles clearing the showmode if it was emtpy or disabled
@@ -6759,7 +6743,6 @@ int showmode(void)
win_redr_ruler(last, true);
}
redraw_cmdline = false;
- redraw_mode = false;
clear_cmdline = false;
return length;
diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c
index 90945eafd7..90af010164 100644
--- a/src/nvim/spellfile.c
+++ b/src/nvim/spellfile.c
@@ -3942,7 +3942,7 @@ static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int
msg_start();
msg_puts(_(msg_compressing));
msg_clr_eos();
- msg_didout = false;
+ msg_didout = FALSE;
msg_col = 0;
ui_flush();
}
diff --git a/src/nvim/testdir/test_bufline.vim b/src/nvim/testdir/test_bufline.vim
index 2567dd2be2..076f03fdd8 100644
--- a/src/nvim/testdir/test_bufline.vim
+++ b/src/nvim/testdir/test_bufline.vim
@@ -19,7 +19,7 @@ func Test_setbufline_getbufline()
let b = bufnr('%')
wincmd w
call assert_equal(1, setbufline(b, 5, ['x']))
- call assert_equal(1, setbufline(bufnr('$') + 1, 1, ['x']))
+ call assert_equal(1, setbufline(1234, 1, ['x']))
call assert_equal(0, setbufline(b, 4, ['d', 'e']))
call assert_equal(['c'], getbufline(b, 3))
call assert_equal(['d'], getbufline(b, 4))
diff --git a/src/nvim/testdir/test_messages.vim b/src/nvim/testdir/test_messages.vim
index d0a8f342c9..30239a90c2 100644
--- a/src/nvim/testdir/test_messages.vim
+++ b/src/nvim/testdir/test_messages.vim
@@ -89,65 +89,6 @@ func Test_echoerr()
call test_ignore_error('RESET')
endfunc
-func Test_mode_message_at_leaving_insert_by_ctrl_c()
- if !has('terminal') || has('gui_running')
- return
- endif
-
- " Set custom statusline built by user-defined function.
- let testfile = 'Xtest.vim'
- call writefile([
- \ 'func StatusLine() abort',
- \ ' return ""',
- \ 'endfunc',
- \ 'set statusline=%!StatusLine()',
- \ 'set laststatus=2',
- \ ], testfile)
-
- let rows = 10
- let buf = term_start([GetVimProg(), '--clean', '-S', testfile], {'term_rows': rows})
- call term_wait(buf, 200)
- call assert_equal('run', job_status(term_getjob(buf)))
-
- call term_sendkeys(buf, "i")
- call WaitForAssert({-> assert_match('^-- INSERT --\s*$', term_getline(buf, rows))})
- call term_sendkeys(buf, "\<C-C>")
- call WaitForAssert({-> assert_match('^\s*$', term_getline(buf, rows))})
-
- call term_sendkeys(buf, ":qall!\<CR>")
- call WaitForAssert({-> assert_equal('dead', job_status(term_getjob(buf)))})
- exe buf . 'bwipe!'
- call delete(testfile)
-endfunc
-
-func Test_mode_message_at_leaving_insert_with_esc_mapped()
- if !has('terminal') || has('gui_running')
- return
- endif
-
- " Set custom statusline built by user-defined function.
- let testfile = 'Xtest.vim'
- call writefile([
- \ 'set laststatus=2',
- \ 'inoremap <Esc> <Esc>00',
- \ ], testfile)
-
- let rows = 10
- let buf = term_start([GetVimProg(), '--clean', '-S', testfile], {'term_rows': rows})
- call term_wait(buf, 200)
- call assert_equal('run', job_status(term_getjob(buf)))
-
- call term_sendkeys(buf, "i")
- call WaitForAssert({-> assert_match('^-- INSERT --\s*$', term_getline(buf, rows))})
- call term_sendkeys(buf, "\<Esc>")
- call WaitForAssert({-> assert_match('^\s*$', term_getline(buf, rows))})
-
- call term_sendkeys(buf, ":qall!\<CR>")
- call WaitForAssert({-> assert_equal('dead', job_status(term_getjob(buf)))})
- exe buf . 'bwipe!'
- call delete(testfile)
-endfunc
-
func Test_echospace()
set noruler noshowcmd laststatus=1
call assert_equal(&columns - 1, v:echospace)
diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim
index 8ef8bbc23a..f71da92bf8 100644
--- a/src/nvim/testdir/test_mksession.vim
+++ b/src/nvim/testdir/test_mksession.vim
@@ -178,15 +178,20 @@ func Test_mksession_rtp()
set sessionoptions&
endfunc
-" Verify that arglist is stored correctly to the session file.
func Test_mksession_arglist()
%argdel
next file1 file2 file3 file4
+ new
+ next | next
mksession! Xtest_mks.out
source Xtest_mks.out
call assert_equal(['file1', 'file2', 'file3', 'file4'], argv())
+ call assert_equal(2, argidx())
+ wincmd w
+ call assert_equal(0, argidx())
call delete('Xtest_mks.out')
+ enew | only
argdel *
endfunc
@@ -220,6 +225,53 @@ func Test_mksession_one_buffer_two_windows()
call delete('Xtest_mks.out')
endfunc
+func Test_mksession_lcd_multiple_tabs()
+ tabnew
+ tabnew
+ lcd .
+ tabfirst
+ lcd .
+ mksession! Xtest_mks.out
+ tabonly
+ source Xtest_mks.out
+ call assert_true(haslocaldir(), 'Tab 1 localdir')
+ tabnext 2
+ call assert_true(!haslocaldir(), 'Tab 2 localdir')
+ tabnext 3
+ call assert_true(haslocaldir(), 'Tab 3 localdir')
+ call delete('Xtest_mks.out')
+endfunc
+
+func Test_mksession_blank_tabs()
+ tabnew
+ tabnew
+ tabnew
+ tabnext 3
+ mksession! Xtest_mks.out
+ tabnew
+ tabnew
+ tabnext 2
+ source Xtest_mks.out
+ call assert_equal(4, tabpagenr('$'), 'session restore should restore number of tabs')
+ call assert_equal(3, tabpagenr(), 'session restore should restore the active tab')
+ call delete('Xtest_mks.out')
+endfunc
+
+func Test_mksession_blank_windows()
+ split
+ split
+ split
+ 3 wincmd w
+ mksession! Xtest_mks.out
+ split
+ split
+ 2 wincmd w
+ source Xtest_mks.out
+ call assert_equal(4, winnr('$'), 'session restore should restore number of windows')
+ call assert_equal(3, winnr(), 'session restore should restore the active window')
+ call delete('Xtest_mks.out')
+endfunc
+
if has('extra_search')
func Test_mksession_hlsearch()
@@ -356,24 +408,28 @@ func Test_mksession_globals()
set sessionoptions+=globals
" create different global variables
- let g:Global_string = "Sun is shining"
+ let g:Global_string = "Sun is shining\r\n"
let g:Global_count = 100
let g:Global_pi = 3.14
+ let g:Global_neg_float = -2.68
mksession! Xtest_mks.out
unlet g:Global_string
unlet g:Global_count
unlet g:Global_pi
+ unlet g:Global_neg_float
source Xtest_mks.out
- call assert_equal("Sun is shining", g:Global_string)
+ call assert_equal("Sun is shining\r\n", g:Global_string)
call assert_equal(100, g:Global_count)
call assert_equal(3.14, g:Global_pi)
+ call assert_equal(-2.68, g:Global_neg_float)
unlet g:Global_string
unlet g:Global_count
unlet g:Global_pi
+ unlet g:Global_neg_float
call delete('Xtest_mks.out')
set sessionoptions&
endfunc
@@ -432,20 +488,123 @@ func Test_mksession_resize()
for line in lines
if line =~ '^set lines='
let found_resize = v:true
+ break
endif
endfor
- call assert_equal(v:false, found_resize)
+ call assert_false(found_resize)
let lines = readfile('Xtest_mks2.out')
let found_resize = v:false
for line in lines
if line =~ '^set lines='
let found_resize = v:true
+ break
+ endif
+ endfor
+ call assert_true(found_resize)
+
+ call delete('Xtest_mks1.out')
+ call delete('Xtest_mks2.out')
+ set sessionoptions&
+endfunc
+
+" Test for mksession with a named scratch buffer
+func Test_mksession_scratch()
+ set sessionoptions&vi
+ enew | only
+ file Xscratch
+ set buftype=nofile
+ mksession! Xtest_mks.out
+ %bwipe
+ source Xtest_mks.out
+ call assert_equal('Xscratch', bufname(''))
+ call assert_equal('nofile', &buftype)
+ %bwipe
+ call delete('Xtest_mks.out')
+ set sessionoptions&
+endfunc
+
+" Test for mksession with fold options
+func Test_mksession_foldopt()
+ set sessionoptions-=options
+ set sessionoptions+=folds
+ new
+ setlocal foldenable
+ setlocal foldmethod=expr
+ setlocal foldmarker=<<<,>>>
+ setlocal foldignore=%
+ setlocal foldlevel=2
+ setlocal foldminlines=10
+ setlocal foldnestmax=15
+ mksession! Xtest_mks.out
+ close
+ %bwipe
+
+ source Xtest_mks.out
+ call assert_true(&foldenable)
+ call assert_equal('expr', &foldmethod)
+ call assert_equal('<<<,>>>', &foldmarker)
+ call assert_equal('%', &foldignore)
+ call assert_equal(2, &foldlevel)
+ call assert_equal(10, &foldminlines)
+ call assert_equal(15, &foldnestmax)
+
+ close
+ %bwipe
+ set sessionoptions&
+endfunc
+
+" Test for mksession with window position
+func Test_mksession_winpos()
+ if !has('gui_running')
+ " Only applicable in GUI Vim
+ return
+ endif
+ set sessionoptions+=winpos
+ mksession! Xtest_mks.out
+ let found_winpos = v:false
+ let lines = readfile('Xtest_mks.out')
+ for line in lines
+ if line =~ '^winpos '
+ let found_winpos = v:true
+ break
+ endif
+ endfor
+ call assert_true(found_winpos)
+ call delete('Xtest_mks.out')
+ set sessionoptions&
+endfunc
+
+" Test for mksession with 'compatible' option
+func Test_mksession_compatible()
+ throw 'skipped: Nvim does not support "compatible" option'
+ mksession! Xtest_mks1.out
+ set compatible
+ mksession! Xtest_mks2.out
+ set nocp
+
+ let test_success = v:false
+ let lines = readfile('Xtest_mks1.out')
+ for line in lines
+ if line =~ '^if &cp | set nocp | endif'
+ let test_success = v:true
+ break
+ endif
+ endfor
+ call assert_true(test_success)
+
+ let test_success = v:false
+ let lines = readfile('Xtest_mks2.out')
+ for line in lines
+ if line =~ '^if !&cp | set cp | endif'
+ let test_success = v:true
+ break
endif
endfor
- call assert_equal(v:true, found_resize)
+ call assert_true(test_success)
call delete('Xtest_mks1.out')
call delete('Xtest_mks2.out')
+ set compatible&
set sessionoptions&
endfunc
diff --git a/src/nvim/testdir/test_window_cmd.vim b/src/nvim/testdir/test_window_cmd.vim
index c630e678fd..bed39d0741 100644
--- a/src/nvim/testdir/test_window_cmd.vim
+++ b/src/nvim/testdir/test_window_cmd.vim
@@ -850,6 +850,14 @@ func Test_window_resize()
exe other_winnr .. 'resize +1'
call assert_equal(12, winheight(other_winnr))
call assert_equal(&lines - 10 - 3 -2, winheight(0))
+ close
+
+ vsplit
+ wincmd l
+ let other_winnr = winnr('h')
+ call assert_notequal(winnr(), other_winnr)
+ exe 'vert ' .. other_winnr .. 'resize -100'
+ call assert_equal(0, winwidth(other_winnr))
%bwipe!
endfunc
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index 685da77b39..c6c09c80d7 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.c
@@ -61,6 +61,9 @@ static bool pending_mode_info_update = false;
static bool pending_mode_update = false;
static handle_T cursor_grid_handle = DEFAULT_GRID_HANDLE;
+static bool has_mouse = false;
+static int pending_has_mouse = -1;
+
#if MIN_LOG_LEVEL > DEBUG_LOG_LEVEL
# define UI_LOG(funname)
#else
@@ -220,6 +223,7 @@ void ui_refresh(void)
ui_mode_info_set();
pending_mode_update = true;
ui_cursor_shape();
+ pending_has_mouse = -1;
}
int ui_pum_get_height(void)
@@ -459,10 +463,69 @@ void ui_flush(void)
ui_call_mode_change(cstr_as_string(full_name), ui_mode_idx);
pending_mode_update = false;
}
+ if (pending_has_mouse != has_mouse) {
+ (has_mouse ? ui_call_mouse_on : ui_call_mouse_off)();
+ pending_has_mouse = has_mouse;
+ }
ui_call_flush();
}
+
+/// Check if 'mouse' is active for the current mode
+///
+/// TODO(bfredl): precompute the State -> active mapping when 'mouse' changes,
+/// then this can be checked directly in ui_flush()
+void ui_check_mouse(void)
+{
+ has_mouse = false;
+ // Be quick when mouse is off.
+ if (*p_mouse == NUL) {
+ return;
+ }
+
+ int checkfor = MOUSE_NORMAL; // assume normal mode
+ if (VIsual_active) {
+ checkfor = MOUSE_VISUAL;
+ } else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE) {
+ checkfor = MOUSE_RETURN;
+ } else if (State & INSERT) {
+ checkfor = MOUSE_INSERT;
+ } else if (State & CMDLINE) {
+ checkfor = MOUSE_COMMAND;
+ } else if (State == CONFIRM || State == EXTERNCMD) {
+ checkfor = ' '; // don't use mouse for ":confirm" or ":!cmd"
+ }
+
+ // mouse should be active if at least one of the following is true:
+ // - "c" is in 'mouse', or
+ // - 'a' is in 'mouse' and "c" is in MOUSE_A, or
+ // - the current buffer is a help file and 'h' is in 'mouse' and we are in a
+ // normal editing mode (not at hit-return message).
+ for (char_u *p = p_mouse; *p; p++) {
+ switch (*p) {
+ case 'a':
+ if (vim_strchr((char_u *)MOUSE_A, checkfor) != NULL) {
+ has_mouse = true;
+ return;
+ }
+ break;
+ case MOUSE_HELP:
+ if (checkfor != MOUSE_RETURN && curbuf->b_help) {
+ has_mouse = true;
+ return;
+ }
+ break;
+ default:
+ if (checkfor == *p) {
+ has_mouse = true;
+ return;
+ }
+ }
+ }
+}
+
/// Check if current mode has changed.
+///
/// May update the shape of the cursor.
void ui_cursor_shape(void)
{
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 2dcce2d8cb..00f49724b6 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -5349,6 +5349,8 @@ void win_setwidth_win(int width, win_T *wp)
width = p_wmw;
if (width == 0)
width = 1;
+ } else if (width < 0) {
+ width = 0;
}
if (wp->w_floating) {
wp->w_float_config.width = width;
diff --git a/test/functional/eval/null_spec.lua b/test/functional/eval/null_spec.lua
index bef41e52d4..fa8f7d873f 100644
--- a/test/functional/eval/null_spec.lua
+++ b/test/functional/eval/null_spec.lua
@@ -121,7 +121,7 @@ describe('NULL', function()
null_test('does not make Neovim crash when v:oldfiles gets assigned to that', ':let v:oldfiles = L|oldfiles', 0)
null_expr_test('does not make complete() crash or error out',
'execute(":normal i\\<C-r>=complete(1, L)[-1]\\n")',
- 0, '', function()
+ '', '\n', function()
eq({''}, curbufmeths.get_lines(0, -1, false))
end)
null_expr_test('is accepted by setmatches()', 'setmatches(L)', 0, 0)
diff --git a/test/functional/eval/timer_spec.lua b/test/functional/eval/timer_spec.lua
index 3f57568b8e..9ee0735e40 100644
--- a/test/functional/eval/timer_spec.lua
+++ b/test/functional/eval/timer_spec.lua
@@ -130,12 +130,12 @@ describe('timers', function()
nvim_async("command", "call timer_start("..load_adjust(100)..", 'AddItem', {'repeat': -1})")
screen:expect([[
- ^ITEM 1 |
+ ITEM 1 |
ITEM 2 |
{1:~ }|
{1:~ }|
{1:~ }|
- |
+ ^ |
]])
nvim_async("command", "let g:cont = 1")
diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua
index 8d654f6e5b..32f9ae030f 100644
--- a/test/functional/ui/float_spec.lua
+++ b/test/functional/ui/float_spec.lua
@@ -5344,45 +5344,6 @@ describe('floatwin', function()
-- at least. Also check invisible EndOfBuffer region blends correctly.
meths.buf_set_lines(buf, 0, -1, true, {" x x x xx", " x x x x"})
win = meths.open_win(buf, false, {relative='editor', width=12, height=3, row=0, col=11, style='minimal'})
- if multigrid then
- screen:expect{grid=[[
- ## grid 1
- [2:----------------------------------------]|
- [2:----------------------------------------]|
- [2:----------------------------------------]|
- [2:----------------------------------------]|
- [2:----------------------------------------]|
- [2:----------------------------------------]|
- [3:----------------------------------------]|
- ## grid 2
- # TODO: 测试字典信息的准确性 |
- # FIXME: 测试字典信息的准确^性 |
- {0:~ }|
- {0:~ }|
- {0:~ }|
- {0:~ }|
- ## grid 3
- |
- ## grid 6
- {1: x x x xx}|
- {1: x x x x}|
- {1: }|
- ]], float_pos={
- [6] = { {
- id = 1003
- }, "NW", 1, 0, 11, true }
- }}
- else
- screen:expect{grid=[[
- # TODO: 测 {1: x x x xx} 确性 |
- # FIXME: 测{1: x x x x}准确^性 |
- {0:~ }{1: }{0: }|
- {0:~ }|
- {0:~ }|
- {0:~ }|
- |
- ]]}
- end
meths.win_set_option(win, 'winblend', 30)
screen:set_default_attr_ids({
[1] = {foreground = tonumber('0xb282b2'), background = tonumber('0xffcfff')},
@@ -5420,7 +5381,7 @@ describe('floatwin', function()
}, "NW", 1, 0, 11, true }
}}
else
- screen:expect{grid=[[
+ screen:expect([[
# TODO: 测 {2: x x x}{1:息}{2: xx} 确性 |
# FIXME: 测{1:试}{2:x x x}{1:息}{2: x}准确^性 |
{3:~ }{4: }{3: }|
@@ -5428,7 +5389,7 @@ describe('floatwin', function()
{3:~ }|
{3:~ }|
|
- ]]}
+ ]])
end
meths.win_set_config(win, {relative='editor', row=0, col=12})
diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua
index a741136111..7bca741ae3 100644
--- a/test/functional/ui/mouse_spec.lua
+++ b/test/functional/ui/mouse_spec.lua
@@ -45,13 +45,33 @@ describe('ui/mouse/input', function()
it('single left click moves cursor', function()
feed('<LeftMouse><2,1>')
- screen:expect([[
+ screen:expect{grid=[[
testing |
mo^use |
support and selection |
{0:~ }|
|
+ ]], mouse_enabled=true}
+ feed('<LeftMouse><0,0>')
+ screen:expect([[
+ ^testing |
+ mouse |
+ support and selection |
+ {0:~ }|
+ |
]])
+ end)
+
+ it("in external ui works with unset 'mouse'", function()
+ meths.set_option('mouse', '')
+ feed('<LeftMouse><2,1>')
+ screen:expect{grid=[[
+ testing |
+ mo^use |
+ support and selection |
+ {0:~ }|
+ |
+ ]], mouse_enabled=false}
feed('<LeftMouse><0,0>')
screen:expect([[
^testing |
diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua
index 5104c58796..fcf6926433 100644
--- a/test/functional/ui/screen.lua
+++ b/test/functional/ui/screen.lua
@@ -170,7 +170,7 @@ function Screen.new(width, height)
ruler = {},
hl_groups = {},
_default_attr_ids = nil,
- _mouse_enabled = true,
+ mouse_enabled = true,
_attrs = {},
_hl_info = {[0]={}},
_attr_table = {[0]={{},{}}},
@@ -318,7 +318,7 @@ function Screen:expect(expected, attr_ids, ...)
assert(next({...}) == nil, "invalid args to expect()")
if type(expected) == "table" then
assert(not (attr_ids ~= nil))
- local is_key = {grid=true, attr_ids=true, condition=true,
+ local is_key = {grid=true, attr_ids=true, condition=true, mouse_enabled=true,
any=true, mode=true, unchanged=true, intermediate=true,
reset=true, timeout=true, request_cb=true, hl_groups=true}
for _, v in ipairs(ext_keys) do
@@ -422,12 +422,15 @@ screen:redraw_debug() to show all intermediate screen states. ]])
if expected.mode ~= nil then
extstate.mode = self.mode
end
+ if expected.mouse_enabled ~= nil then
+ extstate.mouse_enabled = self.mouse_enabled
+ end
if expected.win_viewport == nil then
extstate.win_viewport = nil
end
-- Convert assertion errors into invalid screen state descriptions.
- for _, k in ipairs(concat_tables(ext_keys, {'mode'})) do
+ for _, k in ipairs(concat_tables(ext_keys, {'mode', 'mouse_enabled'})) do
-- Empty states are considered the default and need not be mentioned.
if (not (expected[k] == nil and isempty(extstate[k]))) then
local status, res = pcall(eq, expected[k], extstate[k], k)
@@ -799,17 +802,15 @@ function Screen:_handle_busy_stop()
end
function Screen:_handle_mouse_on()
- self._mouse_enabled = true
+ self.mouse_enabled = true
end
function Screen:_handle_mouse_off()
- self._mouse_enabled = false
+ self.mouse_enabled = false
end
function Screen:_handle_mode_change(mode, idx)
- if self._mode_info ~= nil then
- assert(mode == self._mode_info[idx+1].name)
- end
+ assert(mode == self._mode_info[idx+1].name)
self.mode = mode
end
diff --git a/test/functional/ui/searchhl_spec.lua b/test/functional/ui/searchhl_spec.lua
index 3bb72303bf..656f613c6a 100644
--- a/test/functional/ui/searchhl_spec.lua
+++ b/test/functional/ui/searchhl_spec.lua
@@ -20,7 +20,6 @@ describe('search highlighting', function()
[2] = {background = colors.Yellow}, -- Search
[3] = {reverse = true},
[4] = {foreground = colors.Red}, -- Message
- [5] = {bold = true, reverse = true},
[6] = {foreground = Screen.colors.Blue4, background = Screen.colors.LightGrey}, -- Folded
})
end)
@@ -176,15 +175,7 @@ describe('search highlighting', function()
]])
feed('/foo')
helpers.poke_eventloop()
- screen:expect{grid=[[
- {3:foo} bar baz {3:│} |
- bar baz {2:foo} {3:│} |
- bar {2:foo} baz {3:│} |
- {3:│} |
- {1:~ }{3:│} |
- {5:[No Name] [+] }{3:term }|
- /foo^ |
- ]]}
+ screen:expect_unchanged()
end)
it('works with incsearch', function()
@@ -480,6 +471,19 @@ describe('search highlighting', function()
{4:search hit BOTTOM, continuing at TOP} |
]])
+ -- check hilights work also in folds
+ feed("zf4j")
+ command("%foldopen")
+ screen:expect([[
+ very {5:spec^ial}{2: te}{6:xt} |
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {4:search hit BOTTOM, continuing at TOP} |
+ ]])
+
feed_command("call clearmatches()")
screen:expect([[
very spec{2:^ial te}xt |