defaults_spec.lua 39 KB

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