feat(defaults): session data in $XDG_STATE_HOME #15583

See: 4f2884e16d

- Move session persistent data to $XDG_STATE_HOME Change 'directory',
  'backupdir', 'undodir', 'viewdir' and 'shadafile' default location to
  $XDG_STATE_HOME/nvim.
- Move logs to $XDG_STATE_HOME, too.
- Add stdpath('log') support.

Fixes: #14805
This commit is contained in:
Ivan 2021-09-06 20:35:34 +03:00 committed by Justin M. Keyes
parent a1b663cce8
commit 78a1e6bc00
15 changed files with 303 additions and 224 deletions

View File

@ -188,7 +188,7 @@ loading plugins is also skipped.
Use
.Ar shada
instead of the default
.Pa ~/.local/share/nvim/shada/main.shada .
.Pa ~/.local/state/nvim/shada/main.shada .
If
.Ar shada
is
@ -326,7 +326,7 @@ Print version information and exit.
.Sh ENVIRONMENT
.Bl -tag -width Fl
.It Ev NVIM_LOG_FILE
Low-level log file, usually found at ~/.cache/nvim/log.
Low-level log file, usually found at ~/.local/state/nvim/log.
:help $NVIM_LOG_FILE
.It Ev VIM
Used to locate user files, such as init.vim.
@ -340,12 +340,20 @@ Path to the user-local configuration directory, see
Defaults to
.Pa ~/.config .
:help xdg
.It Ev XDG_DATA_HOME
.It Ev XDG_STATE_HOME
Like
.Ev XDG_CONFIG_HOME ,
but used to store data not generally edited by the user,
namely swap, backup, and ShaDa files.
Defaults to
.Pa ~/.local/state .
:help xdg
.It Ev XDG_DATA_HOME
Like
.Ev XDG_CONFIG_HOME ,
but used to store data not generally edited by the user,
things like runtime files.
Defaults to
.Pa ~/.local/share .
:help xdg
.It Ev VIMINIT

View File

@ -7465,14 +7465,17 @@ stdpath({what}) *stdpath()* *E6100*
directories.
{what} Type Description ~
cache String Cache directory. Arbitrary temporary
cache String Cache directory: arbitrary temporary
storage for plugins, etc.
config String User configuration directory. The
|init.vim| is stored here.
config_dirs List Additional configuration directories.
config String User configuration directory. |init.vim|
is stored here.
config_dirs List Other configuration directories.
data String User data directory. The |shada-file|
is stored here.
data_dirs List Additional data directories.
data_dirs List Other data directories.
log String Logs directory (for use by plugins too).
state String Session state directory: storage for file
drafts, undo history, shada, etc.
Example: >
:echo stdpath("config")

View File

