test_prompt_buffer.vim 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. " Tests for setting 'buftype' to "prompt"
  2. source check.vim
  3. " Nvim's channel implementation differs from Vim's
  4. " CheckFeature channel
  5. source shared.vim
  6. source screendump.vim
  7. func CanTestPromptBuffer()
  8. " We need to use a terminal window to be able to feed keys without leaving
  9. " Insert mode.
  10. CheckFeature terminal
  11. " TODO: make the tests work on MS-Windows
  12. CheckNotMSWindows
  13. endfunc
  14. func WriteScript(name)
  15. call writefile([
  16. \ 'func TextEntered(text)',
  17. \ ' if a:text == "exit"',
  18. \ ' " Reset &modified to allow the buffer to be closed.',
  19. \ ' set nomodified',
  20. \ ' stopinsert',
  21. \ ' close',
  22. \ ' else',
  23. \ ' " Add the output above the current prompt.',
  24. \ ' call append(line("$") - 1, "Command: \"" . a:text . "\"")',
  25. \ ' " Reset &modified to allow the buffer to be closed.',
  26. \ ' set nomodified',
  27. \ ' call timer_start(20, {id -> TimerFunc(a:text)})',
  28. \ ' endif',
  29. \ 'endfunc',
  30. \ '',
  31. \ 'func TimerFunc(text)',
  32. \ ' " Add the output above the current prompt.',
  33. \ ' call append(line("$") - 1, "Result: \"" . a:text . "\"")',
  34. \ ' " Reset &modified to allow the buffer to be closed.',
  35. \ ' set nomodified',
  36. \ 'endfunc',
  37. \ '',
  38. \ 'func SwitchWindows()',
  39. \ ' call timer_start(0, {-> execute("wincmd p|wincmd p", "")})',
  40. \ 'endfunc',
  41. \ '',
  42. \ 'call setline(1, "other buffer")',
  43. \ 'set nomodified',
  44. \ 'new',
  45. \ 'set buftype=prompt',
  46. \ 'call prompt_setcallback(bufnr(""), function("TextEntered"))',
  47. \ 'eval bufnr("")->prompt_setprompt("cmd: ")',
  48. \ 'startinsert',
  49. \ ], a:name)
  50. endfunc
  51. func Test_prompt_basic()
  52. call CanTestPromptBuffer()
  53. let scriptName = 'XpromptscriptBasic'
  54. call WriteScript(scriptName)
  55. let buf = RunVimInTerminal('-S ' . scriptName, {})
  56. call WaitForAssert({-> assert_equal('cmd:', term_getline(buf, 1))})
  57. call term_sendkeys(buf, "hello\<CR>")
  58. call WaitForAssert({-> assert_equal('cmd: hello', term_getline(buf, 1))})
  59. call WaitForAssert({-> assert_equal('Command: "hello"', term_getline(buf, 2))})
  60. call WaitForAssert({-> assert_equal('Result: "hello"', term_getline(buf, 3))})
  61. call term_sendkeys(buf, "exit\<CR>")
  62. call WaitForAssert({-> assert_equal('other buffer', term_getline(buf, 1))})
  63. call StopVimInTerminal(buf)
  64. call delete(scriptName)
  65. endfunc
  66. func Test_prompt_editing()
  67. call CanTestPromptBuffer()
  68. let scriptName = 'XpromptscriptEditing'
  69. call WriteScript(scriptName)
  70. let buf = RunVimInTerminal('-S ' . scriptName, {})
  71. call WaitForAssert({-> assert_equal('cmd:', term_getline(buf, 1))})
  72. let bs = "\<BS>"
  73. call term_sendkeys(buf, "hello" . bs . bs)
  74. call WaitForAssert({-> assert_equal('cmd: hel', term_getline(buf, 1))})
  75. let left = "\<Left>"
  76. call term_sendkeys(buf, left . left . left . bs . '-')
  77. call WaitForAssert({-> assert_equal('cmd: -hel', term_getline(buf, 1))})
  78. call term_sendkeys(buf, "\<C-O>lz")
  79. call WaitForAssert({-> assert_equal('cmd: -hzel', term_getline(buf, 1))})
  80. let end = "\<End>"
  81. call term_sendkeys(buf, end . "x")
  82. call WaitForAssert({-> assert_equal('cmd: -hzelx', term_getline(buf, 1))})
  83. call term_sendkeys(buf, "\<C-U>exit\<CR>")
  84. call WaitForAssert({-> assert_equal('other buffer', term_getline(buf, 1))})
  85. call StopVimInTerminal(buf)
  86. call delete(scriptName)
  87. endfunc
  88. func Test_prompt_switch_windows()
  89. call CanTestPromptBuffer()
  90. let scriptName = 'XpromptSwitchWindows'
  91. call WriteScript(scriptName)
  92. let buf = RunVimInTerminal('-S ' . scriptName, {'rows': 12})
  93. call WaitForAssert({-> assert_equal('cmd:', term_getline(buf, 1))})
  94. call WaitForAssert({-> assert_match('-- INSERT --', term_getline(buf, 12))})
  95. call term_sendkeys(buf, "\<C-O>:call SwitchWindows()\<CR>")
  96. call term_wait(buf, 50)
  97. call WaitForAssert({-> assert_match('-- INSERT --', term_getline(buf, 12))})
  98. call term_sendkeys(buf, "\<Esc>")
  99. call term_wait(buf, 50)
  100. call WaitForAssert({-> assert_match('^ *$', term_getline(buf, 12))})
  101. call StopVimInTerminal(buf)
  102. call delete(scriptName)
  103. endfunc
  104. func Test_prompt_garbage_collect()
  105. func MyPromptCallback(x, text)
  106. " NOP
  107. endfunc
  108. func MyPromptInterrupt(x)
  109. " NOP
  110. endfunc
  111. new
  112. set buftype=prompt
  113. eval bufnr('')->prompt_setcallback(function('MyPromptCallback', [{}]))
  114. eval bufnr('')->prompt_setinterrupt(function('MyPromptInterrupt', [{}]))
  115. call test_garbagecollect_now()
  116. " Must not crash
  117. call feedkeys("\<CR>\<C-C>", 'xt')
  118. call assert_true(v:true)
  119. call assert_fails("call prompt_setcallback(bufnr(), [])", 'E921:')
  120. call assert_equal(0, prompt_setcallback({}, ''))
  121. call assert_fails("call prompt_setinterrupt(bufnr(), [])", 'E921:')
  122. call assert_equal(0, prompt_setinterrupt({}, ''))
  123. delfunc MyPromptCallback
  124. bwipe!
  125. endfunc
  126. func Test_prompt_backspace()
  127. new
  128. set buftype=prompt
  129. call feedkeys("A123456\<Left>\<BS>\<Esc>", 'xt')
  130. call assert_equal('% 12346', getline(1))
  131. bwipe!
  132. endfunc
  133. " Test for editing the prompt buffer
  134. func Test_prompt_buffer_edit()
  135. new
  136. set buftype=prompt
  137. normal! i
  138. call assert_beeps('normal! dd')
  139. call assert_beeps('normal! ~')
  140. call assert_beeps('normal! o')
  141. call assert_beeps('normal! O')
  142. call assert_beeps('normal! p')
  143. call assert_beeps('normal! P')
  144. call assert_beeps('normal! u')
  145. call assert_beeps('normal! ra')
  146. call assert_beeps('normal! s')
  147. call assert_beeps('normal! S')
  148. call assert_beeps("normal! \<C-A>")
  149. call assert_beeps("normal! \<C-X>")
  150. call assert_beeps("normal! dp")
  151. call assert_beeps("normal! do")
  152. " pressing CTRL-W in the prompt buffer should trigger the window commands
  153. call assert_equal(1, winnr())
  154. exe "normal A\<C-W>\<C-W>"
  155. call assert_equal(2, winnr())
  156. wincmd w
  157. close!
  158. call assert_equal(0, prompt_setprompt([], ''))
  159. endfunc
  160. func Test_prompt_buffer_getbufinfo()
  161. new
  162. call assert_equal('', prompt_getprompt('%'))
  163. call assert_equal('', prompt_getprompt(bufnr('%')))
  164. let another_buffer = bufnr('%')
  165. set buftype=prompt
  166. call assert_equal('% ', prompt_getprompt('%'))
  167. call prompt_setprompt( bufnr( '%' ), 'This is a test: ' )
  168. call assert_equal('This is a test: ', prompt_getprompt('%'))
  169. call prompt_setprompt( bufnr( '%' ), '' )
  170. call assert_equal('', '%'->prompt_getprompt())
  171. call prompt_setprompt( bufnr( '%' ), 'Another: ' )
  172. call assert_equal('Another: ', prompt_getprompt('%'))
  173. let another = bufnr('%')
  174. new
  175. call assert_equal('', prompt_getprompt('%'))
  176. call assert_equal('Another: ', prompt_getprompt(another))
  177. " Doesn't exist
  178. let buffers_before = len( getbufinfo() )
  179. call assert_equal('', prompt_getprompt( bufnr('$') + 1))
  180. call assert_equal(buffers_before, len( getbufinfo()))
  181. " invalid type
  182. call assert_fails('call prompt_getprompt({})', 'E728:')
  183. %bwipe!
  184. endfunc
  185. func Test_prompt_while_writing_to_hidden_buffer()
  186. call CanTestPromptBuffer()
  187. CheckUnix
  188. " Make a job continuously write to a hidden buffer, check that the prompt
  189. " buffer is not affected.
  190. let scriptName = 'XpromptscriptHiddenBuf'
  191. let script =<< trim END
  192. set buftype=prompt
  193. call prompt_setprompt( bufnr(), 'cmd:' )
  194. let job = job_start(['/bin/sh', '-c',
  195. \ 'while true;
  196. \ do echo line;
  197. \ sleep 0.1;
  198. \ done'], #{out_io: 'buffer', out_name: ''})
  199. startinsert
  200. END
  201. eval script->writefile(scriptName, 'D')
  202. let buf = RunVimInTerminal('-S ' .. scriptName, {})
  203. call WaitForAssert({-> assert_equal('cmd:', term_getline(buf, 1))})
  204. call term_sendkeys(buf, 'test')
  205. call WaitForAssert({-> assert_equal('cmd:test', term_getline(buf, 1))})
  206. call term_sendkeys(buf, 'test')
  207. call WaitForAssert({-> assert_equal('cmd:testtest', term_getline(buf, 1))})
  208. call term_sendkeys(buf, 'test')
  209. call WaitForAssert({-> assert_equal('cmd:testtesttest', term_getline(buf, 1))})
  210. call StopVimInTerminal(buf)
  211. endfunc
  212. func Test_prompt_appending_while_hidden()
  213. call CanTestPromptBuffer()
  214. let script =<< trim END
  215. new prompt
  216. set buftype=prompt
  217. set bufhidden=hide
  218. func s:TextEntered(text)
  219. if a:text == 'exit'
  220. close
  221. endif
  222. echowin 'Entered:' a:text
  223. endfunc
  224. call prompt_setcallback(bufnr(), function('s:TextEntered'))
  225. func DoAppend()
  226. call appendbufline('prompt', '$', 'Test')
  227. return ''
  228. endfunc
  229. END
  230. call writefile(script, 'XpromptBuffer', 'D')
  231. let buf = RunVimInTerminal('-S XpromptBuffer', {'rows': 10})
  232. call TermWait(buf)
  233. call term_sendkeys(buf, "asomething\<CR>")
  234. call TermWait(buf)
  235. call term_sendkeys(buf, "exit\<CR>")
  236. call WaitForAssert({-> assert_notmatch('-- INSERT --', term_getline(buf, 10))})
  237. call term_sendkeys(buf, ":call DoAppend()\<CR>")
  238. call WaitForAssert({-> assert_notmatch('-- INSERT --', term_getline(buf, 10))})
  239. call term_sendkeys(buf, "i")
  240. call WaitForAssert({-> assert_match('-- INSERT --', term_getline(buf, 10))})
  241. call term_sendkeys(buf, "\<C-R>=DoAppend()\<CR>")
  242. call WaitForAssert({-> assert_match('-- INSERT --', term_getline(buf, 10))})
  243. call term_sendkeys(buf, "\<Esc>")
  244. call StopVimInTerminal(buf)
  245. endfunc
  246. " Modifying a hidden buffer while leaving a prompt buffer should not prevent
  247. " stopping of Insert mode, and returning to the prompt buffer later should
  248. " restore Insert mode.
  249. func Test_prompt_leave_modify_hidden()
  250. call CanTestPromptBuffer()
  251. let script =<< trim END
  252. file hidden
  253. set bufhidden=hide
  254. enew
  255. new prompt
  256. set buftype=prompt
  257. inoremap <buffer> w <Cmd>wincmd w<CR>
  258. inoremap <buffer> q <Cmd>bwipe!<CR>
  259. autocmd BufLeave prompt call appendbufline('hidden', '$', 'Leave')
  260. autocmd BufEnter prompt call appendbufline('hidden', '$', 'Enter')
  261. autocmd BufWinLeave prompt call appendbufline('hidden', '$', 'Close')
  262. END
  263. call writefile(script, 'XpromptLeaveModifyHidden', 'D')
  264. let buf = RunVimInTerminal('-S XpromptLeaveModifyHidden', {'rows': 10})
  265. call TermWait(buf)
  266. call term_sendkeys(buf, "a")
  267. call WaitForAssert({-> assert_match('-- INSERT --', term_getline(buf, 10))})
  268. call term_sendkeys(buf, "w")
  269. call WaitForAssert({-> assert_notmatch('-- INSERT --', term_getline(buf, 10))})
  270. call term_sendkeys(buf, "\<C-W>w")
  271. call WaitForAssert({-> assert_match('-- INSERT --', term_getline(buf, 10))})
  272. call term_sendkeys(buf, "q")
  273. call WaitForAssert({-> assert_notmatch('-- INSERT --', term_getline(buf, 10))})
  274. call term_sendkeys(buf, ":bwipe!\<CR>")
  275. call WaitForAssert({-> assert_equal('Leave', term_getline(buf, 2))})
  276. call WaitForAssert({-> assert_equal('Enter', term_getline(buf, 3))})
  277. call WaitForAssert({-> assert_equal('Leave', term_getline(buf, 4))})
  278. call WaitForAssert({-> assert_equal('Close', term_getline(buf, 5))})
  279. call StopVimInTerminal(buf)
  280. endfunc
  281. " vim: shiftwidth=2 sts=2 expandtab