defaults_spec.lua 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288
  1. --
  2. -- Tests for default options and environment decisions.
  3. --
  4. -- See editor/defaults_spec.lua for default autocmds, mappings, commands, and menus.
  5. --
  6. local t = require('test.testutil')
  7. local n = require('test.functional.testnvim')()
  8. local Screen = require('test.functional.ui.screen')
  9. local assert_alive = n.assert_alive
  10. local assert_log = t.assert_log
  11. local api = n.api
  12. local command = n.command
  13. local clear = n.clear
  14. local exc_exec = n.exc_exec
  15. local exec_lua = n.exec_lua
  16. local eval = n.eval
  17. local eq = t.eq
  18. local ok = t.ok
  19. local fn = n.fn
  20. local insert = n.insert
  21. local neq = t.neq
  22. local mkdir = t.mkdir
  23. local rmdir = n.rmdir
  24. local tbl_contains = vim.tbl_contains
  25. local expect_exit = n.expect_exit
  26. local check_close = n.check_close
  27. local is_os = t.is_os
  28. local testlog = 'Xtest-defaults-log'
  29. describe('startup defaults', function()
  30. describe(':filetype', function()
  31. local function expect_filetype(expected)
  32. local screen = Screen.new(50, 4)
  33. command('filetype')
  34. screen:expect([[
  35. ^ |
  36. {1:~ }|*2
  37. ]] .. expected)
  38. end
  39. it('all ON after `-u NORC`', function()
  40. clear('-u', 'NORC')
  41. expect_filetype('filetype detection:ON plugin:ON indent:ON |')
  42. end)
  43. it('all ON after `:syntax …` #7765', function()
  44. clear('-u', 'NORC', '--cmd', 'syntax on')
  45. expect_filetype('filetype detection:ON plugin:ON indent:ON |')
  46. clear('-u', 'NORC', '--cmd', 'syntax off')
  47. expect_filetype('filetype detection:ON plugin:ON indent:ON |')
  48. end)
  49. it('all OFF after `-u NONE`', function()
  50. clear('-u', 'NONE')
  51. expect_filetype('filetype detection:OFF plugin:OFF indent:OFF |')
  52. end)
  53. it('explicit OFF stays OFF', function()
  54. clear('-u', 'NORC', '--cmd', 'syntax off | filetype off | filetype plugin indent off')
  55. expect_filetype('filetype detection:OFF plugin:OFF indent:OFF |')
  56. clear('-u', 'NORC', '--cmd', 'syntax off | filetype plugin indent off')
  57. expect_filetype('filetype detection:ON plugin:OFF indent:OFF |')
  58. clear('-u', 'NORC', '--cmd', 'filetype indent off')
  59. expect_filetype('filetype detection:ON plugin:ON indent:OFF |')
  60. clear('-u', 'NORC', '--cmd', 'syntax off | filetype off')
  61. expect_filetype('filetype detection:OFF plugin:(on) indent:(on) |')
  62. -- Swap the order.
  63. clear('-u', 'NORC', '--cmd', 'filetype off | syntax off')
  64. expect_filetype('filetype detection:OFF plugin:(on) indent:(on) |')
  65. end)
  66. it('all ON after early `:filetype … on`', function()
  67. -- `:filetype … on` should not change the defaults. #7765
  68. -- Only an explicit `:filetype … off` sets OFF.
  69. clear('-u', 'NORC', '--cmd', 'filetype on')
  70. expect_filetype('filetype detection:ON plugin:ON indent:ON |')
  71. clear('-u', 'NORC', '--cmd', 'filetype plugin on')
  72. expect_filetype('filetype detection:ON plugin:ON indent:ON |')
  73. clear('-u', 'NORC', '--cmd', 'filetype indent on')
  74. expect_filetype('filetype detection:ON plugin:ON indent:ON |')
  75. end)
  76. it('late `:filetype … off` stays OFF', function()
  77. clear('-u', 'NORC', '-c', 'filetype off')
  78. expect_filetype('filetype detection:OFF plugin:(on) indent:(on) |')
  79. clear('-u', 'NORC', '-c', 'filetype plugin off')
  80. expect_filetype('filetype detection:ON plugin:OFF indent:ON |')
  81. clear('-u', 'NORC', '-c', 'filetype indent off')
  82. expect_filetype('filetype detection:ON plugin:ON indent:OFF |')
  83. end)
  84. end)
  85. describe('syntax', function()
  86. it('enabled by `-u NORC`', function()
  87. clear('-u', 'NORC')
  88. eq(1, eval('g:syntax_on'))
  89. end)
  90. it('disabled by `-u NONE`', function()
  91. clear('-u', 'NONE')
  92. eq(0, eval('exists("g:syntax_on")'))
  93. end)
  94. it('`:syntax off` stays off', function()
  95. -- early
  96. clear('-u', 'NORC', '--cmd', 'syntax off')
  97. eq(0, eval('exists("g:syntax_on")'))
  98. -- late
  99. clear('-u', 'NORC', '-c', 'syntax off')
  100. eq(0, eval('exists("g:syntax_on")'))
  101. end)
  102. it('":if 0|syntax on|endif" does not affect default #8728', function()
  103. clear('-u', 'NORC', '--cmd', ':if 0|syntax on|endif')
  104. eq(1, eval('exists("g:syntax_on")'))
  105. clear('-u', 'NORC', '--cmd', ':if 0|syntax off|endif')
  106. eq(1, eval('exists("g:syntax_on")'))
  107. end)
  108. end)
  109. describe("'fillchars'", function()
  110. it('vert/fold flags', function()
  111. clear()
  112. local screen = Screen.new(50, 5)
  113. command('set laststatus=0')
  114. insert([[
  115. 1
  116. 2
  117. 3
  118. 4]])
  119. command('normal! ggjzfj')
  120. command('vsp')
  121. screen:expect([[
  122. 1 │1 |
  123. {13:^+-- 2 lines: 2··········}│{13:+-- 2 lines: 2·········}|
  124. 4 │4 |
  125. {1:~ }│{1:~ }|
  126. |
  127. ]])
  128. -- ambiwidth=double defaults to single-byte fillchars.
  129. command('set ambiwidth=double')
  130. screen:expect([[
  131. 1 |1 |
  132. {13:^+-- 2 lines: 2----------}|{13:+-- 2 lines: 2---------}|
  133. 4 |4 |
  134. {1:~ }|{1:~ }|
  135. |
  136. ]])
  137. -- change "vert" character to single-cell
  138. fn.setcellwidths({ { 0x2502, 0x2502, 1 } })
  139. screen:expect([[
  140. 1 │1 |
  141. {13:^+-- 2 lines: 2----------}│{13:+-- 2 lines: 2---------}|
  142. 4 │4 |
  143. {1:~ }│{1:~ }|
  144. |
  145. ]])
  146. -- change "vert" character to double-cell
  147. fn.setcellwidths({ { 0x2502, 0x2502, 2 } })
  148. screen:expect([[
  149. 1 |1 |
  150. {13:^+-- 2 lines: 2----------}|{13:+-- 2 lines: 2---------}|
  151. 4 |4 |
  152. {1:~ }|{1:~ }|
  153. |
  154. ]])
  155. -- "vert" character should still default to single-byte fillchars because of setcellwidths().
  156. command('set ambiwidth=single')
  157. screen:expect([[
  158. 1 |1 |
  159. {13:^+-- 2 lines: 2··········}|{13:+-- 2 lines: 2·········}|
  160. 4 |4 |
  161. {1:~ }|{1:~ }|
  162. |
  163. ]])
  164. end)
  165. end)
  166. it("'shadafile' ('viminfofile')", function()
  167. local env = {
  168. XDG_DATA_HOME = 'Xtest-userdata',
  169. XDG_STATE_HOME = 'Xtest-userstate',
  170. XDG_CONFIG_HOME = 'Xtest-userconfig',
  171. }
  172. finally(function()
  173. command('set shadafile=NONE') -- Avoid writing shada file on exit
  174. rmdir('Xtest-userstate')
  175. os.remove('Xtest-foo')
  176. end)
  177. clear { args = {}, args_rm = { '-i' }, env = env }
  178. -- Default 'shadafile' is empty.
  179. -- This means use the default location. :help shada-file-name
  180. eq('', api.nvim_get_option_value('shadafile', {}))
  181. eq('', api.nvim_get_option_value('viminfofile', {}))
  182. -- Handles viminfo/viminfofile as alias for shada/shadafile.
  183. eq('\n shadafile=', eval('execute("set shadafile?")'))
  184. eq('\n shadafile=', eval('execute("set viminfofile?")'))
  185. eq("\n shada=!,'100,<50,s10,h", eval('execute("set shada?")'))
  186. eq("\n shada=!,'100,<50,s10,h", eval('execute("set viminfo?")'))
  187. -- Check that shada data (such as v:oldfiles) is saved/restored.
  188. command('edit Xtest-foo')
  189. command('write')
  190. local f = eval('fnamemodify(@%,":p")')
  191. assert(string.len(f) > 3)
  192. expect_exit(command, 'qall')
  193. clear { args = {}, args_rm = { '-i' }, env = env }
  194. eq({ f }, eval('v:oldfiles'))
  195. end)
  196. it("'packpath'", function()
  197. clear {
  198. args_rm = { 'runtimepath' },
  199. }
  200. -- Defaults to &runtimepath.
  201. eq(api.nvim_get_option_value('runtimepath', {}), api.nvim_get_option_value('packpath', {}))
  202. -- Does not follow modifications to runtimepath.
  203. command('set runtimepath+=foo')
  204. neq(api.nvim_get_option_value('runtimepath', {}), api.nvim_get_option_value('packpath', {}))
  205. command('set packpath+=foo')
  206. eq(api.nvim_get_option_value('runtimepath', {}), api.nvim_get_option_value('packpath', {}))
  207. end)
  208. it('v:progpath is set to the absolute path', function()
  209. clear()
  210. eq(eval("fnamemodify(v:progpath, ':p')"), eval('v:progpath'))
  211. end)
  212. describe('$NVIM_LOG_FILE', function()
  213. local xdgdir = 'Xtest-startup-xdg-logpath'
  214. local xdgstatedir = is_os('win') and xdgdir .. '/nvim-data' or xdgdir .. '/nvim'
  215. after_each(function()
  216. os.remove('Xtest-logpath')
  217. rmdir(xdgdir)
  218. end)
  219. it('is used if expansion succeeds', function()
  220. clear({ env = {
  221. NVIM_LOG_FILE = 'Xtest-logpath',
  222. } })
  223. eq('Xtest-logpath', eval('$NVIM_LOG_FILE'))
  224. end)
  225. it('defaults to stdpath("log")/log if empty', function()
  226. eq(true, mkdir(xdgdir) and mkdir(xdgstatedir))
  227. clear({
  228. env = {
  229. XDG_STATE_HOME = xdgdir,
  230. NVIM_LOG_FILE = '', -- Empty is invalid.
  231. },
  232. })
  233. eq(xdgstatedir .. '/log', t.fix_slashes(eval('$NVIM_LOG_FILE')))
  234. end)
  235. it('defaults to stdpath("log")/log if invalid', function()
  236. eq(true, mkdir(xdgdir) and mkdir(xdgstatedir))
  237. clear({
  238. env = {
  239. XDG_STATE_HOME = xdgdir,
  240. NVIM_LOG_FILE = '.', -- Any directory is invalid.
  241. },
  242. })
  243. eq(xdgstatedir .. '/log', t.fix_slashes(eval('$NVIM_LOG_FILE')))
  244. -- Avoid "failed to open $NVIM_LOG_FILE" noise in test output.
  245. expect_exit(command, 'qall!')
  246. end)
  247. end)
  248. end)
  249. describe('XDG defaults', function()
  250. -- Need separate describe() blocks to not run clear() twice.
  251. -- Do not put before_each() here for the same reasons.
  252. after_each(function()
  253. check_close()
  254. os.remove(testlog)
  255. end)
  256. it("&runtimepath data-dir matches stdpath('data') #9910", function()
  257. clear()
  258. local rtp = eval('split(&runtimepath, ",")')
  259. local rv = {}
  260. local expected = (
  261. is_os('win') and { [[\nvim-data\site]], [[\nvim-data\site\after]] }
  262. or { '/nvim/site', '/nvim/site/after' }
  263. )
  264. for _, v in ipairs(rtp) do
  265. local m = string.match(v, [=[[/\]nvim[^/\]*[/\]site.*$]=])
  266. if m and not tbl_contains(rv, m) then
  267. table.insert(rv, m)
  268. end
  269. end
  270. eq(expected, rv)
  271. end)
  272. describe('with empty/broken environment', function()
  273. it('sets correct defaults', function()
  274. clear({
  275. env = {
  276. XDG_CONFIG_HOME = nil,
  277. XDG_DATA_HOME = nil,
  278. XDG_CACHE_HOME = nil,
  279. XDG_STATE_HOME = nil,
  280. XDG_RUNTIME_DIR = nil,
  281. XDG_CONFIG_DIRS = nil,
  282. XDG_DATA_DIRS = nil,
  283. LOCALAPPDATA = nil,
  284. HOMEPATH = nil,
  285. HOMEDRIVE = nil,
  286. HOME = nil,
  287. TEMP = nil,
  288. VIMRUNTIME = nil,
  289. USER = nil,
  290. },
  291. })
  292. eq('.', api.nvim_get_option_value('backupdir', {}))
  293. eq('.', api.nvim_get_option_value('viewdir', {}))
  294. eq('.', api.nvim_get_option_value('directory', {}))
  295. eq('.', api.nvim_get_option_value('undodir', {}))
  296. ok((fn.tempname()):len() > 4)
  297. end)
  298. end)
  299. local function vimruntime_and_libdir()
  300. local vimruntime = eval('$VIMRUNTIME')
  301. -- libdir is hard to calculate reliably across various ci platforms
  302. -- local libdir = string.gsub(vimruntime, "share/nvim/runtime$", "lib/nvim")
  303. local libdir = api.nvim__get_lib_dir()
  304. return vimruntime, libdir
  305. end
  306. local env_sep = is_os('win') and ';' or ':'
  307. local data_dir = is_os('win') and 'nvim-data' or 'nvim'
  308. local state_dir = is_os('win') and 'nvim-data' or 'nvim'
  309. local root_path = is_os('win') and 'C:' or ''
  310. describe('with too long XDG vars', function()
  311. before_each(function()
  312. clear({
  313. -- Ensure valid --listen address despite broken XDG vars (else Nvim won't start).
  314. args = { '--listen', is_os('win') and '' or t.tmpname(false) },
  315. args_rm = { 'runtimepath' },
  316. env = {
  317. NVIM_LOG_FILE = testlog,
  318. XDG_CONFIG_HOME = (root_path .. ('/x'):rep(4096)),
  319. XDG_CONFIG_DIRS = (root_path .. ('/a'):rep(2048) .. env_sep .. root_path .. ('/b'):rep(
  320. 2048
  321. ) .. (env_sep .. root_path .. '/c'):rep(512)),
  322. XDG_DATA_HOME = (root_path .. ('/X'):rep(4096)),
  323. XDG_RUNTIME_DIR = (root_path .. ('/X'):rep(4096)),
  324. XDG_STATE_HOME = (root_path .. ('/X'):rep(4096)),
  325. XDG_DATA_DIRS = (root_path .. ('/A'):rep(2048) .. env_sep .. root_path .. ('/B'):rep(
  326. 2048
  327. ) .. (env_sep .. root_path .. '/C'):rep(512)),
  328. },
  329. })
  330. end)
  331. it('are correctly set', function()
  332. if not is_os('win') then
  333. -- Broken XDG vars cause serverstart() to fail (except on Windows, where servernames are not
  334. -- informed by $XDG_STATE_HOME).
  335. t.matches('Failed to start server: no such file or directory', t.pcall_err(fn.serverstart))
  336. assert_log('Failed to start server: no such file or directory: /X/X/X', testlog, 10)
  337. end
  338. local vimruntime, libdir = vimruntime_and_libdir()
  339. eq(
  340. (
  341. t.fix_slashes(
  342. root_path
  343. .. ('/x'):rep(4096)
  344. .. '/nvim'
  345. .. ','
  346. .. root_path
  347. .. ('/a'):rep(2048)
  348. .. '/nvim'
  349. .. ','
  350. .. root_path
  351. .. ('/b'):rep(2048)
  352. .. '/nvim'
  353. .. (',' .. root_path .. '/c/nvim')
  354. .. ','
  355. .. root_path
  356. .. ('/X'):rep(4096)
  357. .. '/'
  358. .. data_dir
  359. .. '/site'
  360. .. ','
  361. .. root_path
  362. .. ('/A'):rep(2048)
  363. .. '/nvim/site'
  364. .. ','
  365. .. root_path
  366. .. ('/B'):rep(2048)
  367. .. '/nvim/site'
  368. .. (',' .. root_path .. '/C/nvim/site')
  369. .. ','
  370. .. vimruntime
  371. .. ','
  372. .. libdir
  373. .. (',' .. root_path .. '/C/nvim/site/after')
  374. .. ','
  375. .. root_path
  376. .. ('/B'):rep(2048)
  377. .. '/nvim/site/after'
  378. .. ','
  379. .. root_path
  380. .. ('/A'):rep(2048)
  381. .. '/nvim/site/after'
  382. .. ','
  383. .. root_path
  384. .. ('/X'):rep(4096)
  385. .. '/'
  386. .. data_dir
  387. .. '/site/after'
  388. .. (',' .. root_path .. '/c/nvim/after')
  389. .. ','
  390. .. root_path
  391. .. ('/b'):rep(2048)
  392. .. '/nvim/after'
  393. .. ','
  394. .. root_path
  395. .. ('/a'):rep(2048)
  396. .. '/nvim/after'
  397. .. ','
  398. .. root_path
  399. .. ('/x'):rep(4096)
  400. .. '/nvim/after'
  401. )
  402. ),
  403. t.fix_slashes(api.nvim_get_option_value('runtimepath', {}))
  404. )
  405. command('set runtimepath&')
  406. command('set backupdir&')
  407. command('set directory&')
  408. command('set undodir&')
  409. command('set viewdir&')
  410. eq(
  411. (
  412. t.fix_slashes(
  413. root_path
  414. .. ('/x'):rep(4096)
  415. .. '/nvim'
  416. .. ','
  417. .. root_path
  418. .. ('/a'):rep(2048)
  419. .. '/nvim'
  420. .. ','
  421. .. root_path
  422. .. ('/b'):rep(2048)
  423. .. '/nvim'
  424. .. (',' .. root_path .. '/c/nvim')
  425. .. ','
  426. .. root_path
  427. .. ('/X'):rep(4096)
  428. .. '/'
  429. .. data_dir
  430. .. '/site'
  431. .. ','
  432. .. root_path
  433. .. ('/A'):rep(2048)
  434. .. '/nvim/site'
  435. .. ','
  436. .. root_path
  437. .. ('/B'):rep(2048)
  438. .. '/nvim/site'
  439. .. (',' .. root_path .. '/C/nvim/site')
  440. .. ','
  441. .. vimruntime
  442. .. ','
  443. .. libdir
  444. .. (',' .. root_path .. '/C/nvim/site/after')
  445. .. ','
  446. .. root_path
  447. .. ('/B'):rep(2048)
  448. .. '/nvim/site/after'
  449. .. ','
  450. .. root_path
  451. .. ('/A'):rep(2048)
  452. .. '/nvim/site/after'
  453. .. ','
  454. .. root_path
  455. .. ('/X'):rep(4096)
  456. .. '/'
  457. .. data_dir
  458. .. '/site/after'
  459. .. (',' .. root_path .. '/c/nvim/after')
  460. .. ','
  461. .. root_path
  462. .. ('/b'):rep(2048)
  463. .. '/nvim/after'
  464. .. ','
  465. .. root_path
  466. .. ('/a'):rep(2048)
  467. .. '/nvim/after'
  468. .. ','
  469. .. root_path
  470. .. ('/x'):rep(4096)
  471. .. '/nvim/after'
  472. )
  473. ),
  474. t.fix_slashes(api.nvim_get_option_value('runtimepath', {}))
  475. )
  476. eq(
  477. '.,' .. root_path .. ('/X'):rep(4096) .. '/' .. state_dir .. '/backup//',
  478. t.fix_slashes(api.nvim_get_option_value('backupdir', {}))
  479. )
  480. eq(
  481. root_path .. ('/X'):rep(4096) .. '/' .. state_dir .. '/swap//',
  482. t.fix_slashes(api.nvim_get_option_value('directory', {}))
  483. )
  484. eq(
  485. root_path .. ('/X'):rep(4096) .. '/' .. state_dir .. '/undo//',
  486. t.fix_slashes(api.nvim_get_option_value('undodir', {}))
  487. )
  488. eq(
  489. root_path .. ('/X'):rep(4096) .. '/' .. state_dir .. '/view//',
  490. t.fix_slashes(api.nvim_get_option_value('viewdir', {}))
  491. )
  492. end)
  493. end)
  494. describe('with expandable XDG vars', function()
  495. before_each(function()
  496. clear({
  497. -- Ensure valid --listen address despite broken XDG vars (else Nvim won't start).
  498. args = { '--listen', is_os('win') and '' or t.tmpname(false) },
  499. args_rm = { 'runtimepath' },
  500. env = {
  501. NVIM_LOG_FILE = testlog,
  502. XDG_CONFIG_HOME = '$XDG_DATA_HOME',
  503. XDG_CONFIG_DIRS = '$XDG_DATA_DIRS',
  504. XDG_DATA_HOME = '$XDG_CONFIG_HOME',
  505. XDG_RUNTIME_DIR = '$XDG_RUNTIME_DIR',
  506. XDG_STATE_HOME = '$XDG_CONFIG_HOME',
  507. XDG_DATA_DIRS = '$XDG_CONFIG_DIRS',
  508. },
  509. })
  510. end)
  511. after_each(function()
  512. command('set shadafile=NONE') -- Avoid writing shada file on exit
  513. end)
  514. it('are not expanded', function()
  515. if not is_os('win') then
  516. -- Broken XDG vars cause serverstart() to fail (except on Windows, where servernames are not
  517. -- informed by $XDG_STATE_HOME).
  518. t.matches('Failed to start server: no such file or directory', t.pcall_err(fn.serverstart))
  519. assert_log(
  520. 'Failed to start server: no such file or directory: %$XDG_RUNTIME_DIR%/',
  521. testlog,
  522. 10
  523. )
  524. end
  525. local vimruntime, libdir = vimruntime_and_libdir()
  526. eq(
  527. (
  528. t.fix_slashes(
  529. '$XDG_DATA_HOME/nvim'
  530. .. ',$XDG_DATA_DIRS/nvim'
  531. .. ',$XDG_CONFIG_HOME/'
  532. .. data_dir
  533. .. '/site'
  534. .. ',$XDG_CONFIG_DIRS/nvim/site'
  535. .. ','
  536. .. vimruntime
  537. .. ','
  538. .. libdir
  539. .. ',$XDG_CONFIG_DIRS/nvim/site/after'
  540. .. ',$XDG_CONFIG_HOME/'
  541. .. data_dir
  542. .. '/site/after'
  543. .. ',$XDG_DATA_DIRS/nvim/after'
  544. .. ',$XDG_DATA_HOME/nvim/after'
  545. )
  546. ),
  547. t.fix_slashes(api.nvim_get_option_value('runtimepath', {}))
  548. )
  549. command('set runtimepath&')
  550. command('set backupdir&')
  551. command('set directory&')
  552. command('set undodir&')
  553. command('set viewdir&')
  554. eq(
  555. (
  556. t.fix_slashes(
  557. '$XDG_DATA_HOME/nvim'
  558. .. ',$XDG_DATA_DIRS/nvim'
  559. .. ',$XDG_CONFIG_HOME/'
  560. .. data_dir
  561. .. '/site'
  562. .. ',$XDG_CONFIG_DIRS/nvim/site'
  563. .. ','
  564. .. vimruntime
  565. .. ','
  566. .. libdir
  567. .. ',$XDG_CONFIG_DIRS/nvim/site/after'
  568. .. ',$XDG_CONFIG_HOME/'
  569. .. data_dir
  570. .. '/site/after'
  571. .. ',$XDG_DATA_DIRS/nvim/after'
  572. .. ',$XDG_DATA_HOME/nvim/after'
  573. )
  574. ),
  575. t.fix_slashes(api.nvim_get_option_value('runtimepath', {}))
  576. )
  577. eq(
  578. ('.,$XDG_CONFIG_HOME/' .. state_dir .. '/backup//'),
  579. t.fix_slashes(api.nvim_get_option_value('backupdir', {}))
  580. )
  581. eq(
  582. ('$XDG_CONFIG_HOME/' .. state_dir .. '/swap//'),
  583. t.fix_slashes(api.nvim_get_option_value('directory', {}))
  584. )
  585. eq(
  586. ('$XDG_CONFIG_HOME/' .. state_dir .. '/undo//'),
  587. t.fix_slashes(api.nvim_get_option_value('undodir', {}))
  588. )
  589. eq(
  590. ('$XDG_CONFIG_HOME/' .. state_dir .. '/view//'),
  591. t.fix_slashes(api.nvim_get_option_value('viewdir', {}))
  592. )
  593. command('set all&')
  594. eq(
  595. t.fix_slashes(
  596. '$XDG_DATA_HOME/nvim'
  597. .. ',$XDG_DATA_DIRS/nvim'
  598. .. ',$XDG_CONFIG_HOME/'
  599. .. data_dir
  600. .. '/site'
  601. .. ',$XDG_CONFIG_DIRS/nvim/site'
  602. .. ','
  603. .. vimruntime
  604. .. ','
  605. .. libdir
  606. .. ',$XDG_CONFIG_DIRS/nvim/site/after'
  607. .. ',$XDG_CONFIG_HOME/'
  608. .. data_dir
  609. .. '/site/after'
  610. .. ',$XDG_DATA_DIRS/nvim/after'
  611. .. ',$XDG_DATA_HOME/nvim/after'
  612. ),
  613. t.fix_slashes(api.nvim_get_option_value('runtimepath', {}))
  614. )
  615. eq(
  616. ('.,$XDG_CONFIG_HOME/' .. state_dir .. '/backup//'),
  617. t.fix_slashes(api.nvim_get_option_value('backupdir', {}))
  618. )
  619. eq(
  620. ('$XDG_CONFIG_HOME/' .. state_dir .. '/swap//'),
  621. t.fix_slashes(api.nvim_get_option_value('directory', {}))
  622. )
  623. eq(
  624. ('$XDG_CONFIG_HOME/' .. state_dir .. '/undo//'),
  625. t.fix_slashes(api.nvim_get_option_value('undodir', {}))
  626. )
  627. eq(
  628. ('$XDG_CONFIG_HOME/' .. state_dir .. '/view//'),
  629. t.fix_slashes(api.nvim_get_option_value('viewdir', {}))
  630. )
  631. eq(nil, (fn.tempname()):match('XDG_RUNTIME_DIR'))
  632. end)
  633. end)
  634. describe('with commas', function()
  635. before_each(function()
  636. clear({
  637. args_rm = { 'runtimepath' },
  638. env = {
  639. XDG_CONFIG_HOME = ', , ,',
  640. XDG_CONFIG_DIRS = ',-,-,' .. env_sep .. '-,-,-',
  641. XDG_DATA_HOME = ',=,=,',
  642. XDG_STATE_HOME = ',=,=,',
  643. XDG_DATA_DIRS = ',≡,≡,' .. env_sep .. '≡,≡,≡',
  644. },
  645. })
  646. end)
  647. it('are escaped properly', function()
  648. local vimruntime, libdir = vimruntime_and_libdir()
  649. local path_sep = is_os('win') and '\\' or '/'
  650. eq(
  651. (
  652. '\\, \\, \\,'
  653. .. path_sep
  654. .. 'nvim'
  655. .. ',\\,-\\,-\\,'
  656. .. path_sep
  657. .. 'nvim'
  658. .. ',-\\,-\\,-'
  659. .. path_sep
  660. .. 'nvim'
  661. .. ',\\,=\\,=\\,'
  662. .. path_sep
  663. .. data_dir
  664. .. path_sep
  665. .. 'site'
  666. .. ',\\,≡\\,≡\\,'
  667. .. path_sep
  668. .. 'nvim'
  669. .. path_sep
  670. .. 'site'
  671. .. ',≡\\,≡\\,≡'
  672. .. path_sep
  673. .. 'nvim'
  674. .. path_sep
  675. .. 'site'
  676. .. ','
  677. .. vimruntime
  678. .. ','
  679. .. libdir
  680. .. ',≡\\,≡\\,≡'
  681. .. path_sep
  682. .. 'nvim'
  683. .. path_sep
  684. .. 'site'
  685. .. path_sep
  686. .. 'after'
  687. .. ',\\,≡\\,≡\\,'
  688. .. path_sep
  689. .. 'nvim'
  690. .. path_sep
  691. .. 'site'
  692. .. path_sep
  693. .. 'after'
  694. .. ',\\,=\\,=\\,'
  695. .. path_sep
  696. .. data_dir
  697. .. path_sep
  698. .. 'site'
  699. .. path_sep
  700. .. 'after'
  701. .. ',-\\,-\\,-'
  702. .. path_sep
  703. .. 'nvim'
  704. .. path_sep
  705. .. 'after'
  706. .. ',\\,-\\,-\\,'
  707. .. path_sep
  708. .. 'nvim'
  709. .. path_sep
  710. .. 'after'
  711. .. ',\\, \\, \\,'
  712. .. path_sep
  713. .. 'nvim'
  714. .. path_sep
  715. .. 'after'
  716. ),
  717. api.nvim_get_option_value('runtimepath', {})
  718. )
  719. command('set runtimepath&')
  720. command('set backupdir&')
  721. command('set directory&')
  722. command('set undodir&')
  723. command('set viewdir&')
  724. eq(
  725. (
  726. '\\, \\, \\,'
  727. .. path_sep
  728. .. 'nvim'
  729. .. ',\\,-\\,-\\,'
  730. .. path_sep
  731. .. 'nvim'
  732. .. ',-\\,-\\,-'
  733. .. path_sep
  734. .. 'nvim'
  735. .. ',\\,=\\,=\\,'
  736. .. path_sep
  737. .. ''
  738. .. data_dir
  739. .. ''
  740. .. path_sep
  741. .. 'site'
  742. .. ',\\,≡\\,≡\\,'
  743. .. path_sep
  744. .. 'nvim'
  745. .. path_sep
  746. .. 'site'
  747. .. ',≡\\,≡\\,≡'
  748. .. path_sep
  749. .. 'nvim'
  750. .. path_sep
  751. .. 'site'
  752. .. ','
  753. .. vimruntime
  754. .. ','
  755. .. libdir
  756. .. ',≡\\,≡\\,≡'
  757. .. path_sep
  758. .. 'nvim'
  759. .. path_sep
  760. .. 'site'
  761. .. path_sep
  762. .. 'after'
  763. .. ',\\,≡\\,≡\\,'
  764. .. path_sep
  765. .. 'nvim'
  766. .. path_sep
  767. .. 'site'
  768. .. path_sep
  769. .. 'after'
  770. .. ',\\,=\\,=\\,'
  771. .. path_sep
  772. .. ''
  773. .. data_dir
  774. .. ''
  775. .. path_sep
  776. .. 'site'
  777. .. path_sep
  778. .. 'after'
  779. .. ',-\\,-\\,-'
  780. .. path_sep
  781. .. 'nvim'
  782. .. path_sep
  783. .. 'after'
  784. .. ',\\,-\\,-\\,'
  785. .. path_sep
  786. .. 'nvim'
  787. .. path_sep
  788. .. 'after'
  789. .. ',\\, \\, \\,'
  790. .. path_sep
  791. .. 'nvim'
  792. .. path_sep
  793. .. 'after'
  794. ),
  795. api.nvim_get_option_value('runtimepath', {})
  796. )
  797. eq(
  798. '.,\\,=\\,=\\,' .. path_sep .. state_dir .. '' .. path_sep .. 'backup' .. (path_sep):rep(2),
  799. api.nvim_get_option_value('backupdir', {})
  800. )
  801. eq(
  802. '\\,=\\,=\\,'
  803. .. path_sep
  804. .. ''
  805. .. state_dir
  806. .. ''
  807. .. path_sep
  808. .. 'swap'
  809. .. (path_sep):rep(2),
  810. api.nvim_get_option_value('directory', {})
  811. )
  812. eq(
  813. '\\,=\\,=\\,'
  814. .. path_sep
  815. .. ''
  816. .. state_dir
  817. .. ''
  818. .. path_sep
  819. .. 'undo'
  820. .. (path_sep):rep(2),
  821. api.nvim_get_option_value('undodir', {})
  822. )
  823. eq(
  824. '\\,=\\,=\\,'
  825. .. path_sep
  826. .. ''
  827. .. state_dir
  828. .. ''
  829. .. path_sep
  830. .. 'view'
  831. .. (path_sep):rep(2),
  832. api.nvim_get_option_value('viewdir', {})
  833. )
  834. end)
  835. end)
  836. end)
  837. describe('stdpath()', function()
  838. after_each(function()
  839. check_close()
  840. os.remove(testlog)
  841. end)
  842. -- Windows appends 'nvim-data' instead of just 'nvim' to prevent collisions
  843. -- due to XDG_CONFIG_HOME, XDG_DATA_HOME and XDG_STATE_HOME being the same.
  844. local function maybe_data(name)
  845. return is_os('win') and name .. '-data' or name
  846. end
  847. local datadir = maybe_data('nvim')
  848. local statedir = maybe_data('nvim')
  849. local env_sep = is_os('win') and ';' or ':'
  850. it('acceptance', function()
  851. clear() -- Do not explicitly set any env vars.
  852. eq('nvim', fn.fnamemodify(fn.stdpath('cache'), ':t'))
  853. eq('nvim', fn.fnamemodify(fn.stdpath('config'), ':t'))
  854. eq(datadir, fn.fnamemodify(fn.stdpath('data'), ':t'))
  855. eq(statedir, fn.fnamemodify(fn.stdpath('state'), ':t'))
  856. eq('table', type(fn.stdpath('config_dirs')))
  857. eq('table', type(fn.stdpath('data_dirs')))
  858. eq('string', type(fn.stdpath('run')))
  859. assert_alive() -- Check for crash. #8393
  860. end)
  861. it('$NVIM_APPNAME', function()
  862. local appname = 'NVIM_APPNAME_TEST' .. ('_'):rep(106)
  863. clear({ env = { NVIM_APPNAME = appname, NVIM_LOG_FILE = testlog } })
  864. eq(appname, fn.fnamemodify(fn.stdpath('config'), ':t'))
  865. eq(appname, fn.fnamemodify(fn.stdpath('cache'), ':t'))
  866. eq(maybe_data(appname), fn.fnamemodify(fn.stdpath('log'), ':t'))
  867. eq(maybe_data(appname), fn.fnamemodify(fn.stdpath('data'), ':t'))
  868. eq(maybe_data(appname), fn.fnamemodify(fn.stdpath('state'), ':t'))
  869. -- config_dirs and data_dirs are empty on windows, so don't check them on
  870. -- that platform
  871. if not is_os('win') then
  872. eq(appname, fn.fnamemodify(fn.stdpath('config_dirs')[1], ':t'))
  873. eq(appname, fn.fnamemodify(fn.stdpath('data_dirs')[1], ':t'))
  874. end
  875. assert_alive() -- Check for crash. #8393
  876. -- Check that Nvim rejects invalid APPNAMEs
  877. -- Call jobstart() and jobwait() in the same RPC request to reduce flakiness.
  878. local function test_appname(testAppname, expected_exitcode)
  879. local lua_code = string.format(
  880. [[
  881. local child = vim.fn.jobstart({ vim.v.progpath, '--clean', '--headless', '--listen', 'x', '+qall!' }, { env = { NVIM_APPNAME = %q } })
  882. return vim.fn.jobwait({ child }, %d)[1]
  883. ]],
  884. testAppname,
  885. 3000
  886. )
  887. eq(expected_exitcode, exec_lua(lua_code))
  888. end
  889. -- Invalid appnames:
  890. test_appname('a/../b', 1)
  891. test_appname('../a', 1)
  892. test_appname('a/..', 1)
  893. test_appname('..', 1)
  894. test_appname('.', 1)
  895. test_appname('/', 1)
  896. test_appname(is_os('win') and 'C:/a/b' or '/a/b', 1)
  897. -- Valid appnames:
  898. test_appname('a/b', 0)
  899. test_appname('a/b\\c', 0)
  900. end)
  901. it('$NVIM_APPNAME relative path', function()
  902. local tmpdir = t.tmpname(false)
  903. t.mkdir(tmpdir)
  904. clear({
  905. args_rm = { '--listen' },
  906. env = {
  907. NVIM_APPNAME = 'relative/appname',
  908. NVIM_LOG_FILE = testlog,
  909. TMPDIR = tmpdir,
  910. },
  911. })
  912. t.matches(vim.pesc(tmpdir), t.fix_slashes(fn.tempname()))
  913. t.assert_nolog('tempdir', testlog, 100)
  914. t.assert_nolog('TMPDIR', testlog, 100)
  915. t.matches([=[[/\\]relative%-appname.[^/\\]+]=], api.nvim_get_vvar('servername'))
  916. end)
  917. describe('returns a String', function()
  918. describe('with "config"', function()
  919. it('knows XDG_CONFIG_HOME', function()
  920. clear({
  921. env = {
  922. XDG_CONFIG_HOME = '/home/docwhat/.config',
  923. },
  924. })
  925. eq('/home/docwhat/.config/nvim', t.fix_slashes(fn.stdpath('config')))
  926. end)
  927. it('handles changes during runtime', function()
  928. clear({ env = {
  929. XDG_CONFIG_HOME = '/home/original',
  930. } })
  931. eq('/home/original/nvim', t.fix_slashes(fn.stdpath('config')))
  932. command("let $XDG_CONFIG_HOME='/home/new'")
  933. eq('/home/new/nvim', t.fix_slashes(fn.stdpath('config')))
  934. end)
  935. it("doesn't expand $VARIABLES", function()
  936. clear({
  937. env = {
  938. XDG_CONFIG_HOME = '$VARIABLES',
  939. VARIABLES = 'this-should-not-happen',
  940. },
  941. })
  942. eq('$VARIABLES/nvim', t.fix_slashes(fn.stdpath('config')))
  943. end)
  944. it("doesn't expand ~/", function()
  945. clear({ env = {
  946. XDG_CONFIG_HOME = '~/frobnitz',
  947. } })
  948. eq('~/frobnitz/nvim', t.fix_slashes(fn.stdpath('config')))
  949. end)
  950. end)
  951. describe('with "data"', function()
  952. it('knows XDG_DATA_HOME', function()
  953. clear({ env = {
  954. XDG_DATA_HOME = '/home/docwhat/.local',
  955. } })
  956. eq('/home/docwhat/.local/' .. datadir, t.fix_slashes(fn.stdpath('data')))
  957. end)
  958. it('handles changes during runtime', function()
  959. clear({ env = {
  960. XDG_DATA_HOME = '/home/original',
  961. } })
  962. eq('/home/original/' .. datadir, t.fix_slashes(fn.stdpath('data')))
  963. command("let $XDG_DATA_HOME='/home/new'")
  964. eq('/home/new/' .. datadir, t.fix_slashes(fn.stdpath('data')))
  965. end)
  966. it("doesn't expand $VARIABLES", function()
  967. clear({
  968. env = {
  969. XDG_DATA_HOME = '$VARIABLES',
  970. VARIABLES = 'this-should-not-happen',
  971. },
  972. })
  973. eq('$VARIABLES/' .. datadir, t.fix_slashes(fn.stdpath('data')))
  974. end)
  975. it("doesn't expand ~/", function()
  976. clear({ env = {
  977. XDG_DATA_HOME = '~/frobnitz',
  978. } })
  979. eq('~/frobnitz/' .. datadir, t.fix_slashes(fn.stdpath('data')))
  980. end)
  981. end)
  982. describe('with "state"', function()
  983. it('knows XDG_STATE_HOME', function()
  984. clear({
  985. env = {
  986. XDG_STATE_HOME = '/home/docwhat/.local',
  987. },
  988. })
  989. eq('/home/docwhat/.local/' .. statedir, t.fix_slashes(fn.stdpath('state')))
  990. end)
  991. it('handles changes during runtime', function()
  992. clear({ env = {
  993. XDG_STATE_HOME = '/home/original',
  994. } })
  995. eq('/home/original/' .. statedir, t.fix_slashes(fn.stdpath('state')))
  996. command("let $XDG_STATE_HOME='" .. '/home/new' .. "'")
  997. eq('/home/new/' .. statedir, t.fix_slashes(fn.stdpath('state')))
  998. end)
  999. it("doesn't expand $VARIABLES", function()
  1000. clear({
  1001. env = {
  1002. XDG_STATE_HOME = '$VARIABLES',
  1003. VARIABLES = 'this-should-not-happen',
  1004. },
  1005. })
  1006. eq('$VARIABLES/' .. statedir, t.fix_slashes(fn.stdpath('state')))
  1007. end)
  1008. it("doesn't expand ~/", function()
  1009. clear({ env = {
  1010. XDG_STATE_HOME = '~/frobnitz',
  1011. } })
  1012. eq('~/frobnitz/' .. statedir, t.fix_slashes(fn.stdpath('state')))
  1013. end)
  1014. end)
  1015. describe('with "cache"', function()
  1016. it('knows XDG_CACHE_HOME', function()
  1017. clear({
  1018. env = {
  1019. XDG_CACHE_HOME = '/home/docwhat/.cache',
  1020. },
  1021. })
  1022. eq('/home/docwhat/.cache/nvim', t.fix_slashes(fn.stdpath('cache')))
  1023. end)
  1024. it('handles changes during runtime', function()
  1025. clear({ env = {
  1026. XDG_CACHE_HOME = '/home/original',
  1027. } })
  1028. eq('/home/original/nvim', t.fix_slashes(fn.stdpath('cache')))
  1029. command("let $XDG_CACHE_HOME='" .. '/home/new' .. "'")
  1030. eq('/home/new/nvim', t.fix_slashes(fn.stdpath('cache')))
  1031. end)
  1032. it("doesn't expand $VARIABLES", function()
  1033. clear({
  1034. env = {
  1035. XDG_CACHE_HOME = '$VARIABLES',
  1036. VARIABLES = 'this-should-not-happen',
  1037. },
  1038. })
  1039. eq('$VARIABLES/nvim', t.fix_slashes(fn.stdpath('cache')))
  1040. end)
  1041. it("doesn't expand ~/", function()
  1042. clear({ env = {
  1043. XDG_CACHE_HOME = '~/frobnitz',
  1044. } })
  1045. eq('~/frobnitz/nvim', t.fix_slashes(fn.stdpath('cache')))
  1046. end)
  1047. end)
  1048. end)
  1049. describe('returns a List', function()
  1050. -- Some OS specific variables the system would have set.
  1051. local function base_env()
  1052. if is_os('win') then
  1053. return {
  1054. HOME = 'C:\\Users\\docwhat', -- technically, is not a usual PATH
  1055. HOMEDRIVE = 'C:',
  1056. HOMEPATH = '\\Users\\docwhat',
  1057. LOCALAPPDATA = 'C:\\Users\\docwhat\\AppData\\Local',
  1058. NVIM_LOG_FILE = testlog,
  1059. TEMP = 'C:\\Users\\docwhat\\AppData\\Local\\Temp',
  1060. TMPDIR = 'C:\\Users\\docwhat\\AppData\\Local\\Temp',
  1061. TMP = 'C:\\Users\\docwhat\\AppData\\Local\\Temp',
  1062. }
  1063. else
  1064. return {
  1065. HOME = '/home/docwhat',
  1066. HOMEDRIVE = 'HOMEDRIVE-should-be-ignored',
  1067. HOMEPATH = 'HOMEPATH-should-be-ignored',
  1068. LOCALAPPDATA = 'LOCALAPPDATA-should-be-ignored',
  1069. NVIM_LOG_FILE = testlog,
  1070. TEMP = 'TEMP-should-be-ignored',
  1071. TMPDIR = 'TMPDIR-should-be-ignored',
  1072. TMP = 'TMP-should-be-ignored',
  1073. }
  1074. end
  1075. end
  1076. local function set_paths_via_system(var_name, paths)
  1077. local env = base_env()
  1078. env[var_name] = table.concat(paths, env_sep)
  1079. clear({ env = env })
  1080. end
  1081. local function set_paths_at_runtime(var_name, paths)
  1082. clear({ env = base_env() })
  1083. api.nvim_set_var('env_val', table.concat(paths, env_sep))
  1084. command(('let $%s=g:env_val'):format(var_name))
  1085. end
  1086. local function behaves_like_dir_list_env(msg, stdpath_arg, env_var_name, paths, expected_paths)
  1087. describe(msg, function()
  1088. it('set via system', function()
  1089. set_paths_via_system(env_var_name, paths)
  1090. eq(expected_paths, t.fix_slashes(fn.stdpath(stdpath_arg)))
  1091. if not is_os('win') then
  1092. assert_log('$TMPDIR tempdir not a directory.*TMPDIR%-should%-be%-ignored', testlog, 100)
  1093. end
  1094. end)
  1095. it('set at runtime', function()
  1096. set_paths_at_runtime(env_var_name, paths)
  1097. eq(expected_paths, t.fix_slashes(fn.stdpath(stdpath_arg)))
  1098. if not is_os('win') then
  1099. assert_log('$TMPDIR tempdir not a directory.*TMPDIR%-should%-be%-ignored', testlog, 100)
  1100. end
  1101. end)
  1102. end)
  1103. end
  1104. describe('with "config_dirs"', function()
  1105. behaves_like_dir_list_env(
  1106. 'handles XDG_CONFIG_DIRS with one path',
  1107. 'config_dirs',
  1108. 'XDG_CONFIG_DIRS',
  1109. {
  1110. t.fix_slashes('/home/docwhat/.config'),
  1111. },
  1112. {
  1113. t.fix_slashes('/home/docwhat/.config/nvim'),
  1114. }
  1115. )
  1116. behaves_like_dir_list_env(
  1117. 'handles XDG_CONFIG_DIRS with two paths',
  1118. 'config_dirs',
  1119. 'XDG_CONFIG_DIRS',
  1120. {
  1121. t.fix_slashes('/home/docwhat/.config'),
  1122. t.fix_slashes('/etc/config'),
  1123. },
  1124. {
  1125. t.fix_slashes('/home/docwhat/.config/nvim'),
  1126. t.fix_slashes('/etc/config/nvim'),
  1127. }
  1128. )
  1129. behaves_like_dir_list_env(
  1130. "doesn't expand $VAR and $IBLES",
  1131. 'config_dirs',
  1132. 'XDG_CONFIG_DIRS',
  1133. { '$HOME', '$TMP' },
  1134. {
  1135. t.fix_slashes('$HOME/nvim'),
  1136. t.fix_slashes('$TMP/nvim'),
  1137. }
  1138. )
  1139. behaves_like_dir_list_env("doesn't expand ~/", 'config_dirs', 'XDG_CONFIG_DIRS', {
  1140. t.fix_slashes('~/.oldconfig'),
  1141. t.fix_slashes('~/.olderconfig'),
  1142. }, {
  1143. t.fix_slashes('~/.oldconfig/nvim'),
  1144. t.fix_slashes('~/.olderconfig/nvim'),
  1145. })
  1146. end)
  1147. describe('with "data_dirs"', function()
  1148. behaves_like_dir_list_env('knows XDG_DATA_DIRS with one path', 'data_dirs', 'XDG_DATA_DIRS', {
  1149. t.fix_slashes('/home/docwhat/.data'),
  1150. }, {
  1151. t.fix_slashes('/home/docwhat/.data/nvim'),
  1152. })
  1153. behaves_like_dir_list_env(
  1154. 'knows XDG_DATA_DIRS with two paths',
  1155. 'data_dirs',
  1156. 'XDG_DATA_DIRS',
  1157. {
  1158. t.fix_slashes('/home/docwhat/.data'),
  1159. t.fix_slashes('/etc/local'),
  1160. },
  1161. {
  1162. t.fix_slashes('/home/docwhat/.data/nvim'),
  1163. t.fix_slashes('/etc/local/nvim'),
  1164. }
  1165. )
  1166. behaves_like_dir_list_env(
  1167. "doesn't expand $VAR and $IBLES",
  1168. 'data_dirs',
  1169. 'XDG_DATA_DIRS',
  1170. { '$HOME', '$TMP' },
  1171. {
  1172. t.fix_slashes('$HOME/nvim'),
  1173. t.fix_slashes('$TMP/nvim'),
  1174. }
  1175. )
  1176. behaves_like_dir_list_env("doesn't expand ~/", 'data_dirs', 'XDG_DATA_DIRS', {
  1177. t.fix_slashes('~/.oldconfig'),
  1178. t.fix_slashes('~/.olderconfig'),
  1179. }, {
  1180. t.fix_slashes('~/.oldconfig/nvim'),
  1181. t.fix_slashes('~/.olderconfig/nvim'),
  1182. })
  1183. end)
  1184. end)
  1185. describe('errors', function()
  1186. before_each(clear)
  1187. it('on unknown strings', function()
  1188. eq('Vim(call):E6100: "capybara" is not a valid stdpath', exc_exec('call stdpath("capybara")'))
  1189. eq('Vim(call):E6100: "" is not a valid stdpath', exc_exec('call stdpath("")'))
  1190. eq('Vim(call):E6100: "23" is not a valid stdpath', exc_exec('call stdpath(23)'))
  1191. end)
  1192. it('on non-strings', function()
  1193. eq('Vim(call):E731: Using a Dictionary as a String', exc_exec('call stdpath({"eris": 23})'))
  1194. eq('Vim(call):E730: Using a List as a String', exc_exec('call stdpath([23])'))
  1195. end)
  1196. end)
  1197. end)