messages_spec.lua 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  1. local n = require('test.functional.testnvim')()
  2. local Screen = require('test.functional.ui.screen')
  3. local clear = n.clear
  4. local command = n.command
  5. local exec = n.exec
  6. local feed = n.feed
  7. local api = n.api
  8. local nvim_dir = n.nvim_dir
  9. local assert_alive = n.assert_alive
  10. before_each(clear)
  11. describe('messages', function()
  12. local screen
  13. -- oldtest: Test_warning_scroll()
  14. it('a warning causes scrolling if and only if it has a stacktrace', function()
  15. screen = Screen.new(75, 6)
  16. -- When the warning comes from a script, messages are scrolled so that the
  17. -- stacktrace is visible.
  18. -- It is a bit hard to assert the screen when sourcing a script, so skip this part.
  19. -- When the warning does not come from a script, messages are not scrolled.
  20. command('enew')
  21. command('set readonly')
  22. feed('u')
  23. screen:expect({
  24. grid = [[
  25. |
  26. {1:~ }|*4
  27. {19:W10: Warning: Changing a readonly file}^ |
  28. ]],
  29. timeout = 500,
  30. })
  31. screen:expect([[
  32. ^ |
  33. {1:~ }|*4
  34. Already at oldest change |
  35. ]])
  36. end)
  37. -- oldtest: Test_message_not_cleared_after_mode()
  38. it('clearing mode does not remove message', function()
  39. screen = Screen.new(60, 10)
  40. exec([[
  41. nmap <silent> gx :call DebugSilent('normal')<CR>
  42. vmap <silent> gx :call DebugSilent('visual')<CR>
  43. function DebugSilent(arg)
  44. echomsg "from DebugSilent" a:arg
  45. endfunction
  46. set showmode
  47. set cmdheight=1
  48. call setline(1, ['one', 'NoSuchFile', 'three'])
  49. ]])
  50. feed('gx')
  51. screen:expect([[
  52. ^one |
  53. NoSuchFile |
  54. three |
  55. {1:~ }|*6
  56. from DebugSilent normal |
  57. ]])
  58. -- removing the mode message used to also clear the intended message
  59. feed('vEgx')
  60. screen:expect([[
  61. ^one |
  62. NoSuchFile |
  63. three |
  64. {1:~ }|*6
  65. from DebugSilent visual |
  66. ]])
  67. -- removing the mode message used to also clear the error message
  68. command('set cmdheight=2')
  69. feed('2GvEgf')
  70. screen:expect([[
  71. one |
  72. NoSuchFil^e |
  73. three |
  74. {1:~ }|*5
  75. |
  76. {9:E447: Can't find file "NoSuchFile" in path} |
  77. ]])
  78. end)
  79. describe('more prompt', function()
  80. before_each(function()
  81. command('set more')
  82. end)
  83. -- oldtest: Test_message_more()
  84. it('works', function()
  85. screen = Screen.new(75, 6)
  86. screen:set_default_attr_ids({
  87. [1] = { bold = true, foreground = Screen.colors.SeaGreen }, -- MoreMsg
  88. [2] = { foreground = Screen.colors.Brown }, -- LineNr
  89. })
  90. command('call setline(1, range(1, 100))')
  91. feed(':%pfoo<C-H><C-H><C-H>#')
  92. screen:expect([[
  93. 1 |
  94. 2 |
  95. 3 |
  96. 4 |
  97. 5 |
  98. :%p#^ |
  99. ]])
  100. feed('\n')
  101. screen:expect([[
  102. {2: 1 }1 |
  103. {2: 2 }2 |
  104. {2: 3 }3 |
  105. {2: 4 }4 |
  106. {2: 5 }5 |
  107. {1:-- More --}^ |
  108. ]])
  109. feed('?')
  110. screen:expect([[
  111. {2: 1 }1 |
  112. {2: 2 }2 |
  113. {2: 3 }3 |
  114. {2: 4 }4 |
  115. {2: 5 }5 |
  116. {1:-- More -- SPACE/d/j: screen/page/line down, b/u/k: up, q: quit }^ |
  117. ]])
  118. -- Down a line with j, <CR>, <NL> or <Down>.
  119. feed('j')
  120. screen:expect([[
  121. {2: 2 }2 |
  122. {2: 3 }3 |
  123. {2: 4 }4 |
  124. {2: 5 }5 |
  125. {2: 6 }6 |
  126. {1:-- More --}^ |
  127. ]])
  128. feed('<NL>')
  129. screen:expect([[
  130. {2: 3 }3 |
  131. {2: 4 }4 |
  132. {2: 5 }5 |
  133. {2: 6 }6 |
  134. {2: 7 }7 |
  135. {1:-- More --}^ |
  136. ]])
  137. feed('<CR>')
  138. screen:expect([[
  139. {2: 4 }4 |
  140. {2: 5 }5 |
  141. {2: 6 }6 |
  142. {2: 7 }7 |
  143. {2: 8 }8 |
  144. {1:-- More --}^ |
  145. ]])
  146. feed('<Down>')
  147. screen:expect([[
  148. {2: 5 }5 |
  149. {2: 6 }6 |
  150. {2: 7 }7 |
  151. {2: 8 }8 |
  152. {2: 9 }9 |
  153. {1:-- More --}^ |
  154. ]])
  155. -- Down a screen with <Space>, f, or <PageDown>.
  156. feed('f')
  157. screen:expect([[
  158. {2: 10 }10 |
  159. {2: 11 }11 |
  160. {2: 12 }12 |
  161. {2: 13 }13 |
  162. {2: 14 }14 |
  163. {1:-- More --}^ |
  164. ]])
  165. feed('<Space>')
  166. screen:expect([[
  167. {2: 15 }15 |
  168. {2: 16 }16 |
  169. {2: 17 }17 |
  170. {2: 18 }18 |
  171. {2: 19 }19 |
  172. {1:-- More --}^ |
  173. ]])
  174. feed('<PageDown>')
  175. screen:expect([[
  176. {2: 20 }20 |
  177. {2: 21 }21 |
  178. {2: 22 }22 |
  179. {2: 23 }23 |
  180. {2: 24 }24 |
  181. {1:-- More --}^ |
  182. ]])
  183. -- Down a page (half a screen) with d.
  184. feed('d')
  185. screen:expect([[
  186. {2: 23 }23 |
  187. {2: 24 }24 |
  188. {2: 25 }25 |
  189. {2: 26 }26 |
  190. {2: 27 }27 |
  191. {1:-- More --}^ |
  192. ]])
  193. -- Down all the way with 'G'.
  194. feed('G')
  195. screen:expect([[
  196. {2: 96 }96 |
  197. {2: 97 }97 |
  198. {2: 98 }98 |
  199. {2: 99 }99 |
  200. {2:100 }100 |
  201. {1:Press ENTER or type command to continue}^ |
  202. ]])
  203. -- Up a line k, <BS> or <Up>.
  204. feed('k')
  205. screen:expect([[
  206. {2: 95 }95 |
  207. {2: 96 }96 |
  208. {2: 97 }97 |
  209. {2: 98 }98 |
  210. {2: 99 }99 |
  211. {1:-- More --}^ |
  212. ]])
  213. feed('<BS>')
  214. screen:expect([[
  215. {2: 94 }94 |
  216. {2: 95 }95 |
  217. {2: 96 }96 |
  218. {2: 97 }97 |
  219. {2: 98 }98 |
  220. {1:-- More --}^ |
  221. ]])
  222. feed('<Up>')
  223. screen:expect([[
  224. {2: 93 }93 |
  225. {2: 94 }94 |
  226. {2: 95 }95 |
  227. {2: 96 }96 |
  228. {2: 97 }97 |
  229. {1:-- More --}^ |
  230. ]])
  231. -- Up a screen with b or <PageUp>.
  232. feed('b')
  233. screen:expect([[
  234. {2: 88 }88 |
  235. {2: 89 }89 |
  236. {2: 90 }90 |
  237. {2: 91 }91 |
  238. {2: 92 }92 |
  239. {1:-- More --}^ |
  240. ]])
  241. feed('<PageUp>')
  242. screen:expect([[
  243. {2: 83 }83 |
  244. {2: 84 }84 |
  245. {2: 85 }85 |
  246. {2: 86 }86 |
  247. {2: 87 }87 |
  248. {1:-- More --}^ |
  249. ]])
  250. -- Up a page (half a screen) with u.
  251. feed('u')
  252. screen:expect([[
  253. {2: 80 }80 |
  254. {2: 81 }81 |
  255. {2: 82 }82 |
  256. {2: 83 }83 |
  257. {2: 84 }84 |
  258. {1:-- More --}^ |
  259. ]])
  260. -- Up all the way with 'g'.
  261. feed('g')
  262. screen:expect([[
  263. :%p# |
  264. {2: 1 }1 |
  265. {2: 2 }2 |
  266. {2: 3 }3 |
  267. {2: 4 }4 |
  268. {1:-- More --}^ |
  269. ]])
  270. -- All the way down. Pressing f should do nothing but pressing
  271. -- space should end the more prompt.
  272. feed('G')
  273. screen:expect([[
  274. {2: 96 }96 |
  275. {2: 97 }97 |
  276. {2: 98 }98 |
  277. {2: 99 }99 |
  278. {2:100 }100 |
  279. {1:Press ENTER or type command to continue}^ |
  280. ]])
  281. feed('f')
  282. screen:expect_unchanged()
  283. feed('<Space>')
  284. screen:expect([[
  285. 96 |
  286. 97 |
  287. 98 |
  288. 99 |
  289. ^100 |
  290. |
  291. ]])
  292. -- Pressing g< shows the previous command output.
  293. feed('g<lt>')
  294. screen:expect([[
  295. {2: 96 }96 |
  296. {2: 97 }97 |
  297. {2: 98 }98 |
  298. {2: 99 }99 |
  299. {2:100 }100 |
  300. {1:Press ENTER or type command to continue}^ |
  301. ]])
  302. -- A command line that doesn't print text is appended to scrollback,
  303. -- even if it invokes a nested command line.
  304. feed([[:<C-R>=':'<CR>:<CR>g<lt>]])
  305. screen:expect([[
  306. {2: 97 }97 |
  307. {2: 98 }98 |
  308. {2: 99 }99 |
  309. {2:100 }100 |
  310. ::: |
  311. {1:Press ENTER or type command to continue}^ |
  312. ]])
  313. feed(':%p#\n')
  314. screen:expect([[
  315. {2: 1 }1 |
  316. {2: 2 }2 |
  317. {2: 3 }3 |
  318. {2: 4 }4 |
  319. {2: 5 }5 |
  320. {1:-- More --}^ |
  321. ]])
  322. -- Stop command output with q, <Esc> or CTRL-C.
  323. feed('q')
  324. screen:expect([[
  325. 96 |
  326. 97 |
  327. 98 |
  328. 99 |
  329. ^100 |
  330. |
  331. ]])
  332. -- Execute a : command from the more prompt
  333. feed(':%p#\n')
  334. screen:expect([[
  335. {2: 1 }1 |
  336. {2: 2 }2 |
  337. {2: 3 }3 |
  338. {2: 4 }4 |
  339. {2: 5 }5 |
  340. {1:-- More --}^ |
  341. ]])
  342. feed(':')
  343. screen:expect([[
  344. {2: 1 }1 |
  345. {2: 2 }2 |
  346. {2: 3 }3 |
  347. {2: 4 }4 |
  348. {2: 5 }5 |
  349. :^ |
  350. ]])
  351. feed("echo 'Hello'\n")
  352. screen:expect([[
  353. {2: 2 }2 |
  354. {2: 3 }3 |
  355. {2: 4 }4 |
  356. {2: 5 }5 |
  357. Hello |
  358. {1:Press ENTER or type command to continue}^ |
  359. ]])
  360. end)
  361. -- oldtest: Test_echo_verbose_system()
  362. it('verbose message before echo command', function()
  363. screen = Screen.new(60, 10)
  364. command('cd ' .. nvim_dir)
  365. api.nvim_set_option_value('shell', './shell-test', {})
  366. api.nvim_set_option_value('shellcmdflag', 'REP 20', {})
  367. api.nvim_set_option_value('shellxquote', '', {}) -- win: avoid extra quotes
  368. -- display a page and go back, results in exactly the same view
  369. feed([[:4 verbose echo system('foo')<CR>]])
  370. screen:expect([[
  371. Executing command: "'./shell-test' 'REP' '20' 'foo'" |
  372. |
  373. 0: foo |
  374. 1: foo |
  375. 2: foo |
  376. 3: foo |
  377. 4: foo |
  378. 5: foo |
  379. 6: foo |
  380. {6:-- More --}^ |
  381. ]])
  382. feed('<Space>')
  383. screen:expect([[
  384. 7: foo |
  385. 8: foo |
  386. 9: foo |
  387. 10: foo |
  388. 11: foo |
  389. 12: foo |
  390. 13: foo |
  391. 14: foo |
  392. 15: foo |
  393. {6:-- More --}^ |
  394. ]])
  395. feed('b')
  396. screen:expect([[
  397. Executing command: "'./shell-test' 'REP' '20' 'foo'" |
  398. |
  399. 0: foo |
  400. 1: foo |
  401. 2: foo |
  402. 3: foo |
  403. 4: foo |
  404. 5: foo |
  405. 6: foo |
  406. {6:-- More --}^ |
  407. ]])
  408. -- do the same with 'cmdheight' set to 2
  409. feed('q')
  410. command('set ch=2')
  411. screen:expect([[
  412. ^ |
  413. {1:~ }|*7
  414. |*2
  415. ]])
  416. feed([[:4 verbose echo system('foo')<CR>]])
  417. screen:expect([[
  418. Executing command: "'./shell-test' 'REP' '20' 'foo'" |
  419. |
  420. 0: foo |
  421. 1: foo |
  422. 2: foo |
  423. 3: foo |
  424. 4: foo |
  425. 5: foo |
  426. 6: foo |
  427. {6:-- More --}^ |
  428. ]])
  429. feed('<Space>')
  430. screen:expect([[
  431. 7: foo |
  432. 8: foo |
  433. 9: foo |
  434. 10: foo |
  435. 11: foo |
  436. 12: foo |
  437. 13: foo |
  438. 14: foo |
  439. 15: foo |
  440. {6:-- More --}^ |
  441. ]])
  442. feed('b')
  443. screen:expect([[
  444. Executing command: "'./shell-test' 'REP' '20' 'foo'" |
  445. |
  446. 0: foo |
  447. 1: foo |
  448. 2: foo |
  449. 3: foo |
  450. 4: foo |
  451. 5: foo |
  452. 6: foo |
  453. {6:-- More --}^ |
  454. ]])
  455. end)
  456. -- oldtest: Test_quit_long_message()
  457. it('with control characters can be quit vim-patch:8.2.1844', function()
  458. screen = Screen.new(40, 10)
  459. feed([[:echom range(9999)->join("\x01")<CR>]])
  460. screen:expect([[
  461. 0{18:^A}1{18:^A}2{18:^A}3{18:^A}4{18:^A}5{18:^A}6{18:^A}7{18:^A}8{18:^A}9{18:^A}10{18:^A}11{18:^A}12|
  462. {18:^A}13{18:^A}14{18:^A}15{18:^A}16{18:^A}17{18:^A}18{18:^A}19{18:^A}20{18:^A}21{18:^A}22|
  463. {18:^A}23{18:^A}24{18:^A}25{18:^A}26{18:^A}27{18:^A}28{18:^A}29{18:^A}30{18:^A}31{18:^A}32|
  464. {18:^A}33{18:^A}34{18:^A}35{18:^A}36{18:^A}37{18:^A}38{18:^A}39{18:^A}40{18:^A}41{18:^A}42|
  465. {18:^A}43{18:^A}44{18:^A}45{18:^A}46{18:^A}47{18:^A}48{18:^A}49{18:^A}50{18:^A}51{18:^A}52|
  466. {18:^A}53{18:^A}54{18:^A}55{18:^A}56{18:^A}57{18:^A}58{18:^A}59{18:^A}60{18:^A}61{18:^A}62|
  467. {18:^A}63{18:^A}64{18:^A}65{18:^A}66{18:^A}67{18:^A}68{18:^A}69{18:^A}70{18:^A}71{18:^A}72|
  468. {18:^A}73{18:^A}74{18:^A}75{18:^A}76{18:^A}77{18:^A}78{18:^A}79{18:^A}80{18:^A}81{18:^A}82|
  469. {18:^A}83{18:^A}84{18:^A}85{18:^A}86{18:^A}87{18:^A}88{18:^A}89{18:^A}90{18:^A}91{18:^A}92|
  470. {6:-- More --}^ |
  471. ]])
  472. feed('q')
  473. screen:expect([[
  474. ^ |
  475. {1:~ }|*8
  476. |
  477. ]])
  478. end)
  479. end)
  480. describe('mode is cleared when', function()
  481. before_each(function()
  482. screen = Screen.new(40, 6)
  483. end)
  484. -- oldtest: Test_mode_message_at_leaving_insert_by_ctrl_c()
  485. it('leaving Insert mode with Ctrl-C vim-patch:8.1.1189', function()
  486. exec([[
  487. func StatusLine() abort
  488. return ""
  489. endfunc
  490. set statusline=%!StatusLine()
  491. set laststatus=2
  492. ]])
  493. feed('i')
  494. screen:expect([[
  495. ^ |
  496. {1:~ }|*3
  497. {3: }|
  498. {5:-- INSERT --} |
  499. ]])
  500. feed('<C-C>')
  501. screen:expect([[
  502. ^ |
  503. {1:~ }|*3
  504. {3: }|
  505. |
  506. ]])
  507. end)
  508. -- oldtest: Test_mode_message_at_leaving_insert_with_esc_mapped()
  509. it('leaving Insert mode with ESC in the middle of a mapping vim-patch:8.1.1192', function()
  510. exec([[
  511. set laststatus=2
  512. inoremap <Esc> <Esc>00
  513. ]])
  514. feed('i')
  515. screen:expect([[
  516. ^ |
  517. {1:~ }|*3
  518. {3:[No Name] }|
  519. {5:-- INSERT --} |
  520. ]])
  521. feed('<Esc>')
  522. screen:expect([[
  523. ^ |
  524. {1:~ }|*3
  525. {3:[No Name] }|
  526. |
  527. ]])
  528. end)
  529. -- oldtest: Test_mode_updated_after_ctrl_c()
  530. it('pressing Ctrl-C in i_CTRL-O', function()
  531. feed('i<C-O>')
  532. screen:expect([[
  533. ^ |
  534. {1:~ }|*4
  535. {5:-- (insert) --} |
  536. ]])
  537. feed('<C-C>')
  538. screen:expect([[
  539. ^ |
  540. {1:~ }|*4
  541. |
  542. ]])
  543. end)
  544. end)
  545. -- oldtest: Test_ask_yesno()
  546. it('y/n prompt works', function()
  547. screen = Screen.new(75, 6)
  548. command('set noincsearch nohlsearch inccommand=')
  549. command('call setline(1, range(1, 2))')
  550. feed(':2,1s/^/n/\n')
  551. screen:expect([[
  552. 1 |
  553. 2 |
  554. {1:~ }|*3
  555. {6:Backwards range given, OK to swap (y/n)?}^ |
  556. ]])
  557. feed('n')
  558. screen:expect([[
  559. ^1 |
  560. 2 |
  561. {1:~ }|*3
  562. {6:Backwards range given, OK to swap (y/n)?}n |
  563. ]])
  564. feed(':2,1s/^/Esc/\n')
  565. screen:expect([[
  566. 1 |
  567. 2 |
  568. {1:~ }|*3
  569. {6:Backwards range given, OK to swap (y/n)?}^ |
  570. ]])
  571. feed('<Esc>')
  572. screen:expect([[
  573. ^1 |
  574. 2 |
  575. {1:~ }|*3
  576. {6:Backwards range given, OK to swap (y/n)?}n |
  577. ]])
  578. feed(':2,1s/^/y/\n')
  579. screen:expect([[
  580. 1 |
  581. 2 |
  582. {1:~ }|*3
  583. {6:Backwards range given, OK to swap (y/n)?}^ |
  584. ]])
  585. feed('y')
  586. screen:expect([[
  587. y1 |
  588. ^y2 |
  589. {1:~ }|*3
  590. {6:Backwards range given, OK to swap (y/n)?}y |
  591. ]])
  592. end)
  593. -- oldtest: Test_fileinfo_tabpage_cmdheight()
  594. it("fileinfo works when 'cmdheight' has just decreased", function()
  595. screen = Screen.new(40, 6)
  596. exec([[
  597. set shortmess-=o
  598. set shortmess-=O
  599. set shortmess-=F
  600. tabnew
  601. set cmdheight=2
  602. ]])
  603. screen:expect([[
  604. {24: [No Name] }{5: [No Name] }{2: }{24:X}|
  605. ^ |
  606. {1:~ }|*2
  607. |*2
  608. ]])
  609. feed(':tabprev | edit Xfileinfo.txt<CR>')
  610. screen:expect([[
  611. {5: Xfileinfo.txt }{24: [No Name] }{2: }{24:X}|
  612. ^ |
  613. {1:~ }|*3
  614. "Xfileinfo.txt" [New] |
  615. ]])
  616. assert_alive()
  617. end)
  618. -- oldtest: Test_fileinfo_after_echo()
  619. it('fileinfo does not overwrite echo message vim-patch:8.2.4156', function()
  620. screen = Screen.new(40, 6)
  621. exec([[
  622. set shortmess-=F
  623. file a.txt
  624. hide edit b.txt
  625. call setline(1, "hi")
  626. setlocal modified
  627. hide buffer a.txt
  628. autocmd CursorHold * buf b.txt | w | echo "'b' written"
  629. ]])
  630. command('set updatetime=50')
  631. feed('0$')
  632. screen:expect([[
  633. ^hi |
  634. {1:~ }|*4
  635. 'b' written |
  636. ]])
  637. os.remove('b.txt')
  638. end)
  639. -- oldtest: Test_messagesopt_wait()
  640. it('&messagesopt "wait"', function()
  641. screen = Screen.new(45, 6)
  642. command('set cmdheight=1')
  643. -- Check hit-enter prompt
  644. command('set messagesopt=hit-enter,history:500')
  645. feed(":echo 'foo' | echo 'bar' | echo 'baz'\n")
  646. screen:expect([[
  647. |
  648. {3: }|
  649. foo |
  650. bar |
  651. baz |
  652. {6:Press ENTER or type command to continue}^ |
  653. ]])
  654. feed('<CR>')
  655. -- Check no hit-enter prompt when "wait:" is set
  656. command('set messagesopt=wait:500,history:500')
  657. feed(":echo 'foo' | echo 'bar' | echo 'baz'\n")
  658. screen:expect({
  659. grid = [[
  660. |
  661. {1:~ }|
  662. {3: }|
  663. foo |
  664. bar |
  665. baz |
  666. ]],
  667. timeout = 500,
  668. })
  669. screen:expect([[
  670. ^ |
  671. {1:~ }|*4
  672. |
  673. ]])
  674. end)
  675. end)