cmd_map_spec.lua 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. local t = require('test.testutil')
  2. local n = require('test.functional.testnvim')()
  3. local Screen = require('test.functional.ui.screen')
  4. local clear = n.clear
  5. local feed = n.feed
  6. local eq = t.eq
  7. local expect = n.expect
  8. local eval = n.eval
  9. local fn = n.fn
  10. local insert = n.insert
  11. local write_file = t.write_file
  12. local exc_exec = n.exc_exec
  13. local command = n.command
  14. describe('mappings with <Cmd>', function()
  15. local screen
  16. local tmpfile = 'X_ex_cmds_cmd_map'
  17. local function cmdmap(lhs, rhs)
  18. command('noremap ' .. lhs .. ' <Cmd>' .. rhs .. '<cr>')
  19. command('noremap! ' .. lhs .. ' <Cmd>' .. rhs .. '<cr>')
  20. end
  21. before_each(function()
  22. clear()
  23. screen = Screen.new(65, 8)
  24. screen:set_default_attr_ids({
  25. [1] = { bold = true, foreground = Screen.colors.Blue1 },
  26. [2] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red },
  27. [3] = { bold = true, foreground = Screen.colors.SeaGreen4 },
  28. [4] = { bold = true },
  29. [5] = { foreground = Screen.colors.Black, background = Screen.colors.LightGrey },
  30. [6] = { foreground = Screen.colors.Blue1 },
  31. [7] = { bold = true, reverse = true },
  32. [8] = { background = Screen.colors.WebGray },
  33. [9] = { background = Screen.colors.LightMagenta },
  34. [10] = { foreground = Screen.colors.Red },
  35. })
  36. cmdmap('<F3>', 'let m = mode(1)')
  37. cmdmap('<F4>', 'normal! ww')
  38. cmdmap('<F5>', 'normal! "ay')
  39. cmdmap('<F6>', 'throw "very error"')
  40. command([[
  41. function! TextObj()
  42. if mode() !=# "v"
  43. normal! v
  44. end
  45. call cursor(1,3)
  46. normal! o
  47. call cursor(2,4)
  48. endfunction]])
  49. cmdmap('<F7>', 'call TextObj()')
  50. insert([[
  51. some short lines
  52. of test text]])
  53. feed('gg')
  54. cmdmap('<F8>', 'startinsert')
  55. cmdmap('<F9>', 'stopinsert')
  56. command('abbr foo <Cmd>let g:y = 17<cr>bar')
  57. end)
  58. after_each(function()
  59. os.remove(tmpfile)
  60. end)
  61. it('can be displayed', function()
  62. command('map <F3>')
  63. screen:expect([[
  64. ^some short lines |
  65. of test text |
  66. {1:~ }|*5
  67. {6:<F3>} {6:*} {6:<Cmd>}let m = mode(1){6:<CR>} |
  68. ]])
  69. end)
  70. it('handles invalid mappings', function()
  71. command('let x = 0')
  72. command('noremap <F3> <Cmd><Cmd>let x = 1<cr>')
  73. feed('<F3>')
  74. screen:expect([[
  75. ^some short lines |
  76. of test text |
  77. {1:~ }|*5
  78. {2:E1136: <Cmd> mapping must end with <CR> before second <Cmd>} |
  79. ]])
  80. command('noremap <F3> <Cmd>let x = 3')
  81. feed('<F3>')
  82. screen:expect([[
  83. ^some short lines |
  84. of test text |
  85. {1:~ }|*5
  86. {2:E1255: <Cmd> mapping must end with <CR>} |
  87. ]])
  88. eq(0, eval('x'))
  89. end)
  90. it('allows special keys and modifiers', function()
  91. command('noremap <F3> <Cmd>normal! <Down><CR>')
  92. feed('<F3>')
  93. screen:expect([[
  94. some short lines |
  95. ^of test text |
  96. {1:~ }|*5
  97. |
  98. ]])
  99. command('noremap <F3> <Cmd>normal! <C-Right><CR>')
  100. feed('<F3>')
  101. screen:expect([[
  102. some short lines |
  103. of ^test text |
  104. {1:~ }|*5
  105. |
  106. ]])
  107. end)
  108. it('handles string containing K_SPECIAL (0x80) bytes correctly', function()
  109. command([[noremap <F3> <Cmd>let g:str = 'foo…bar'<CR>]])
  110. feed('<F3>')
  111. eq('foo…bar', eval('g:str'))
  112. local str = eval([["foo\<D-…>bar"]])
  113. command([[noremap <F3> <Cmd>let g:str = ']] .. str .. [['<CR>]])
  114. feed('<F3>')
  115. eq(str, eval('g:str'))
  116. command([[noremap <F3> <Cmd>let g:str = 'foo<D-…>bar'<CR>]])
  117. feed('<F3>')
  118. eq(str, eval('g:str'))
  119. end)
  120. it('works in various modes and sees correct `mode()` value', function()
  121. -- normal mode
  122. feed('<F3>')
  123. eq('n', eval('m'))
  124. -- visual mode
  125. feed('v<F3>')
  126. eq('v', eval('m'))
  127. -- didn't leave visual mode
  128. eq('v', eval('mode(1)'))
  129. feed('<esc>')
  130. eq('n', eval('mode(1)'))
  131. -- visual mapping in select mode
  132. feed('gh<F3>')
  133. eq('v', eval('m'))
  134. -- didn't leave select mode
  135. eq('s', eval('mode(1)'))
  136. feed('<esc>')
  137. eq('n', eval('mode(1)'))
  138. -- select mode mapping
  139. command('snoremap <F3> <Cmd>let m = mode(1)<cr>')
  140. feed('gh<F3>')
  141. eq('s', eval('m'))
  142. -- didn't leave select mode
  143. eq('s', eval('mode(1)'))
  144. feed('<esc>')
  145. eq('n', eval('mode(1)'))
  146. -- operator-pending mode
  147. feed('d<F3>')
  148. eq('no', eval('m'))
  149. -- did leave operator-pending mode
  150. eq('n', eval('mode(1)'))
  151. --insert mode
  152. feed('i<F3>')
  153. eq('i', eval('m'))
  154. eq('i', eval('mode(1)'))
  155. -- replace mode
  156. feed('<Ins><F3>')
  157. eq('R', eval('m'))
  158. eq('R', eval('mode(1)'))
  159. feed('<esc>')
  160. eq('n', eval('mode(1)'))
  161. -- virtual replace mode
  162. feed('gR<F3>')
  163. eq('Rv', eval('m'))
  164. eq('Rv', eval('mode(1)'))
  165. feed('<esc>')
  166. eq('n', eval('mode(1)'))
  167. -- langmap works, but is not distinguished in mode(1)
  168. feed(':set iminsert=1<cr>i<F3>')
  169. eq('i', eval('m'))
  170. eq('i', eval('mode(1)'))
  171. feed('<esc>')
  172. eq('n', eval('mode(1)'))
  173. feed(':<F3>')
  174. eq('c', eval('m'))
  175. eq('c', eval('mode(1)'))
  176. feed('<esc>')
  177. eq('n', eval('mode(1)'))
  178. -- terminal mode
  179. command('tnoremap <F3> <Cmd>let m = mode(1)<cr>')
  180. command('split | terminal')
  181. feed('i')
  182. eq('t', eval('mode(1)'))
  183. feed('<F3>')
  184. eq('t', eval('m'))
  185. eq('t', eval('mode(1)'))
  186. end)
  187. it('works in normal mode', function()
  188. cmdmap('<F2>', 'let s = [mode(1), v:count, v:register]')
  189. -- check v:count and v:register works
  190. feed('<F2>')
  191. eq({ 'n', 0, '"' }, eval('s'))
  192. feed('7<F2>')
  193. eq({ 'n', 7, '"' }, eval('s'))
  194. feed('"e<F2>')
  195. eq({ 'n', 0, 'e' }, eval('s'))
  196. feed('5"k<F2>')
  197. eq({ 'n', 5, 'k' }, eval('s'))
  198. feed('"+2<F2>')
  199. eq({ 'n', 2, '+' }, eval('s'))
  200. -- text object enters visual mode
  201. feed('<F7>')
  202. screen:expect([[
  203. so{5:me short lines} |
  204. {5:of }^test text |
  205. {1:~ }|*5
  206. {4:-- VISUAL --} |
  207. ]])
  208. feed('<esc>')
  209. -- startinsert
  210. feed('<F8>')
  211. eq('i', eval('mode(1)'))
  212. feed('<esc>')
  213. eq('n', eval('mode(1)'))
  214. cmdmap(',a', 'call feedkeys("aalpha") \\| let g:a = getline(2)')
  215. cmdmap(',b', 'call feedkeys("abeta", "x") \\| let g:b = getline(2)')
  216. feed(',a<F3>')
  217. screen:expect([[
  218. some short lines |
  219. of alpha^test text |
  220. {1:~ }|*5
  221. {4:-- INSERT --} |
  222. ]])
  223. -- feedkeys were not executed immediately
  224. eq({ 'n', 'of test text' }, eval('[m,a]'))
  225. eq('i', eval('mode(1)'))
  226. feed('<esc>')
  227. feed(',b<F3>')
  228. screen:expect([[
  229. some short lines |
  230. of alphabet^atest text |
  231. {1:~ }|*5
  232. |
  233. ]])
  234. -- feedkeys(..., 'x') was executed immediately, but insert mode gets aborted
  235. eq({ 'n', 'of alphabetatest text' }, eval('[m,b]'))
  236. eq('n', eval('mode(1)'))
  237. end)
  238. it('works in :normal command', function()
  239. command('noremap ,x <Cmd>call append(1, "xx")\\| call append(1, "aa")<cr>')
  240. command('noremap ,f <Cmd>nosuchcommand<cr>')
  241. command('noremap ,e <Cmd>throw "very error"\\| call append(1, "yy")<cr>')
  242. command('noremap ,m <Cmd>echoerr "The message."\\| call append(1, "zz")<cr>')
  243. command(
  244. 'noremap ,w <Cmd>for i in range(5)\\|if i==1\\|echoerr "Err"\\|endif\\|call append(1, i)\\|endfor<cr>'
  245. )
  246. feed(':normal ,x<cr>')
  247. screen:expect([[
  248. ^some short lines |
  249. aa |
  250. xx |
  251. of test text |
  252. {1:~ }|*3
  253. :normal ,x |
  254. ]])
  255. eq('Vim:E492: Not an editor command: nosuchcommand', exc_exec('normal ,f'))
  256. eq('very error', exc_exec('normal ,e'))
  257. eq('Vim(echoerr):The message.', exc_exec('normal ,m'))
  258. feed('w')
  259. screen:expect([[
  260. some ^short lines |
  261. aa |
  262. xx |
  263. of test text |
  264. {1:~ }|*3
  265. :normal ,x |
  266. ]])
  267. command(':%d')
  268. eq('Vim(echoerr):Err', exc_exec('normal ,w'))
  269. screen:expect([[
  270. ^ |
  271. 0 |
  272. {1:~ }|*5
  273. --No lines in buffer-- |
  274. ]])
  275. command(':%d')
  276. feed(':normal ,w<cr>')
  277. screen:expect([[
  278. ^ |
  279. 4 |
  280. 3 |
  281. 2 |
  282. 1 |
  283. 0 |
  284. {1:~ }|
  285. {2:Err} |
  286. ]])
  287. end)
  288. it('works in visual mode', function()
  289. -- can extend visual mode
  290. feed('v<F4>')
  291. screen:expect([[
  292. {5:some short }^lines |
  293. of test text |
  294. {1:~ }|*5
  295. {4:-- VISUAL --} |
  296. ]])
  297. eq('v', fn.mode(1))
  298. -- can invoke operator, ending visual mode
  299. feed('<F5>')
  300. eq('n', fn.mode(1))
  301. eq({ 'some short l' }, fn.getreg('a', 1, 1))
  302. -- error doesn't interrupt visual mode
  303. feed('ggvw<F6>')
  304. screen:expect([[
  305. {5:some }short lines |
  306. of test text |
  307. {1:~ }|*2
  308. {7: }|
  309. {2:Error detected while processing :} |
  310. {2:E605: Exception not caught: very error} |
  311. {3:Press ENTER or type command to continue}^ |
  312. ]])
  313. feed('<cr>')
  314. eq('E605: Exception not caught: very error', eval('v:errmsg'))
  315. -- still in visual mode, <cr> was consumed by the error prompt
  316. screen:expect([[
  317. {5:some }^short lines |
  318. of test text |
  319. {1:~ }|*5
  320. {4:-- VISUAL --} |
  321. ]])
  322. eq('v', fn.mode(1))
  323. feed('<F7>')
  324. screen:expect([[
  325. so{5:me short lines} |
  326. {5:of }^test text |
  327. {1:~ }|*5
  328. {4:-- VISUAL --} |
  329. ]])
  330. eq('v', fn.mode(1))
  331. -- startinsert gives "-- (insert) VISUAL --" mode
  332. feed('<F8>')
  333. screen:expect([[
  334. so{5:me short lines} |
  335. {5:of }^test text |
  336. {1:~ }|*5
  337. {4:-- (insert) VISUAL --} |
  338. ]])
  339. eq('v', eval('mode(1)'))
  340. feed('<esc>')
  341. eq('i', eval('mode(1)'))
  342. end)
  343. it('works in select mode', function()
  344. command('snoremap <F1> <cmd>throw "very error"<cr>')
  345. command('snoremap <F2> <cmd>normal! <c-g>"by<cr>')
  346. -- can extend select mode
  347. feed('gh<F4>')
  348. screen:expect([[
  349. {5:some short }^lines |
  350. of test text |
  351. {1:~ }|*5
  352. {4:-- SELECT --} |
  353. ]])
  354. eq('s', fn.mode(1))
  355. -- visual mapping in select mode restart select mode after operator
  356. feed('<F5>')
  357. eq('s', fn.mode(1))
  358. eq({ 'some short l' }, fn.getreg('a', 1, 1))
  359. -- select mode mapping works, and does not restart select mode
  360. feed('<F2>')
  361. eq('n', fn.mode(1))
  362. eq({ 'some short l' }, fn.getreg('b', 1, 1))
  363. -- error doesn't interrupt temporary visual mode
  364. feed('<esc>ggvw<c-g><F6>')
  365. screen:expect([[
  366. {5:some }short lines |
  367. of test text |
  368. {1:~ }|*2
  369. {7: }|
  370. {2:Error detected while processing :} |
  371. {2:E605: Exception not caught: very error} |
  372. {3:Press ENTER or type command to continue}^ |
  373. ]])
  374. feed('<cr>')
  375. eq('E605: Exception not caught: very error', eval('v:errmsg'))
  376. -- still in visual mode, <cr> was consumed by the error prompt
  377. screen:expect([[
  378. {5:some }^short lines |
  379. of test text |
  380. {1:~ }|*5
  381. {4:-- VISUAL --} |
  382. ]])
  383. -- quirk: restoration of select mode is not performed
  384. eq('v', fn.mode(1))
  385. -- error doesn't interrupt select mode
  386. feed('<esc>ggvw<c-g><F1>')
  387. screen:expect([[
  388. {5:some }short lines |
  389. of test text |
  390. {1:~ }|*2
  391. {7: }|
  392. {2:Error detected while processing :} |
  393. {2:E605: Exception not caught: very error} |
  394. {3:Press ENTER or type command to continue}^ |
  395. ]])
  396. feed('<cr>')
  397. eq('E605: Exception not caught: very error', eval('v:errmsg'))
  398. -- still in select mode, <cr> was consumed by the error prompt
  399. screen:expect([[
  400. {5:some }^short lines |
  401. of test text |
  402. {1:~ }|*5
  403. {4:-- SELECT --} |
  404. ]])
  405. -- quirk: restoration of select mode is not performed
  406. eq('s', fn.mode(1))
  407. feed('<F7>')
  408. screen:expect([[
  409. so{5:me short lines} |
  410. {5:of }^test text |
  411. {1:~ }|*5
  412. {4:-- SELECT --} |
  413. ]])
  414. eq('s', fn.mode(1))
  415. -- startinsert gives "-- SELECT (insert) --" mode
  416. feed('<F8>')
  417. screen:expect([[
  418. so{5:me short lines} |
  419. {5:of }^test text |
  420. {1:~ }|*5
  421. {4:-- (insert) SELECT --} |
  422. ]])
  423. eq('s', eval('mode(1)'))
  424. feed('<esc>')
  425. eq('i', eval('mode(1)'))
  426. end)
  427. it('works in operator-pending mode', function()
  428. feed('d<F4>')
  429. expect([[
  430. lines
  431. of test text]])
  432. eq({ 'some short ' }, fn.getreg('"', 1, 1))
  433. feed('.')
  434. expect([[
  435. test text]])
  436. eq({ 'lines', 'of ' }, fn.getreg('"', 1, 1))
  437. feed('uu')
  438. expect([[
  439. some short lines
  440. of test text]])
  441. -- error aborts operator-pending, operator not performed
  442. feed('d<F6>')
  443. screen:expect([[
  444. some short lines |
  445. of test text |
  446. {1:~ }|*2
  447. {7: }|
  448. {2:Error detected while processing :} |
  449. {2:E605: Exception not caught: very error} |
  450. {3:Press ENTER or type command to continue}^ |
  451. ]])
  452. feed('<cr>')
  453. eq('E605: Exception not caught: very error', eval('v:errmsg'))
  454. expect([[
  455. some short lines
  456. of test text]])
  457. feed('"bd<F7>')
  458. expect([[
  459. soest text]])
  460. eq({ 'me short lines', 'of t' }, fn.getreg('b', 1, 1))
  461. -- startinsert aborts operator
  462. feed('d<F8>')
  463. eq('i', eval('mode(1)'))
  464. expect([[
  465. soest text]])
  466. end)
  467. it('works in insert mode', function()
  468. -- works the same as <c-o>w<c-o>w
  469. feed('iindeed <F4>little ')
  470. screen:expect([[
  471. indeed some short little ^lines |
  472. of test text |
  473. {1:~ }|*5
  474. {4:-- INSERT --} |
  475. ]])
  476. feed('<F6>')
  477. screen:expect([[
  478. indeed some short little lines |
  479. of test text |
  480. {1:~ }|*2
  481. {7: }|
  482. {2:Error detected while processing :} |
  483. {2:E605: Exception not caught: very error} |
  484. {3:Press ENTER or type command to continue}^ |
  485. ]])
  486. feed('<cr>')
  487. eq('E605: Exception not caught: very error', eval('v:errmsg'))
  488. -- still in insert
  489. screen:expect([[
  490. indeed some short little ^lines |
  491. of test text |
  492. {1:~ }|*5
  493. {4:-- INSERT --} |
  494. ]])
  495. eq('i', eval('mode(1)'))
  496. -- When entering visual mode from InsertEnter autocmd, an async event, or
  497. -- a <cmd> mapping, vim ends up in undocumented "INSERT VISUAL" mode. If a
  498. -- vim patch decides to disable this mode, this test is expected to fail.
  499. feed('<F7>stuff ')
  500. screen:expect([[
  501. in{5:deed some short little lines} |
  502. {5:of stuff }^test text |
  503. {1:~ }|*5
  504. {4:-- INSERT VISUAL --} |
  505. ]])
  506. expect([[
  507. indeed some short little lines
  508. of stuff test text]])
  509. feed('<F5>')
  510. eq({ 'deed some short little lines', 'of stuff t' }, fn.getreg('a', 1, 1))
  511. -- still in insert
  512. screen:expect([[
  513. in^deed some short little lines |
  514. of stuff test text |
  515. {1:~ }|*5
  516. {4:-- INSERT --} |
  517. ]])
  518. eq('i', eval('mode(1)'))
  519. -- also works as part of abbreviation
  520. feed('<space>foo ')
  521. screen:expect([[
  522. in bar ^deed some short little lines |
  523. of stuff test text |
  524. {1:~ }|*5
  525. {4:-- INSERT --} |
  526. ]])
  527. eq(17, eval('g:y'))
  528. -- :startinsert does nothing
  529. feed('<F8>')
  530. eq('i', eval('mode(1)'))
  531. -- :stopinsert works
  532. feed('<F9>')
  533. eq('n', eval('mode(1)'))
  534. end)
  535. it('works in insert completion (Ctrl-X) mode', function()
  536. feed('os<c-x><c-n>')
  537. screen:expect([[
  538. some short lines |
  539. some^ |
  540. {8:some } |
  541. {9:short }{1: }|
  542. {1:~ }|*3
  543. {4:-- Keyword Local completion (^N^P) }{3:match 1 of 2} |
  544. ]])
  545. feed('<f3>')
  546. eq('ic', eval('m'))
  547. -- ensure a redraw, this would have moved the cursor
  548. -- instead if CTRL-X mode was left.
  549. feed('<up>')
  550. screen:expect([[
  551. some short lines |
  552. some^ |
  553. {9:some } |
  554. {9:short }{1: }|
  555. {1:~ }|*3
  556. {4:-- Keyword Local completion (^N^P) }{10:Back at original} |
  557. ]])
  558. end)
  559. it('works in cmdline mode', function()
  560. feed(':text<F3>')
  561. eq('c', eval('m'))
  562. -- didn't leave cmdline mode
  563. eq('c', eval('mode(1)'))
  564. feed('<cr>')
  565. eq('n', eval('mode(1)'))
  566. screen:expect([[
  567. ^some short lines |
  568. of test text |
  569. {1:~ }|*5
  570. {2:E492: Not an editor command: text} |
  571. ]])
  572. feed(':echo 2<F6>')
  573. screen:expect([[
  574. some short lines |
  575. of test text |
  576. {1:~ }|
  577. {7: }|
  578. :echo 2 |
  579. {2:Error detected while processing :} |
  580. {2:E605: Exception not caught: very error} |
  581. :echo 2^ |
  582. ]])
  583. eq('E605: Exception not caught: very error', eval('v:errmsg'))
  584. -- didn't leave cmdline mode
  585. eq('c', eval('mode(1)'))
  586. feed('+2<cr>')
  587. screen:expect([[
  588. some short lines |
  589. of test text |
  590. {7: }|
  591. :echo 2 |
  592. {2:Error detected while processing :} |
  593. {2:E605: Exception not caught: very error} |
  594. 4 |
  595. {3:Press ENTER or type command to continue}^ |
  596. ]])
  597. -- however, message scrolling may cause extra CR prompt
  598. -- This is consistent with output from async events.
  599. feed('<cr>')
  600. screen:expect([[
  601. ^some short lines |
  602. of test text |
  603. {1:~ }|*5
  604. |
  605. ]])
  606. eq('n', eval('mode(1)'))
  607. feed(':let g:x = 3<F4>')
  608. screen:expect([[
  609. some short lines |
  610. of test text |
  611. {1:~ }|*5
  612. :let g:x = 3^ |
  613. ]])
  614. feed('+2<cr>')
  615. -- cursor was moved in the background
  616. screen:expect([[
  617. some short ^lines |
  618. of test text |
  619. {1:~ }|*5
  620. :let g:x = 3+2 |
  621. ]])
  622. eq(5, eval('g:x'))
  623. feed(':let g:y = 7<F8>')
  624. screen:expect([[
  625. some short lines |
  626. of test text |
  627. {1:~ }|*5
  628. :let g:y = 7^ |
  629. ]])
  630. eq('c', eval('mode(1)'))
  631. feed('+2<cr>')
  632. -- startinsert takes effect after leaving cmdline mode
  633. screen:expect([[
  634. some short ^lines |
  635. of test text |
  636. {1:~ }|*5
  637. {4:-- INSERT --} |
  638. ]])
  639. eq('i', eval('mode(1)'))
  640. eq(9, eval('g:y'))
  641. end)
  642. it("doesn't crash when invoking cmdline mode recursively #8859", function()
  643. cmdmap('<F2>', 'norm! :foo')
  644. feed(':bar')
  645. screen:expect([[
  646. some short lines |
  647. of test text |
  648. {1:~ }|*5
  649. :bar^ |
  650. ]])
  651. feed('<f2>x')
  652. screen:expect([[
  653. some short lines |
  654. of test text |
  655. {1:~ }|*5
  656. :barx^ |
  657. ]])
  658. end)
  659. it('works with <SID> mappings', function()
  660. command('new!')
  661. write_file(
  662. tmpfile,
  663. [[
  664. map <f2> <Cmd>call <SID>do_it()<Cr>
  665. function! s:do_it()
  666. let g:x = 10
  667. endfunction
  668. ]]
  669. )
  670. command('source ' .. tmpfile)
  671. feed('<f2>')
  672. eq('', eval('v:errmsg'))
  673. eq(10, eval('g:x'))
  674. end)
  675. end)