aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/functional/eval/input_spec.lua55
-rw-r--r--test/functional/fixtures/tty-test.c79
-rw-r--r--test/functional/terminal/buffer_spec.lua4
-rw-r--r--test/functional/terminal/cursor_spec.lua2
-rw-r--r--test/functional/terminal/ex_terminal_spec.lua11
-rw-r--r--test/functional/terminal/helpers.lua1
-rw-r--r--test/functional/terminal/highlight_spec.lua5
-rw-r--r--test/functional/terminal/mouse_spec.lua5
-rw-r--r--test/functional/terminal/scrollback_spec.lua86
-rw-r--r--test/functional/terminal/window_spec.lua2
-rw-r--r--test/functional/terminal/window_split_tab_spec.lua41
-rw-r--r--test/functional/ui/cmdline_highlight_spec.lua893
-rw-r--r--test/functional/ui/screen.lua2
13 files changed, 1086 insertions, 100 deletions
diff --git a/test/functional/eval/input_spec.lua b/test/functional/eval/input_spec.lua
index 74ad32bc6c..5ae23e17d0 100644
--- a/test/functional/eval/input_spec.lua
+++ b/test/functional/eval/input_spec.lua
@@ -23,10 +23,41 @@ before_each(function()
function CustomListCompl(...)
return ['FOO']
endfunction
+
+ highlight RBP1 guibg=Red
+ highlight RBP2 guibg=Yellow
+ highlight RBP3 guibg=Green
+ highlight RBP4 guibg=Blue
+ let g:NUM_LVLS = 4
+ function Redraw()
+ redraw!
+ return ''
+ endfunction
+ cnoremap <expr> {REDRAW} Redraw()
+ function RainBowParens(cmdline)
+ let ret = []
+ let i = 0
+ let lvl = 0
+ while i < len(a:cmdline)
+ if a:cmdline[i] is# '('
+ call add(ret, [i, i + 1, 'RBP' . ((lvl % g:NUM_LVLS) + 1)])
+ let lvl += 1
+ elseif a:cmdline[i] is# ')'
+ let lvl -= 1
+ call add(ret, [i, i + 1, 'RBP' . ((lvl % g:NUM_LVLS) + 1)])
+ endif
+ let i += 1
+ endwhile
+ return ret
+ endfunction
]])
screen:set_default_attr_ids({
EOB={bold = true, foreground = Screen.colors.Blue1},
T={foreground=Screen.colors.Red},
+ RBP1={background=Screen.colors.Red},
+ RBP2={background=Screen.colors.Yellow},
+ RBP3={background=Screen.colors.Green},
+ RBP4={background=Screen.colors.Blue},
})
end)
@@ -196,6 +227,18 @@ describe('input()', function()
eq('Vim(call):E118: Too many arguments for function: input',
exc_exec('call input("prompt> ", "default", "file", "extra")'))
end)
+ it('supports highlighting', function()
+ command('nnoremap <expr> X input({"highlight": "RainBowParens"})[-1]')
+ feed([[X]])
+ feed('(())')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {RBP1:(}{RBP2:()}{RBP1:)}^ |
+ ]])
+ end)
end)
describe('inputdialog()', function()
it('works with multiline prompts', function()
@@ -363,4 +406,16 @@ describe('inputdialog()', function()
eq('Vim(call):E118: Too many arguments for function: inputdialog',
exc_exec('call inputdialog("prompt> ", "default", "file", "extra")'))
end)
+ it('supports highlighting', function()
+ command('nnoremap <expr> X inputdialog({"highlight": "RainBowParens"})[-1]')
+ feed([[X]])
+ feed('(())')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {RBP1:(}{RBP2:()}{RBP1:)}^ |
+ ]])
+ end)
end)
diff --git a/test/functional/fixtures/tty-test.c b/test/functional/fixtures/tty-test.c
index 7ba21d652a..edcbe23f86 100644
--- a/test/functional/fixtures/tty-test.c
+++ b/test/functional/fixtures/tty-test.c
@@ -5,42 +5,45 @@
#include <stdio.h>
#include <stdlib.h>
#include <uv.h>
+#ifdef _WIN32
+# include <windows.h>
+#else
+# include <unistd.h>
+#endif
// -V:STRUCT_CAST:641
#define STRUCT_CAST(Type, obj) ((Type *)(obj))
+#define is_terminal(stream) (uv_guess_handle(fileno(stream)) == UV_TTY)
+#define BUF_SIZE 0xfff
+#define CTRL_C 0x03
uv_tty_t tty;
+uv_tty_t tty_out;
-#ifdef _WIN32
-#include <windows.h>
bool owns_tty(void)
{
- HWND consoleWnd = GetConsoleWindow();
- DWORD dwProcessId;
- GetWindowThreadProcessId(consoleWnd, &dwProcessId);
- return GetCurrentProcessId() == dwProcessId;
-}
+#ifdef _WIN32
+ // XXX: We need to make proper detect owns tty
+ // HWND consoleWnd = GetConsoleWindow();
+ // DWORD dwProcessId;
+ // GetWindowThreadProcessId(consoleWnd, &dwProcessId);
+ // return GetCurrentProcessId() == dwProcessId;
+ return true;
#else
-#include <unistd.h>
-bool owns_tty(void)
-{
return getsid(0) == getpid();
-}
#endif
+}
-#define is_terminal(stream) (uv_guess_handle(fileno(stream)) == UV_TTY)
-#define BUF_SIZE 0xfff
-
-static void walk_cb(uv_handle_t *handle, void *arg) {
+static void walk_cb(uv_handle_t *handle, void *arg)
+{
if (!uv_is_closing(handle)) {
uv_close(handle, NULL);
}
}
-#ifndef WIN32
static void sig_handler(int signum)
{
- switch(signum) {
+ switch (signum) {
case SIGWINCH: {
int width, height;
uv_tty_get_winsize(&tty, &width, &height);
@@ -54,15 +57,15 @@ static void sig_handler(int signum)
return;
}
}
-#endif
-// static void sigwinch_cb(uv_signal_t *handle, int signum)
-// {
-// int width, height;
-// uv_tty_t *tty = handle->data;
-// uv_tty_get_winsize(tty, &width, &height);
-// fprintf(stderr, "rows: %d, cols: %d\n", height, width);
-// }
+#ifdef WIN32
+static void sigwinch_cb(uv_signal_t *handle, int signum)
+{
+ int width, height;
+ uv_tty_get_winsize(&tty_out, &width, &height);
+ fprintf(stderr, "rows: %d, cols: %d\n", height, width);
+}
+#endif
static void alloc_cb(uv_handle_t *handle, size_t suggested, uv_buf_t *buf)
{
@@ -80,7 +83,7 @@ static void read_cb(uv_stream_t *stream, ssize_t cnt, const uv_buf_t *buf)
int *interrupted = stream->data;
for (int i = 0; i < cnt; i++) {
- if (buf->base[i] == 3) {
+ if (buf->base[i] == CTRL_C) {
(*interrupted)++;
}
}
@@ -88,11 +91,13 @@ static void read_cb(uv_stream_t *stream, ssize_t cnt, const uv_buf_t *buf)
uv_loop_t write_loop;
uv_loop_init(&write_loop);
uv_tty_t out;
- uv_tty_init(&write_loop, &out, 1, 0);
+ uv_tty_init(&write_loop, &out, fileno(stdout), 0);
+
uv_write_t req;
uv_buf_t b = {.base = buf->base, .len = (size_t)cnt};
uv_write(&req, STRUCT_CAST(uv_stream_t, &out), &b, 1, NULL);
uv_run(&write_loop, UV_RUN_DEFAULT);
+
uv_close(STRUCT_CAST(uv_handle_t, &out), NULL);
uv_run(&write_loop, UV_RUN_DEFAULT);
if (uv_loop_close(&write_loop)) {
@@ -137,7 +142,7 @@ int main(int argc, char **argv)
if (argc > 1) {
int count = atoi(argv[1]);
- for (int i = 0; i < count; ++i) {
+ for (int i = 0; i < count; i++) {
printf("line%d\n", i);
}
fflush(stdout);
@@ -148,8 +153,14 @@ int main(int argc, char **argv)
uv_prepare_t prepare;
uv_prepare_init(uv_default_loop(), &prepare);
uv_prepare_start(&prepare, prepare_cb);
- // uv_tty_t tty;
+#ifndef WIN32
uv_tty_init(uv_default_loop(), &tty, fileno(stderr), 1);
+#else
+ uv_tty_init(uv_default_loop(), &tty, fileno(stdin), 1);
+ uv_tty_init(uv_default_loop(), &tty_out, fileno(stdout), 0);
+ int width, height;
+ uv_tty_get_winsize(&tty_out, &width, &height);
+#endif
uv_tty_set_mode(&tty, UV_TTY_MODE_RAW);
tty.data = &interrupted;
uv_read_start(STRUCT_CAST(uv_stream_t, &tty), alloc_cb, read_cb);
@@ -160,15 +171,17 @@ int main(int argc, char **argv)
sa.sa_handler = sig_handler;
sigaction(SIGHUP, &sa, NULL);
sigaction(SIGWINCH, &sa, NULL);
- // uv_signal_t sigwinch_watcher;
- // uv_signal_init(uv_default_loop(), &sigwinch_watcher);
- // sigwinch_watcher.data = &tty;
- // uv_signal_start(&sigwinch_watcher, sigwinch_cb, SIGWINCH);
+#else
+ uv_signal_t sigwinch_watcher;
+ uv_signal_init(uv_default_loop(), &sigwinch_watcher);
+ uv_signal_start(&sigwinch_watcher, sigwinch_cb, SIGWINCH);
#endif
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+#ifndef WIN32
// XXX: Without this the SIGHUP handler is skipped on some systems.
sleep(100);
+#endif
return 0;
}
diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua
index 48b8512bf0..4ce33fef7b 100644
--- a/test/functional/terminal/buffer_spec.lua
+++ b/test/functional/terminal/buffer_spec.lua
@@ -6,8 +6,6 @@ local eval, feed_command, source = helpers.eval, helpers.feed_command, helpers.s
local eq, neq = helpers.eq, helpers.neq
local write_file = helpers.write_file
-if helpers.pending_win32(pending) then return end
-
describe('terminal buffer', function()
local screen
@@ -160,6 +158,7 @@ describe('terminal buffer', function()
end)
it('handles loss of focus gracefully', function()
+ if helpers.pending_win32(pending) then return end
-- Change the statusline to avoid printing the file name, which varies.
nvim('set_option', 'statusline', '==========')
feed_command('set laststatus=0')
@@ -205,7 +204,6 @@ describe('terminal buffer', function()
end)
describe('No heap-buffer-overflow when using', function()
-
local testfilename = 'Xtestfile-functional-terminal-buffers_spec'
before_each(function()
diff --git a/test/functional/terminal/cursor_spec.lua b/test/functional/terminal/cursor_spec.lua
index 84d0322f12..d49f1bfc23 100644
--- a/test/functional/terminal/cursor_spec.lua
+++ b/test/functional/terminal/cursor_spec.lua
@@ -7,8 +7,6 @@ local feed_command = helpers.feed_command
local hide_cursor = thelpers.hide_cursor
local show_cursor = thelpers.show_cursor
-if helpers.pending_win32(pending) then return end
-
describe('terminal cursor', function()
local screen
diff --git a/test/functional/terminal/ex_terminal_spec.lua b/test/functional/terminal/ex_terminal_spec.lua
index be0fd9f8ff..9930efc402 100644
--- a/test/functional/terminal/ex_terminal_spec.lua
+++ b/test/functional/terminal/ex_terminal_spec.lua
@@ -3,10 +3,10 @@ local Screen = require('test.functional.ui.screen')
local clear, wait, nvim = helpers.clear, helpers.wait, helpers.nvim
local nvim_dir, source, eq = helpers.nvim_dir, helpers.source, helpers.eq
local feed_command, eval = helpers.feed_command, helpers.eval
-
-if helpers.pending_win32(pending) then return end
+local iswin = helpers.iswin
describe(':terminal', function()
+ if helpers.pending_win32(pending) then return end
local screen
before_each(function()
@@ -174,12 +174,15 @@ describe(':terminal (with fake shell)', function()
eq('term://', string.match(eval('bufname("%")'), "^term://"))
helpers.feed([[<C-\><C-N>]])
feed_command([[find */shadacat.py]])
- eq('scripts/shadacat.py', eval('bufname("%")'))
+ if iswin() then
+ eq('scripts\\shadacat.py', eval('bufname("%")'))
+ else
+ eq('scripts/shadacat.py', eval('bufname("%")'))
+ end
end)
it('works with gf', function()
terminal_with_fake_shell([[echo "scripts/shadacat.py"]])
- wait()
screen:expect([[
ready $ echo "scripts/shadacat.py" |
|
diff --git a/test/functional/terminal/helpers.lua b/test/functional/terminal/helpers.lua
index 3b04d17705..bd24b9785d 100644
--- a/test/functional/terminal/helpers.lua
+++ b/test/functional/terminal/helpers.lua
@@ -33,7 +33,6 @@ local function disable_mouse() feed_termcode('[?1002l') end
local default_command = '["'..nvim_dir..'/tty-test'..'"]'
-
local function screen_setup(extra_rows, command, cols)
extra_rows = extra_rows and extra_rows or 0
command = command and command or default_command
diff --git a/test/functional/terminal/highlight_spec.lua b/test/functional/terminal/highlight_spec.lua
index bb40770235..fddc0bbb71 100644
--- a/test/functional/terminal/highlight_spec.lua
+++ b/test/functional/terminal/highlight_spec.lua
@@ -5,8 +5,6 @@ local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim
local nvim_dir, command = helpers.nvim_dir, helpers.command
local eq, eval = helpers.eq, helpers.eval
-if helpers.pending_win32(pending) then return end
-
describe('terminal window highlighting', function()
local screen
@@ -55,6 +53,7 @@ describe('terminal window highlighting', function()
end)
local function pass_attrs()
+ if helpers.pending_win32(pending) then return end
screen:expect(sub([[
tty ready |
{NUM:text}text{10: } |
@@ -69,6 +68,7 @@ describe('terminal window highlighting', function()
it('will pass the corresponding attributes', pass_attrs)
it('will pass the corresponding attributes on scrollback', function()
+ if helpers.pending_win32(pending) then return end
pass_attrs()
local lines = {}
for i = 1, 8 do
@@ -145,6 +145,7 @@ describe('terminal window highlighting with custom palette', function()
end)
it('will use the custom color', function()
+ if helpers.pending_win32(pending) then return end
thelpers.set_fg(3)
thelpers.feed_data('text')
thelpers.clear_attrs()
diff --git a/test/functional/terminal/mouse_spec.lua b/test/functional/terminal/mouse_spec.lua
index 9239c2ad31..29c62d7be7 100644
--- a/test/functional/terminal/mouse_spec.lua
+++ b/test/functional/terminal/mouse_spec.lua
@@ -4,8 +4,6 @@ local clear, eq, eval = helpers.clear, helpers.eq, helpers.eval
local feed, nvim = helpers.feed, helpers.nvim
local feed_data = thelpers.feed_data
-if helpers.pending_win32(pending) then return end
-
describe('terminal mouse', function()
local screen
@@ -67,6 +65,7 @@ describe('terminal mouse', function()
end)
it('will forward mouse clicks to the program', function()
+ if helpers.pending_win32(pending) then return end
feed('<LeftMouse><1,2>')
screen:expect([[
line27 |
@@ -80,6 +79,7 @@ describe('terminal mouse', function()
end)
it('will forward mouse scroll to the program', function()
+ if helpers.pending_win32(pending) then return end
feed('<ScrollWheelUp><0,0>')
screen:expect([[
line27 |
@@ -94,6 +94,7 @@ describe('terminal mouse', function()
end)
describe('with a split window and other buffer', function()
+ if helpers.pending_win32(pending) then return end
before_each(function()
feed('<c-\\><c-n>:vsp<cr>')
screen:expect([[
diff --git a/test/functional/terminal/scrollback_spec.lua b/test/functional/terminal/scrollback_spec.lua
index 05f81295c2..af9b414311 100644
--- a/test/functional/terminal/scrollback_spec.lua
+++ b/test/functional/terminal/scrollback_spec.lua
@@ -3,6 +3,7 @@ local helpers = require('test.functional.helpers')(after_each)
local thelpers = require('test.functional.terminal.helpers')
local clear, eq, curbuf = helpers.clear, helpers.eq, helpers.curbuf
local feed, nvim_dir, feed_command = helpers.feed, helpers.nvim_dir, helpers.feed_command
+local iswin = helpers.iswin
local eval = helpers.eval
local command = helpers.command
local wait = helpers.wait
@@ -11,8 +12,6 @@ local curbufmeths = helpers.curbufmeths
local nvim = helpers.nvim
local feed_data = thelpers.feed_data
-if helpers.pending_win32(pending) then return end
-
describe('terminal scrollback', function()
local screen
@@ -58,7 +57,7 @@ describe('terminal scrollback', function()
end)
end)
- describe('with the cursor at the last row', function()
+ describe('with cursor at last row', function()
before_each(function()
feed_data({'line1', 'line2', 'line3', 'line4', ''})
screen:expect([[
@@ -139,16 +138,18 @@ describe('terminal scrollback', function()
end)
- describe('and the height is decreased by 1', function()
+ describe('and height decreased by 1', function()
+ if helpers.pending_win32(pending) then return end
local function will_hide_top_line()
- screen:try_resize(screen._width, screen._height - 1)
+ feed([[<C-\><C-N>:]]) -- Go to cmdline-mode, so cursor is at bottom.
+ screen:try_resize(screen._width - 2, screen._height - 1)
screen:expect([[
- line2 |
- line3 |
- line4 |
- rows: 5, cols: 30 |
- {1: } |
- {3:-- TERMINAL --} |
+ line2 |
+ line3 |
+ line4 |
+ rows: 5, cols: 28 |
+ {2: } |
+ :^ |
]])
end
@@ -157,23 +158,23 @@ describe('terminal scrollback', function()
describe('and then decreased by 2', function()
before_each(function()
will_hide_top_line()
- screen:try_resize(screen._width, screen._height - 2)
+ screen:try_resize(screen._width - 2, screen._height - 2)
end)
it('will hide the top 3 lines', function()
screen:expect([[
- rows: 5, cols: 30 |
- rows: 3, cols: 30 |
- {1: } |
- {3:-- TERMINAL --} |
+ rows: 5, cols: 28 |
+ rows: 3, cols: 26 |
+ {2: } |
+ :^ |
]])
eq(8, curbuf('line_count'))
- feed('<c-\\><c-n>3k')
+ feed([[<C-\><C-N>3k]])
screen:expect([[
- ^line4 |
- rows: 5, cols: 30 |
- rows: 3, cols: 30 |
- |
+ ^line4 |
+ rows: 5, cols: 28 |
+ rows: 3, cols: 26 |
+ |
]])
end)
end)
@@ -181,6 +182,11 @@ describe('terminal scrollback', function()
end)
describe('with empty lines after the cursor', function()
+ -- XXX: Can't test this reliably on Windows unless the cursor is _moved_
+ -- by the resize. http://docs.libuv.org/en/v1.x/signal.html
+ -- See also: https://github.com/rprichard/winpty/issues/110
+ if helpers.pending_win32(pending) then return end
+
describe('and the height is decreased by 2', function()
before_each(function()
screen:try_resize(screen._width, screen._height - 2)
@@ -255,6 +261,10 @@ describe('terminal scrollback', function()
end)
describe('and the height is increased by 1', function()
+ -- XXX: Can't test this reliably on Windows unless the cursor is _moved_
+ -- by the resize. http://docs.libuv.org/en/v1.x/signal.html
+ -- See also: https://github.com/rprichard/winpty/issues/110
+ if helpers.pending_win32(pending) then return end
local function pop_then_push()
screen:try_resize(screen._width, screen._height + 1)
screen:expect([[
@@ -384,10 +394,20 @@ describe("'scrollback' option", function()
end
it('set to 0 behaves as 1', function()
- local screen = thelpers.screen_setup(nil, "['sh']", 30)
+ local screen
+ if iswin() then
+ screen = thelpers.screen_setup(nil,
+ "['powershell.exe', '-NoLogo', '-NoProfile', '-NoExit', '-Command', 'function global:prompt {return "..'"$"'.."}']", 30)
+ else
+ screen = thelpers.screen_setup(nil, "['sh']", 30)
+ end
curbufmeths.set_option('scrollback', 0)
- feed_data('for i in $(seq 1 30); do echo "line$i"; done\n')
+ if iswin() then
+ feed_data('for($i=1;$i -le 30;$i++){Write-Host \"line$i\"}\r')
+ else
+ feed_data('for i in $(seq 1 30); do echo "line$i"; done\n')
+ end
screen:expect('line30 ', nil, nil, nil, true)
retry(nil, nil, function() expect_lines(7) end)
@@ -395,7 +415,13 @@ describe("'scrollback' option", function()
end)
it('deletes lines (only) if necessary', function()
- local screen = thelpers.screen_setup(nil, "['sh']", 30)
+ local screen
+ if iswin() then
+ screen = thelpers.screen_setup(nil,
+ "['powershell.exe', '-NoLogo', '-NoProfile', '-NoExit', '-Command', 'function global:prompt {return "..'"$"'.."}']", 30)
+ else
+ screen = thelpers.screen_setup(nil, "['sh']", 30)
+ end
curbufmeths.set_option('scrollback', 200)
@@ -403,7 +429,11 @@ describe("'scrollback' option", function()
screen:expect('$', nil, nil, nil, true)
wait()
- feed_data('for i in $(seq 1 30); do echo "line$i"; done\n')
+ if iswin() then
+ feed_data('for($i=1;$i -le 30;$i++){Write-Host \"line$i\"}\r')
+ else
+ feed_data('for i in $(seq 1 30); do echo "line$i"; done\n')
+ end
screen:expect('line30 ', nil, nil, nil, true)
@@ -416,7 +446,11 @@ describe("'scrollback' option", function()
-- Terminal job data is received asynchronously, may happen before the
-- 'scrollback' option is synchronized with the internal sb_buffer.
command('sleep 100m')
- feed_data('for i in $(seq 1 40); do echo "line$i"; done\n')
+ if iswin() then
+ feed_data('for($i=1;$i -le 40;$i++){Write-Host \"line$i\"}\r')
+ else
+ feed_data('for i in $(seq 1 40); do echo "line$i"; done\n')
+ end
screen:expect('line40 ', nil, nil, nil, true)
diff --git a/test/functional/terminal/window_spec.lua b/test/functional/terminal/window_spec.lua
index 888b1e1328..0f705cfe40 100644
--- a/test/functional/terminal/window_spec.lua
+++ b/test/functional/terminal/window_spec.lua
@@ -3,8 +3,6 @@ local thelpers = require('test.functional.terminal.helpers')
local feed, clear = helpers.feed, helpers.clear
local wait = helpers.wait
-if helpers.pending_win32(pending) then return end
-
describe('terminal window', function()
local screen
diff --git a/test/functional/terminal/window_split_tab_spec.lua b/test/functional/terminal/window_split_tab_spec.lua
index 4867e0d9fa..c5199f620e 100644
--- a/test/functional/terminal/window_split_tab_spec.lua
+++ b/test/functional/terminal/window_split_tab_spec.lua
@@ -4,8 +4,6 @@ local clear = helpers.clear
local feed, nvim = helpers.feed, helpers.nvim
local feed_command = helpers.feed_command
-if helpers.pending_win32(pending) then return end
-
describe('terminal', function()
local screen
@@ -25,6 +23,7 @@ describe('terminal', function()
end)
it('resets its size when entering terminal window', function()
+ if helpers.pending_win32(pending) then return end
feed('<c-\\><c-n>')
feed_command('2split')
screen:expect([[
@@ -69,31 +68,25 @@ describe('terminal', function()
describe('when the screen is resized', function()
it('will forward a resize request to the program', function()
- screen:try_resize(screen._width + 3, screen._height + 5)
+ feed([[<C-\><C-N>:]]) -- Go to cmdline-mode, so cursor is at bottom.
+ screen:try_resize(screen._width - 3, screen._height - 2)
screen:expect([[
- tty ready |
- rows: 14, cols: 53 |
- {1: } |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- {3:-- TERMINAL --} |
+ tty ready |
+ rows: 7, cols: 47 |
+ {2: } |
+ |
+ |
+ |
+ |
+ :^ |
]])
- screen:try_resize(screen._width - 6, screen._height - 10)
+ screen:try_resize(screen._width - 6, screen._height - 3)
screen:expect([[
- tty ready |
- rows: 14, cols: 53 |
- rows: 4, cols: 47 |
- {1: } |
- {3:-- TERMINAL --} |
+ tty ready |
+ rows: 7, cols: 47 |
+ rows: 4, cols: 41 |
+ {2: } |
+ :^ |
]])
end)
end)
diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua
new file mode 100644
index 0000000000..d87ce72599
--- /dev/null
+++ b/test/functional/ui/cmdline_highlight_spec.lua
@@ -0,0 +1,893 @@
+local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
+
+local eq = helpers.eq
+local feed = helpers.feed
+local clear = helpers.clear
+local meths = helpers.meths
+local funcs = helpers.funcs
+local source = helpers.source
+local dedent = helpers.dedent
+local command = helpers.command
+local curbufmeths = helpers.curbufmeths
+
+local screen
+
+-- Bug in input() handling: :redraw! will erase the whole prompt up until
+-- user types something. It exists in Vim as well, so using `h<BS>` as
+-- a workaround.
+local function redraw_input()
+ feed('{REDRAW}h<BS>')
+end
+
+before_each(function()
+ clear()
+ screen = Screen.new(40, 8)
+ screen:attach()
+ source([[
+ highlight RBP1 guibg=Red
+ highlight RBP2 guibg=Yellow
+ highlight RBP3 guibg=Green
+ highlight RBP4 guibg=Blue
+ let g:NUM_LVLS = 4
+ function Redraw()
+ redraw!
+ return ''
+ endfunction
+ let g:id = ''
+ cnoremap <expr> {REDRAW} Redraw()
+ function DoPrompt(do_return) abort
+ let id = g:id
+ let Cb = g:Nvim_color_input{g:id}
+ let out = input({'prompt': ':', 'highlight': Cb})
+ let g:out{id} = out
+ return (a:do_return ? out : '')
+ endfunction
+ nnoremap <expr> {PROMPT} DoPrompt(0)
+ cnoremap <expr> {PROMPT} DoPrompt(1)
+ function RainBowParens(cmdline)
+ let ret = []
+ let i = 0
+ let lvl = 0
+ while i < len(a:cmdline)
+ if a:cmdline[i] is# '('
+ call add(ret, [i, i + 1, 'RBP' . ((lvl % g:NUM_LVLS) + 1)])
+ let lvl += 1
+ elseif a:cmdline[i] is# ')'
+ let lvl -= 1
+ call add(ret, [i, i + 1, 'RBP' . ((lvl % g:NUM_LVLS) + 1)])
+ endif
+ let i += 1
+ endwhile
+ return ret
+ endfunction
+ function SplittedMultibyteStart(cmdline)
+ let ret = []
+ let i = 0
+ while i < len(a:cmdline)
+ let char = nr2char(char2nr(a:cmdline[i:]))
+ if a:cmdline[i:i + len(char) - 1] is# char
+ if len(char) > 1
+ call add(ret, [i + 1, i + len(char), 'RBP2'])
+ endif
+ let i += len(char)
+ else
+ let i += 1
+ endif
+ endwhile
+ return ret
+ endfunction
+ function SplittedMultibyteEnd(cmdline)
+ let ret = []
+ let i = 0
+ while i < len(a:cmdline)
+ let char = nr2char(char2nr(a:cmdline[i:]))
+ if a:cmdline[i:i + len(char) - 1] is# char
+ if len(char) > 1
+ call add(ret, [i, i + 1, 'RBP1'])
+ endif
+ let i += len(char)
+ else
+ let i += 1
+ endif
+ endwhile
+ return ret
+ endfunction
+ function Echoing(cmdline)
+ echo 'HERE'
+ return v:_null_list
+ endfunction
+ function Echoning(cmdline)
+ echon 'HERE'
+ return v:_null_list
+ endfunction
+ function Echomsging(cmdline)
+ echomsg 'HERE'
+ return v:_null_list
+ endfunction
+ function Echoerring(cmdline)
+ echoerr 'HERE'
+ return v:_null_list
+ endfunction
+ function Redrawing(cmdline)
+ redraw!
+ return v:_null_list
+ endfunction
+ function Throwing(cmdline)
+ throw "ABC"
+ return v:_null_list
+ endfunction
+ function Halting(cmdline)
+ while 1
+ endwhile
+ endfunction
+ function ReturningGlobal(cmdline)
+ return g:callback_return
+ endfunction
+ function ReturningGlobal2(cmdline)
+ return g:callback_return[:len(a:cmdline)-1]
+ endfunction
+ function ReturningGlobalN(n, cmdline)
+ return g:callback_return{a:n}
+ endfunction
+ let g:recording_calls = []
+ function Recording(cmdline)
+ call add(g:recording_calls, a:cmdline)
+ return []
+ endfunction
+ ]])
+ screen:set_default_attr_ids({
+ RBP1={background = Screen.colors.Red},
+ RBP2={background = Screen.colors.Yellow},
+ RBP3={background = Screen.colors.Green},
+ RBP4={background = Screen.colors.Blue},
+ EOB={bold = true, foreground = Screen.colors.Blue1},
+ ERR={foreground = Screen.colors.Grey100, background = Screen.colors.Red},
+ SK={foreground = Screen.colors.Blue},
+ PE={bold = true, foreground = Screen.colors.SeaGreen4}
+ })
+end)
+
+local function set_color_cb(funcname, callback_return, id)
+ meths.set_var('id', id or '')
+ if id and id ~= '' and funcs.exists('*' .. funcname .. 'N') then
+ command(('let g:Nvim_color_input%s = {cmdline -> %sN(%s, cmdline)}'):format(
+ id, funcname, id))
+ if callback_return then
+ meths.set_var('callback_return' .. id, callback_return)
+ end
+ else
+ meths.set_var('Nvim_color_input', funcname)
+ if callback_return then
+ meths.set_var('callback_return', callback_return)
+ end
+ end
+end
+local function start_prompt(text)
+ feed('{PROMPT}' .. (text or ''))
+end
+
+describe('Command-line coloring', function()
+ it('works', function()
+ set_color_cb('RainBowParens')
+ meths.set_option('more', false)
+ start_prompt()
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :^ |
+ ]])
+ feed('e')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :e^ |
+ ]])
+ feed('cho ')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :echo ^ |
+ ]])
+ feed('(')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :echo {RBP1:(}^ |
+ ]])
+ feed('(')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :echo {RBP1:(}{RBP2:(}^ |
+ ]])
+ feed('42')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :echo {RBP1:(}{RBP2:(}42^ |
+ ]])
+ feed('))')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :echo {RBP1:(}{RBP2:(}42{RBP2:)}{RBP1:)}^ |
+ ]])
+ feed('<BS>')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :echo {RBP1:(}{RBP2:(}42{RBP2:)}^ |
+ ]])
+ redraw_input()
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :echo {RBP1:(}{RBP2:(}42{RBP2:)}^ |
+ ]])
+ end)
+ for _, func_part in ipairs({'', 'n', 'msg'}) do
+ it('disables :echo' .. func_part .. ' messages', function()
+ set_color_cb('Echo' .. func_part .. 'ing')
+ start_prompt('echo')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :echo^ |
+ ]])
+ end)
+ end
+ it('does the right thing when hl start appears to split multibyte char',
+ function()
+ set_color_cb('SplittedMultibyteStart')
+ start_prompt('echo "«')
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :echo " |
+ {ERR:E5405: Chunk 0 start 7 splits multibyte }|
+ {ERR:character} |
+ :echo "«^ |
+ ]])
+ feed('»')
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :echo " |
+ {ERR:E5405: Chunk 0 start 7 splits multibyte }|
+ {ERR:character} |
+ :echo "«»^ |
+ ]])
+ end)
+ it('does the right thing when hl end appears to split multibyte char',
+ function()
+ set_color_cb('SplittedMultibyteEnd')
+ start_prompt('echo "«')
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :echo " |
+ {ERR:E5406: Chunk 0 end 7 splits multibyte ch}|
+ {ERR:aracter} |
+ :echo "«^ |
+ ]])
+ end)
+ it('does the right thing when errorring', function()
+ set_color_cb('Echoerring')
+ start_prompt('e')
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ : |
+ {ERR:E5407: Callback has thrown an exception:}|
+ {ERR: Vim(echoerr):HERE} |
+ :e^ |
+ ]])
+ end)
+ it('silences :echo', function()
+ set_color_cb('Echoing')
+ start_prompt('e')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :e^ |
+ ]])
+ eq('', meths.command_output('messages'))
+ end)
+ it('silences :echon', function()
+ set_color_cb('Echoning')
+ start_prompt('e')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :e^ |
+ ]])
+ eq('', meths.command_output('messages'))
+ end)
+ it('silences :echomsg', function()
+ set_color_cb('Echomsging')
+ start_prompt('e')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :e^ |
+ ]])
+ eq('', meths.command_output('messages'))
+ end)
+ it('does the right thing when throwing', function()
+ set_color_cb('Throwing')
+ start_prompt('e')
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ : |
+ {ERR:E5407: Callback has thrown an exception:}|
+ {ERR: ABC} |
+ :e^ |
+ ]])
+ end)
+ it('stops executing callback after a number of errors', function()
+ set_color_cb('SplittedMultibyteStart')
+ start_prompt('let x = "«»«»«»«»«»"\n')
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :let x = " |
+ {ERR:E5405: Chunk 0 start 10 splits multibyte}|
+ {ERR: character} |
+ ^:let x = "«»«»«»«»«»" |
+ ]])
+ feed('\n')
+ screen:expect([[
+ ^ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ |
+ ]])
+ eq('let x = "«»«»«»«»«»"', meths.get_var('out'))
+ local msg = '\nE5405: Chunk 0 start 10 splits multibyte character'
+ eq(msg:rep(1), funcs.execute('messages'))
+ end)
+ it('allows interrupting callback with <C-c>', function()
+ set_color_cb('Halting')
+ start_prompt('echo 42')
+ screen:expect([[
+ ^ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ |
+ ]])
+ screen:sleep(500)
+ feed('<C-c>')
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ : |
+ {ERR:E5407: Callback has thrown an exception:}|
+ {ERR: Keyboard interrupt} |
+ :echo 42^ |
+ ]])
+ redraw_input()
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :echo 42^ |
+ ]])
+ feed('\n')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ ^:echo 42 |
+ ]])
+ feed('\n')
+ eq('echo 42', meths.get_var('out'))
+ feed('<C-c>')
+ screen:expect([[
+ ^ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ Type :quit<Enter> to exit Nvim |
+ ]])
+ end)
+ it('works fine with NUL, NL, CR', function()
+ set_color_cb('RainBowParens')
+ start_prompt('echo ("<C-v><CR><C-v><Nul><C-v><NL>")')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :echo {RBP1:(}"{SK:^M^@^@}"{RBP1:)}^ |
+ ]])
+ end)
+ it('errors out when callback returns something wrong', function()
+ command('cnoremap + ++')
+ set_color_cb('ReturningGlobal', '')
+ start_prompt('#')
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ : |
+ {ERR:E5400: Callback should return list} |
+ :#^ |
+ ]])
+
+ feed('<CR><CR><CR>')
+ set_color_cb('ReturningGlobal', {{0, 1, 'Normal'}, 42})
+ start_prompt('#')
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ : |
+ {ERR:E5401: List item 1 is not a List} |
+ :#^ |
+ ]])
+
+ feed('<CR><CR><CR>')
+ set_color_cb('ReturningGlobal2', {{0, 1, 'Normal'}, {1}})
+ start_prompt('+')
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :+ |
+ {ERR:E5402: List item 1 has incorrect length:}|
+ {ERR: 1 /= 3} |
+ :++^ |
+ ]])
+
+ feed('<CR><CR><CR>')
+ set_color_cb('ReturningGlobal2', {{0, 1, 'Normal'}, {2, 3, 'Normal'}})
+ start_prompt('+')
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :+ |
+ {ERR:E5403: Chunk 1 start 2 not in range [1, }|
+ {ERR:2)} |
+ :++^ |
+ ]])
+
+ feed('<CR><CR><CR>')
+ set_color_cb('ReturningGlobal2', {{0, 1, 'Normal'}, {1, 3, 'Normal'}})
+ start_prompt('+')
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :+ |
+ {ERR:E5404: Chunk 1 end 3 not in range (1, 2]}|
+ |
+ :++^ |
+ ]])
+ end)
+ it('does not error out when called from a errorred out cycle', function()
+ set_color_cb('ReturningGlobal', {{0, 1, 'Normal'}})
+ feed(dedent([[
+ :set regexpengine=2
+ :for pat in [' \ze*', ' \zs*']
+ : try
+ : let l = matchlist('x x', pat)
+ : $put =input({'prompt':'>','highlight':'ReturningGlobal'})
+ :
+ : $put ='E888 NOT detected for ' . pat
+ : catch
+ : $put =input({'prompt':'>','highlight':'ReturningGlobal'})
+ :
+ : $put ='E888 detected for ' . pat
+ : endtry
+ :endfor
+ :
+ :
+ :
+ :
+ :
+ :
+ ]]))
+ eq({'', ':', 'E888 detected for \\ze*', ':', 'E888 detected for \\zs*'},
+ curbufmeths.get_lines(0, -1, false))
+ eq('', funcs.execute('messages'))
+ end)
+ it('allows nesting input()s', function()
+ set_color_cb('ReturningGlobal', {{0, 1, 'RBP1'}}, '')
+ start_prompt('1')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :{RBP1:1}^ |
+ ]])
+
+ set_color_cb('ReturningGlobal', {{0, 1, 'RBP2'}}, '1')
+ start_prompt('2')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :{RBP2:2}^ |
+ ]])
+
+ set_color_cb('ReturningGlobal', {{0, 1, 'RBP3'}}, '2')
+ start_prompt('3')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :{RBP3:3}^ |
+ ]])
+
+ set_color_cb('ReturningGlobal', {{0, 1, 'RBP4'}}, '3')
+ start_prompt('4')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :{RBP4:4}^ |
+ ]])
+
+ feed('<CR>')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :{RBP3:3}4^ |
+ ]])
+ feed('<CR>')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :{RBP2:2}34^ |
+ ]])
+ feed('<CR>')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :{RBP1:1}234^ |
+ ]])
+ feed('<CR><CR><C-l>')
+ screen:expect([[
+ ^ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ |
+ ]])
+ eq('1234', meths.get_var('out'))
+ eq('234', meths.get_var('out1'))
+ eq('34', meths.get_var('out2'))
+ eq('4', meths.get_var('out3'))
+ eq(0, funcs.exists('g:out4'))
+ end)
+ it('runs callback with the same data only once', function()
+ local function new_recording_calls(...)
+ eq({...}, meths.get_var('recording_calls'))
+ meths.set_var('recording_calls', {})
+ end
+ set_color_cb('Recording')
+ start_prompt('')
+ -- Regression test. Disambiguation:
+ --
+ -- new_recording_calls(expected_result) -- (actual_before_fix)
+ --
+ feed('a')
+ new_recording_calls('a') -- ('a', 'a')
+ feed('b')
+ new_recording_calls('ab') -- ('a', 'ab', 'ab')
+ feed('c')
+ new_recording_calls('abc') -- ('ab', 'abc', 'abc')
+ feed('<BS>')
+ new_recording_calls('ab') -- ('abc', 'ab', 'ab')
+ feed('<BS>')
+ new_recording_calls('a') -- ('ab', 'a', 'a')
+ feed('<BS>')
+ new_recording_calls() -- ('a')
+ feed('<CR><CR>')
+ eq('', meths.get_var('out'))
+ end)
+end)
+describe('Ex commands coloring support', function()
+ it('works', function()
+ meths.set_var('Nvim_color_cmdline', 'RainBowParens')
+ feed(':echo (((1)))')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :echo {RBP1:(}{RBP2:(}{RBP3:(}1{RBP3:)}{RBP2:)}{RBP1:)}^ |
+ ]])
+ end)
+ it('still executes command-line even if errored out', function()
+ meths.set_var('Nvim_color_cmdline', 'SplittedMultibyteStart')
+ feed(':let x = "«"\n')
+ eq('«', meths.get_var('x'))
+ local msg = 'E5405: Chunk 0 start 10 splits multibyte character'
+ eq('\n'..msg, funcs.execute('messages'))
+ end)
+ it('does not error out when called from a errorred out cycle', function()
+ -- Apparently when there is a cycle in which one of the commands errors out
+ -- this error may be caught by color_cmdline before it is presented to the
+ -- user.
+ feed(dedent([[
+ :set regexpengine=2
+ :for pat in [' \ze*', ' \zs*']
+ : try
+ : let l = matchlist('x x', pat)
+ : $put ='E888 NOT detected for ' . pat
+ : catch
+ : $put ='E888 detected for ' . pat
+ : endtry
+ :endfor
+ ]]))
+ eq({'', 'E888 detected for \\ze*', 'E888 detected for \\zs*'},
+ curbufmeths.get_lines(0, -1, false))
+ eq('', funcs.execute('messages'))
+ end)
+ it('does not crash when using `n` in debug mode', function()
+ feed(':debug execute "echo 1"\n')
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ Entering Debug mode. Type "cont" to con|
+ tinue. |
+ cmd: execute "echo 1" |
+ >^ |
+ ]])
+ feed('n\n')
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ Entering Debug mode. Type "cont" to con|
+ tinue. |
+ cmd: execute "echo 1" |
+ >n |
+ 1 |
+ {PE:Press ENTER or type command to continue}^ |
+ ]])
+ feed('\n')
+ screen:expect([[
+ ^ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ |
+ ]])
+ end)
+ it('does not prevent mapping error from cancelling prompt', function()
+ command("cnoremap <expr> x execute('throw 42')[-1]")
+ feed(':#x')
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ :# |
+ {ERR:Error detected while processing :} |
+ {ERR:E605: Exception not caught: 42} |
+ :#^ |
+ ]])
+ feed('<CR>')
+ screen:expect([[
+ ^ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ |
+ ]])
+ feed('<CR>')
+ screen:expect([[
+ ^ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ |
+ ]])
+ eq('\nError detected while processing :\nE605: Exception not caught: 42',
+ meths.command_output('messages'))
+ end)
+ it('errors out when failing to get callback', function()
+ meths.set_var('Nvim_color_cmdline', 42)
+ feed(':#')
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ : |
+ {ERR:E5408: Unable to get g:Nvim_color_cmdlin}|
+ {ERR:e callback: Vim:E6000: Argument is not a}|
+ {ERR: function or function name} |
+ :#^ |
+ ]])
+ end)
+end)
+describe('Expressions coloring support', function()
+ it('works', function()
+ meths.set_var('Nvim_color_expr', 'RainBowParens')
+ feed(':echo <C-r>=(((1)))')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ ={RBP1:(}{RBP2:(}{RBP3:(}1{RBP3:)}{RBP2:)}{RBP1:)}^ |
+ ]])
+ end)
+ it('errors out when failing to get callback', function()
+ meths.set_var('Nvim_color_expr', 42)
+ feed(':<C-r>=1')
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ = |
+ {ERR:E5409: Unable to get g:Nvim_color_expr c}|
+ {ERR:allback: Vim:E6000: Argument is not a fu}|
+ {ERR:nction or function name} |
+ =1^ |
+ ]])
+ end)
+end)
diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua
index 5408e1e195..a6b7fb2997 100644
--- a/test/functional/ui/screen.lua
+++ b/test/functional/ui/screen.lua
@@ -251,7 +251,7 @@ function Screen:expect(expected, attr_ids, attr_ignore, condition, any)
..'Expected:\n |'..table.concat(msg_expected_rows, '|\n |')..'|\n'
..'Actual:\n |'..table.concat(actual_rows, '|\n |')..'|\n\n'..[[
To print the expect() call that would assert the current screen state, use
-screen:snaphot_util(). In case of non-deterministic failures, use
+screen:snapshot_util(). In case of non-deterministic failures, use
screen:redraw_debug() to show all intermediate screen states. ]])
end
end