mirror of
https://github.com/neovim/neovim.git
synced 2026-08-14 11:29:31 +00:00
Problem: Traditionally, the ruler in the last line is one cell shorter than in the statusline, leaving the last cell of the screen blank. According to code comments, this is in order to prevent unwanted scrolling on "some" (unspecified, but presumably ancient) terminals. Berkeley vi is more specific in its `vs_modeline` function: dumb terminals with hardware scroll, SunOS 4.1.1 and Ultrix 4.2 curses. (n)curses still has a similar limitation in `(w)addstr`, but apparently only for historical reasons. Maintaining the different widths leads to awkward inconsistencies when the ruler is configured with 'rulerformat', except for the special case where it contains a top-level `%=`. Shifting the ruler in the last line to the left would be a solution, but the empty cell at the end doesn't seem to be relevant anymore. Solution: extend the ruler in the last line all the way to the right edge of the screen, just like in the statusline. The exact same amount of place will be available to the rest of the UI as before. BREAKING CHANGE: - the default ruler width is now 18 cells - the last cell of the screen is no longer empty Closes #41076
717 lines
28 KiB
Lua
717 lines
28 KiB
Lua
local n = require('test.functional.testnvim')()
|
|
local t = require('test.testutil')
|
|
local Screen = require('test.functional.ui.screen')
|
|
|
|
local describe, it, before_each = t.describe, t.it, t.before_each
|
|
local clear = n.clear
|
|
local command = n.command
|
|
local feed = n.feed
|
|
local feed_command = n.feed_command
|
|
local exec = n.exec
|
|
local api = n.api
|
|
|
|
describe('cmdline', function()
|
|
before_each(clear)
|
|
|
|
-- oldtest: Test_cmdlineclear_tabenter()
|
|
it('is cleared when switching tabs', function()
|
|
local screen = Screen.new(30, 10)
|
|
|
|
feed_command([[call setline(1, range(30))]])
|
|
screen:expect([[
|
|
^0 |
|
|
1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
:call setline(1, range(30)) |
|
|
]])
|
|
|
|
feed [[:tabnew<cr>]]
|
|
screen:expect {
|
|
grid = [[
|
|
{24: + [No Name] }{5: [No Name] }{2: }{24:X}|
|
|
^ |
|
|
{1:~ }|*7
|
|
:tabnew |
|
|
]],
|
|
}
|
|
|
|
feed [[<C-w>-<C-w>-]]
|
|
screen:expect {
|
|
grid = [[
|
|
{24: + [No Name] }{5: [No Name] }{2: }{24:X}|
|
|
^ |
|
|
{1:~ }|*5
|
|
|*3
|
|
]],
|
|
}
|
|
|
|
feed [[gt]]
|
|
screen:expect {
|
|
grid = [[
|
|
{5: + [No Name] }{24: [No Name] }{2: }{24:X}|
|
|
^0 |
|
|
1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
|
|
|
]],
|
|
}
|
|
|
|
feed [[gt]]
|
|
screen:expect([[
|
|
{24: + [No Name] }{5: [No Name] }{2: }{24:X}|
|
|
^ |
|
|
{1:~ }|*5
|
|
|*3
|
|
]])
|
|
end)
|
|
|
|
-- oldtest: Test_verbose_option()
|
|
it('prints every executed Ex command if verbose >= 16', function()
|
|
local screen = Screen.new(60, 12)
|
|
exec([[
|
|
command DoSomething echo 'hello' |set ts=4 |let v = '123' |echo v
|
|
call feedkeys("\r", 't') " for the hit-enter prompt
|
|
set verbose=20
|
|
]])
|
|
feed_command('DoSomething')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*2
|
|
{3: }|
|
|
Executing: DoSomething |
|
|
Executing: echo 'hello' |set ts=4 |let v = '123' |echo v |
|
|
hello |
|
|
Executing: set ts=4 |let v = '123' |echo v |
|
|
Executing: let v = '123' |echo v |
|
|
Executing: echo v |
|
|
123 |
|
|
{6:Press ENTER or type command to continue}^ |
|
|
]])
|
|
end)
|
|
|
|
-- oldtest: Test_cmdline_redraw_tabline()
|
|
it('tabline is redrawn on entering cmdline', function()
|
|
local screen = Screen.new(30, 6)
|
|
exec([[
|
|
set showtabline=2
|
|
autocmd CmdlineEnter * set tabline=foo
|
|
]])
|
|
feed(':')
|
|
screen:expect([[
|
|
{2:foo }|
|
|
|
|
|
{1:~ }|*3
|
|
:^ |
|
|
]])
|
|
end)
|
|
|
|
-- oldtest: Test_wildmenu_with_input_func()
|
|
it('wildmenu works with input() function', function()
|
|
local screen = Screen.new(60, 8)
|
|
screen:add_extra_attr_ids({
|
|
[100] = { background = Screen.colors.Yellow, foreground = Screen.colors.Black },
|
|
})
|
|
|
|
feed(":call input('Command? ', '', 'command')<CR>")
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*6
|
|
Command? ^ |
|
|
]])
|
|
feed('ech<Tab>')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*5
|
|
{100:echo}{3: echoerr echohl echomsg echon }|
|
|
Command? echo^ |
|
|
]])
|
|
feed('<Space>')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*6
|
|
Command? echo ^ |
|
|
]])
|
|
feed('bufn<Tab>')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*5
|
|
{100:bufname(}{3: bufnr( }|
|
|
Command? echo bufname(^ |
|
|
]])
|
|
feed('<CR>')
|
|
|
|
command('set wildoptions+=pum')
|
|
|
|
feed(":call input('Command? ', '', 'command')<CR>")
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*6
|
|
Command? ^ |
|
|
]])
|
|
feed('ech<Tab>')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|
|
|
{1:~ }{12: echo }{1: }|
|
|
{1:~ }{4: echoerr }{1: }|
|
|
{1:~ }{4: echohl }{1: }|
|
|
{1:~ }{4: echomsg }{1: }|
|
|
{1:~ }{4: echon }{1: }|
|
|
Command? echo^ |
|
|
]])
|
|
feed('<Space>')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*6
|
|
Command? echo ^ |
|
|
]])
|
|
feed('bufn<Tab>')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*4
|
|
{1:~ }{12: bufname( }{1: }|
|
|
{1:~ }{4: bufnr( }{1: }|
|
|
Command? echo bufname(^ |
|
|
]])
|
|
feed('<CR>')
|
|
end)
|
|
|
|
-- oldtest: Test_redraw_in_autocmd()
|
|
it('cmdline cursor position is correct after :redraw with cmdheight=2', function()
|
|
local screen = Screen.new(30, 6)
|
|
exec([[
|
|
set cmdheight=2
|
|
autocmd CmdlineChanged * redraw
|
|
]])
|
|
feed(':for i in range(3)<CR>')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*3
|
|
:for i in range(3) |
|
|
: ^ |
|
|
]])
|
|
feed(':let i =')
|
|
-- Note: this may still be considered broken, ref #18140
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*3
|
|
: :let i =^ |
|
|
|
|
|
]])
|
|
end)
|
|
|
|
-- oldtest: Test_changing_cmdheight()
|
|
it("changing 'cmdheight'", function()
|
|
local screen = Screen.new(60, 8)
|
|
exec([[
|
|
set cmdheight=1 laststatus=2
|
|
func EchoOne()
|
|
set laststatus=2 cmdheight=1
|
|
echo 'foo'
|
|
echo 'bar'
|
|
set cmdheight=2
|
|
endfunc
|
|
func EchoTwo()
|
|
set laststatus=2
|
|
set cmdheight=5
|
|
echo 'foo'
|
|
echo 'bar'
|
|
set cmdheight=1
|
|
endfunc
|
|
]])
|
|
|
|
feed(':resize -3<CR>')
|
|
screen:expect([[
|
|
^ |
|
|
{1:~ }|*2
|
|
{3:[No Name] }|
|
|
|*4
|
|
]])
|
|
|
|
-- :resize now also changes 'cmdheight' accordingly
|
|
feed(':set cmdheight+=1<CR>')
|
|
screen:expect([[
|
|
^ |
|
|
{1:~ }|
|
|
{3:[No Name] }|
|
|
|*5
|
|
]])
|
|
|
|
-- using more space moves the status line up
|
|
feed(':set cmdheight+=1<CR>')
|
|
screen:expect([[
|
|
^ |
|
|
{3:[No Name] }|
|
|
|*6
|
|
]])
|
|
|
|
-- reducing cmdheight moves status line down
|
|
feed(':set cmdheight-=3<CR>')
|
|
screen:expect([[
|
|
^ |
|
|
{1:~ }|*3
|
|
{3:[No Name] }|
|
|
|*3
|
|
]])
|
|
|
|
-- reducing window size and then setting cmdheight
|
|
feed(':resize -1<CR>')
|
|
feed(':set cmdheight=1<CR>')
|
|
screen:expect([[
|
|
^ |
|
|
{1:~ }|*5
|
|
{3:[No Name] }|
|
|
|
|
|
]])
|
|
|
|
-- setting 'cmdheight' works after outputting two messages
|
|
feed(':call EchoTwo()')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*5
|
|
{3:[No Name] }|
|
|
:call EchoTwo()^ |
|
|
]])
|
|
feed('<CR>')
|
|
screen:expect([[
|
|
^ |
|
|
{1:~ }|*5
|
|
{3:[No Name] }|
|
|
|
|
|
]])
|
|
|
|
-- increasing 'cmdheight' doesn't clear the messages that need hit-enter
|
|
feed(':call EchoOne()<CR>')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*3
|
|
{3: }|
|
|
foo |
|
|
bar |
|
|
{6:Press ENTER or type command to continue}^ |
|
|
]])
|
|
|
|
-- window commands do not reduce 'cmdheight' to value lower than :set by user
|
|
feed('<CR>:wincmd _<CR>')
|
|
screen:expect([[
|
|
^ |
|
|
{1:~ }|*4
|
|
{3:[No Name] }|
|
|
:wincmd _ |
|
|
|
|
|
]])
|
|
end)
|
|
|
|
-- oldtest: Test_cmdheight_tabline()
|
|
it("changing 'cmdheight' when there is a tabline", function()
|
|
local screen = Screen.new(60, 8)
|
|
api.nvim_set_option_value('laststatus', 2, {})
|
|
api.nvim_set_option_value('showtabline', 2, {})
|
|
api.nvim_set_option_value('cmdheight', 1, {})
|
|
screen:expect([[
|
|
{5: [No Name] }{2: }|
|
|
^ |
|
|
{1:~ }|*4
|
|
{3:[No Name] }|
|
|
|
|
|
]])
|
|
end)
|
|
|
|
-- oldtest: Test_wildmenu_with_pum_foldexpr()
|
|
it('pum when using &foldtext', function()
|
|
local screen = Screen.new(60, 10)
|
|
exec([[
|
|
call setline(1, ['folded one', 'folded two', 'some more text'])
|
|
func MyFoldText()
|
|
return 'foo'
|
|
endfunc
|
|
set foldtext=MyFoldText() wildoptions=pum
|
|
normal ggzfj
|
|
]])
|
|
feed(':set<Tab>')
|
|
screen:expect([[
|
|
{13:foo·························································}|
|
|
some more text |
|
|
{1:~ }|*3
|
|
{12: set }{1: }|
|
|
{4: setfiletype }{1: }|
|
|
{4: setglobal }{1: }|
|
|
{4: setlocal }{1: }|
|
|
:set^ |
|
|
]])
|
|
feed('<Esc>')
|
|
screen:expect([[
|
|
{13:^foo·························································}|
|
|
some more text |
|
|
{1:~ }|*7
|
|
|
|
|
]])
|
|
end)
|
|
|
|
-- oldtest: Test_rulerformat_position()
|
|
it("ruler has correct position with 'rulerformat' set", function()
|
|
local screen = Screen.new(20, 3)
|
|
api.nvim_set_option_value('ruler', true, {})
|
|
api.nvim_set_option_value('rulerformat', 'longish', {})
|
|
api.nvim_set_option_value('laststatus', 0, {})
|
|
api.nvim_set_option_value('winwidth', 1, {})
|
|
feed [[<C-W>v<C-W>|<C-W>p]]
|
|
screen:expect [[
|
|
│^ |
|
|
{1:~ }│{1:~}|
|
|
longish |
|
|
]]
|
|
end)
|
|
|
|
-- oldtest: Test_rulerformat_function()
|
|
it("'rulerformat' can use %!", function()
|
|
local screen = Screen.new(40, 2)
|
|
exec([[
|
|
func TestRulerFn()
|
|
return '10,20%=30%%'
|
|
endfunc
|
|
]])
|
|
api.nvim_set_option_value('ruler', true, {})
|
|
api.nvim_set_option_value('rulerformat', '%!TestRulerFn()', {})
|
|
screen:expect([[
|
|
^ |
|
|
10,20 30%|
|
|
]])
|
|
end)
|
|
|
|
-- oldtest: Test_search_wildmenu_screendump()
|
|
it('wildmenu for search completion', function()
|
|
local screen = Screen.new(60, 10)
|
|
screen:add_extra_attr_ids({
|
|
[100] = { background = Screen.colors.Yellow, foreground = Screen.colors.Black },
|
|
})
|
|
exec([[
|
|
set wildmenu wildcharm=<f5> wildoptions-=pum
|
|
call setline(1, ['the', 'these', 'the', 'foobar', 'thethe', 'thethere'])
|
|
]])
|
|
|
|
-- Pattern has newline at EOF
|
|
feed('gg2j/e\\n<f5>')
|
|
screen:expect([[
|
|
the |
|
|
these |
|
|
the |
|
|
foobar |
|
|
thethe |
|
|
thethere |
|
|
{1:~ }|*2
|
|
{100:e\nfoobar}{3: e\nthethere e\nthese e\nthe }|
|
|
/e\nfoobar^ |
|
|
]])
|
|
|
|
-- longest:full
|
|
feed('<esc>')
|
|
command('set wim=longest,full')
|
|
feed('gg/t<f5>')
|
|
screen:expect([[
|
|
the |
|
|
these |
|
|
the |
|
|
foobar |
|
|
thethe |
|
|
thethere |
|
|
{1:~ }|*3
|
|
/the^ |
|
|
]])
|
|
|
|
-- list:full
|
|
feed('<esc>')
|
|
command('set wim=list,full')
|
|
feed('gg/t<f5>')
|
|
screen:expect([[
|
|
{10:t}he |
|
|
{10:t}hese |
|
|
{10:t}he |
|
|
foobar |
|
|
{10:t}he{10:t}he |
|
|
{10:t}he{10:t}here |
|
|
{3: }|
|
|
/t |
|
|
these the thethe thethere there |
|
|
/t^ |
|
|
]])
|
|
|
|
-- noselect:full
|
|
feed('<esc>')
|
|
command('set wim=noselect,full')
|
|
feed('gg/t<f5>')
|
|
screen:expect([[
|
|
the |
|
|
these |
|
|
the |
|
|
foobar |
|
|
thethe |
|
|
thethere |
|
|
{1:~ }|*2
|
|
{3:these the thethe thethere there }|
|
|
/t^ |
|
|
]])
|
|
|
|
-- Multiline
|
|
feed('<esc>gg/t.*\\n.*\\n.<tab>')
|
|
screen:expect([[
|
|
the |
|
|
these |
|
|
the |
|
|
foobar |
|
|
thethe |
|
|
thethere |
|
|
{1:~ }|*2
|
|
{3:t.*\n.*\n.oobar t.*\n.*\n.hethe t.*\n.*\n.he }|
|
|
/t.*\n.*\n.^ |
|
|
]])
|
|
|
|
-- 'incsearch' is redrawn after accepting completion
|
|
feed('<esc>')
|
|
command('set wim=full')
|
|
command('set incsearch hlsearch')
|
|
feed('/th')
|
|
screen:expect([[
|
|
{10:th}e |
|
|
{2:th}ese |
|
|
{10:th}e |
|
|
foobar |
|
|
{10:th}e{10:th}e |
|
|
{10:th}e{10:th}ere |
|
|
{1:~ }|*3
|
|
/th^ |
|
|
]])
|
|
feed('<f5>')
|
|
screen:expect([[
|
|
{10:th}e |
|
|
{2:th}ese |
|
|
{10:th}e |
|
|
foobar |
|
|
{10:th}e{10:th}e |
|
|
{10:th}e{10:th}ere |
|
|
{1:~ }|*2
|
|
{100:these}{3: the thethe thethere there }|
|
|
/these^ |
|
|
]])
|
|
feed('<c-n><c-y>')
|
|
screen:expect([[
|
|
{10:the} |
|
|
{2:the}se |
|
|
{10:the} |
|
|
foobar |
|
|
{10:thethe} |
|
|
{10:thethe}re |
|
|
{1:~ }|*3
|
|
/the^ |
|
|
]])
|
|
|
|
-- 'incsearch' highlight is restored after dismissing popup (Ctrl_E)
|
|
feed('<esc>')
|
|
command('set wop=pum is nohls')
|
|
feed('gg/th<tab><c-e>')
|
|
screen:expect([[
|
|
the |
|
|
{2:th}ese |
|
|
the |
|
|
foobar |
|
|
thethe |
|
|
thethere |
|
|
{1:~ }|*3
|
|
/th^ |
|
|
]])
|
|
|
|
feed('<esc>')
|
|
end)
|
|
|
|
-- oldtest: Test_search_wildmenu_iminsert()
|
|
it('search wildmenu pum with iminsert=1', function()
|
|
local screen = Screen.new(65, 12)
|
|
exec([[
|
|
set wop=pum imi=1
|
|
setlocal iskeyword=!-~,192-255
|
|
call setline(1, [
|
|
\ "global toggle global-local global/local glyphs toggles English",
|
|
\ "accordingly. toggled accordingly single-byte",
|
|
\ ])
|
|
call cursor(2, 42)
|
|
]])
|
|
feed('/gl<Tab>')
|
|
screen:expect([[
|
|
{12: global }obal-local global/local glyphs toggles English |
|
|
{4: gle }gled accordingly single-byte |
|
|
{4: global-local }{1: }|
|
|
{4: global/local }{1: }|
|
|
{4: glyphs }{1: }|
|
|
{4: gles }{1: }|
|
|
{4: glish }{1: }|
|
|
{4: gly. }{1: }|
|
|
{4: gled }{1: }|
|
|
{4: gly }{1: }|
|
|
{4: gle-byte }{1: }|
|
|
/global^ |
|
|
]])
|
|
end)
|
|
|
|
-- oldtest: Test_wildtrigger_update_screen()
|
|
it('pum by wildtrigger() avoids flicker', function()
|
|
local screen = Screen.new(40, 10)
|
|
exec([[
|
|
command! -nargs=* -complete=customlist,TestFn TestCmd echo
|
|
func TestFn(cmdarg, b, c)
|
|
if a:cmdarg == 'ax'
|
|
return []
|
|
else
|
|
return map(range(1, 5), 'printf("abc%d", v:val)')
|
|
endif
|
|
endfunc
|
|
set wildmode=noselect,full
|
|
set wildoptions=pum
|
|
set wildmenu
|
|
cnoremap <F8> <C-R>=wildtrigger()[-1]<CR>
|
|
]])
|
|
|
|
feed(':TestCmd a<F8>')
|
|
local s1 = [[
|
|
|
|
|
{1:~ }|*3
|
|
{1:~ }{4: abc1 }{1: }|
|
|
{1:~ }{4: abc2 }{1: }|
|
|
{1:~ }{4: abc3 }{1: }|
|
|
{1:~ }{4: abc4 }{1: }|
|
|
{1:~ }{4: abc5 }{1: }|
|
|
:TestCmd a^ |
|
|
]]
|
|
screen:expect(s1)
|
|
|
|
-- Typing a character when pum is open does not close the pum window
|
|
-- This is needed to prevent pum window from flickering during
|
|
-- ':h cmdline-autocompletion'.
|
|
feed('x')
|
|
local s2 = [[
|
|
|
|
|
{1:~ }|*3
|
|
{1:~ }{4: abc1 }{1: }|
|
|
{1:~ }{4: abc2 }{1: }|
|
|
{1:~ }{4: abc3 }{1: }|
|
|
{1:~ }{4: abc4 }{1: }|
|
|
{1:~ }{4: abc5 }{1: }|
|
|
:TestCmd ax^ |
|
|
]]
|
|
screen:expect(s2)
|
|
|
|
-- pum is closed when no completion candidates are available
|
|
feed('<F8>')
|
|
local s3 = [[
|
|
|
|
|
{1:~ }|*8
|
|
:TestCmd ax^ |
|
|
]]
|
|
screen:expect(s3)
|
|
|
|
feed('<BS><F8>')
|
|
screen:expect(s1)
|
|
|
|
feed('x')
|
|
screen:expect(s2)
|
|
|
|
-- pum is closed when leaving cmdline mode
|
|
feed('<Esc>')
|
|
screen:expect([[
|
|
^ |
|
|
{1:~ }|*8
|
|
|
|
|
]])
|
|
|
|
feed(':TestCmd a<F8>')
|
|
screen:expect(s1)
|
|
command('redraw')
|
|
screen:expect_unchanged()
|
|
feed('x')
|
|
screen:expect(s2)
|
|
-- outdated pum is closed by :redraw #36808
|
|
command('redraw')
|
|
screen:expect(s3)
|
|
end)
|
|
|
|
-- oldtest: Test_long_line_noselect()
|
|
it("long line is shown properly with noselect in 'wildmode'", function()
|
|
local screen = Screen.new(60, 8)
|
|
exec([[
|
|
set wildmenu wildoptions=pum wildmode=noselect,full
|
|
command -nargs=1 -complete=custom,Entries DoubleEntry echo
|
|
func Entries(a, b, c)
|
|
return 'loooooooooooooooong quite loooooooooooong, really loooooooooooong, probably too looooooooooooooooooooooooooong entry'
|
|
endfunc
|
|
]])
|
|
|
|
feed(':DoubleEntry <Tab>')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*5
|
|
{1:~ }{4: loooooooooooooooong quite loooooooooooong, rea>}|
|
|
:DoubleEntry ^ |
|
|
]])
|
|
|
|
feed('<C-N>')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*3
|
|
{3: }|
|
|
:DoubleEntry loooooooooooooooong quite loooooooooooong, real|
|
|
ly loooooooo{12: loooooooooooooooong quite loooooooooooong, rea>}|
|
|
ong entry^ |
|
|
]])
|
|
|
|
feed('<C-N>')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*3
|
|
{3: }{4: loooooooooooooooong quite loooooooooooong, rea>}|
|
|
:DoubleEntry ^ |
|
|
|*2
|
|
]])
|
|
|
|
feed('<Esc>')
|
|
end)
|
|
|
|
-- oldtest: Test_update_screen_after_wildtrigger()
|
|
it('pum is dismissed after wildtrigger() and whitespace', function()
|
|
local screen = Screen.new(40, 10)
|
|
exec([[
|
|
set wildmode=noselect:lastused,full wildmenu wildoptions=pum
|
|
autocmd CmdlineChanged : if getcmdcompltype() != 'shellcmd' | call wildtrigger() | endif
|
|
]])
|
|
|
|
feed(':term')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*7
|
|
{4: terminal }{1: }|
|
|
:term^ |
|
|
]])
|
|
feed(' ')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*8
|
|
:term ^ |
|
|
]])
|
|
feed('foo')
|
|
screen:expect([[
|
|
|
|
|
{1:~ }|*8
|
|
:term foo^ |
|
|
]])
|
|
end)
|
|
end)
|