defaults_spec.lua 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. local helpers = require('test.functional.helpers')(after_each)
  2. local Screen = require('test.functional.ui.screen')
  3. local meths = helpers.meths
  4. local command = helpers.command
  5. local clear = helpers.clear
  6. local exc_exec = helpers.exc_exec
  7. local eval = helpers.eval
  8. local eq = helpers.eq
  9. local funcs = helpers.funcs
  10. local insert = helpers.insert
  11. local iswin = helpers.iswin
  12. local neq = helpers.neq
  13. local mkdir = helpers.mkdir
  14. local rmdir = helpers.rmdir
  15. local alter_slashes = helpers.alter_slashes
  16. describe('startup defaults', function()
  17. describe(':filetype', function()
  18. local function expect_filetype(expected)
  19. local screen = Screen.new(50, 4)
  20. screen:attach()
  21. command('filetype')
  22. screen:expect([[
  23. ^ |
  24. ~ |
  25. ~ |
  26. ]]..expected
  27. )
  28. end
  29. it('all ON after `-u NORC`', function()
  30. clear('-u', 'NORC')
  31. expect_filetype(
  32. 'filetype detection:ON plugin:ON indent:ON |')
  33. end)
  34. it('all ON after `:syntax …` #7765', function()
  35. clear('-u', 'NORC', '--cmd', 'syntax on')
  36. expect_filetype(
  37. 'filetype detection:ON plugin:ON indent:ON |')
  38. clear('-u', 'NORC', '--cmd', 'syntax off')
  39. expect_filetype(
  40. 'filetype detection:ON plugin:ON indent:ON |')
  41. end)
  42. it('all OFF after `-u NONE`', function()
  43. clear('-u', 'NONE')
  44. expect_filetype(
  45. 'filetype detection:OFF plugin:OFF indent:OFF |')
  46. end)
  47. it('explicit OFF stays OFF', function()
  48. clear('-u', 'NORC', '--cmd',
  49. 'syntax off | filetype off | filetype plugin indent off')
  50. expect_filetype(
  51. 'filetype detection:OFF plugin:OFF indent:OFF |')
  52. clear('-u', 'NORC', '--cmd', 'syntax off | filetype plugin indent off')
  53. expect_filetype(
  54. 'filetype detection:ON plugin:OFF indent:OFF |')
  55. clear('-u', 'NORC', '--cmd', 'filetype indent off')
  56. expect_filetype(
  57. 'filetype detection:ON plugin:ON indent:OFF |')
  58. clear('-u', 'NORC', '--cmd', 'syntax off | filetype off')
  59. expect_filetype(
  60. 'filetype detection:OFF plugin:(on) indent:(on) |')
  61. -- Swap the order.
  62. clear('-u', 'NORC', '--cmd', 'filetype off | syntax off')
  63. expect_filetype(
  64. '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(
  71. 'filetype detection:ON plugin:ON indent:ON |')
  72. clear('-u', 'NORC', '--cmd', 'filetype plugin on')
  73. expect_filetype(
  74. 'filetype detection:ON plugin:ON indent:ON |')
  75. clear('-u', 'NORC', '--cmd', 'filetype indent on')
  76. expect_filetype(
  77. 'filetype detection:ON plugin:ON indent:ON |')
  78. end)
  79. it('late `:filetype … off` stays OFF', function()
  80. clear('-u', 'NORC', '-c', 'filetype off')
  81. expect_filetype(
  82. 'filetype detection:OFF plugin:(on) indent:(on) |')
  83. clear('-u', 'NORC', '-c', 'filetype plugin off')
  84. expect_filetype(
  85. 'filetype detection:ON plugin:OFF indent:ON |')
  86. clear('-u', 'NORC', '-c', 'filetype indent off')
  87. expect_filetype(
  88. 'filetype detection:ON plugin:ON indent:OFF |')
  89. end)
  90. end)
  91. describe('syntax', function()
  92. it('enabled by `-u NORC`', function()
  93. clear('-u', 'NORC')
  94. eq(1, eval('g:syntax_on'))
  95. end)
  96. it('disabled by `-u NONE`', function()
  97. clear('-u', 'NONE')
  98. eq(0, eval('exists("g:syntax_on")'))
  99. end)
  100. it('`:syntax off` stays off', function()
  101. -- early
  102. clear('-u', 'NORC', '--cmd', 'syntax off')
  103. eq(0, eval('exists("g:syntax_on")'))
  104. -- late
  105. clear('-u', 'NORC', '-c', 'syntax off')
  106. eq(0, eval('exists("g:syntax_on")'))
  107. end)
  108. it('":if 0|syntax on|endif" does not affect default #8728', function()
  109. clear('-u', 'NORC', '--cmd', ':if 0|syntax on|endif')
  110. eq(1, eval('exists("g:syntax_on")'))
  111. clear('-u', 'NORC', '--cmd', ':if 0|syntax off|endif')
  112. eq(1, eval('exists("g:syntax_on")'))
  113. end)
  114. end)
  115. describe("'fillchars'", function()
  116. it('vert/fold flags', function()
  117. clear()
  118. local screen = Screen.new(50, 5)
  119. screen:attach()
  120. command('set laststatus=0')
  121. insert([[
  122. 1
  123. 2
  124. 3
  125. 4]])
  126. command('normal! ggjzfj')
  127. command('vsp')
  128. screen:expect([[
  129. 1 │1 |
  130. ^+-- 2 lines: 2··········│+-- 2 lines: 2·········|
  131. 4 │4 |
  132. ~ │~ |
  133. |
  134. ]])
  135. -- ambiwidth=double defaults to single-byte fillchars.
  136. command('set ambiwidth=double')
  137. screen:expect([[
  138. 1 |1 |
  139. ^+-- 2 lines: 2----------|+-- 2 lines: 2---------|
  140. 4 |4 |
  141. ~ |~ |
  142. |
  143. ]])
  144. end)
  145. end)
  146. describe("'packpath'", function()
  147. it('defaults to &runtimepath', function()
  148. eq(meths.get_option('runtimepath'), meths.get_option('packpath'))
  149. end)
  150. it('does not follow modifications to runtimepath', function()
  151. meths.command('set runtimepath+=foo')
  152. neq(meths.get_option('runtimepath'), meths.get_option('packpath'))
  153. meths.command('set packpath+=foo')
  154. eq(meths.get_option('runtimepath'), meths.get_option('packpath'))
  155. end)
  156. end)
  157. it('v:progpath is set to the absolute path', function()
  158. eq(eval("fnamemodify(v:progpath, ':p')"), eval('v:progpath'))
  159. end)
  160. describe('$NVIM_LOG_FILE', function()
  161. local datasubdir = iswin() and 'nvim-data' or 'nvim'
  162. local xdgdir = 'Xtest-startup-xdg-logpath'
  163. local xdgdatadir = xdgdir..'/'..datasubdir
  164. after_each(function()
  165. os.remove('Xtest-logpath')
  166. rmdir(xdgdir)
  167. end)
  168. it('is used if expansion succeeds', function()
  169. clear({env={
  170. NVIM_LOG_FILE='Xtest-logpath',
  171. }})
  172. eq('Xtest-logpath', eval('$NVIM_LOG_FILE'))
  173. end)
  174. it('defaults to stdpath("data")/log if empty', function()
  175. eq(true, mkdir(xdgdir) and mkdir(xdgdatadir))
  176. clear({env={
  177. XDG_DATA_HOME=xdgdir,
  178. NVIM_LOG_FILE='', -- Empty is invalid.
  179. }})
  180. -- server_start() calls ELOG, which tickles log_path_init().
  181. pcall(command, 'call serverstart(serverlist()[0])')
  182. eq(xdgdir..'/'..datasubdir..'/log', string.gsub(eval('$NVIM_LOG_FILE'), '\\', '/'))
  183. end)
  184. it('defaults to stdpath("data")/log if invalid', function()
  185. eq(true, mkdir(xdgdir) and mkdir(xdgdatadir))
  186. clear({env={
  187. XDG_DATA_HOME=xdgdir,
  188. NVIM_LOG_FILE='.', -- Any directory is invalid.
  189. }})
  190. -- server_start() calls ELOG, which tickles log_path_init().
  191. pcall(command, 'call serverstart(serverlist()[0])')
  192. eq(xdgdir..'/'..datasubdir..'/log', string.gsub(eval('$NVIM_LOG_FILE'), '\\', '/'))
  193. end)
  194. it('defaults to .nvimlog if stdpath("data") is invalid', function()
  195. clear({env={
  196. XDG_DATA_HOME='Xtest-missing-xdg-dir',
  197. NVIM_LOG_FILE='.', -- Any directory is invalid.
  198. }})
  199. -- server_start() calls ELOG, which tickles log_path_init().
  200. pcall(command, 'call serverstart(serverlist()[0])')
  201. eq('.nvimlog', eval('$NVIM_LOG_FILE'))
  202. end)
  203. end)
  204. end)
  205. describe('XDG-based defaults', function()
  206. -- Need separate describe() blocks to not run clear() twice.
  207. -- Do not put before_each() here for the same reasons.
  208. describe('with empty/broken environment', function()
  209. it('sets correct defaults', function()
  210. clear({env={
  211. XDG_CONFIG_HOME=nil,
  212. XDG_DATA_HOME=nil,
  213. XDG_CACHE_HOME=nil,
  214. XDG_RUNTIME_DIR=nil,
  215. XDG_CONFIG_DIRS=nil,
  216. XDG_DATA_DIRS=nil,
  217. LOCALAPPDATA=nil,
  218. HOMEPATH=nil,
  219. HOMEDRIVE=nil,
  220. HOME=nil,
  221. TEMP=nil,
  222. VIMRUNTIME=nil,
  223. USER=nil,
  224. }})
  225. eq('.', meths.get_option('backupdir'))
  226. eq('.', meths.get_option('viewdir'))
  227. eq('.', meths.get_option('directory'))
  228. eq('.', meths.get_option('undodir'))
  229. end)
  230. end)
  231. -- TODO(jkeyes): tests below fail on win32 because of path separator.
  232. if helpers.pending_win32(pending) then return end
  233. describe('with too long XDG variables', function()
  234. before_each(function()
  235. clear({env={
  236. XDG_CONFIG_HOME=('/x'):rep(4096),
  237. XDG_CONFIG_DIRS=(('/a'):rep(2048)
  238. .. ':' .. ('/b'):rep(2048)
  239. .. (':/c'):rep(512)),
  240. XDG_DATA_HOME=('/X'):rep(4096),
  241. XDG_DATA_DIRS=(('/A'):rep(2048)
  242. .. ':' .. ('/B'):rep(2048)
  243. .. (':/C'):rep(512)),
  244. }})
  245. end)
  246. it('are correctly set', function()
  247. eq((('/x'):rep(4096) .. '/nvim'
  248. .. ',' .. ('/a'):rep(2048) .. '/nvim'
  249. .. ',' .. ('/b'):rep(2048) .. '/nvim'
  250. .. (',' .. '/c/nvim'):rep(512)
  251. .. ',' .. ('/X'):rep(4096) .. '/nvim/site'
  252. .. ',' .. ('/A'):rep(2048) .. '/nvim/site'
  253. .. ',' .. ('/B'):rep(2048) .. '/nvim/site'
  254. .. (',' .. '/C/nvim/site'):rep(512)
  255. .. ',' .. eval('$VIMRUNTIME')
  256. .. (',' .. '/C/nvim/site/after'):rep(512)
  257. .. ',' .. ('/B'):rep(2048) .. '/nvim/site/after'
  258. .. ',' .. ('/A'):rep(2048) .. '/nvim/site/after'
  259. .. ',' .. ('/X'):rep(4096) .. '/nvim/site/after'
  260. .. (',' .. '/c/nvim/after'):rep(512)
  261. .. ',' .. ('/b'):rep(2048) .. '/nvim/after'
  262. .. ',' .. ('/a'):rep(2048) .. '/nvim/after'
  263. .. ',' .. ('/x'):rep(4096) .. '/nvim/after'
  264. ), meths.get_option('runtimepath'))
  265. meths.command('set runtimepath&')
  266. meths.command('set backupdir&')
  267. meths.command('set directory&')
  268. meths.command('set undodir&')
  269. meths.command('set viewdir&')
  270. eq((('/x'):rep(4096) .. '/nvim'
  271. .. ',' .. ('/a'):rep(2048) .. '/nvim'
  272. .. ',' .. ('/b'):rep(2048) .. '/nvim'
  273. .. (',' .. '/c/nvim'):rep(512)
  274. .. ',' .. ('/X'):rep(4096) .. '/nvim/site'
  275. .. ',' .. ('/A'):rep(2048) .. '/nvim/site'
  276. .. ',' .. ('/B'):rep(2048) .. '/nvim/site'
  277. .. (',' .. '/C/nvim/site'):rep(512)
  278. .. ',' .. eval('$VIMRUNTIME')
  279. .. (',' .. '/C/nvim/site/after'):rep(512)
  280. .. ',' .. ('/B'):rep(2048) .. '/nvim/site/after'
  281. .. ',' .. ('/A'):rep(2048) .. '/nvim/site/after'
  282. .. ',' .. ('/X'):rep(4096) .. '/nvim/site/after'
  283. .. (',' .. '/c/nvim/after'):rep(512)
  284. .. ',' .. ('/b'):rep(2048) .. '/nvim/after'
  285. .. ',' .. ('/a'):rep(2048) .. '/nvim/after'
  286. .. ',' .. ('/x'):rep(4096) .. '/nvim/after'
  287. ), meths.get_option('runtimepath'))
  288. eq('.,' .. ('/X'):rep(4096) .. '/nvim/backup',
  289. meths.get_option('backupdir'))
  290. eq(('/X'):rep(4096) .. '/nvim/swap//', meths.get_option('directory'))
  291. eq(('/X'):rep(4096) .. '/nvim/undo', meths.get_option('undodir'))
  292. eq(('/X'):rep(4096) .. '/nvim/view', meths.get_option('viewdir'))
  293. end)
  294. end)
  295. describe('with XDG variables that can be expanded', function()
  296. before_each(function()
  297. clear({env={
  298. XDG_CONFIG_HOME='$XDG_DATA_HOME',
  299. XDG_CONFIG_DIRS='$XDG_DATA_DIRS',
  300. XDG_DATA_HOME='$XDG_CONFIG_HOME',
  301. XDG_DATA_DIRS='$XDG_CONFIG_DIRS',
  302. }})
  303. end)
  304. it('are not expanded', function()
  305. eq(('$XDG_DATA_HOME/nvim'
  306. .. ',$XDG_DATA_DIRS/nvim'
  307. .. ',$XDG_CONFIG_HOME/nvim/site'
  308. .. ',$XDG_CONFIG_DIRS/nvim/site'
  309. .. ',' .. eval('$VIMRUNTIME')
  310. .. ',$XDG_CONFIG_DIRS/nvim/site/after'
  311. .. ',$XDG_CONFIG_HOME/nvim/site/after'
  312. .. ',$XDG_DATA_DIRS/nvim/after'
  313. .. ',$XDG_DATA_HOME/nvim/after'
  314. ), meths.get_option('runtimepath'))
  315. meths.command('set runtimepath&')
  316. meths.command('set backupdir&')
  317. meths.command('set directory&')
  318. meths.command('set undodir&')
  319. meths.command('set viewdir&')
  320. eq(('$XDG_DATA_HOME/nvim'
  321. .. ',$XDG_DATA_DIRS/nvim'
  322. .. ',$XDG_CONFIG_HOME/nvim/site'
  323. .. ',$XDG_CONFIG_DIRS/nvim/site'
  324. .. ',' .. eval('$VIMRUNTIME')
  325. .. ',$XDG_CONFIG_DIRS/nvim/site/after'
  326. .. ',$XDG_CONFIG_HOME/nvim/site/after'
  327. .. ',$XDG_DATA_DIRS/nvim/after'
  328. .. ',$XDG_DATA_HOME/nvim/after'
  329. ), meths.get_option('runtimepath'))
  330. eq('.,$XDG_CONFIG_HOME/nvim/backup', meths.get_option('backupdir'))
  331. eq('$XDG_CONFIG_HOME/nvim/swap//', meths.get_option('directory'))
  332. eq('$XDG_CONFIG_HOME/nvim/undo', meths.get_option('undodir'))
  333. eq('$XDG_CONFIG_HOME/nvim/view', meths.get_option('viewdir'))
  334. meths.command('set all&')
  335. eq(('$XDG_DATA_HOME/nvim'
  336. .. ',$XDG_DATA_DIRS/nvim'
  337. .. ',$XDG_CONFIG_HOME/nvim/site'
  338. .. ',$XDG_CONFIG_DIRS/nvim/site'
  339. .. ',' .. eval('$VIMRUNTIME')
  340. .. ',$XDG_CONFIG_DIRS/nvim/site/after'
  341. .. ',$XDG_CONFIG_HOME/nvim/site/after'
  342. .. ',$XDG_DATA_DIRS/nvim/after'
  343. .. ',$XDG_DATA_HOME/nvim/after'
  344. ), meths.get_option('runtimepath'))
  345. eq('.,$XDG_CONFIG_HOME/nvim/backup', meths.get_option('backupdir'))
  346. eq('$XDG_CONFIG_HOME/nvim/swap//', meths.get_option('directory'))
  347. eq('$XDG_CONFIG_HOME/nvim/undo', meths.get_option('undodir'))
  348. eq('$XDG_CONFIG_HOME/nvim/view', meths.get_option('viewdir'))
  349. end)
  350. end)
  351. describe('with commas', function()
  352. before_each(function()
  353. clear({env={
  354. XDG_CONFIG_HOME=', , ,',
  355. XDG_CONFIG_DIRS=',-,-,:-,-,-',
  356. XDG_DATA_HOME=',=,=,',
  357. XDG_DATA_DIRS=',≡,≡,:≡,≡,≡',
  358. }})
  359. end)
  360. it('are escaped properly', function()
  361. eq(('\\, \\, \\,/nvim'
  362. .. ',\\,-\\,-\\,/nvim'
  363. .. ',-\\,-\\,-/nvim'
  364. .. ',\\,=\\,=\\,/nvim/site'
  365. .. ',\\,≡\\,≡\\,/nvim/site'
  366. .. ',≡\\,≡\\,≡/nvim/site'
  367. .. ',' .. eval('$VIMRUNTIME')
  368. .. ',≡\\,≡\\,≡/nvim/site/after'
  369. .. ',\\,≡\\,≡\\,/nvim/site/after'
  370. .. ',\\,=\\,=\\,/nvim/site/after'
  371. .. ',-\\,-\\,-/nvim/after'
  372. .. ',\\,-\\,-\\,/nvim/after'
  373. .. ',\\, \\, \\,/nvim/after'
  374. ), meths.get_option('runtimepath'))
  375. meths.command('set runtimepath&')
  376. meths.command('set backupdir&')
  377. meths.command('set directory&')
  378. meths.command('set undodir&')
  379. meths.command('set viewdir&')
  380. eq(('\\, \\, \\,/nvim'
  381. .. ',\\,-\\,-\\,/nvim'
  382. .. ',-\\,-\\,-/nvim'
  383. .. ',\\,=\\,=\\,/nvim/site'
  384. .. ',\\,≡\\,≡\\,/nvim/site'
  385. .. ',≡\\,≡\\,≡/nvim/site'
  386. .. ',' .. eval('$VIMRUNTIME')
  387. .. ',≡\\,≡\\,≡/nvim/site/after'
  388. .. ',\\,≡\\,≡\\,/nvim/site/after'
  389. .. ',\\,=\\,=\\,/nvim/site/after'
  390. .. ',-\\,-\\,-/nvim/after'
  391. .. ',\\,-\\,-\\,/nvim/after'
  392. .. ',\\, \\, \\,/nvim/after'
  393. ), meths.get_option('runtimepath'))
  394. eq('.,\\,=\\,=\\,/nvim/backup', meths.get_option('backupdir'))
  395. eq('\\,=\\,=\\,/nvim/swap//', meths.get_option('directory'))
  396. eq('\\,=\\,=\\,/nvim/undo', meths.get_option('undodir'))
  397. eq('\\,=\\,=\\,/nvim/view', meths.get_option('viewdir'))
  398. end)
  399. end)
  400. end)
  401. describe('stdpath()', function()
  402. -- Windows appends 'nvim-data' instead of just 'nvim' to prevent collisions
  403. -- due to XDG_CONFIG_HOME and XDG_DATA_HOME being the same.
  404. local datadir = iswin() and 'nvim-data' or 'nvim'
  405. it('acceptance', function()
  406. clear() -- Do not explicitly set any env vars.
  407. eq('nvim', funcs.fnamemodify(funcs.stdpath('cache'), ':t'))
  408. eq('nvim', funcs.fnamemodify(funcs.stdpath('config'), ':t'))
  409. eq(datadir, funcs.fnamemodify(funcs.stdpath('data'), ':t'))
  410. eq('table', type(funcs.stdpath('config_dirs')))
  411. eq('table', type(funcs.stdpath('data_dirs')))
  412. -- Check for crash. #8393
  413. eq(2, eval('1+1'))
  414. end)
  415. context('returns a String', function()
  416. describe('with "config"' , function ()
  417. it('knows XDG_CONFIG_HOME', function()
  418. clear({env={
  419. XDG_CONFIG_HOME=alter_slashes('/home/docwhat/.config'),
  420. }})
  421. eq(alter_slashes('/home/docwhat/.config/nvim'), funcs.stdpath('config'))
  422. end)
  423. it('handles changes during runtime', function()
  424. clear({env={
  425. XDG_CONFIG_HOME=alter_slashes('/home/original'),
  426. }})
  427. eq(alter_slashes('/home/original/nvim'), funcs.stdpath('config'))
  428. command("let $XDG_CONFIG_HOME='"..alter_slashes('/home/new').."'")
  429. eq(alter_slashes('/home/new/nvim'), funcs.stdpath('config'))
  430. end)
  431. it("doesn't expand $VARIABLES", function()
  432. clear({env={
  433. XDG_CONFIG_HOME='$VARIABLES',
  434. VARIABLES='this-should-not-happen',
  435. }})
  436. eq(alter_slashes('$VARIABLES/nvim'), funcs.stdpath('config'))
  437. end)
  438. it("doesn't expand ~/", function()
  439. clear({env={
  440. XDG_CONFIG_HOME=alter_slashes('~/frobnitz'),
  441. }})
  442. eq(alter_slashes('~/frobnitz/nvim'), funcs.stdpath('config'))
  443. end)
  444. end)
  445. describe('with "data"' , function ()
  446. it('knows XDG_DATA_HOME', function()
  447. clear({env={
  448. XDG_DATA_HOME=alter_slashes('/home/docwhat/.local'),
  449. }})
  450. eq(alter_slashes('/home/docwhat/.local/'..datadir), funcs.stdpath('data'))
  451. end)
  452. it('handles changes during runtime', function()
  453. clear({env={
  454. XDG_DATA_HOME=alter_slashes('/home/original'),
  455. }})
  456. eq(alter_slashes('/home/original/'..datadir), funcs.stdpath('data'))
  457. command("let $XDG_DATA_HOME='"..alter_slashes('/home/new').."'")
  458. eq(alter_slashes('/home/new/'..datadir), funcs.stdpath('data'))
  459. end)
  460. it("doesn't expand $VARIABLES", function()
  461. clear({env={
  462. XDG_DATA_HOME='$VARIABLES',
  463. VARIABLES='this-should-not-happen',
  464. }})
  465. eq(alter_slashes('$VARIABLES/'..datadir), funcs.stdpath('data'))
  466. end)
  467. it("doesn't expand ~/", function()
  468. clear({env={
  469. XDG_DATA_HOME=alter_slashes('~/frobnitz'),
  470. }})
  471. eq(alter_slashes('~/frobnitz/'..datadir), funcs.stdpath('data'))
  472. end)
  473. end)
  474. describe('with "cache"' , function ()
  475. it('knows XDG_CACHE_HOME', function()
  476. clear({env={
  477. XDG_CACHE_HOME=alter_slashes('/home/docwhat/.cache'),
  478. }})
  479. eq(alter_slashes('/home/docwhat/.cache/nvim'), funcs.stdpath('cache'))
  480. end)
  481. it('handles changes during runtime', function()
  482. clear({env={
  483. XDG_CACHE_HOME=alter_slashes('/home/original'),
  484. }})
  485. eq(alter_slashes('/home/original/nvim'), funcs.stdpath('cache'))
  486. command("let $XDG_CACHE_HOME='"..alter_slashes('/home/new').."'")
  487. eq(alter_slashes('/home/new/nvim'), funcs.stdpath('cache'))
  488. end)
  489. it("doesn't expand $VARIABLES", function()
  490. clear({env={
  491. XDG_CACHE_HOME='$VARIABLES',
  492. VARIABLES='this-should-not-happen',
  493. }})
  494. eq(alter_slashes('$VARIABLES/nvim'), funcs.stdpath('cache'))
  495. end)
  496. it("doesn't expand ~/", function()
  497. clear({env={
  498. XDG_CACHE_HOME=alter_slashes('~/frobnitz'),
  499. }})
  500. eq(alter_slashes('~/frobnitz/nvim'), funcs.stdpath('cache'))
  501. end)
  502. end)
  503. end)
  504. context('returns a List', function()
  505. -- Some OS specific variables the system would have set.
  506. local function base_env()
  507. if iswin() then
  508. return {
  509. HOME='C:\\Users\\docwhat', -- technically, is not a usual PATH
  510. HOMEDRIVE='C:',
  511. HOMEPATH='\\Users\\docwhat',
  512. LOCALAPPDATA='C:\\Users\\docwhat\\AppData\\Local',
  513. TEMP='C:\\Users\\docwhat\\AppData\\Local\\Temp',
  514. TMPDIR='C:\\Users\\docwhat\\AppData\\Local\\Temp',
  515. TMP='C:\\Users\\docwhat\\AppData\\Local\\Temp',
  516. }
  517. else
  518. return {
  519. HOME='/home/docwhat',
  520. HOMEDRIVE='HOMEDRIVE-should-be-ignored',
  521. HOMEPATH='HOMEPATH-should-be-ignored',
  522. LOCALAPPDATA='LOCALAPPDATA-should-be-ignored',
  523. TEMP='TEMP-should-be-ignored',
  524. TMPDIR='TMPDIR-should-be-ignored',
  525. TMP='TMP-should-be-ignored',
  526. }
  527. end
  528. end
  529. local function set_paths_via_system(var_name, paths)
  530. local env = base_env()
  531. env[var_name] = table.concat(paths, ':')
  532. clear({env=env})
  533. end
  534. local function set_paths_at_runtime(var_name, paths)
  535. clear({env=base_env()})
  536. meths.set_var('env_val', table.concat(paths, ':'))
  537. command(('let $%s=g:env_val'):format(var_name))
  538. end
  539. local function behaves_like_dir_list_env(msg, stdpath_arg, env_var_name, paths, expected_paths)
  540. describe(msg, function()
  541. it('set via system', function()
  542. set_paths_via_system(env_var_name, paths)
  543. eq(expected_paths, funcs.stdpath(stdpath_arg))
  544. end)
  545. it('set at runtime', function()
  546. set_paths_at_runtime(env_var_name, paths)
  547. eq(expected_paths, funcs.stdpath(stdpath_arg))
  548. end)
  549. end)
  550. end
  551. describe('with "config_dirs"' , function ()
  552. behaves_like_dir_list_env(
  553. 'handles XDG_CONFIG_DIRS with one path',
  554. 'config_dirs', 'XDG_CONFIG_DIRS',
  555. {
  556. alter_slashes('/home/docwhat/.config')
  557. },
  558. {
  559. alter_slashes('/home/docwhat/.config/nvim')
  560. })
  561. behaves_like_dir_list_env(
  562. 'handles XDG_CONFIG_DIRS with two paths',
  563. 'config_dirs', 'XDG_CONFIG_DIRS',
  564. {
  565. alter_slashes('/home/docwhat/.config'),
  566. alter_slashes('/etc/config')
  567. },
  568. {
  569. alter_slashes('/home/docwhat/.config/nvim'),
  570. alter_slashes('/etc/config/nvim')
  571. })
  572. behaves_like_dir_list_env(
  573. "doesn't expand $VAR and $IBLES",
  574. 'config_dirs', 'XDG_CONFIG_DIRS',
  575. { '$HOME', '$TMP' },
  576. {
  577. alter_slashes('$HOME/nvim'),
  578. alter_slashes('$TMP/nvim')
  579. })
  580. behaves_like_dir_list_env(
  581. "doesn't expand ~/",
  582. 'config_dirs', 'XDG_CONFIG_DIRS',
  583. {
  584. alter_slashes('~/.oldconfig'),
  585. alter_slashes('~/.olderconfig')
  586. },
  587. {
  588. alter_slashes('~/.oldconfig/nvim'),
  589. alter_slashes('~/.olderconfig/nvim')
  590. })
  591. end)
  592. describe('with "data_dirs"' , function ()
  593. behaves_like_dir_list_env(
  594. 'knows XDG_DATA_DIRS with one path',
  595. 'data_dirs', 'XDG_DATA_DIRS',
  596. {
  597. alter_slashes('/home/docwhat/.data')
  598. },
  599. {
  600. alter_slashes('/home/docwhat/.data/nvim')
  601. })
  602. behaves_like_dir_list_env(
  603. 'knows XDG_DATA_DIRS with two paths',
  604. 'data_dirs', 'XDG_DATA_DIRS',
  605. {
  606. alter_slashes('/home/docwhat/.data'),
  607. alter_slashes('/etc/local')
  608. },
  609. {
  610. alter_slashes('/home/docwhat/.data/nvim'),
  611. alter_slashes('/etc/local/nvim'),
  612. })
  613. behaves_like_dir_list_env(
  614. "doesn't expand $VAR and $IBLES",
  615. 'data_dirs', 'XDG_DATA_DIRS',
  616. { '$HOME', '$TMP' },
  617. {
  618. alter_slashes('$HOME/nvim'),
  619. alter_slashes('$TMP/nvim')
  620. })
  621. behaves_like_dir_list_env(
  622. "doesn't expand ~/",
  623. 'data_dirs', 'XDG_DATA_DIRS',
  624. {
  625. alter_slashes('~/.oldconfig'),
  626. alter_slashes('~/.olderconfig')
  627. },
  628. {
  629. alter_slashes('~/.oldconfig/nvim'),
  630. alter_slashes('~/.olderconfig/nvim'),
  631. })
  632. end)
  633. end)
  634. describe('errors', function()
  635. it('on unknown strings', function()
  636. eq('Vim(call):E6100: "capybara" is not a valid stdpath', exc_exec('call stdpath("capybara")'))
  637. eq('Vim(call):E6100: "" is not a valid stdpath', exc_exec('call stdpath("")'))
  638. eq('Vim(call):E6100: "23" is not a valid stdpath', exc_exec('call stdpath(23)'))
  639. end)
  640. it('on non-strings', function()
  641. eq('Vim(call):E731: using Dictionary as a String', exc_exec('call stdpath({"eris": 23})'))
  642. eq('Vim(call):E730: using List as a String', exc_exec('call stdpath([23])'))
  643. end)
  644. end)
  645. end)