aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/functional/api/vim_spec.lua23
-rw-r--r--test/functional/eval/backtick_expansion_spec.lua16
-rw-r--r--test/functional/eval/execute_spec.lua9
-rw-r--r--test/functional/ex_cmds/bang_filter_spec.lua51
-rw-r--r--test/functional/fixtures/shell-test.c23
-rw-r--r--test/functional/fixtures/shell_data.txtbin0 -> 50 bytes
-rw-r--r--test/functional/legacy/arglist_spec.lua11
-rw-r--r--test/functional/legacy/edit_spec.lua25
-rw-r--r--test/functional/legacy/search_spec.lua110
-rw-r--r--test/functional/plugin/man_spec.lua4
-rw-r--r--test/functional/terminal/ex_terminal_spec.lua50
-rw-r--r--test/functional/terminal/tui_spec.lua4
-rw-r--r--test/functional/ui/bufhl_spec.lua15
-rw-r--r--test/functional/ui/highlight_spec.lua1
-rw-r--r--test/functional/ui/mouse_spec.lua2
-rw-r--r--test/functional/ui/output_spec.lua179
-rw-r--r--test/functional/ui/screen.lua3
-rw-r--r--test/functional/ui/spell_spec.lua49
-rw-r--r--test/helpers.lua23
-rw-r--r--test/unit/viml/expressions/parser_tests.lua60
20 files changed, 517 insertions, 141 deletions
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index 39db831fe3..1faed4e9b1 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -11,6 +11,7 @@ local funcs = helpers.funcs
local request = helpers.request
local meth_pcall = helpers.meth_pcall
local command = helpers.command
+local iswin = helpers.iswin
local intchar2lua = global_helpers.intchar2lua
local format_string = global_helpers.format_string
@@ -99,8 +100,9 @@ describe('api', function()
[[echo nvim_command_output('echo "nested1\nnested2"') | ls]]))
end)
- it('does not return shell |:!| output', function()
- eq(':!echo "foo"\r\n', nvim('command_output', [[!echo "foo"]]))
+ it('returns shell |:!| output', function()
+ local win_lf = iswin() and '\r' or ''
+ eq(':!echo foo\r\n\nfoo'..win_lf..'\n', nvim('command_output', [[!echo foo]]))
end)
it("parse error: fails (specific error), does NOT update v:errmsg", function()
@@ -951,9 +953,20 @@ describe('api', function()
end
end)
if not err then
- msg = format_string('Error while processing test (%r, %s):\n%s',
- str, FLAGS_TO_STR[flags], msg)
- error(msg)
+ if type(msg) == 'table' then
+ local merr, new_msg = pcall(
+ format_string, 'table error:\n%s\n\n(%r)', msg.message, msg)
+ if merr then
+ msg = new_msg
+ else
+ msg = format_string('table error without .message:\n(%r)',
+ msg)
+ end
+ elseif type(msg) ~= 'string' then
+ msg = format_string('non-string non-table error:\n%r', msg)
+ end
+ error(format_string('Error while processing test (%r, %s):\n%s',
+ str, FLAGS_TO_STR[flags], msg))
end
end
end
diff --git a/test/functional/eval/backtick_expansion_spec.lua b/test/functional/eval/backtick_expansion_spec.lua
index 81e8e295fa..b1b44cfa8b 100644
--- a/test/functional/eval/backtick_expansion_spec.lua
+++ b/test/functional/eval/backtick_expansion_spec.lua
@@ -21,11 +21,19 @@ describe("backtick expansion", function()
end)
it("with default 'shell'", function()
- if helpers.pending_win32(pending) then return end -- Need win32 shell fixes
- command(":silent args `echo ***2`")
+ if helpers.iswin() then
+ command(":silent args `dir /b *2`")
+ else
+ command(":silent args `echo ***2`")
+ end
eq({ "file2", }, eval("argv()"))
- command(":silent args `echo */*4`")
- eq({ "subdir/file4", }, eval("argv()"))
+ if helpers.iswin() then
+ command(":silent args `dir /s/b *4`")
+ eq({ "subdir\\file4", }, eval("map(argv(), 'fnamemodify(v:val, \":.\")')"))
+ else
+ command(":silent args `echo */*4`")
+ eq({ "subdir/file4", }, eval("argv()"))
+ end
end)
it("with shell=fish", function()
diff --git a/test/functional/eval/execute_spec.lua b/test/functional/eval/execute_spec.lua
index 91966ed3dd..183884a51e 100644
--- a/test/functional/eval/execute_spec.lua
+++ b/test/functional/eval/execute_spec.lua
@@ -9,6 +9,7 @@ local funcs = helpers.funcs
local Screen = require('test.functional.ui.screen')
local command = helpers.command
local feed = helpers.feed
+local iswin = helpers.iswin
describe('execute()', function()
before_each(clear)
@@ -118,9 +119,11 @@ describe('execute()', function()
feed('<CR>')
end)
- -- This matches Vim behavior.
- it('does not capture shell-command output', function()
- eq('\n:!echo "foo"\13\n', funcs.execute('!echo "foo"'))
+ -- This deviates from vim behavior, but is consistent
+ -- with how nvim currently displays the output.
+ it('does capture shell-command output', function()
+ local win_lf = iswin() and '\13' or ''
+ eq('\n:!echo foo\r\n\nfoo'..win_lf..'\n', funcs.execute('!echo foo'))
end)
describe('{silent} argument', function()
diff --git a/test/functional/ex_cmds/bang_filter_spec.lua b/test/functional/ex_cmds/bang_filter_spec.lua
deleted file mode 100644
index aaec983b73..0000000000
--- a/test/functional/ex_cmds/bang_filter_spec.lua
+++ /dev/null
@@ -1,51 +0,0 @@
--- Specs for bang/filter commands
-
-local helpers = require('test.functional.helpers')(after_each)
-local feed, command, clear = helpers.feed, helpers.command, helpers.clear
-local mkdir, write_file, rmdir = helpers.mkdir, helpers.write_file, helpers.rmdir
-
-if helpers.pending_win32(pending) then return end
-
-local Screen = require('test.functional.ui.screen')
-
-
-describe('issues', function()
- local screen
-
- before_each(function()
- clear()
- rmdir('bang_filter_spec')
- mkdir('bang_filter_spec')
- write_file('bang_filter_spec/f1', 'f1')
- write_file('bang_filter_spec/f2', 'f2')
- write_file('bang_filter_spec/f3', 'f3')
- screen = Screen.new()
- screen:attach()
- end)
-
- after_each(function()
- rmdir('bang_filter_spec')
- end)
-
- it('#3269 Last line of shell output is not truncated', function()
- command([[nnoremap <silent>\l :!ls bang_filter_spec<cr>]])
- feed([[\l]])
- screen:expect([[
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- :!ls bang_filter_spec |
- |
- f1 |
- f2 |
- f3 |
- Press ENTER or type command to continue^ |
- ]])
- end)
-
-end)
diff --git a/test/functional/fixtures/shell-test.c b/test/functional/fixtures/shell-test.c
index 8dbec2aaee..38695ce76b 100644
--- a/test/functional/fixtures/shell-test.c
+++ b/test/functional/fixtures/shell-test.c
@@ -4,6 +4,13 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h>
+#include <unistd.h>
+
+static void wait(void)
+{
+ fflush(stdout);
+ usleep(10*1000);
+}
static void help(void)
{
@@ -61,6 +68,22 @@ int main(int argc, char **argv)
for (uint8_t i = 0; i < number; i++) {
printf("%d: %s\n", (int) i, argv[3]);
}
+ } else if (strcmp(argv[1], "UTF-8") == 0) {
+ // test split-up UTF-8 sequence
+ printf("\xc3"); wait();
+ printf("\xa5\n"); wait();
+
+ // split up a 2+2 grapheme clusters all possible ways
+ printf("ref: \xc3\xa5\xcc\xb2\n"); wait();
+
+ printf("1: \xc3"); wait();
+ printf("\xa5\xcc\xb2\n"); wait();
+
+ printf("2: \xc3\xa5"); wait();
+ printf("\xcc\xb2\n"); wait();
+
+ printf("3: \xc3\xa5\xcc"); wait();
+ printf("\xb2\n"); wait();
} else {
fprintf(stderr, "Unknown first argument\n");
return 3;
diff --git a/test/functional/fixtures/shell_data.txt b/test/functional/fixtures/shell_data.txt
new file mode 100644
index 0000000000..ef3506c5b1
--- /dev/null
+++ b/test/functional/fixtures/shell_data.txt
Binary files differ
diff --git a/test/functional/legacy/arglist_spec.lua b/test/functional/legacy/arglist_spec.lua
index 191f145095..ec754a533b 100644
--- a/test/functional/legacy/arglist_spec.lua
+++ b/test/functional/legacy/arglist_spec.lua
@@ -222,20 +222,19 @@ describe('argument list commands', function()
eq({'a', 'b'}, eval('argv()'))
eq('b', eval('expand("%:t")'))
command('argedit a')
- eq({'a', 'b'}, eval('argv()'))
+ eq({'a', 'b', 'a'}, eval('argv()'))
eq('a', eval('expand("%:t")'))
command('argedit c')
- eq({'a', 'c', 'b'}, eval('argv()'))
+ eq({'a', 'b', 'a', 'c'}, eval('argv()'))
command('0argedit x')
- eq({'x', 'a', 'c', 'b'}, eval('argv()'))
+ eq({'x', 'a', 'b', 'a', 'c'}, eval('argv()'))
command('enew! | set modified')
assert_fails('argedit y', 'E37:')
command('argedit! y')
- eq({'x', 'y', 'a', 'c', 'b'}, eval('argv()'))
+ eq({'x', 'y', 'y', 'a', 'b', 'a', 'c'}, eval('argv()'))
command('%argd')
- -- Nvim allows unescaped spaces in filename on all platforms. #6010
command('argedit a b')
- eq({'a b'}, eval('argv()'))
+ eq({'a', 'b'}, eval('argv()'))
end)
it('test for :argdelete command', function()
diff --git a/test/functional/legacy/edit_spec.lua b/test/functional/legacy/edit_spec.lua
new file mode 100644
index 0000000000..91d602924c
--- /dev/null
+++ b/test/functional/legacy/edit_spec.lua
@@ -0,0 +1,25 @@
+-- Test for edit functions
+-- See also: src/nvim/testdir/test_edit.vim
+
+local helpers = require('test.functional.helpers')(after_each)
+local source = helpers.source
+local eq, eval = helpers.eq, helpers.eval
+local funcs = helpers.funcs
+local clear = helpers.clear
+
+describe('edit', function()
+ before_each(clear)
+
+ it('reset insertmode from i_ctrl-r_=', function()
+ source([=[
+ call setline(1, ['abc'])
+ call cursor(1, 4)
+ call feedkeys(":set im\<cr>ZZZ\<c-r>=setbufvar(1,'&im', 0)\<cr>",'tnix')
+ ]=])
+ eq({'abZZZc'}, funcs.getline(1,'$'))
+ eq({0, 1, 1, 0}, funcs.getpos('.'))
+ eq(0, eval('&im'))
+ end)
+
+end)
+
diff --git a/test/functional/legacy/search_spec.lua b/test/functional/legacy/search_spec.lua
index 5f71861821..277d8d6c7f 100644
--- a/test/functional/legacy/search_spec.lua
+++ b/test/functional/legacy/search_spec.lua
@@ -6,6 +6,7 @@ local eq = helpers.eq
local eval = helpers.eval
local feed = helpers.feed
local funcs = helpers.funcs
+local wait = helpers.wait
describe('search cmdline', function()
local screen
@@ -471,4 +472,113 @@ describe('search cmdline', function()
coladd = 0, skipcol = 0, curswant = 0},
funcs.winsaveview())
end)
+
+ it("CTRL-G with 'incsearch' and ? goes in the right direction", function()
+ -- oldtest: Test_search_cmdline4().
+ screen:detach()
+ screen = Screen.new(40, 4)
+ screen:attach()
+ screen:set_default_attr_ids({
+ inc = {reverse = true},
+ err = { foreground = Screen.colors.Grey100, background = Screen.colors.Red },
+ more = { bold = true, foreground = Screen.colors.SeaGreen4 },
+ tilde = { bold = true, foreground = Screen.colors.Blue1 },
+ })
+ command('enew!')
+ funcs.setline(1, {' 1 the first', ' 2 the second', ' 3 the third'})
+ command('set laststatus=0 shortmess+=s')
+ command('set incsearch')
+ command('$')
+ -- Send the input in chunks, so the cmdline logic regards it as
+ -- "interactive". This mimics Vim's test_override("char_avail").
+ -- (See legacy test: test_search.vim)
+ feed('?the')
+ wait()
+ feed('<c-g>')
+ wait()
+ feed('<cr>')
+ screen:expect([[
+ 1 the first |
+ 2 the second |
+ 3 ^the third |
+ ?the |
+ ]])
+
+ command('$')
+ feed('?the')
+ wait()
+ feed('<c-g>')
+ wait()
+ feed('<c-g>')
+ wait()
+ feed('<cr>')
+ screen:expect([[
+ 1 ^the first |
+ 2 the second |
+ 3 the third |
+ ?the |
+ ]])
+
+ command('$')
+ feed('?the')
+ wait()
+ feed('<c-g>')
+ wait()
+ feed('<c-g>')
+ wait()
+ feed('<c-g>')
+ wait()
+ feed('<cr>')
+ screen:expect([[
+ 1 the first |
+ 2 ^the second |
+ 3 the third |
+ ?the |
+ ]])
+
+ command('$')
+ feed('?the')
+ wait()
+ feed('<c-t>')
+ wait()
+ feed('<cr>')
+ screen:expect([[
+ 1 ^the first |
+ 2 the second |
+ 3 the third |
+ ?the |
+ ]])
+
+ command('$')
+ feed('?the')
+ wait()
+ feed('<c-t>')
+ wait()
+ feed('<c-t>')
+ wait()
+ feed('<cr>')
+ screen:expect([[
+ 1 the first |
+ 2 the second |
+ 3 ^the third |
+ ?the |
+ ]])
+
+ command('$')
+ feed('?the')
+ wait()
+ feed('<c-t>')
+ wait()
+ feed('<c-t>')
+ wait()
+ feed('<c-t>')
+ wait()
+ feed('<cr>')
+ screen:expect([[
+ 1 the first |
+ 2 ^the second |
+ 3 the third |
+ ?the |
+ ]])
+ end)
end)
diff --git a/test/functional/plugin/man_spec.lua b/test/functional/plugin/man_spec.lua
index dc189b8f8e..e5da7932a5 100644
--- a/test/functional/plugin/man_spec.lua
+++ b/test/functional/plugin/man_spec.lua
@@ -66,13 +66,13 @@ describe(':Man', function()
ithis <C-v><ESC>[1mis <C-v><ESC>[3ma <C-v><ESC>[4mtest<C-v><ESC>[0m
<C-v><ESC>[4mwith<C-v><ESC>[24m <C-v><ESC>[4mescaped<C-v><ESC>[24m <C-v><ESC>[4mtext<C-v><ESC>[24m<ESC>]])
- screen:expect([[
+ screen:expect([=[
this ^[[1mis ^[[3ma ^[[4mtest^[[0m |
^[[4mwith^[[24m ^[[4mescaped^[[24m ^[[4mtext^[[24^m |
~ |
~ |
|
- ]])
+ ]=])
eval('man#init_pager()')
diff --git a/test/functional/terminal/ex_terminal_spec.lua b/test/functional/terminal/ex_terminal_spec.lua
index ee92ba6865..0a30b9bb02 100644
--- a/test/functional/terminal/ex_terminal_spec.lua
+++ b/test/functional/terminal/ex_terminal_spec.lua
@@ -2,8 +2,11 @@ local helpers = require('test.functional.helpers')(after_each)
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 = helpers.feed
local feed_command, eval = helpers.feed_command, helpers.eval
+local funcs = helpers.funcs
local retry = helpers.retry
+local ok = helpers.ok
local iswin = helpers.iswin
describe(':terminal', function()
@@ -24,13 +27,16 @@ describe(':terminal', function()
]])
-- Invoke a command that emits frequent terminal activity.
if iswin() then
- feed_command([[terminal for /L \\%I in (1,0,2) do echo \\%I]])
+ feed_command([[terminal for /L \%I in (1,0,2) do echo \%I]])
else
feed_command([[terminal while true; do echo X; done]])
end
- helpers.feed([[<C-\><C-N>]])
+ feed([[<C-\><C-N>]])
wait()
- screen:sleep(10) -- Let some terminal activity happen.
+ -- Wait for some terminal activity.
+ retry(nil, 4000, function()
+ ok(funcs.line('$') > 6)
+ end)
feed_command("messages")
screen:expect([[
msg1 |
@@ -46,7 +52,7 @@ describe(':terminal', function()
else
feed_command([[terminal while true; do echo foo; sleep .1; done]])
end
- helpers.feed([[<C-\><C-N>M]]) -- move cursor away from last line
+ feed([[<C-\><C-N>M]]) -- move cursor away from last line
wait()
eq(3, eval("line('$')")) -- window height
eq(2, eval("line('.')")) -- cursor is in the middle
@@ -56,6 +62,32 @@ describe(':terminal', function()
eq(2, eval("line('.')")) -- cursor stays where we put it
end)
+ it('Enter/Leave does not increment jumplist #3723', function()
+ feed_command('terminal')
+ local function enter_and_leave()
+ local lines_before = funcs.line('$')
+ -- Create a new line (in the shell). For a normal buffer this
+ -- increments the jumplist; for a terminal-buffer it should not. #3723
+ feed('i')
+ wait()
+ feed('<CR><CR><CR><CR>')
+ wait()
+ feed([[<C-\><C-N>]])
+ wait()
+ -- Wait for >=1 lines to be created.
+ retry(nil, 4000, function()
+ ok(funcs.line('$') > lines_before)
+ end)
+ end
+ enter_and_leave()
+ enter_and_leave()
+ enter_and_leave()
+ ok(funcs.line('$') > 6) -- Verify assumption.
+ local jumps = funcs.split(funcs.execute('jumps'), '\n')
+ eq(' jump line col file/text', jumps[1])
+ eq(3, #jumps)
+ end)
+
end)
describe(':terminal (with fake shell)', function()
@@ -151,12 +183,12 @@ describe(':terminal (with fake shell)', function()
it('ignores writes if the backing stream closes', function()
terminal_with_fake_shell()
- helpers.feed('iiXXXXXXX')
+ feed('iiXXXXXXX')
wait()
-- Race: Though the shell exited (and streams were closed by SIGCHLD
-- handler), :terminal cleanup is pending on the main-loop.
-- This write should be ignored (not crash, #5445).
- helpers.feed('iiYYYYYYY')
+ feed('iiYYYYYYY')
eq(2, eval("1+1")) -- Still alive?
end)
@@ -175,7 +207,7 @@ describe(':terminal (with fake shell)', function()
:terminal |
]])
eq('term://', string.match(eval('bufname("%")'), "^term://"))
- helpers.feed([[<C-\><C-N>]])
+ feed([[<C-\><C-N>]])
feed_command([[find */shadacat.py]])
if iswin() then
eq('scripts\\shadacat.py', eval('bufname("%")'))
@@ -192,9 +224,9 @@ describe(':terminal (with fake shell)', function()
[Process exited 0] |
:terminal echo "scripts/shadacat.py" |
]])
- helpers.feed([[<C-\><C-N>]])
+ feed([[<C-\><C-N>]])
eq('term://', string.match(eval('bufname("%")'), "^term://"))
- helpers.feed([[ggf"lgf]])
+ feed([[ggf"lgf]])
eq('scripts/shadacat.py', eval('bufname("%")'))
end)
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index a62c03b70f..171745eb57 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -242,7 +242,7 @@ describe('tui', function()
{9:~ }|
{9:~ }|
{3:[No Name] [+] }|
- |
+ :set termguicolors |
{4:-- TERMINAL --} |
]])
@@ -253,7 +253,7 @@ describe('tui', function()
{2:~ }|
{2:~ }|
{3:[No Name] [+] }|
- |
+ :set notermguicolors |
{4:-- TERMINAL --} |
]])
end)
diff --git a/test/functional/ui/bufhl_spec.lua b/test/functional/ui/bufhl_spec.lua
index 091c45596d..5b38921e50 100644
--- a/test/functional/ui/bufhl_spec.lua
+++ b/test/functional/ui/bufhl_spec.lua
@@ -2,11 +2,11 @@ local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
-local command, request, neq = helpers.command, helpers.request, helpers.neq
+local command, neq = helpers.command, helpers.neq
+local curbufmeths = helpers.curbufmeths
describe('Buffer highlighting', function()
local screen
- local curbuf
before_each(function()
clear()
@@ -25,21 +25,14 @@ describe('Buffer highlighting', function()
[9] = {foreground = Screen.colors.SlateBlue, underline = true},
[10] = {foreground = Screen.colors.Red}
})
- curbuf = request('nvim_get_current_buf')
end)
after_each(function()
screen:detach()
end)
- local function add_hl(...)
- return request('nvim_buf_add_highlight', curbuf, ...)
- end
-
- local function clear_hl(...)
- return request('nvim_buf_clear_highlight', curbuf, ...)
- end
-
+ local add_hl = curbufmeths.add_highlight
+ local clear_hl = curbufmeths.clear_highlight
it('works', function()
insert([[
diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua
index 2252e3580f..95fb2ce21c 100644
--- a/test/functional/ui/highlight_spec.lua
+++ b/test/functional/ui/highlight_spec.lua
@@ -905,6 +905,7 @@ describe("'winhighlight' highlight", function()
end)
it('background applies also to non-text', function()
+ command('set sidescroll=0')
insert('Lorem ipsum dolor sit amet ')
command('set shiftwidth=2')
feed('>>')
diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua
index 13820af3b8..e5708d51ef 100644
--- a/test/functional/ui/mouse_spec.lua
+++ b/test/functional/ui/mouse_spec.lua
@@ -3,6 +3,7 @@ local Screen = require('test.functional.ui.screen')
local clear, feed, meths = helpers.clear, helpers.feed, helpers.meths
local insert, feed_command = helpers.insert, helpers.feed_command
local eq, funcs = helpers.eq, helpers.funcs
+local command = helpers.command
describe('ui/mouse/input', function()
local screen
@@ -706,6 +707,7 @@ describe('ui/mouse/input', function()
end)
it('horizontal scrolling', function()
+ command('set sidescroll=0')
feed("<esc>:set nowrap<cr>")
feed("a <esc>20Ab<esc>")
diff --git a/test/functional/ui/output_spec.lua b/test/functional/ui/output_spec.lua
index c6d564e8dc..4246020fab 100644
--- a/test/functional/ui/output_spec.lua
+++ b/test/functional/ui/output_spec.lua
@@ -1,14 +1,24 @@
-local session = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
+local helpers = require('test.functional.helpers')(after_each)
local child_session = require('test.functional.terminal.helpers')
-
-if session.pending_win32(pending) then return end
+local mkdir, write_file, rmdir = helpers.mkdir, helpers.write_file, helpers.rmdir
+local eq = helpers.eq
+local eval = helpers.eval
+local feed = helpers.feed
+local feed_command = helpers.feed_command
+local iswin = helpers.iswin
+local clear = helpers.clear
+local command = helpers.command
+local nvim_dir = helpers.nvim_dir
describe("shell command :!", function()
+ if helpers.pending_win32(pending) then return end
+
local screen
before_each(function()
- session.clear()
- screen = child_session.screen_setup(0, '["'..session.nvim_prog..
- '", "-u", "NONE", "-i", "NONE", "--cmd", "'..session.nvim_set..'"]')
+ clear()
+ screen = child_session.screen_setup(0, '["'..helpers.nvim_prog..
+ '", "-u", "NONE", "-i", "NONE", "--cmd", "'..helpers.nvim_set..'"]')
screen:expect([[
{1: } |
{4:~ }|
@@ -33,15 +43,15 @@ describe("shell command :!", function()
{4:~ }|
{4:~ }|
{4:~ }|
+ {4:~ }|
:!printf foo; sleep 200 |
- |
foo |
{3:-- TERMINAL --} |
]])
end)
it("throttles shell-command output greater than ~10KB", function()
- if os.getenv("TRAVIS") and session.os_name() == "osx" then
+ if os.getenv("TRAVIS") and helpers.os_name() == "osx" then
pending("[Unreliable on Travis macOS.]", function() end)
return
end
@@ -56,13 +66,164 @@ describe("shell command :!", function()
-- Final chunk of output should always be displayed, never skipped.
-- (Throttling is non-deterministic, this test is merely a sanity check.)
screen:expect([[
- XXXXXXXXXX 2996 |
XXXXXXXXXX 2997 |
XXXXXXXXXX 2998 |
XXXXXXXXXX 2999 |
XXXXXXXXXX 3000 |
+ |
{10:Press ENTER or type command to continue}{1: } |
{3:-- TERMINAL --} |
]])
end)
end)
+
+describe("shell command :!", function()
+ before_each(function()
+ clear()
+ end)
+
+ it("cat a binary file #4142", function()
+ feed(":exe 'silent !cat '.shellescape(v:progpath)<CR>")
+ eq(2, eval('1+1')) -- Still alive?
+ end)
+
+ it([[display \x08 char #4142]], function()
+ feed(":silent !echo \08<CR>")
+ eq(2, eval('1+1')) -- Still alive?
+ end)
+
+ it([[handles control codes]], function()
+ if iswin() then
+ pending('missing printf', function() end)
+ return
+ end
+ local screen = Screen.new(50, 4)
+ screen:attach()
+ -- Print TAB chars. #2958
+ feed([[:!printf '1\t2\t3'<CR>]])
+ screen:expect([[
+ ~ |
+ :!printf '1\t2\t3' |
+ 1 2 3 |
+ Press ENTER or type command to continue^ |
+ ]])
+ feed([[<CR>]])
+ -- Print BELL control code. #4338
+ screen.bell = false
+ feed([[:!printf '\x07\x07\x07\x07text'<CR>]])
+ screen:expect([[
+ ~ |
+ :!printf '\x07\x07\x07\x07text' |
+ text |
+ Press ENTER or type command to continue^ |
+ ]], nil, nil, function()
+ eq(true, screen.bell)
+ end)
+ feed([[<CR>]])
+ -- Print BS control code.
+ feed([[:echo system('printf ''\x08\n''')<CR>]])
+ screen:expect([[
+ ~ |
+ ^H |
+ |
+ Press ENTER or type command to continue^ |
+ ]])
+ feed([[<CR>]])
+ -- Print LF control code.
+ feed([[:!printf '\n'<CR>]])
+ screen:expect([[
+ :!printf '\n' |
+ |
+ |
+ Press ENTER or type command to continue^ |
+ ]])
+ feed([[<CR>]])
+ end)
+
+ describe('', function()
+ local screen
+ before_each(function()
+ rmdir('bang_filter_spec')
+ mkdir('bang_filter_spec')
+ write_file('bang_filter_spec/f1', 'f1')
+ write_file('bang_filter_spec/f2', 'f2')
+ write_file('bang_filter_spec/f3', 'f3')
+ screen = Screen.new(53,10)
+ screen:set_default_attr_ids({
+ [1] = {bold = true, foreground = Screen.colors.Blue1},
+ [2] = {foreground = Screen.colors.Blue1},
+ [3] = {bold = true, foreground = Screen.colors.SeaGreen4},
+ })
+ screen:attach()
+ end)
+
+ after_each(function()
+ rmdir('bang_filter_spec')
+ end)
+
+ it("doesn't truncate Last line of shell output #3269", function()
+ command(helpers.iswin()
+ and [[nnoremap <silent>\l :!dir /b bang_filter_spec<cr>]]
+ or [[nnoremap <silent>\l :!ls bang_filter_spec<cr>]])
+ local result = (helpers.iswin()
+ and [[:!dir /b bang_filter_spec]]
+ or [[:!ls bang_filter_spec ]])
+ feed([[\l]])
+ screen:expect([[
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ ]]..result..[[ |
+ f1 |
+ f2 |
+ f3 |
+ |
+ {3:Press ENTER or type command to continue}^ |
+ ]])
+ end)
+
+ it('handles binary and multibyte data', function()
+ feed_command('!cat test/functional/fixtures/shell_data.txt')
+ screen.bell = false
+ screen:expect([[
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ :!cat test/functional/fixtures/shell_data.txt |
+ {2:^@^A^B^C^D^E^F^H} |
+ {2:^N^O^P^Q^R^S^T^U^V^W^X^Y^Z^[^\^]^^^_} |
+ ö 한글 {2:<a5><c3>} |
+ t {2:<ff>} |
+ |
+ {3:Press ENTER or type command to continue}^ |
+ ]], nil, nil, function()
+ eq(true, screen.bell)
+ end)
+ end)
+
+ it('handles multibyte sequences split over buffer boundaries', function()
+ command('cd '..nvim_dir)
+ local cmd
+ if iswin() then
+ cmd = '!shell-test UTF-8 '
+ else
+ cmd = '!./shell-test UTF-8'
+ end
+ feed_command(cmd)
+ -- Note: only the first example of split composed char works
+ screen:expect([[
+ {1:~ }|
+ {1:~ }|
+ :]]..cmd..[[ |
+ å |
+ ref: å̲ |
+ 1: å̲ |
+ 2: å ̲ |
+ 3: å ̲ |
+ |
+ {3:Press ENTER or type command to continue}^ |
+ ]])
+ end)
+ end)
+end)
diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua
index 696feabeed..52e108f389 100644
--- a/test/functional/ui/screen.lua
+++ b/test/functional/ui/screen.lua
@@ -455,6 +455,9 @@ function Screen:_handle_visual_bell()
self.visual_bell = true
end
+function Screen:_handle_default_colors_set()
+end
+
function Screen:_handle_update_fg(fg)
self._fg = fg
end
diff --git a/test/functional/ui/spell_spec.lua b/test/functional/ui/spell_spec.lua
new file mode 100644
index 0000000000..913f1b9bed
--- /dev/null
+++ b/test/functional/ui/spell_spec.lua
@@ -0,0 +1,49 @@
+-- Test for scenarios involving 'spell'
+
+local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
+local clear = helpers.clear
+local feed = helpers.feed
+local feed_command = helpers.feed_command
+local insert = helpers.insert
+
+describe("'spell'", function()
+ local screen
+
+ before_each(function()
+ clear()
+ screen = Screen.new(80, 8)
+ screen:attach()
+ screen:set_default_attr_ids( {
+ [0] = {bold=true, foreground=Screen.colors.Blue},
+ [1] = {special = Screen.colors.Red, undercurl = true}
+ })
+ end)
+
+ after_each(function()
+ screen:detach()
+ end)
+
+ it('joins long lines #7937', function()
+ feed_command('set spell')
+ insert([[
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+ quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+ consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
+ cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
+ non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+ ]])
+ feed('ggJJJJJJ0')
+ screen:expect([[
+ {1:^Lorem} {1:ipsum} dolor sit {1:amet}, {1:consectetur} {1:adipiscing} {1:elit}, {1:sed} do {1:eiusmod} {1:tempor} {1:i}|
+ {1:ncididunt} {1:ut} {1:labore} {1:et} {1:dolore} {1:magna} {1:aliqua}. {1:Ut} {1:enim} ad minim {1:veniam}, {1:quis} {1:nostru}|
+ {1:d} {1:exercitation} {1:ullamco} {1:laboris} {1:nisi} {1:ut} {1:aliquip} ex ea {1:commodo} {1:consequat}. {1:Duis} {1:aut}|
+ {1:e} {1:irure} dolor in {1:reprehenderit} in {1:voluptate} {1:velit} {1:esse} {1:cillum} {1:dolore} {1:eu} {1:fugiat} {1:n}|
+ {1:ulla} {1:pariatur}. {1:Excepteur} {1:sint} {1:occaecat} {1:cupidatat} non {1:proident}, {1:sunt} in culpa {1:qui}|
+ {1:officia} {1:deserunt} {1:mollit} {1:anim} id est {1:laborum}. |
+ {0:~ }|
+ |
+ ]])
+ end)
+end)
diff --git a/test/helpers.lua b/test/helpers.lua
index faf5c8e7f2..1c64f41b65 100644
--- a/test/helpers.lua
+++ b/test/helpers.lua
@@ -423,11 +423,13 @@ format_luav = function(v, indent, opts)
if opts.literal_strings then
ret = v
else
- ret = tostring(v):gsub('[\'\\]', '\\%0'):gsub(
- '[%z\1-\31]', function(match)
- return SUBTBL[match:byte() + 1]
- end)
- ret = '\'' .. ret .. '\''
+ local quote = opts.dquote_strings and '"' or '\''
+ ret = quote .. tostring(v):gsub(
+ opts.dquote_strings and '["\\]' or '[\'\\]',
+ '\\%0'):gsub(
+ '[%z\1-\31]', function(match)
+ return SUBTBL[match:byte() + 1]
+ end) .. quote
end
elseif type(v) == 'table' then
if v == REMOVE_THIS then
@@ -490,11 +492,14 @@ local function format_string(fmt, ...)
if subfmt:sub(-1) ~= '%' then
arg = getarg()
end
- if subfmt:sub(-1) == 'r' then
- -- %r is like %q, but it is supposed to single-quote strings and not
- -- double-quote them, and also work not only for strings.
+ if subfmt:sub(-1) == 'r' or subfmt:sub(-1) == 'q' then
+ -- %r is like built-in %q, but it is supposed to single-quote strings and
+ -- not double-quote them, and also work not only for strings.
+ -- Builtin %q is replaced here as it gives invalid and inconsistent with
+ -- luajit results for e.g. "\e" on lua: luajit transforms that into `\27`,
+ -- lua leaves as-is.
+ arg = format_luav(arg, nil, {dquote_strings = (subfmt:sub(-1) == 'q')})
subfmt = subfmt:sub(1, -2) .. 's'
- arg = format_luav(arg)
end
if subfmt == '%e' then
return format_float(arg)
diff --git a/test/unit/viml/expressions/parser_tests.lua b/test/unit/viml/expressions/parser_tests.lua
index e085d7e932..da61672bb1 100644
--- a/test/unit/viml/expressions/parser_tests.lua
+++ b/test/unit/viml/expressions/parser_tests.lua
@@ -5025,7 +5025,7 @@ return function(itp, _check_parsing, hl, fmtn)
-- 0123456789012345
-- 0 1
ast = {
- [[DoubleQuotedString(val="\8\27\12\13\9\\"):0:0:"\b\e\f\r\t\\"]],
+ [[DoubleQuotedString(val="\008\027\012\r\t\\"):0:0:"\b\e\f\r\t\\"]],
},
}, {
hl('DoubleQuote', '"'),
@@ -5040,7 +5040,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\n\n"', {
-- 01234
ast = {
- fmtn('DoubleQuotedString', 'val="\\\n\\\n"', ':0:0:"\\n\n"'),
+ fmtn('DoubleQuotedString', 'val="\\n\\n"', ':0:0:"\\n\n"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5051,7 +5051,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\x00"', {
-- 012345
ast = {
- fmtn('DoubleQuotedString', 'val="\\0"', ':0:0:"\\x00"'),
+ fmtn('DoubleQuotedString', 'val="\\000"', ':0:0:"\\x00"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5071,7 +5071,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\xF"', {
-- 012345
ast = {
- fmtn('DoubleQuotedString', 'val="\\15"', ':0:0:"\\xF"'),
+ fmtn('DoubleQuotedString', 'val="\\015"', ':0:0:"\\xF"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5126,7 +5126,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\xF', {
-- 0123
ast = {
- fmtn('DoubleQuotedString', 'val="\\15"', ':0:0:"\\xF'),
+ fmtn('DoubleQuotedString', 'val="\\015"', ':0:0:"\\xF'),
},
err = {
arg = '"\\xF',
@@ -5190,7 +5190,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\xFX"', {
-- 012345
ast = {
- fmtn('DoubleQuotedString', 'val="\\15X"', ':0:0:"\\xFX"'),
+ fmtn('DoubleQuotedString', 'val="\\015X"', ':0:0:"\\xFX"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5202,7 +5202,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\XFX"', {
-- 012345
ast = {
- fmtn('DoubleQuotedString', 'val="\\15X"', ':0:0:"\\XFX"'),
+ fmtn('DoubleQuotedString', 'val="\\015X"', ':0:0:"\\XFX"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5262,7 +5262,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\x0X"', {
-- 012345
ast = {
- fmtn('DoubleQuotedString', 'val="\\0X"', ':0:0:"\\x0X"'),
+ fmtn('DoubleQuotedString', 'val="\\000X"', ':0:0:"\\x0X"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5274,7 +5274,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\X0X"', {
-- 012345
ast = {
- fmtn('DoubleQuotedString', 'val="\\0X"', ':0:0:"\\X0X"'),
+ fmtn('DoubleQuotedString', 'val="\\000X"', ':0:0:"\\X0X"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5286,7 +5286,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\u0X"', {
-- 012345
ast = {
- fmtn('DoubleQuotedString', 'val="\\0X"', ':0:0:"\\u0X"'),
+ fmtn('DoubleQuotedString', 'val="\\000X"', ':0:0:"\\u0X"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5298,7 +5298,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\U0X"', {
-- 012345
ast = {
- fmtn('DoubleQuotedString', 'val="\\0X"', ':0:0:"\\U0X"'),
+ fmtn('DoubleQuotedString', 'val="\\000X"', ':0:0:"\\U0X"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5310,7 +5310,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\x00X"', {
-- 0123456
ast = {
- fmtn('DoubleQuotedString', 'val="\\0X"', ':0:0:"\\x00X"'),
+ fmtn('DoubleQuotedString', 'val="\\000X"', ':0:0:"\\x00X"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5322,7 +5322,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\X00X"', {
-- 0123456
ast = {
- fmtn('DoubleQuotedString', 'val="\\0X"', ':0:0:"\\X00X"'),
+ fmtn('DoubleQuotedString', 'val="\\000X"', ':0:0:"\\X00X"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5334,7 +5334,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\u00X"', {
-- 0123456
ast = {
- fmtn('DoubleQuotedString', 'val="\\0X"', ':0:0:"\\u00X"'),
+ fmtn('DoubleQuotedString', 'val="\\000X"', ':0:0:"\\u00X"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5346,7 +5346,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\U00X"', {
-- 0123456
ast = {
- fmtn('DoubleQuotedString', 'val="\\0X"', ':0:0:"\\U00X"'),
+ fmtn('DoubleQuotedString', 'val="\\000X"', ':0:0:"\\U00X"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5358,7 +5358,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\u000X"', {
-- 01234567
ast = {
- fmtn('DoubleQuotedString', 'val="\\0X"', ':0:0:"\\u000X"'),
+ fmtn('DoubleQuotedString', 'val="\\000X"', ':0:0:"\\u000X"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5370,7 +5370,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\U000X"', {
-- 01234567
ast = {
- fmtn('DoubleQuotedString', 'val="\\0X"', ':0:0:"\\U000X"'),
+ fmtn('DoubleQuotedString', 'val="\\000X"', ':0:0:"\\U000X"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5382,7 +5382,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\u0000X"', {
-- 012345678
ast = {
- fmtn('DoubleQuotedString', 'val="\\0X"', ':0:0:"\\u0000X"'),
+ fmtn('DoubleQuotedString', 'val="\\000X"', ':0:0:"\\u0000X"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5394,7 +5394,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\U0000X"', {
-- 012345678
ast = {
- fmtn('DoubleQuotedString', 'val="\\0X"', ':0:0:"\\U0000X"'),
+ fmtn('DoubleQuotedString', 'val="\\000X"', ':0:0:"\\U0000X"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5406,7 +5406,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\U00000X"', {
-- 0123456789
ast = {
- fmtn('DoubleQuotedString', 'val="\\0X"', ':0:0:"\\U00000X"'),
+ fmtn('DoubleQuotedString', 'val="\\000X"', ':0:0:"\\U00000X"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5419,7 +5419,7 @@ return function(itp, _check_parsing, hl, fmtn)
-- 01234567890
-- 0 1
ast = {
- fmtn('DoubleQuotedString', 'val="\\0X"', ':0:0:"\\U000000X"'),
+ fmtn('DoubleQuotedString', 'val="\\000X"', ':0:0:"\\U000000X"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5432,7 +5432,7 @@ return function(itp, _check_parsing, hl, fmtn)
-- 012345678901
-- 0 1
ast = {
- fmtn('DoubleQuotedString', 'val="\\0X"', ':0:0:"\\U0000000X"'),
+ fmtn('DoubleQuotedString', 'val="\\000X"', ':0:0:"\\U0000000X"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5445,7 +5445,7 @@ return function(itp, _check_parsing, hl, fmtn)
-- 0123456789012
-- 0 1
ast = {
- fmtn('DoubleQuotedString', 'val="\\0X"', ':0:0:"\\U00000000X"'),
+ fmtn('DoubleQuotedString', 'val="\\000X"', ':0:0:"\\U00000000X"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5506,7 +5506,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\0"', {
-- 0123
ast = {
- fmtn('DoubleQuotedString', 'val="\\0"', ':0:0:"\\0"'),
+ fmtn('DoubleQuotedString', 'val="\\000"', ':0:0:"\\0"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5517,7 +5517,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\00"', {
-- 01234
ast = {
- fmtn('DoubleQuotedString', 'val="\\0"', ':0:0:"\\00"'),
+ fmtn('DoubleQuotedString', 'val="\\000"', ':0:0:"\\00"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5528,7 +5528,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\000"', {
-- 012345
ast = {
- fmtn('DoubleQuotedString', 'val="\\0"', ':0:0:"\\000"'),
+ fmtn('DoubleQuotedString', 'val="\\000"', ':0:0:"\\000"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -5620,7 +5620,7 @@ return function(itp, _check_parsing, hl, fmtn)
check_parsing('"\\<C-u>"', {
-- 012345
ast = {
- fmtn('DoubleQuotedString', 'val="\\21"', ':0:0:"\\<C-u>"'),
+ fmtn('DoubleQuotedString', 'val="\\021"', ':0:0:"\\<C-u>"'),
},
}, {
hl('DoubleQuote', '"'),
@@ -7119,7 +7119,7 @@ return function(itp, _check_parsing, hl, fmtn)
'Or:0:0:|',
children = {
'Missing:0:0:',
- fmtn('DoubleQuotedString', 'val="\\27"', ':0:1:"\\e"'),
+ fmtn('DoubleQuotedString', 'val="\\027"', ':0:1:"\\e"'),
},
},
},
@@ -7180,9 +7180,9 @@ return function(itp, _check_parsing, hl, fmtn)
hl('InvalidDoubleQuotedUnknownEscape', '\\<'),
})
check_parsing('"\\1', {
- -- 012
+ -- 01 2
ast = {
- fmtn('DoubleQuotedString', 'val="\\1"', ':0:0:"\\1'),
+ fmtn('DoubleQuotedString', 'val="\\001"', ':0:0:"\\1'),
},
err = {
arg = '"\\1',