source_spec.lua 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. local t = require('test.testutil')
  2. local n = require('test.functional.testnvim')()
  3. local command = n.command
  4. local insert = n.insert
  5. local eq = t.eq
  6. local clear = n.clear
  7. local api = n.api
  8. local feed = n.feed
  9. local feed_command = n.feed_command
  10. local write_file = t.write_file
  11. local tmpname = t.tmpname
  12. local exec = n.exec
  13. local exc_exec = n.exc_exec
  14. local exec_lua = n.exec_lua
  15. local eval = n.eval
  16. local exec_capture = n.exec_capture
  17. local neq = t.neq
  18. local matches = t.matches
  19. local mkdir = t.mkdir
  20. local rmdir = n.rmdir
  21. local is_os = t.is_os
  22. describe(':source', function()
  23. before_each(function()
  24. clear()
  25. end)
  26. it('sourcing a file that is deleted and recreated is consistent vim-patch:8.1.0151', function()
  27. local test_file = 'Xfile.vim'
  28. local other_file = 'Xfoobar'
  29. local script = [[
  30. func Func()
  31. endfunc
  32. ]]
  33. write_file(test_file, script)
  34. command('source ' .. test_file)
  35. os.remove(test_file)
  36. write_file(test_file, script)
  37. command('source ' .. test_file)
  38. os.remove(test_file)
  39. write_file(other_file, '')
  40. write_file(test_file, script)
  41. command('source ' .. test_file)
  42. os.remove(other_file)
  43. os.remove(test_file)
  44. end)
  45. it("changing 'shellslash' changes the result of expand()", function()
  46. if not is_os('win') then
  47. pending("'shellslash' only works on Windows")
  48. return
  49. end
  50. api.nvim_set_option_value('shellslash', false, {})
  51. mkdir('Xshellslash')
  52. write_file(
  53. [[Xshellslash/Xstack.vim]],
  54. [[
  55. let g:stack1 = expand('<stack>')
  56. set shellslash
  57. let g:stack2 = expand('<stack>')
  58. set noshellslash
  59. let g:stack3 = expand('<stack>')
  60. ]]
  61. )
  62. for _ = 1, 2 do
  63. command([[source Xshellslash/Xstack.vim]])
  64. matches([[Xshellslash\Xstack%.vim]], api.nvim_get_var('stack1'))
  65. matches([[Xshellslash/Xstack%.vim]], api.nvim_get_var('stack2'))
  66. matches([[Xshellslash\Xstack%.vim]], api.nvim_get_var('stack3'))
  67. end
  68. write_file(
  69. [[Xshellslash/Xstack.lua]],
  70. [[
  71. vim.g.stack1 = vim.fn.expand('<stack>')
  72. vim.o.shellslash = true
  73. vim.g.stack2 = vim.fn.expand('<stack>')
  74. vim.o.shellslash = false
  75. vim.g.stack3 = vim.fn.expand('<stack>')
  76. ]]
  77. )
  78. for _ = 1, 2 do
  79. command([[source Xshellslash/Xstack.lua]])
  80. matches([[Xshellslash\Xstack%.lua]], api.nvim_get_var('stack1'))
  81. matches([[Xshellslash/Xstack%.lua]], api.nvim_get_var('stack2'))
  82. matches([[Xshellslash\Xstack%.lua]], api.nvim_get_var('stack3'))
  83. end
  84. rmdir('Xshellslash')
  85. end)
  86. it('current buffer', function()
  87. insert([[
  88. let a = 2
  89. let b = #{
  90. \ k: "v"
  91. "\ (o_o)
  92. \ }
  93. let c = expand("<SID>")->empty()
  94. let s:s = 0zbeef.cafe
  95. let d = s:s]])
  96. command('source')
  97. eq('2', exec_capture('echo a'))
  98. eq("{'k': 'v'}", exec_capture('echo b'))
  99. -- Script items are created only on script var access
  100. eq('1', exec_capture('echo c'))
  101. eq('0zBEEFCAFE', exec_capture('echo d'))
  102. exec('set cpoptions+=C')
  103. eq("Vim(let):E723: Missing end of Dictionary '}': ", exc_exec('source'))
  104. end)
  105. it('selection in current buffer', function()
  106. insert([[
  107. let a = 2
  108. let a = 3
  109. let a = 4
  110. let b = #{
  111. "\ (>_<)
  112. \ K: "V"
  113. \ }
  114. function! s:C() abort
  115. return expand("<SID>") .. "C()"
  116. endfunction
  117. let D = {-> s:C()}]])
  118. -- Source the 2nd line only
  119. feed('ggjV')
  120. feed_command(':source')
  121. eq('3', exec_capture('echo a'))
  122. -- Source from 2nd line to end of file
  123. feed('ggjVG')
  124. feed_command(':source')
  125. eq('4', exec_capture('echo a'))
  126. eq("{'K': 'V'}", exec_capture('echo b'))
  127. eq('<SNR>1_C()', exec_capture('echo D()'))
  128. -- Source last line only
  129. feed_command(':$source')
  130. eq('Vim(echo):E117: Unknown function: s:C', exc_exec('echo D()'))
  131. exec('set cpoptions+=C')
  132. eq("Vim(let):E723: Missing end of Dictionary '}': ", exc_exec("'<,'>source"))
  133. end)
  134. it('does not break if current buffer is modified while sourced', function()
  135. insert [[
  136. bwipeout!
  137. let a = 123
  138. ]]
  139. command('source')
  140. eq('123', exec_capture('echo a'))
  141. end)
  142. it('multiline heredoc command', function()
  143. insert([[
  144. lua << EOF
  145. y = 4
  146. EOF]])
  147. command('source')
  148. eq('4', exec_capture('echo luaeval("y")'))
  149. end)
  150. it('can source lua files', function()
  151. local test_file = 'test.lua'
  152. write_file(
  153. test_file,
  154. [[
  155. vim.g.sourced_lua = 1
  156. vim.g.sfile_value = vim.fn.expand('<sfile>')
  157. vim.g.stack_value = vim.fn.expand('<stack>')
  158. vim.g.script_value = vim.fn.expand('<script>')
  159. ]]
  160. )
  161. command('set shellslash')
  162. command('source ' .. test_file)
  163. eq(1, eval('g:sourced_lua'))
  164. matches([[/test%.lua$]], api.nvim_get_var('sfile_value'))
  165. matches([[/test%.lua$]], api.nvim_get_var('stack_value'))
  166. matches([[/test%.lua$]], api.nvim_get_var('script_value'))
  167. os.remove(test_file)
  168. end)
  169. describe('can source current buffer', function()
  170. local function test_source_lua_curbuf()
  171. it('selected region', function()
  172. insert([[
  173. vim.g.b = 5
  174. vim.g.b = 6
  175. vim.g.b = 7
  176. a = [=[
  177. "\ a
  178. \ b]=]
  179. ]])
  180. feed('dd')
  181. feed('ggjV')
  182. feed_command(':source')
  183. eq(6, eval('g:b'))
  184. feed('GVkk')
  185. feed_command(':source')
  186. eq(' "\\ a\n \\ b', exec_lua('return _G.a'))
  187. end)
  188. it('whole buffer', function()
  189. insert([[
  190. vim.g.c = 10
  191. vim.g.c = 11
  192. vim.g.c = 12
  193. a = [=[
  194. \ 1
  195. "\ 2]=]
  196. vim.g.sfile_value = vim.fn.expand('<sfile>')
  197. vim.g.stack_value = vim.fn.expand('<stack>')
  198. vim.g.script_value = vim.fn.expand('<script>')
  199. ]])
  200. feed('dd')
  201. feed_command(':source')
  202. eq(12, eval('g:c'))
  203. eq(' \\ 1\n "\\ 2', exec_lua('return _G.a'))
  204. eq(':source (no file)', api.nvim_get_var('sfile_value'))
  205. eq(':source (no file)', api.nvim_get_var('stack_value'))
  206. eq(':source (no file)', api.nvim_get_var('script_value'))
  207. end)
  208. end
  209. describe('with ft=lua', function()
  210. before_each(function()
  211. command('setlocal ft=lua')
  212. end)
  213. test_source_lua_curbuf()
  214. end)
  215. describe('with .lua extension', function()
  216. before_each(function()
  217. command('edit ' .. tmpname() .. '.lua')
  218. end)
  219. test_source_lua_curbuf()
  220. end)
  221. end)
  222. it("doesn't throw E484 for lua parsing/runtime errors", function()
  223. local test_file = 'test.lua'
  224. -- Does throw E484 for unreadable files
  225. local ok, result = pcall(exec_capture, ':source ' .. test_file .. 'noexisting')
  226. eq(false, ok)
  227. neq(nil, result:find('E484'))
  228. -- Doesn't throw for parsing error
  229. write_file(test_file, 'vim.g.c = ')
  230. ok, result = pcall(exec_capture, ':source ' .. test_file)
  231. eq(false, ok)
  232. eq(nil, result:find('E484'))
  233. os.remove(test_file)
  234. -- Doesn't throw for runtime error
  235. write_file(test_file, "error('Cause error anyway :D')")
  236. ok, result = pcall(exec_capture, ':source ' .. test_file)
  237. eq(false, ok)
  238. eq(nil, result:find('E484'))
  239. os.remove(test_file)
  240. end)
  241. end)