@ -841,7 +841,7 @@ A jump table for the options with a short description can be found at |Q_op|.
again not rename the file.
*'backupdir'* *'bdir'*
'backupdir' 'bdir' string (default ".,$XDG_DATA_HOME/nvim/backup//")
'backupdir' 'bdir' string (default ".,$XDG_STATE_HOME/nvim/backup//")
global
List of directories for the backup file, separated with commas.
- The backup file will be created in the first directory in the list
@ -2063,7 +2063,7 @@ A jump table for the options with a short description can be found at |Q_op|.
{char2}. See |digraphs|.
*'directory'* *'dir'*
'directory' 'dir' string (default "$XDG_DATA_HOME/nvim/swap//")
'directory' 'dir' string (default "$XDG_STATE_HOME/nvim/swap//")
global
List of directory names for the swap file, separated with commas.
@ -3502,7 +3502,7 @@ A jump table for the options with a short description can be found at |Q_op|.
option. For '@' only characters up to 255 are used.
Careful: If you change this option, it might break expanding
environment variables. E.g., when '/' is included and Vim tries to
expand "$HOME/.local/share/nvim/shada/main.shada". Maybe you should
expand "$HOME/.local/state/nvim/shada/main.shada". Maybe you should
change 'iskeyword' instead.
*'iskeyword'* *'isk'*
@ -4942,9 +4942,12 @@ A jump table for the options with a short description can be found at |Q_op|.
but are not part of the Nvim distribution. XDG_DATA_DIRS defaults
to /usr/local/share/:/usr/share/, so system administrators are
expected to install site plugins to /usr/share/nvim/site.
5. $VIMRUNTIME, for files distributed with Neovim.
5. Applications state home directory, for files that contain your
session state (eg. backupdir, viewdir, undodir, etc).
Given by `stdpath("state")`. |$XDG_STATE_HOME|
6. $VIMRUNTIME, for files distributed with Neovim.
*after-directory*
6, 7, 8, 9. In after/ subdirectories of 1, 2, 3 and 4, with reverse
7, 8, 9, 10. In after/ subdirectories of 1, 2, 3 and 4, with reverse
ordering. This is for preferences to overrule or add to the
distributed defaults or system-wide settings (rarely needed).
@ -6623,7 +6626,7 @@ A jump table for the options with a short description can be found at |Q_op|.
'ttyfast' 'tf' Removed. |vim-differences|
*'undodir'* *'udir'* *E5003*
'undodir' 'udir' string (default "$XDG_DATA_HOME/nvim/undo//")
'undodir' 'udir' string (default "$XDG_STATE_HOME/nvim/undo//")
global
List of directory names for undo files, separated with commas.
See 'backupdir' for details of the format.
@ -6786,7 +6789,7 @@ A jump table for the options with a short description can be found at |Q_op|.
displayed when 'verbosefile' is set.
*'viewdir'* *'vdir'*
'viewdir' 'vdir' string (default: "$XDG_DATA_HOME/nvim/view//")
'viewdir' 'vdir' string (default: "$XDG_STATE_HOME/nvim/view//")
global
Name of the directory where to store files for |:mkview|.
This option cannot be set from a |modeline| or in the |sandbox|, for

View File

@ -1044,8 +1044,8 @@ even if other entries (with known name/type/etc) are merged. |shada-merging|
SHADA FILE NAME *shada-file-name*
- Default name of the |shada| file is:
Unix: "$XDG_DATA_HOME/nvim/shada/main.shada"
Windows: "$XDG_DATA_HOME/nvim-data/shada/main.shada"
Unix: "$XDG_STATE_HOME/nvim/shada/main.shada"
Windows: "$XDG_STATE_HOME/nvim-data/shada/main.shada"
See also |base-directories|.
- To choose a different file name you can use:
- The "n" flag in the 'shada' option.
@ -1135,7 +1135,7 @@ running) you have additional options:
When you get error "E929: All .tmp.X files exist,
cannot write ShaDa file!" check that no old temp files
were left behind (e.g.
~/.local/share/nvim/shada/main.shada.tmp*).
~/.local/state/nvim/shada/main.shada.tmp*).
Note: Executing :wshada will reset all |'quote| marks.
@ -1329,8 +1329,8 @@ paths.
*base-directories* *xdg*
The "base" (root) directories conform to the XDG Base Directory Specification.
https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
The $XDG_CONFIG_HOME and $XDG_DATA_HOME environment variables are used if they
exist, otherwise default values (listed below) are used.
The $XDG_CONFIG_HOME, $XDG_DATA_HOME and $XDG_STATE_HOME environment variables
are used if they exist, otherwise default values (listed below) are used.
CONFIG DIRECTORY (DEFAULT) ~
*$XDG_CONFIG_HOME* Nvim: stdpath("config")
@ -1342,6 +1342,11 @@ DATA DIRECTORY (DEFAULT) ~
Unix: ~/.local/share ~/.local/share/nvim
Windows: ~/AppData/Local ~/AppData/Local/nvim-data
STATE DIRECTORY (DEFAULT) ~
*$XDG_STATE_HOME* Nvim: stdpath("state")
Unix: ~/.local/state ~/.local/state/nvim
Windows: ~/AppData/Local ~/AppData/Local/nvim-data
Note: Throughout the user manual these defaults are used as placeholders, e.g.
"~/.config" is understood to mean "$XDG_CONFIG_HOME or ~/.config".
@ -1349,7 +1354,7 @@ LOG FILE *$NVIM_LOG_FILE*
Besides 'debug' and 'verbose', Nvim keeps a general log file for internal
debugging, plugins and RPC clients. >
:echo $NVIM_LOG_FILE
By default, the file is located at stdpath('cache')/log unless that path
By default, the file is located at stdpath('log')/log unless that path
is inaccessible or if $NVIM_LOG_FILE was set before |startup|.

