output_spec.lua 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. local Screen = require('test.functional.ui.screen')
  2. local helpers = require('test.functional.helpers')(after_each)
  3. local child_session = require('test.functional.terminal.helpers')
  4. local mkdir, write_file, rmdir = helpers.mkdir, helpers.write_file, helpers.rmdir
  5. local eq = helpers.eq
  6. local eval = helpers.eval
  7. local feed = helpers.feed
  8. local feed_command = helpers.feed_command
  9. local iswin = helpers.iswin
  10. local clear = helpers.clear
  11. local command = helpers.command
  12. local nvim_dir = helpers.nvim_dir
  13. local has_powershell = helpers.has_powershell
  14. local set_shell_powershell = helpers.set_shell_powershell
  15. describe("shell command :!", function()
  16. local screen
  17. before_each(function()
  18. clear()
  19. screen = child_session.screen_setup(0, '["'..helpers.nvim_prog..
  20. '", "-u", "NONE", "-i", "NONE", "--cmd", "'..helpers.nvim_set..'"]')
  21. screen:expect([[
  22. {1: } |
  23. {4:~ }|
  24. {4:~ }|
  25. {4:~ }|
  26. {4:~ }|
  27. |
  28. {3:-- TERMINAL --} |
  29. ]])
  30. end)
  31. after_each(function()
  32. child_session.feed_data("\3") -- Ctrl-C
  33. end)
  34. it("displays output without LF/EOF. #4646 #4569 #3772", function()
  35. if helpers.pending_win32(pending) then return end
  36. -- NOTE: We use a child nvim (within a :term buffer)
  37. -- to avoid triggering a UI flush.
  38. child_session.feed_data(":!printf foo; sleep 200\n")
  39. screen:expect([[
  40. |
  41. {4:~ }|
  42. {4:~ }|
  43. {5: }|
  44. :!printf foo; sleep 200 |
  45. foo |
  46. {3:-- TERMINAL --} |
  47. ]])
  48. end)
  49. it("throttles shell-command output greater than ~10KB", function()
  50. if 'openbsd' == helpers.uname() then
  51. pending('FIXME #10804')
  52. end
  53. child_session.feed_data(":!"..nvim_dir.."/shell-test REP 30001 foo\n")
  54. -- If we observe any line starting with a dot, then throttling occurred.
  55. -- Avoid false failure on slow systems.
  56. screen:expect{any="\n%.", timeout=20000}
  57. -- Final chunk of output should always be displayed, never skipped.
  58. -- (Throttling is non-deterministic, this test is merely a sanity check.)
  59. screen:expect([[
  60. 29997: foo |
  61. 29998: foo |
  62. 29999: foo |
  63. 30000: foo |
  64. |
  65. {10:Press ENTER or type command to continue}{1: } |
  66. {3:-- TERMINAL --} |
  67. ]], {
  68. -- test/functional/helpers.lua defaults to background=light.
  69. [1] = {reverse = true},
  70. [3] = {bold = true},
  71. [10] = {foreground = 2},
  72. })
  73. end)
  74. end)
  75. describe("shell command :!", function()
  76. before_each(function()
  77. clear()
  78. end)
  79. it("cat a binary file #4142", function()
  80. feed(":exe 'silent !cat '.shellescape(v:progpath)<CR>")
  81. eq(2, eval('1+1')) -- Still alive?
  82. end)
  83. it([[display \x08 char #4142]], function()
  84. feed(":silent !echo \08<CR>")
  85. eq(2, eval('1+1')) -- Still alive?
  86. end)
  87. it('handles control codes', function()
  88. if iswin() then
  89. pending('missing printf')
  90. end
  91. local screen = Screen.new(50, 4)
  92. screen:attach()
  93. command("set display-=msgsep")
  94. -- Print TAB chars. #2958
  95. feed([[:!printf '1\t2\t3'<CR>]])
  96. screen:expect([[
  97. ~ |
  98. :!printf '1\t2\t3' |
  99. 1 2 3 |
  100. Press ENTER or type command to continue^ |
  101. ]])
  102. feed([[<CR>]])
  103. -- Print BELL control code. #4338
  104. screen.bell = false
  105. feed([[:!printf '\007\007\007\007text'<CR>]])
  106. screen:expect{grid=[[
  107. ~ |
  108. :!printf '\007\007\007\007text' |
  109. text |
  110. Press ENTER or type command to continue^ |
  111. ]], condition=function()
  112. eq(true, screen.bell)
  113. end}
  114. feed([[<CR>]])
  115. -- Print BS control code.
  116. feed([[:echo system('printf ''\010\n''')<CR>]])
  117. screen:expect([[
  118. ~ |
  119. ^H |
  120. |
  121. Press ENTER or type command to continue^ |
  122. ]])
  123. feed([[<CR>]])
  124. -- Print LF control code.
  125. feed([[:!printf '\n'<CR>]])
  126. screen:expect([[
  127. :!printf '\n' |
  128. |
  129. |
  130. Press ENTER or type command to continue^ |
  131. ]])
  132. feed([[<CR>]])
  133. end)
  134. describe('', function()
  135. local screen
  136. before_each(function()
  137. rmdir('bang_filter_spec')
  138. mkdir('bang_filter_spec')
  139. write_file('bang_filter_spec/f1', 'f1')
  140. write_file('bang_filter_spec/f2', 'f2')
  141. write_file('bang_filter_spec/f3', 'f3')
  142. screen = Screen.new(53,10)
  143. screen:set_default_attr_ids({
  144. [1] = {bold = true, foreground = Screen.colors.Blue1},
  145. [2] = {foreground = Screen.colors.Blue1},
  146. [3] = {bold = true, foreground = Screen.colors.SeaGreen4},
  147. [4] = {bold = true, reverse = true},
  148. })
  149. screen:attach()
  150. end)
  151. after_each(function()
  152. rmdir('bang_filter_spec')
  153. end)
  154. it("doesn't truncate Last line of shell output #3269", function()
  155. command(helpers.iswin()
  156. and [[nnoremap <silent>\l :!dir /b bang_filter_spec<cr>]]
  157. or [[nnoremap <silent>\l :!ls bang_filter_spec<cr>]])
  158. local result = (helpers.iswin()
  159. and [[:!dir /b bang_filter_spec]]
  160. or [[:!ls bang_filter_spec ]])
  161. feed([[\l]])
  162. screen:expect([[
  163. |
  164. {1:~ }|
  165. {1:~ }|
  166. {4: }|
  167. ]]..result..[[ |
  168. f1 |
  169. f2 |
  170. f3 |
  171. |
  172. {3:Press ENTER or type command to continue}^ |
  173. ]])
  174. end)
  175. it('handles binary and multibyte data', function()
  176. feed_command('!cat test/functional/fixtures/shell_data.txt')
  177. screen.bell = false
  178. screen:expect{grid=[[
  179. |
  180. {1:~ }|
  181. {4: }|
  182. :!cat test/functional/fixtures/shell_data.txt |
  183. {2:^@^A^B^C^D^E^F^H} |
  184. {2:^N^O^P^Q^R^S^T^U^V^W^X^Y^Z^[^\^]^^^_} |
  185. ö 한글 {2:<a5><c3>} |
  186. t {2:<ff>} |
  187. |
  188. {3:Press ENTER or type command to continue}^ |
  189. ]], condition=function()
  190. eq(true, screen.bell)
  191. end}
  192. end)
  193. it('handles multibyte sequences split over buffer boundaries', function()
  194. command('cd '..nvim_dir)
  195. local cmd
  196. if iswin() then
  197. cmd = '!shell-test UTF-8 '
  198. else
  199. cmd = '!./shell-test UTF-8'
  200. end
  201. feed_command(cmd)
  202. -- Note: only the first example of split composed char works
  203. screen:expect([[
  204. |
  205. {4: }|
  206. :]]..cmd..[[ |
  207. å |
  208. ref: å̲ |
  209. 1: å̲ |
  210. 2: å ̲ |
  211. 3: å ̲ |
  212. |
  213. {3:Press ENTER or type command to continue}^ |
  214. ]])
  215. end)
  216. end)
  217. if has_powershell() then
  218. it('powershell supports literal strings', function()
  219. set_shell_powershell()
  220. local screen = Screen.new(45, 4)
  221. screen:attach()
  222. feed_command([[!'Write-Output $a']])
  223. screen:expect([[
  224. :!'Write-Output $a' |
  225. Write-Output $a |
  226. |
  227. Press ENTER or type command to continue^ |
  228. ]])
  229. feed_command([[!$a = 1; Write-Output '$a']])
  230. screen:expect([[
  231. :!$a = 1; Write-Output '$a' |
  232. $a |
  233. |
  234. Press ENTER or type command to continue^ |
  235. ]])
  236. feed_command([[!"Write-Output $a"]])
  237. screen:expect([[
  238. :!"Write-Output $a" |
  239. Write-Output |
  240. |
  241. Press ENTER or type command to continue^ |
  242. ]])
  243. feed_command([[!$a = 1; Write-Output "$a"]])
  244. screen:expect([[
  245. :!$a = 1; Write-Output "$a" |
  246. 1 |
  247. |
  248. Press ENTER or type command to continue^ |
  249. ]])
  250. if iswin() then
  251. feed_command([[!& 'cmd.exe' /c 'echo $a']])
  252. screen:expect([[
  253. :!& 'cmd.exe' /c 'echo $a' |
  254. $a |
  255. |
  256. Press ENTER or type command to continue^ |
  257. ]])
  258. else
  259. feed_command([[!& '/bin/sh' -c 'echo ''$a''']])
  260. screen:expect([[
  261. :!& '/bin/sh' -c 'echo ''$a''' |
  262. $a |
  263. |
  264. Press ENTER or type command to continue^ |
  265. ]])
  266. end
  267. end)
  268. end
  269. end)