mirror of
https://github.com/neovim/neovim.git
synced 2024-12-24 21:25:04 -07:00
e61228a214
Before calling "attach" a screen object is just a dummy container for (row, col) values whose purpose is to be sent as part of the "attach" function call anyway. Just create the screen in an attached state directly. Keep the complete (row, col, options) config together. It is still completely valid to later detach and re-attach as needed, including to another session.
745 lines
28 KiB
Lua
745 lines
28 KiB
Lua
local t = require('test.testutil')
|
|
local n = require('test.functional.testnvim')()
|
|
local Screen = require('test.functional.ui.screen')
|
|
|
|
local clear = n.clear
|
|
local feed = n.feed
|
|
local eq = t.eq
|
|
local expect = n.expect
|
|
local eval = n.eval
|
|
local fn = n.fn
|
|
local insert = n.insert
|
|
local write_file = t.write_file
|
|
local exc_exec = n.exc_exec
|
|
local command = n.command
|
|
|
|
describe('mappings with <Cmd>', function()
|
|
local screen
|
|
local tmpfile = 'X_ex_cmds_cmd_map'
|
|
|
|
local function cmdmap(lhs, rhs)
|
|
command('noremap ' .. lhs .. ' <Cmd>' .. rhs .. '<cr>')
|
|
command('noremap! ' .. lhs .. ' <Cmd>' .. rhs .. '<cr>')
|
|
end
|
|
|
|
before_each(function()
|
|
clear()
|
|
screen = Screen.new(65, 8)
|
|
screen:set_default_attr_ids({
|
|
[1] = { bold = true, foreground = Screen.colors.Blue1 },
|
|
[2] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red },
|
|
[3] = { bold = true, foreground = Screen.colors.SeaGreen4 },
|
|
[4] = { bold = true },
|
|
[5] = { foreground = Screen.colors.Black, background = Screen.colors.LightGrey },
|
|
[6] = { foreground = Screen.colors.Blue1 },
|
|
[7] = { bold = true, reverse = true },
|
|
[8] = { background = Screen.colors.WebGray },
|
|
[9] = { background = Screen.colors.LightMagenta },
|
|
[10] = { foreground = Screen.colors.Red },
|
|
})
|
|
|
|
cmdmap('<F3>', 'let m = mode(1)')
|
|
cmdmap('<F4>', 'normal! ww')
|
|
cmdmap('<F5>', 'normal! "ay')
|
|
cmdmap('<F6>', 'throw "very error"')
|
|
command([[
|
|
function! TextObj()
|
|
if mode() !=# "v"
|
|
normal! v
|
|
end
|
|
call cursor(1,3)
|
|
normal! o
|
|
call cursor(2,4)
|
|
endfunction]])
|
|
cmdmap('<F7>', 'call TextObj()')
|
|
insert([[
|
|
some short lines
|
|
of test text]])
|
|
feed('gg')
|
|
cmdmap('<F8>', 'startinsert')
|
|
cmdmap('<F9>', 'stopinsert')
|
|
command('abbr foo <Cmd>let g:y = 17<cr>bar')
|
|
end)
|
|
|
|
after_each(function()
|
|
os.remove(tmpfile)
|
|
end)
|
|
|
|
it('can be displayed', function()
|
|
command('map <F3>')
|
|
screen:expect([[
|
|
^some short lines |
|
|
of test text |
|
|
{1:~ }|*5
|
|
{6:<F3>} {6:*} {6:<Cmd>}let m = mode(1){6:<CR>} |
|
|
]])
|
|
end)
|
|
|
|
it('handles invalid mappings', function()
|
|
command('let x = 0')
|
|
command('noremap <F3> <Cmd><Cmd>let x = 1<cr>')
|
|
feed('<F3>')
|
|
screen:expect([[
|
|
^some short lines |
|
|
of test text |
|
|
{1:~ }|*5
|
|
{2:E1136: <Cmd> mapping must end with <CR> before second <Cmd>} |
|
|
]])
|
|
|
|
command('noremap <F3> <Cmd>let x = 3')
|
|
feed('<F3>')
|
|
screen:expect([[
|
|
^some short lines |
|
|
of test text |
|
|
{1:~ }|*5
|
|
{2:E1255: <Cmd> mapping must end with <CR>} |
|
|
]])
|
|
eq(0, eval('x'))
|
|
end)
|
|
|
|
it('allows special keys and modifiers', function()
|
|
command('noremap <F3> <Cmd>normal! <Down><CR>')
|
|
feed('<F3>')
|
|
screen:expect([[
|
|
some short lines |
|
|
^of test text |
|
|
{1:~ }|*5
|
|
|
|
|
]])
|
|
|
|
command('noremap <F3> <Cmd>normal! <C-Right><CR>')
|
|
feed('<F3>')
|
|
screen:expect([[
|
|
some short lines |
|
|
of ^test text |
|
|
{1:~ }|*5
|
|
|
|
|
]])
|
|
end)
|
|
|
|
it('handles string containing K_SPECIAL (0x80) bytes correctly', function()
|
|
command([[noremap <F3> <Cmd>let g:str = 'foo…bar'<CR>]])
|
|
feed('<F3>')
|
|
eq('foo…bar', eval('g:str'))
|
|
local str = eval([["foo\<D-…>bar"]])
|
|
command([[noremap <F3> <Cmd>let g:str = ']] .. str .. [['<CR>]])
|
|
feed('<F3>')
|
|
eq(str, eval('g:str'))
|
|
command([[noremap <F3> <Cmd>let g:str = 'foo<D-…>bar'<CR>]])
|
|
feed('<F3>')
|
|
eq(str, eval('g:str'))
|
|
end)
|
|
|
|
it('works in various modes and sees correct `mode()` value', function()
|
|
-- normal mode
|
|
feed('<F3>')
|
|
eq('n', eval('m'))
|
|
|
|
-- visual mode
|
|
feed('v<F3>')
|
|
eq('v', eval('m'))
|
|
-- didn't leave visual mode
|
|
eq('v', eval('mode(1)'))
|
|
feed('<esc>')
|
|
eq('n', eval('mode(1)'))
|
|
|
|
-- visual mapping in select mode
|
|
feed('gh<F3>')
|
|
eq('v', eval('m'))
|
|
-- didn't leave select mode
|
|
eq('s', eval('mode(1)'))
|
|
feed('<esc>')
|
|
eq('n', eval('mode(1)'))
|
|
|
|
-- select mode mapping
|
|
command('snoremap <F3> <Cmd>let m = mode(1)<cr>')
|
|
feed('gh<F3>')
|
|
eq('s', eval('m'))
|
|
-- didn't leave select mode
|
|
eq('s', eval('mode(1)'))
|
|
feed('<esc>')
|
|
eq('n', eval('mode(1)'))
|
|
|
|
-- operator-pending mode
|
|
feed('d<F3>')
|
|
eq('no', eval('m'))
|
|
-- did leave operator-pending mode
|
|
eq('n', eval('mode(1)'))
|
|
|
|
--insert mode
|
|
feed('i<F3>')
|
|
eq('i', eval('m'))
|
|
eq('i', eval('mode(1)'))
|
|
|
|
-- replace mode
|
|
feed('<Ins><F3>')
|
|
eq('R', eval('m'))
|
|
eq('R', eval('mode(1)'))
|
|
feed('<esc>')
|
|
eq('n', eval('mode(1)'))
|
|
|
|
-- virtual replace mode
|
|
feed('gR<F3>')
|
|
eq('Rv', eval('m'))
|
|
eq('Rv', eval('mode(1)'))
|
|
feed('<esc>')
|
|
eq('n', eval('mode(1)'))
|
|
|
|
-- langmap works, but is not distinguished in mode(1)
|
|
feed(':set iminsert=1<cr>i<F3>')
|
|
eq('i', eval('m'))
|
|
eq('i', eval('mode(1)'))
|
|
feed('<esc>')
|
|
eq('n', eval('mode(1)'))
|
|
|
|
feed(':<F3>')
|
|
eq('c', eval('m'))
|
|
eq('c', eval('mode(1)'))
|
|
feed('<esc>')
|
|
eq('n', eval('mode(1)'))
|
|
|
|
-- terminal mode
|
|
command('tnoremap <F3> <Cmd>let m = mode(1)<cr>')
|
|
command('split | terminal')
|
|
feed('i')
|
|
eq('t', eval('mode(1)'))
|
|
feed('<F3>')
|
|
eq('t', eval('m'))
|
|
eq('t', eval('mode(1)'))
|
|
end)
|
|
|
|
it('works in normal mode', function()
|
|
cmdmap('<F2>', 'let s = [mode(1), v:count, v:register]')
|
|
|
|
-- check v:count and v:register works
|
|
feed('<F2>')
|
|
eq({ 'n', 0, '"' }, eval('s'))
|
|
feed('7<F2>')
|
|
eq({ 'n', 7, '"' }, eval('s'))
|
|
feed('"e<F2>')
|
|
eq({ 'n', 0, 'e' }, eval('s'))
|
|
feed('5"k<F2>')
|
|
eq({ 'n', 5, 'k' }, eval('s'))
|
|
feed('"+2<F2>')
|
|
eq({ 'n', 2, '+' }, eval('s'))
|
|
|
|
-- text object enters visual mode
|
|
feed('<F7>')
|
|
screen:expect([[
|
|
so{5:me short lines} |
|
|
{5:of }^test text |
|
|
{1:~ }|*5
|
|
{4:-- VISUAL --} |
|
|
]])
|
|
feed('<esc>')
|
|
|
|
-- startinsert
|
|
feed('<F8>')
|
|
eq('i', eval('mode(1)'))
|
|
feed('<esc>')
|
|
|
|
eq('n', eval('mode(1)'))
|
|
cmdmap(',a', 'call feedkeys("aalpha") \\| let g:a = getline(2)')
|
|
cmdmap(',b', 'call feedkeys("abeta", "x") \\| let g:b = getline(2)')
|
|
|
|
feed(',a<F3>')
|
|
screen:expect([[
|
|
some short lines |
|
|
of alpha^test text |
|
|
{1:~ }|*5
|
|
{4:-- INSERT --} |
|
|
]])
|
|
-- feedkeys were not executed immediately
|
|
eq({ 'n', 'of test text' }, eval('[m,a]'))
|
|
eq('i', eval('mode(1)'))
|
|
feed('<esc>')
|
|
|
|
feed(',b<F3>')
|
|
screen:expect([[
|
|
some short lines |
|
|
of alphabet^atest text |
|
|
{1:~ }|*5
|
|
|
|
|
]])
|
|
-- feedkeys(..., 'x') was executed immediately, but insert mode gets aborted
|
|
eq({ 'n', 'of alphabetatest text' }, eval('[m,b]'))
|
|
eq('n', eval('mode(1)'))
|
|
end)
|
|
|
|
it('works in :normal command', function()
|
|
command('noremap ,x <Cmd>call append(1, "xx")\\| call append(1, "aa")<cr>')
|
|
command('noremap ,f <Cmd>nosuchcommand<cr>')
|
|
command('noremap ,e <Cmd>throw "very error"\\| call append(1, "yy")<cr>')
|
|
command('noremap ,m <Cmd>echoerr "The message."\\| call append(1, "zz")<cr>')
|
|
command(
|
|
'noremap ,w <Cmd>for i in range(5)\\|if i==1\\|echoerr "Err"\\|endif\\|call append(1, i)\\|endfor<cr>'
|
|
)
|
|
|
|
feed(':normal ,x<cr>')
|
|
screen:expect([[
|
|
^some short lines |
|
|
aa |
|
|
xx |
|
|
of test text |
|
|
{1:~ }|*3
|
|
:normal ,x |
|
|
]])
|
|
|
|
eq('Vim:E492: Not an editor command: nosuchcommand', exc_exec('normal ,f'))
|
|
eq('very error', exc_exec('normal ,e'))
|
|
eq('Vim(echoerr):The message.', exc_exec('normal ,m'))
|
|
feed('w')
|
|
screen:expect([[
|
|
some ^short lines |
|
|
aa |
|
|
xx |
|
|
of test text |
|
|
{1:~ }|*3
|
|
:normal ,x |
|
|
]])
|
|
|
|
command(':%d')
|
|
eq('Vim(echoerr):Err', exc_exec('normal ,w'))
|
|
screen:expect([[
|
|
^ |
|
|
0 |
|
|
{1:~ }|*5
|
|
--No lines in buffer-- |
|
|
]])
|
|
|
|
command(':%d')
|
|
feed(':normal ,w<cr>')
|
|
screen:expect([[
|
|
^ |
|
|
4 |
|
|
3 |
|
|
2 |
|
|
1 |
|
|
0 |
|
|
{1:~ }|
|
|
{2:Err} |
|
|
]])
|
|
end)
|
|
|
|
it('works in visual mode', function()
|
|
-- can extend visual mode
|
|
feed('v<F4>')
|
|
screen:expect([[
|
|
{5:some short }^lines |
|
|
of test text |
|
|
{1:~ }|*5
|
|
{4:-- VISUAL --} |
|
|
]])
|
|
eq('v', fn.mode(1))
|
|
|
|
-- can invoke operator, ending visual mode
|
|
feed('<F5>')
|
|
eq('n', fn.mode(1))
|
|
eq({ 'some short l' }, fn.getreg('a', 1, 1))
|
|
|
|
-- error doesn't interrupt visual mode
|
|
feed('ggvw<F6>')
|
|
screen:expect([[
|
|
{5:some }short lines |
|
|
of test text |
|
|
{1:~ }|*2
|
|
{7: }|
|
|
{2:Error detected while processing :} |
|
|
{2:E605: Exception not caught: very error} |
|
|
{3:Press ENTER or type command to continue}^ |
|
|
]])
|
|
feed('<cr>')
|
|
eq('E605: Exception not caught: very error', eval('v:errmsg'))
|
|
-- still in visual mode, <cr> was consumed by the error prompt
|
|
screen:expect([[
|
|
{5:some }^short lines |
|
|
of test text |
|
|
{1:~ }|*5
|
|
{4:-- VISUAL --} |
|
|
]])
|
|
eq('v', fn.mode(1))
|
|
feed('<F7>')
|
|
screen:expect([[
|
|
so{5:me short lines} |
|
|
{5:of }^test text |
|
|
{1:~ }|*5
|
|
{4:-- VISUAL --} |
|
|
]])
|
|
eq('v', fn.mode(1))
|
|
|
|
-- startinsert gives "-- (insert) VISUAL --" mode
|
|
feed('<F8>')
|
|
screen:expect([[
|
|
so{5:me short lines} |
|
|
{5:of }^test text |
|
|
{1:~ }|*5
|
|
{4:-- (insert) VISUAL --} |
|
|
]])
|
|
eq('v', eval('mode(1)'))
|
|
feed('<esc>')
|
|
eq('i', eval('mode(1)'))
|
|
end)
|
|
|
|
it('works in select mode', function()
|
|
command('snoremap <F1> <cmd>throw "very error"<cr>')
|
|
command('snoremap <F2> <cmd>normal! <c-g>"by<cr>')
|
|
-- can extend select mode
|
|
feed('gh<F4>')
|
|
screen:expect([[
|
|
{5:some short }^lines |
|
|
of test text |
|
|
{1:~ }|*5
|
|
{4:-- SELECT --} |
|
|
]])
|
|
eq('s', fn.mode(1))
|
|
|
|
-- visual mapping in select mode restart select mode after operator
|
|
feed('<F5>')
|
|
eq('s', fn.mode(1))
|
|
eq({ 'some short l' }, fn.getreg('a', 1, 1))
|
|
|
|
-- select mode mapping works, and does not restart select mode
|
|
feed('<F2>')
|
|
eq('n', fn.mode(1))
|
|
eq({ 'some short l' }, fn.getreg('b', 1, 1))
|
|
|
|
-- error doesn't interrupt temporary visual mode
|
|
feed('<esc>ggvw<c-g><F6>')
|
|
screen:expect([[
|
|
{5:some }short lines |
|
|
of test text |
|
|
{1:~ }|*2
|
|
{7: }|
|
|
{2:Error detected while processing :} |
|
|
{2:E605: Exception not caught: very error} |
|
|
{3:Press ENTER or type command to continue}^ |
|
|
]])
|
|
feed('<cr>')
|
|
eq('E605: Exception not caught: very error', eval('v:errmsg'))
|
|
-- still in visual mode, <cr> was consumed by the error prompt
|
|
screen:expect([[
|
|
{5:some }^short lines |
|
|
of test text |
|
|
{1:~ }|*5
|
|
{4:-- VISUAL --} |
|
|
]])
|
|
-- quirk: restoration of select mode is not performed
|
|
eq('v', fn.mode(1))
|
|
|
|
-- error doesn't interrupt select mode
|
|
feed('<esc>ggvw<c-g><F1>')
|
|
screen:expect([[
|
|
{5:some }short lines |
|
|
of test text |
|
|
{1:~ }|*2
|
|
{7: }|
|
|
{2:Error detected while processing :} |
|
|
{2:E605: Exception not caught: very error} |
|
|
{3:Press ENTER or type command to continue}^ |
|
|
]])
|
|
feed('<cr>')
|
|
eq('E605: Exception not caught: very error', eval('v:errmsg'))
|
|
-- still in select mode, <cr> was consumed by the error prompt
|
|
screen:expect([[
|
|
{5:some }^short lines |
|
|
of test text |
|
|
{1:~ }|*5
|
|
{4:-- SELECT --} |
|
|
]])
|
|
-- quirk: restoration of select mode is not performed
|
|
eq('s', fn.mode(1))
|
|
|
|
feed('<F7>')
|
|
screen:expect([[
|
|
so{5:me short lines} |
|
|
{5:of }^test text |
|
|
{1:~ }|*5
|
|
{4:-- SELECT --} |
|
|
]])
|
|
eq('s', fn.mode(1))
|
|
|
|
-- startinsert gives "-- SELECT (insert) --" mode
|
|
feed('<F8>')
|
|
screen:expect([[
|
|
so{5:me short lines} |
|
|
{5:of }^test text |
|
|
{1:~ }|*5
|
|
{4:-- (insert) SELECT --} |
|
|
]])
|
|
eq('s', eval('mode(1)'))
|
|
feed('<esc>')
|
|
eq('i', eval('mode(1)'))
|
|
end)
|
|
|
|
it('works in operator-pending mode', function()
|
|
feed('d<F4>')
|
|
expect([[
|
|
lines
|
|
of test text]])
|
|
eq({ 'some short ' }, fn.getreg('"', 1, 1))
|
|
feed('.')
|
|
expect([[
|
|
test text]])
|
|
eq({ 'lines', 'of ' }, fn.getreg('"', 1, 1))
|
|
feed('uu')
|
|
expect([[
|
|
some short lines
|
|
of test text]])
|
|
|
|
-- error aborts operator-pending, operator not performed
|
|
feed('d<F6>')
|
|
screen:expect([[
|
|
some short lines |
|
|
of test text |
|
|
{1:~ }|*2
|
|
{7: }|
|
|
{2:Error detected while processing :} |
|
|
{2:E605: Exception not caught: very error} |
|
|
{3:Press ENTER or type command to continue}^ |
|
|
]])
|
|
feed('<cr>')
|
|
eq('E605: Exception not caught: very error', eval('v:errmsg'))
|
|
expect([[
|
|
some short lines
|
|
of test text]])
|
|
|
|
feed('"bd<F7>')
|
|
expect([[
|
|
soest text]])
|
|
eq({ 'me short lines', 'of t' }, fn.getreg('b', 1, 1))
|
|
|
|
-- startinsert aborts operator
|
|
feed('d<F8>')
|
|
eq('i', eval('mode(1)'))
|
|
expect([[
|
|
soest text]])
|
|
end)
|
|
|
|
it('works in insert mode', function()
|
|
-- works the same as <c-o>w<c-o>w
|
|
feed('iindeed <F4>little ')
|
|
screen:expect([[
|
|
indeed some short little ^lines |
|
|
of test text |
|
|
{1:~ }|*5
|
|
{4:-- INSERT --} |
|
|
]])
|
|
|
|
feed('<F6>')
|
|
screen:expect([[
|
|
indeed some short little lines |
|
|
of test text |
|
|
{1:~ }|*2
|
|
{7: }|
|
|
{2:Error detected while processing :} |
|
|
{2:E605: Exception not caught: very error} |
|
|
{3:Press ENTER or type command to continue}^ |
|
|
]])
|
|
|
|
feed('<cr>')
|
|
eq('E605: Exception not caught: very error', eval('v:errmsg'))
|
|
-- still in insert
|
|
screen:expect([[
|
|
indeed some short little ^lines |
|
|
of test text |
|
|
{1:~ }|*5
|
|
{4:-- INSERT --} |
|
|
]])
|
|
eq('i', eval('mode(1)'))
|
|
|
|
-- When entering visual mode from InsertEnter autocmd, an async event, or
|
|
-- a <cmd> mapping, vim ends up in undocumented "INSERT VISUAL" mode. If a
|
|
-- vim patch decides to disable this mode, this test is expected to fail.
|
|
feed('<F7>stuff ')
|
|
screen:expect([[
|
|
in{5:deed some short little lines} |
|
|
{5:of stuff }^test text |
|
|
{1:~ }|*5
|
|
{4:-- INSERT VISUAL --} |
|
|
]])
|
|
expect([[
|
|
indeed some short little lines
|
|
of stuff test text]])
|
|
|
|
feed('<F5>')
|
|
eq({ 'deed some short little lines', 'of stuff t' }, fn.getreg('a', 1, 1))
|
|
|
|
-- still in insert
|
|
screen:expect([[
|
|
in^deed some short little lines |
|
|
of stuff test text |
|
|
{1:~ }|*5
|
|
{4:-- INSERT --} |
|
|
]])
|
|
eq('i', eval('mode(1)'))
|
|
|
|
-- also works as part of abbreviation
|
|
feed('<space>foo ')
|
|
screen:expect([[
|
|
in bar ^deed some short little lines |
|
|
of stuff test text |
|
|
{1:~ }|*5
|
|
{4:-- INSERT --} |
|
|
]])
|
|
eq(17, eval('g:y'))
|
|
|
|
-- :startinsert does nothing
|
|
feed('<F8>')
|
|
eq('i', eval('mode(1)'))
|
|
|
|
-- :stopinsert works
|
|
feed('<F9>')
|
|
eq('n', eval('mode(1)'))
|
|
end)
|
|
|
|
it('works in insert completion (Ctrl-X) mode', function()
|
|
feed('os<c-x><c-n>')
|
|
screen:expect([[
|
|
some short lines |
|
|
some^ |
|
|
{8:some } |
|
|
{9:short }{1: }|
|
|
{1:~ }|*3
|
|
{4:-- Keyword Local completion (^N^P) }{3:match 1 of 2} |
|
|
]])
|
|
|
|
feed('<f3>')
|
|
eq('ic', eval('m'))
|
|
|
|
-- ensure a redraw, this would have moved the cursor
|
|
-- instead if CTRL-X mode was left.
|
|
feed('<up>')
|
|
screen:expect([[
|
|
some short lines |
|
|
some^ |
|
|
{9:some } |
|
|
{9:short }{1: }|
|
|
{1:~ }|*3
|
|
{4:-- Keyword Local completion (^N^P) }{10:Back at original} |
|
|
]])
|
|
end)
|
|
|
|
it('works in cmdline mode', function()
|
|
feed(':text<F3>')
|
|
eq('c', eval('m'))
|
|
-- didn't leave cmdline mode
|
|
eq('c', eval('mode(1)'))
|
|
feed('<cr>')
|
|
eq('n', eval('mode(1)'))
|
|
screen:expect([[
|
|
^some short lines |
|
|
of test text |
|
|
{1:~ }|*5
|
|
{2:E492: Not an editor command: text} |
|
|
]])
|
|
|
|
feed(':echo 2<F6>')
|
|
screen:expect([[
|
|
some short lines |
|
|
of test text |
|
|
{1:~ }|
|
|
{7: }|
|
|
:echo 2 |
|
|
{2:Error detected while processing :} |
|
|
{2:E605: Exception not caught: very error} |
|
|
:echo 2^ |
|
|
]])
|
|
eq('E605: Exception not caught: very error', eval('v:errmsg'))
|
|
-- didn't leave cmdline mode
|
|
eq('c', eval('mode(1)'))
|
|
feed('+2<cr>')
|
|
screen:expect([[
|
|
some short lines |
|
|
of test text |
|
|
{7: }|
|
|
:echo 2 |
|
|
{2:Error detected while processing :} |
|
|
{2:E605: Exception not caught: very error} |
|
|
4 |
|
|
{3:Press ENTER or type command to continue}^ |
|
|
]])
|
|
-- however, message scrolling may cause extra CR prompt
|
|
-- This is consistent with output from async events.
|
|
feed('<cr>')
|
|
screen:expect([[
|
|
^some short lines |
|
|
of test text |
|
|
{1:~ }|*5
|
|
|
|
|
]])
|
|
eq('n', eval('mode(1)'))
|
|
|
|
feed(':let g:x = 3<F4>')
|
|
screen:expect([[
|
|
some short lines |
|
|
of test text |
|
|
{1:~ }|*5
|
|
:let g:x = 3^ |
|
|
]])
|
|
feed('+2<cr>')
|
|
-- cursor was moved in the background
|
|
screen:expect([[
|
|
some short ^lines |
|
|
of test text |
|
|
{1:~ }|*5
|
|
:let g:x = 3+2 |
|
|
]])
|
|
eq(5, eval('g:x'))
|
|
|
|
feed(':let g:y = 7<F8>')
|
|
screen:expect([[
|
|
some short lines |
|
|
of test text |
|
|
{1:~ }|*5
|
|
:let g:y = 7^ |
|
|
]])
|
|
eq('c', eval('mode(1)'))
|
|
feed('+2<cr>')
|
|
-- startinsert takes effect after leaving cmdline mode
|
|
screen:expect([[
|
|
some short ^lines |
|
|
of test text |
|
|
{1:~ }|*5
|
|
{4:-- INSERT --} |
|
|
]])
|
|
eq('i', eval('mode(1)'))
|
|
eq(9, eval('g:y'))
|
|
end)
|
|
|
|
it("doesn't crash when invoking cmdline mode recursively #8859", function()
|
|
cmdmap('<F2>', 'norm! :foo')
|
|
feed(':bar')
|
|
screen:expect([[
|
|
some short lines |
|
|
of test text |
|
|
{1:~ }|*5
|
|
:bar^ |
|
|
]])
|
|
|
|
feed('<f2>x')
|
|
screen:expect([[
|
|
some short lines |
|
|
of test text |
|
|
{1:~ }|*5
|
|
:barx^ |
|
|
]])
|
|
end)
|
|
|
|
it('works with <SID> mappings', function()
|
|
command('new!')
|
|
write_file(
|
|
tmpfile,
|
|
[[
|
|
map <f2> <Cmd>call <SID>do_it()<Cr>
|
|
function! s:do_it()
|
|
let g:x = 10
|
|
endfunction
|
|
]]
|
|
)
|
|
command('source ' .. tmpfile)
|
|
feed('<f2>')
|
|
eq('', eval('v:errmsg'))
|
|
eq(10, eval('g:x'))
|
|
end)
|
|
end)
|