View File

@ -352,12 +352,12 @@ another session.
this yourself then. Example: >
:mksession! ~/.config/nvim/secret.vim
:wshada! ~/.local/share/nvim/shada/secret.shada
:wshada! ~/.local/state/nvim/shada/secret.shada
And to restore this again: >
:source ~/.config/nvim/secret.vim
:rshada! ~/.local/share/nvim/shada/secret.shada
:rshada! ~/.local/state/nvim/shada/secret.shada
==============================================================================
*21.5* Views

View File

@ -17,7 +17,7 @@ centralized reference of the differences.
- Use `$XDG_CONFIG_HOME/nvim/init.vim` instead of `.vimrc` for your |config|.
- Use `$XDG_CONFIG_HOME/nvim` instead of `.vim` to store configuration files.
- Use `$XDG_DATA_HOME/nvim/shada/main.shada` instead of `.viminfo` for persistent
- Use `$XDG_STATE_HOME/nvim/shada/main.shada` instead of `.viminfo` for persistent
session information. |shada|
==============================================================================
@ -32,12 +32,12 @@ centralized reference of the differences.
- 'autoread' is enabled
- 'background' defaults to "dark" (unless set automatically by the terminal/UI)
- 'backspace' defaults to "indent,eol,start"
- 'backupdir' defaults to .,~/.local/share/nvim/backup// (|xdg|), auto-created
- 'backupdir' defaults to .,~/.local/state/nvim/backup// (|xdg|), auto-created
- 'belloff' defaults to "all"
- 'compatible' is always disabled
- 'complete' excludes "i"
- 'cscopeverbose' is enabled
- 'directory' defaults to ~/.local/share/nvim/swap// (|xdg|), auto-created
- 'directory' defaults to ~/.local/state/nvim/swap// (|xdg|), auto-created
- 'display' defaults to "lastline,msgsep"
- 'encoding' is UTF-8 (cf. 'fileencoding' for file-content encoding)
- 'fillchars' defaults (in effect) to "vert:│,fold:·,sep:│"
@ -65,7 +65,7 @@ centralized reference of the differences.
- 'tags' defaults to "./tags;,tags"
- 'ttimeoutlen' defaults to 50
- 'ttyfast' is always set
- 'undodir' defaults to ~/.local/share/nvim/undo// (|xdg|), auto-created
- 'undodir' defaults to ~/.local/state/nvim/undo// (|xdg|), auto-created
- 'viewoptions' includes "unix,slash", excludes "options"
- 'viminfo' includes "!"
- 'wildmenu' is enabled

View File

@ -25,12 +25,12 @@ do
local function path_join(...)
return table.concat(vim.tbl_flatten({ ... }), path_sep)
end
local logfilename = path_join(vim.fn.stdpath('cache'), 'lsp.log')
local logfilename = path_join(vim.fn.stdpath('log'), 'lsp.log')
-- TODO: Ideally the directory should be created in open_logfile(), right
-- before opening the log file, but open_logfile() can be called from libuv
-- callbacks, where using fn.mkdir() is not allowed.
vim.fn.mkdir(vim.fn.stdpath('cache'), 'p')
vim.fn.mkdir(vim.fn.stdpath('log'), 'p')
--- Returns the log filename.
---@returns (string) log filename

View File

@ -38,7 +38,7 @@ alternate file (e.g. stderr) use `LOG_CALLSTACK_TO_FILE(FILE*)`. Requires
Many log messages have a shared prefix, such as "UI" or "RPC". Use the shell to
filter the log, e.g. at DEBUG level you might want to exclude UI messages:
tail -F ~/.cache/nvim/log | cat -v | stdbuf -o0 grep -v UI | stdbuf -o0 tee -a log
tail -F ~/.local/state/nvim/log | cat -v | stdbuf -o0 grep -v UI | stdbuf -o0 tee -a log
Build with ASAN
---------------

View File

@ -9842,6 +9842,10 @@ static void f_stdpath(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_string = get_xdg_home(kXDGDataHome);
} else if (strequal(p, "cache")) {
rettv->vval.v_string = get_xdg_home(kXDGCacheHome);
} else if (strequal(p, "state")) {
rettv->vval.v_string = get_xdg_home(kXDGStateHome);
} else if (strequal(p, "log")) {
rettv->vval.v_string = get_xdg_home(kXDGStateHome);
} else if (strequal(p, "config_dirs")) {
get_xdg_var_list(kXDGConfigDirs, rettv);
} else if (strequal(p, "data_dirs")) {

View File

@ -51,7 +51,7 @@ static bool log_try_create(char *fname)
/// Initializes path to log file. Sets $NVIM_LOG_FILE if empty.
///
/// Tries $NVIM_LOG_FILE, or falls back to $XDG_CACHE_HOME/nvim/log. Path to log
/// Tries $NVIM_LOG_FILE, or falls back to $XDG_STATE_HOME/nvim/log. Path to log
/// file is cached, so only the first call has effect, unless first call was not
/// successful. Failed initialization indicates either a bug in expand_env()
/// or both $NVIM_LOG_FILE and $HOME environment variables are undefined.
@ -69,16 +69,16 @@ static bool log_path_init(void)
|| log_file_path[0] == '\0'
|| os_isdir((char_u *)log_file_path)
|| !log_try_create(log_file_path)) {
// Make kXDGCacheHome if it does not exist.
char *cachehome = get_xdg_home(kXDGCacheHome);
// Make kXDGStateHome if it does not exist.
char *loghome = get_xdg_home(kXDGStateHome);
char *failed_dir = NULL;
bool log_dir_failure = false;
if (!os_isdir((char_u *)cachehome)) {
log_dir_failure = (os_mkdir_recurse(cachehome, 0700, &failed_dir) != 0);
if (!os_isdir((char_u *)loghome)) {
log_dir_failure = (os_mkdir_recurse(loghome, 0700, &failed_dir) != 0);
}
XFREE_CLEAR(cachehome);
XFREE_CLEAR(loghome);
// Invalid $NVIM_LOG_FILE or failed to expand; fall back to default.
char *defaultpath = stdpaths_user_cache_subpath("log");
char *defaultpath = stdpaths_user_state_subpath("log", 0, true);
size_t len = xstrlcpy(log_file_path, defaultpath, size);
xfree(defaultpath);
// Fall back to .nvimlog

View File

@ -491,17 +491,17 @@ void set_init_1(bool clean_arg)
#endif
false);
char *backupdir = stdpaths_user_data_subpath("backup", 2, true);
char *backupdir = stdpaths_user_state_subpath("backup", 2, true);
const size_t backupdir_len = strlen(backupdir);
backupdir = xrealloc(backupdir, backupdir_len + 3);
memmove(backupdir + 2, backupdir, backupdir_len + 1);
memmove(backupdir, ".,", 2);
set_string_default("backupdir", backupdir, true);
set_string_default("viewdir", stdpaths_user_data_subpath("view", 2, true),
set_string_default("viewdir", stdpaths_user_state_subpath("view", 2, true),
true);
set_string_default("directory", stdpaths_user_data_subpath("swap", 2, true),
set_string_default("directory", stdpaths_user_state_subpath("swap", 2, true),
true);
set_string_default("undodir", stdpaths_user_data_subpath("undo", 2, true),
set_string_default("undodir", stdpaths_user_state_subpath("undo", 2, true),
true);
// Set default for &runtimepath. All necessary expansions are performed in
// this function.

View File

@ -14,6 +14,7 @@ static const char *xdg_env_vars[] = {
[kXDGConfigHome] = "XDG_CONFIG_HOME",
[kXDGDataHome] = "XDG_DATA_HOME",
[kXDGCacheHome] = "XDG_CACHE_HOME",
[kXDGStateHome] = "XDG_STATE_HOME",
[kXDGRuntimeDir] = "XDG_RUNTIME_DIR",
[kXDGConfigDirs] = "XDG_CONFIG_DIRS",
[kXDGDataDirs] = "XDG_DATA_DIRS",
@ -24,6 +25,7 @@ static const char *const xdg_defaults_env_vars[] = {
[kXDGConfigHome] = "LOCALAPPDATA",
[kXDGDataHome] = "LOCALAPPDATA",
[kXDGCacheHome] = "TEMP",
[kXDGStateHome] = "LOCALAPPDATA",
[kXDGRuntimeDir] = NULL,
[kXDGConfigDirs] = NULL,
[kXDGDataDirs] = NULL,
@ -38,6 +40,7 @@ static const char *const xdg_defaults[] = {
[kXDGConfigHome] = "~\\AppData\\Local",
[kXDGDataHome] = "~\\AppData\\Local",
[kXDGCacheHome] = "~\\AppData\\Local\\Temp",
[kXDGStateHome] = "~\\AppData\\Local",
[kXDGRuntimeDir] = NULL,
[kXDGConfigDirs] = NULL,
[kXDGDataDirs] = NULL,
@ -45,6 +48,7 @@ static const char *const xdg_defaults[] = {
[kXDGConfigHome] = "~/.config",
[kXDGDataHome] = "~/.local/share",
[kXDGCacheHome] = "~/.cache",
[kXDGStateHome] = "~/.local/state",
[kXDGRuntimeDir] = NULL,
[kXDGConfigDirs] = "/etc/xdg/",
[kXDGDataDirs] = "/usr/local/share/:/usr/share/",
@ -133,15 +137,26 @@ char *stdpaths_user_conf_subpath(const char *fname)
/// Return subpath of $XDG_DATA_HOME
///
/// @param[in] fname New component of the path.
///
/// @return [allocated] `$XDG_DATA_HOME/nvim/{fname}`
char *stdpaths_user_data_subpath(const char *fname)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
{
return concat_fnames_realloc(get_xdg_home(kXDGDataHome), fname, true);
}
/// Return subpath of $XDG_STATE_HOME
///
/// @param[in] fname New component of the path.
/// @param[in] trailing_pathseps Amount of trailing path separators to add.
/// @param[in] escape_commas If true, all commas will be escaped.
///
/// @return [allocated] `$XDG_DATA_HOME/nvim/{fname}`.
char *stdpaths_user_data_subpath(const char *fname, const size_t trailing_pathseps,
const bool escape_commas)
/// @return [allocated] `$XDG_STATE_HOME/nvim/{fname}`.
char *stdpaths_user_state_subpath(const char *fname, const size_t trailing_pathseps,
const bool escape_commas)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
{
char *ret = concat_fnames_realloc(get_xdg_home(kXDGDataHome), fname, true);
char *ret = concat_fnames_realloc(get_xdg_home(kXDGStateHome), fname, true);
const size_t len = strlen(ret);
const size_t numcommas = (escape_commas ? memcnt(ret, ',', len) : 0);
if (numcommas || trailing_pathseps) {

View File

@ -7,6 +7,7 @@ typedef enum {
kXDGConfigHome, ///< XDG_CONFIG_HOME
kXDGDataHome, ///< XDG_DATA_HOME
kXDGCacheHome, ///< XDG_CACHE_HOME
kXDGStateHome, ///< XDG_STATE_HOME
kXDGRuntimeDir, ///< XDG_RUNTIME_DIR
kXDGConfigDirs, ///< XDG_CONFIG_DIRS
kXDGDataDirs, ///< XDG_DATA_DIRS

View File

@ -1447,7 +1447,7 @@ static const char *shada_get_default_file(void)
FUNC_ATTR_WARN_UNUSED_RESULT
{
if (default_shada_file == NULL) {
char *shada_dir = stdpaths_user_data_subpath("shada", 0, false);
char *shada_dir = stdpaths_user_state_subpath("shada", 0, false);
default_shada_file = concat_fnames_realloc(shada_dir, "main.shada", true);
}
return default_shada_file;

View File

@ -163,7 +163,7 @@ describe('startup defaults', function()
end)
it("'shadafile' ('viminfofile')", function()
local env = {XDG_DATA_HOME='Xtest-userdata', XDG_CONFIG_HOME='Xtest-userconfig'}
local env = {XDG_DATA_HOME='Xtest-userdata', XDG_STATE_HOME='Xtest-userstate', XDG_CONFIG_HOME='Xtest-userconfig'}
clear{args={}, args_rm={'-i'}, env=env}
-- Default 'shadafile' is empty.
-- This means use the default location. :help shada-file-name
@ -178,7 +178,7 @@ describe('startup defaults', function()
clear{args={}, args_rm={'-i'}, env=env}
eq({ f }, eval('v:oldfiles'))
os.remove('Xtest-foo')
rmdir('Xtest-userdata')
rmdir('Xtest-userstate')
-- Handles viminfo/viminfofile as alias for shada/shadafile.
eq('\n shadafile=', eval('execute("set shadafile?")'))
@ -206,7 +206,7 @@ describe('startup defaults', function()
describe('$NVIM_LOG_FILE', function()
local xdgdir = 'Xtest-startup-xdg-logpath'
local xdgcachedir = xdgdir..'/nvim'
local xdgstatedir = xdgdir..'/nvim'
after_each(function()
os.remove('Xtest-logpath')
rmdir(xdgdir)
@ -218,21 +218,21 @@ describe('startup defaults', function()
}})
eq('Xtest-logpath', eval('$NVIM_LOG_FILE'))
end)
it('defaults to stdpath("cache")/log if empty', function()
eq(true, mkdir(xdgdir) and mkdir(xdgcachedir))
it('defaults to stdpath("log")/log if empty', function()
eq(true, mkdir(xdgdir) and mkdir(xdgstatedir))
clear({env={
XDG_CACHE_HOME=xdgdir,
XDG_STATE_HOME=xdgdir,
NVIM_LOG_FILE='', -- Empty is invalid.
}})
eq(xdgcachedir..'/log', string.gsub(eval('$NVIM_LOG_FILE'), '\\', '/'))
eq(xdgstatedir..'/log', string.gsub(eval('$NVIM_LOG_FILE'), '\\', '/'))
end)
it('defaults to stdpath("cache")/log if invalid', function()
eq(true, mkdir(xdgdir) and mkdir(xdgcachedir))
it('defaults to stdpath("log")/log if invalid', function()
eq(true, mkdir(xdgdir) and mkdir(xdgstatedir))
clear({env={
XDG_CACHE_HOME=xdgdir,
XDG_STATE_HOME=xdgdir,
NVIM_LOG_FILE='.', -- Any directory is invalid.
}})
eq(xdgcachedir..'/log', string.gsub(eval('$NVIM_LOG_FILE'), '\\', '/'))
eq(xdgstatedir..'/log', string.gsub(eval('$NVIM_LOG_FILE'), '\\', '/'))
end)
end)
end)
@ -264,6 +264,7 @@ describe('XDG-based defaults', function()
XDG_CONFIG_HOME=nil,
XDG_DATA_HOME=nil,
XDG_CACHE_HOME=nil,
XDG_STATE_HOME=nil,
XDG_RUNTIME_DIR=nil,
XDG_CONFIG_DIRS=nil,
XDG_DATA_DIRS=nil,
@ -293,6 +294,7 @@ describe('XDG-based defaults', function()
local env_sep = iswin() and ';' or ':'
local data_dir = iswin() and 'nvim-data' or 'nvim'
local state_dir = iswin() and 'nvim-data' or 'nvim'
local root_path = iswin() and 'C:' or ''
describe('with too long XDG variables', function()
@ -303,6 +305,7 @@ describe('XDG-based defaults', function()
.. env_sep.. root_path .. ('/b'):rep(2048)
.. (env_sep .. root_path .. '/c'):rep(512)),
XDG_DATA_HOME=(root_path .. ('/X'):rep(4096)),
XDG_STATE_HOME=(root_path .. ('/X'):rep(4096)),
XDG_DATA_DIRS=(root_path .. ('/A'):rep(2048)
.. env_sep .. root_path .. ('/B'):rep(2048)
.. (env_sep .. root_path .. '/C'):rep(512)),
@ -355,13 +358,13 @@ describe('XDG-based defaults', function()
.. ',' .. root_path .. ('/a'):rep(2048) .. '/nvim/after'
.. ',' .. root_path .. ('/x'):rep(4096) .. '/nvim/after'
):gsub('\\', '/')), (meths.get_option('runtimepath')):gsub('\\', '/'))
eq('.,' .. root_path .. ('/X'):rep(4096).. '/' .. data_dir .. '/backup//',
eq('.,' .. root_path .. ('/X'):rep(4096).. '/' .. state_dir .. '/backup//',
(meths.get_option('backupdir'):gsub('\\', '/')))
eq(root_path .. ('/X'):rep(4096) .. '/' .. data_dir .. '/swap//',
eq(root_path .. ('/X'):rep(4096) .. '/' .. state_dir .. '/swap//',
(meths.get_option('directory')):gsub('\\', '/'))
eq(root_path .. ('/X'):rep(4096) .. '/' .. data_dir .. '/undo//',
eq(root_path .. ('/X'):rep(4096) .. '/' .. state_dir .. '/undo//',
(meths.get_option('undodir')):gsub('\\', '/'))
eq(root_path .. ('/X'):rep(4096) .. '/' .. data_dir .. '/view//',
eq(root_path .. ('/X'):rep(4096) .. '/' .. state_dir .. '/view//',
(meths.get_option('viewdir')):gsub('\\', '/'))
end)
end)
@ -372,6 +375,7 @@ describe('XDG-based defaults', function()
XDG_CONFIG_HOME='$XDG_DATA_HOME',
XDG_CONFIG_DIRS='$XDG_DATA_DIRS',
XDG_DATA_HOME='$XDG_CONFIG_HOME',
XDG_STATE_HOME='$XDG_CONFIG_HOME',
XDG_DATA_DIRS='$XDG_CONFIG_DIRS',
}})
end)
@ -405,13 +409,13 @@ describe('XDG-based defaults', function()
.. ',$XDG_DATA_DIRS/nvim/after'
.. ',$XDG_DATA_HOME/nvim/after'
):gsub('\\', '/')), (meths.get_option('runtimepath')):gsub('\\', '/'))
eq(('.,$XDG_CONFIG_HOME/' .. data_dir .. '/backup//'),
eq(('.,$XDG_CONFIG_HOME/' .. state_dir .. '/backup//'),
meths.get_option('backupdir'):gsub('\\', '/'))
eq(('$XDG_CONFIG_HOME/' .. data_dir .. '/swap//'),
eq(('$XDG_CONFIG_HOME/' .. state_dir .. '/swap//'),
meths.get_option('directory'):gsub('\\', '/'))
eq(('$XDG_CONFIG_HOME/' .. data_dir .. '/undo//'),
eq(('$XDG_CONFIG_HOME/' .. state_dir .. '/undo//'),
meths.get_option('undodir'):gsub('\\', '/'))
eq(('$XDG_CONFIG_HOME/' .. data_dir .. '/view//'),
eq(('$XDG_CONFIG_HOME/' .. state_dir .. '/view//'),
meths.get_option('viewdir'):gsub('\\', '/'))
meths.command('set all&')
eq(('$XDG_DATA_HOME/nvim'
@ -425,13 +429,13 @@ describe('XDG-based defaults', function()
.. ',$XDG_DATA_DIRS/nvim/after'
.. ',$XDG_DATA_HOME/nvim/after'
):gsub('\\', '/'), (meths.get_option('runtimepath')):gsub('\\', '/'))
eq(('.,$XDG_CONFIG_HOME/' .. data_dir .. '/backup//'),
eq(('.,$XDG_CONFIG_HOME/' .. state_dir .. '/backup//'),
meths.get_option('backupdir'):gsub('\\', '/'))
eq(('$XDG_CONFIG_HOME/' .. data_dir .. '/swap//'),
eq(('$XDG_CONFIG_HOME/' .. state_dir .. '/swap//'),
meths.get_option('directory'):gsub('\\', '/'))
eq(('$XDG_CONFIG_HOME/' .. data_dir .. '/undo//'),
eq(('$XDG_CONFIG_HOME/' .. state_dir .. '/undo//'),
meths.get_option('undodir'):gsub('\\', '/'))
eq(('$XDG_CONFIG_HOME/' .. data_dir .. '/view//'),
eq(('$XDG_CONFIG_HOME/' .. state_dir .. '/view//'),
meths.get_option('viewdir'):gsub('\\', '/'))
end)
end)
@ -442,6 +446,7 @@ describe('XDG-based defaults', function()
XDG_CONFIG_HOME=', , ,',
XDG_CONFIG_DIRS=',-,-,' .. env_sep .. '-,-,-',
XDG_DATA_HOME=',=,=,',
XDG_STATE_HOME=',=,=,',
XDG_DATA_DIRS=',≡,≡,' .. env_sep .. '≡,≡,≡',
}})
end)
@ -484,13 +489,13 @@ describe('XDG-based defaults', function()
.. ',\\,-\\,-\\,' .. path_sep ..'nvim' .. path_sep ..'after'
.. ',\\, \\, \\,' .. path_sep ..'nvim' .. path_sep ..'after'
), meths.get_option('runtimepath'))
eq('.,\\,=\\,=\\,' .. path_sep .. data_dir .. '' .. path_sep ..'backup' .. (path_sep):rep(2),
eq('.,\\,=\\,=\\,' .. path_sep .. state_dir .. '' .. path_sep ..'backup' .. (path_sep):rep(2),
meths.get_option('backupdir'))
eq('\\,=\\,=\\,' .. path_sep ..'' .. data_dir .. '' .. path_sep ..'swap' .. (path_sep):rep(2),
eq('\\,=\\,=\\,' .. path_sep ..'' .. state_dir .. '' .. path_sep ..'swap' .. (path_sep):rep(2),
meths.get_option('directory'))
eq('\\,=\\,=\\,' .. path_sep ..'' .. data_dir .. '' .. path_sep ..'undo' .. (path_sep):rep(2),
eq('\\,=\\,=\\,' .. path_sep ..'' .. state_dir .. '' .. path_sep ..'undo' .. (path_sep):rep(2),
meths.get_option('undodir'))
eq('\\,=\\,=\\,' .. path_sep ..'' .. data_dir .. '' .. path_sep ..'view' .. (path_sep):rep(2),
eq('\\,=\\,=\\,' .. path_sep ..'' .. state_dir .. '' .. path_sep ..'view' .. (path_sep):rep(2),
meths.get_option('viewdir'))
end)
end)
@ -499,8 +504,9 @@ end)
describe('stdpath()', function()
-- Windows appends 'nvim-data' instead of just 'nvim' to prevent collisions
-- due to XDG_CONFIG_HOME and XDG_DATA_HOME being the same.
-- due to XDG_CONFIG_HOME, XDG_DATA_HOME and XDG_STATE_HOME being the same.
local datadir = iswin() and 'nvim-data' or 'nvim'
local statedir = iswin() and 'nvim-data' or 'nvim'
local env_sep = iswin() and ';' or ':'
it('acceptance', function()
@ -509,6 +515,7 @@ describe('stdpath()', function()
eq('nvim', funcs.fnamemodify(funcs.stdpath('cache'), ':t'))
eq('nvim', funcs.fnamemodify(funcs.stdpath('config'), ':t'))
eq(datadir, funcs.fnamemodify(funcs.stdpath('data'), ':t'))
eq(statedir, funcs.fnamemodify(funcs.stdpath('state'), ':t'))
eq('table', type(funcs.stdpath('config_dirs')))
eq('table', type(funcs.stdpath('data_dirs')))
assert_alive() -- Check for crash. #8393
@ -582,6 +589,39 @@ describe('stdpath()', function()
end)
end)
describe('with "state"' , function ()
it('knows XDG_STATE_HOME', function()
clear({env={
XDG_STATE_HOME=alter_slashes('/home/docwhat/.local'),
}})
eq(alter_slashes('/home/docwhat/.local/'..statedir), funcs.stdpath('state'))
end)
it('handles changes during runtime', function()
clear({env={
XDG_STATE_HOME=alter_slashes('/home/original'),
}})
eq(alter_slashes('/home/original/'..statedir), funcs.stdpath('state'))
command("let $XDG_STATE_HOME='"..alter_slashes('/home/new').."'")
eq(alter_slashes('/home/new/'..statedir), funcs.stdpath('state'))
end)
it("doesn't expand $VARIABLES", function()
clear({env={
XDG_STATE_HOME='$VARIABLES',
VARIABLES='this-should-not-happen',
}})
eq(alter_slashes('$VARIABLES/'..statedir), funcs.stdpath('state'))
end)
it("doesn't expand ~/", function()
clear({env={
XDG_STATE_HOME=alter_slashes('~/frobnitz'),
}})
eq(alter_slashes('~/frobnitz/'..statedir), funcs.stdpath('state'))
end)
end)
describe('with "cache"' , function ()
it('knows XDG_CACHE_HOME', function()
clear({env={