mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 18:55:14 -07:00
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:
parent
a1b663cce8
commit
78a1e6bc00
14
man/nvim.1
14
man/nvim.1
@ -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
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
@ -367,7 +367,7 @@ argument.
|
||||
*--headless*
|
||||
--headless Start without UI, and do not wait for `nvim_ui_attach`. The
|
||||
builtin TUI is not used, so stdio works as an arbitrary
|
||||
communication channel. |channel-stdio|
|
||||
communication channel. |channel-stdio|
|
||||
|
||||
Also useful for scripting (tests) to see messages that would
|
||||
not be printed by |-es|.
|
||||
@ -584,7 +584,7 @@ setting can affect the entire editor in ways that are not initially obvious.
|
||||
To find the cause of a problem in your config, you must "bisect" it:
|
||||
1. Remove or disable half of your |config|.
|
||||
2. Restart Nvim.
|
||||
3. If the problem still occurs, goto 1.
|
||||
3. If the problem still occurs, goto 1.
|
||||
4. If the problem is gone, restore half of the removed lines.
|
||||
5. Continue narrowing your config in this way, until you find the setting or
|
||||
plugin causing the issue.
|
||||
@ -701,7 +701,7 @@ vimrc file.
|
||||
These commands will write ":map" and ":set" commands to a file, in such a way
|
||||
that when these commands are executed, the current key mappings and options
|
||||
will be set to the same values. The options 'columns', 'endofline',
|
||||
'fileformat', 'lines', 'modified', and 'scroll' are not included, because
|
||||
'fileformat', 'lines', 'modified', and 'scroll' are not included, because
|
||||
these are terminal or file dependent.
|
||||
Note that the options 'binary', 'paste' and 'readonly' are included, this
|
||||
might not always be what you want.
|
||||
@ -718,7 +718,7 @@ with ":map" and ":set" commands and write the modified file. First read the
|
||||
default vimrc in with a command like ":source ~piet/.vimrc.Cprogs", change
|
||||
the settings and then save them in the current directory with ":mkvimrc!". If
|
||||
you want to make this file your default |config|, move it to
|
||||
$XDG_CONFIG_HOME/nvim. You could also use autocommands |autocommand| and/or
|
||||
$XDG_CONFIG_HOME/nvim. You could also use autocommands |autocommand| and/or
|
||||
modelines |modeline|.
|
||||
|
||||
*vimrc-option-example*
|
||||
@ -886,7 +886,7 @@ Shada ("shared data") file *shada* *shada-file*
|
||||
|
||||
If you exit Vim and later start it again, you would normally lose a lot of
|
||||
information. The ShaDa file can be used to remember that information, which
|
||||
enables you to continue where you left off. Its name is the abbreviation of
|
||||
enables you to continue where you left off. Its name is the abbreviation of
|
||||
SHAred DAta because it is used for sharing data between Neovim sessions.
|
||||
|
||||
This is introduced in section |21.3| of the user manual.
|
||||
@ -917,9 +917,9 @@ The |v:oldfiles| variable is filled. The marks are not read in at startup
|
||||
option upon startup.
|
||||
|
||||
*shada-write*
|
||||
When Vim exits and 'shada' is non-empty, the info is stored in the ShaDa file
|
||||
(it's actually merged with the existing one, if one exists |shada-merging|).
|
||||
The 'shada' option is a string containing information about what info should
|
||||
When Vim exits and 'shada' is non-empty, the info is stored in the ShaDa file
|
||||
(it's actually merged with the existing one, if one exists |shada-merging|).
|
||||
The 'shada' option is a string containing information about what info should
|
||||
be stored, and contains limits on how much should be stored (see 'shada').
|
||||
|
||||
Notes for Unix:
|
||||
@ -977,75 +977,75 @@ remembered.
|
||||
|
||||
MERGING *shada-merging*
|
||||
|
||||
When writing ShaDa files with |:wshada| without bang or at regular exit
|
||||
information in the existing ShaDa file is merged with information from current
|
||||
Neovim instance. For this purpose ShaDa files store timestamps associated
|
||||
When writing ShaDa files with |:wshada| without bang or at regular exit
|
||||
information in the existing ShaDa file is merged with information from current
|
||||
Neovim instance. For this purpose ShaDa files store timestamps associated
|
||||
with ShaDa entries. Specifically the following is being done:
|
||||
|
||||
1. History lines are merged, ordered by timestamp. Maximum amount of items in
|
||||
ShaDa file is defined by 'shada' option (|shada-/|, |shada-:|, |shada-@|,
|
||||
etc: one suboption for each character that represents history name
|
||||
1. History lines are merged, ordered by timestamp. Maximum amount of items in
|
||||
ShaDa file is defined by 'shada' option (|shada-/|, |shada-:|, |shada-@|,
|
||||
etc: one suboption for each character that represents history name
|
||||
(|:history|)).
|
||||
2. Local marks and changes for files that were not opened by Neovim are copied
|
||||
to new ShaDa file. Marks for files that were opened by Neovim are merged,
|
||||
2. Local marks and changes for files that were not opened by Neovim are copied
|
||||
to new ShaDa file. Marks for files that were opened by Neovim are merged,
|
||||
changes to files opened by Neovim are ignored. |shada-'|
|
||||
3. Jump list is merged: jumps are ordered by timestamp, identical jumps
|
||||
3. Jump list is merged: jumps are ordered by timestamp, identical jumps
|
||||
(identical position AND timestamp) are squashed.
|
||||
4. Search patterns and substitute strings are not merged: search pattern or
|
||||
substitute string which has greatest timestamp will be the only one copied
|
||||
4. Search patterns and substitute strings are not merged: search pattern or
|
||||
substitute string which has greatest timestamp will be the only one copied
|
||||
to ShaDa file.
|
||||
5. For each register entity with greatest timestamp is the only saved.
|
||||
5. For each register entity with greatest timestamp is the only saved.
|
||||
|shada-<|
|
||||
6. All saved variables are saved from current Neovim instance. Additionally
|
||||
existing variable values are copied, meaning that the only way to remove
|
||||
variable from a ShaDa file is either removing it by hand or disabling
|
||||
6. All saved variables are saved from current Neovim instance. Additionally
|
||||
existing variable values are copied, meaning that the only way to remove
|
||||
variable from a ShaDa file is either removing it by hand or disabling
|
||||
writing variables completely. |shada-!|
|
||||
7. For each global mark entity with greatest timestamp is the only saved.
|
||||
8. Buffer list and header are the only entries which are not merged in any
|
||||
fashion: the only header and buffer list present are the ones from the
|
||||
8. Buffer list and header are the only entries which are not merged in any
|
||||
fashion: the only header and buffer list present are the ones from the
|
||||
Neovim instance which was last writing the file. |shada-%|
|
||||
|
||||
COMPATIBILITY *shada-compatibility*
|
||||
|
||||
ShaDa files are forward and backward compatible. This means that
|
||||
|
||||
1. Entries which have unknown type (i.e. that hold unidentified data) are
|
||||
1. Entries which have unknown type (i.e. that hold unidentified data) are
|
||||
ignored when reading and blindly copied when writing.
|
||||
2. Register entries with unknown register name are ignored when reading and
|
||||
blindly copied when writing. Limitation: only registers that use name with
|
||||
2. Register entries with unknown register name are ignored when reading and
|
||||
blindly copied when writing. Limitation: only registers that use name with
|
||||
code in interval [1, 255] are supported. |registers|
|
||||
3. Register entries with unknown register type are ignored when reading and
|
||||
3. Register entries with unknown register type are ignored when reading and
|
||||
merged as usual when writing. |getregtype()|
|
||||
4. Local and global mark entries with unknown mark names are ignored when
|
||||
reading. When writing global mark entries are blindly copied and local mark
|
||||
entries are also blindly copied, but only if file they are attached to fits
|
||||
in the |shada-'| limit. Unknown local mark entry's timestamp is also taken
|
||||
into account when calculating which files exactly should fit into this
|
||||
limit. Limitation: only marks that use name with code in interval [1, 255]
|
||||
4. Local and global mark entries with unknown mark names are ignored when
|
||||
reading. When writing global mark entries are blindly copied and local mark
|
||||
entries are also blindly copied, but only if file they are attached to fits
|
||||
in the |shada-'| limit. Unknown local mark entry's timestamp is also taken
|
||||
into account when calculating which files exactly should fit into this
|
||||
limit. Limitation: only marks that use name with code in interval [1, 255]
|
||||
are supported. |mark-motions|
|
||||
5. History entries with unknown history type are ignored when reading and
|
||||
blindly copied when writing. Limitation: there can be only up to 256
|
||||
5. History entries with unknown history type are ignored when reading and
|
||||
blindly copied when writing. Limitation: there can be only up to 256
|
||||
history types. |history|
|
||||
6. Unknown keys found in register, local mark, global mark, change, jump and
|
||||
search pattern entries are saved internally and dumped when writing.
|
||||
6. Unknown keys found in register, local mark, global mark, change, jump and
|
||||
search pattern entries are saved internally and dumped when writing.
|
||||
Entries created during Neovim session never have such additions.
|
||||
7. Additional elements found in replacement string and history entries are
|
||||
saved internally and dumped. Entries created during Neovim session never
|
||||
7. Additional elements found in replacement string and history entries are
|
||||
saved internally and dumped. Entries created during Neovim session never
|
||||
have such additions.
|
||||
8. Additional elements found in variable entries are simply ignored when
|
||||
reading. When writing new variables they will be preserved during merging,
|
||||
but that's all. Variable values dumped from current Neovim session never
|
||||
have additional elements, even if variables themselves were obtained by
|
||||
8. Additional elements found in variable entries are simply ignored when
|
||||
reading. When writing new variables they will be preserved during merging,
|
||||
but that's all. Variable values dumped from current Neovim session never
|
||||
have additional elements, even if variables themselves were obtained by
|
||||
reading ShaDa files.
|
||||
|
||||
"Blindly" here means that there will be no attempts to somehow merge them,
|
||||
"Blindly" here means that there will be no attempts to somehow merge them,
|
||||
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.
|
||||
@ -1067,55 +1067,55 @@ however that this means everything will be overwritten with information from
|
||||
the first Vim, including the command line history, etc.
|
||||
|
||||
The ShaDa file itself can be edited by hand too, although we suggest you
|
||||
start with an existing one to get the format right. You need to understand
|
||||
MessagePack (or, more likely, find software that is able to use it) format to
|
||||
do this. This can be useful in order to create a second file, say
|
||||
"~/.my.shada" which could contain certain settings that you always want when
|
||||
you first start Neovim. For example, you can preload registers with
|
||||
particular data, or put certain commands in the command line history. A line
|
||||
start with an existing one to get the format right. You need to understand
|
||||
MessagePack (or, more likely, find software that is able to use it) format to
|
||||
do this. This can be useful in order to create a second file, say
|
||||
"~/.my.shada" which could contain certain settings that you always want when
|
||||
you first start Neovim. For example, you can preload registers with
|
||||
particular data, or put certain commands in the command line history. A line
|
||||
in your |config| file like >
|
||||
:rshada! ~/.my.shada
|
||||
can be used to load this information. You could even have different ShaDa
|
||||
files for different types of files (e.g., C code) and load them based on the
|
||||
file name, using the ":autocmd" command (see |:autocmd|). More information on
|
||||
can be used to load this information. You could even have different ShaDa
|
||||
files for different types of files (e.g., C code) and load them based on the
|
||||
file name, using the ":autocmd" command (see |:autocmd|). More information on
|
||||
ShaDa file format is contained in |shada-format| section.
|
||||
|
||||
*E136* *E929* *shada-error-handling*
|
||||
Some errors make Neovim leave temporary file named `{basename}.tmp.X` (X is
|
||||
any free letter from `a` to `z`) while normally it will create this file,
|
||||
write to it and then rename `{basename}.tmp.X` to `{basename}`. Such errors
|
||||
Some errors make Neovim leave temporary file named `{basename}.tmp.X` (X is
|
||||
any free letter from `a` to `z`) while normally it will create this file,
|
||||
write to it and then rename `{basename}.tmp.X` to `{basename}`. Such errors
|
||||
include:
|
||||
|
||||
- Errors which make Neovim think that read file is not a ShaDa file at all:
|
||||
non-ShaDa files are not overwritten for safety reasons to avoid accidentally
|
||||
destroying an unrelated file. This could happen e.g. when typing "nvim -i
|
||||
file" in place of "nvim -R file" (yes, somebody did that at least with Vim).
|
||||
- Errors which make Neovim think that read file is not a ShaDa file at all:
|
||||
non-ShaDa files are not overwritten for safety reasons to avoid accidentally
|
||||
destroying an unrelated file. This could happen e.g. when typing "nvim -i
|
||||
file" in place of "nvim -R file" (yes, somebody did that at least with Vim).
|
||||
Such errors are listed at |shada-critical-contents-errors|.
|
||||
- If writing to the temporary file failed: e.g. because of the insufficient
|
||||
- If writing to the temporary file failed: e.g. because of the insufficient
|
||||
space left.
|
||||
- If renaming file failed: e.g. because of insufficient permissions.
|
||||
- If target ShaDa file has different from the Neovim instance's owners (user
|
||||
and group) and changing them failed. Unix-specific, applies only when
|
||||
- If target ShaDa file has different from the Neovim instance's owners (user
|
||||
and group) and changing them failed. Unix-specific, applies only when
|
||||
Neovim was launched from root.
|
||||
|
||||
Do not forget to remove the temporary file or replace the target file with
|
||||
temporary one after getting one of the above errors or all attempts to create
|
||||
a ShaDa file may fail with |E929|. If you got one of them when using
|
||||
|:wshada| (and not when exiting Neovim: i.e. when you have Neovim session
|
||||
Do not forget to remove the temporary file or replace the target file with
|
||||
temporary one after getting one of the above errors or all attempts to create
|
||||
a ShaDa file may fail with |E929|. If you got one of them when using
|
||||
|:wshada| (and not when exiting Neovim: i.e. when you have Neovim session
|
||||
running) you have additional options:
|
||||
|
||||
- First thing which you should consider if you got any error, except failure
|
||||
to write to the temporary file: remove existing file and replace it with the
|
||||
- First thing which you should consider if you got any error, except failure
|
||||
to write to the temporary file: remove existing file and replace it with the
|
||||
temporary file. Do it even if you have running Neovim instance.
|
||||
- Fix the permissions and/or file ownership, free some space and attempt to
|
||||
- Fix the permissions and/or file ownership, free some space and attempt to
|
||||
write again. Do not remove the existing file.
|
||||
- Use |:wshada| with bang. Does not help in case of permission error. If
|
||||
target file was actually the ShaDa file some information may be lost in this
|
||||
case. To make the matters slightly better use |:rshada| prior to writing,
|
||||
but this still will loose buffer-local marks and change list entries for any
|
||||
- Use |:wshada| with bang. Does not help in case of permission error. If
|
||||
target file was actually the ShaDa file some information may be lost in this
|
||||
case. To make the matters slightly better use |:rshada| prior to writing,
|
||||
but this still will loose buffer-local marks and change list entries for any
|
||||
file which is not opened in the current Neovim instance.
|
||||
- Remove the target file from shell and use |:wshada|. Consequences are not
|
||||
different from using |:wshada| with bang, but "rm -f" works in some cases
|
||||
- Remove the target file from shell and use |:wshada|. Consequences are not
|
||||
different from using |:wshada| with bang, but "rm -f" works in some cases
|
||||
when you don't have write permissions.
|
||||
|
||||
*:rsh* *:rshada* *E886*
|
||||
@ -1129,13 +1129,13 @@ running) you have additional options:
|
||||
The information in the file is first read in to make
|
||||
a merge between old and new info. When [!] is used,
|
||||
the old information is not read first, only the
|
||||
internal info is written (also disables safety checks
|
||||
described in |shada-error-handling|). If 'shada' is
|
||||
internal info is written (also disables safety checks
|
||||
described in |shada-error-handling|). If 'shada' is
|
||||
empty, marks for up to 100 files will be written.
|
||||
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*).
|
||||
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/state/nvim/shada/main.shada.tmp*).
|
||||
|
||||
Note: Executing :wshada will reset all |'quote| marks.
|
||||
|
||||
@ -1158,82 +1158,82 @@ running) you have additional options:
|
||||
|
||||
SHADA FILE FORMAT *shada-format*
|
||||
|
||||
ShaDa files are concats of MessagePack entries. Each entry is a concat of
|
||||
ShaDa files are concats of MessagePack entries. Each entry is a concat of
|
||||
exactly four MessagePack objects:
|
||||
|
||||
1. First goes type of the entry. Object type must be an unsigned integer.
|
||||
1. First goes type of the entry. Object type must be an unsigned integer.
|
||||
Object type must not be equal to zero.
|
||||
2. Second goes entry timestamp. It must also be an unsigned integer.
|
||||
3. Third goes the length of the fourth entry. Unsigned integer as well, used
|
||||
3. Third goes the length of the fourth entry. Unsigned integer as well, used
|
||||
for fast skipping without parsing.
|
||||
4. Fourth is actual entry data. All currently used ShaDa entries use
|
||||
containers to hold data: either map or array. All string values in those
|
||||
containers are either binary (applies to filenames) or UTF-8, yet parser
|
||||
4. Fourth is actual entry data. All currently used ShaDa entries use
|
||||
containers to hold data: either map or array. All string values in those
|
||||
containers are either binary (applies to filenames) or UTF-8, yet parser
|
||||
needs to expect that invalid bytes may be present in a UTF-8 string.
|
||||
|
||||
Exact format depends on the entry type:
|
||||
|
||||
Entry type (name) Entry data ~
|
||||
1 (Header) Map containing data that describes the generator
|
||||
instance that wrote this ShaDa file. It is ignored
|
||||
1 (Header) Map containing data that describes the generator
|
||||
instance that wrote this ShaDa file. It is ignored
|
||||
when reading ShaDa files. Contains the following data:
|
||||
Key Data ~
|
||||
generator Binary, software used to generate ShaDa
|
||||
file. Is equal to "nvim" when ShaDa file was
|
||||
generator Binary, software used to generate ShaDa
|
||||
file. Is equal to "nvim" when ShaDa file was
|
||||
written by Neovim.
|
||||
version Binary, generator version.
|
||||
encoding Binary, effective 'encoding' value.
|
||||
max_kbyte Integer, effective |shada-s| limit value.
|
||||
pid Integer, instance process ID.
|
||||
* It is allowed to have any number of
|
||||
* It is allowed to have any number of
|
||||
additional keys with any data.
|
||||
2 (SearchPattern) Map containing data describing last used search or
|
||||
substitute pattern. Normally ShaDa file contains two
|
||||
such entries: one with "ss" key set to true (describes
|
||||
substitute pattern, see |:substitute|), and one set to
|
||||
false (describes search pattern, see
|
||||
|search-commands|). "su" key should be true on one of
|
||||
the entries. If key value is equal to default then it
|
||||
2 (SearchPattern) Map containing data describing last used search or
|
||||
substitute pattern. Normally ShaDa file contains two
|
||||
such entries: one with "ss" key set to true (describes
|
||||
substitute pattern, see |:substitute|), and one set to
|
||||
false (describes search pattern, see
|
||||
|search-commands|). "su" key should be true on one of
|
||||
the entries. If key value is equal to default then it
|
||||
is normally not present. Keys:
|
||||
Key Type Default Description ~
|
||||
sm Boolean true Effective 'magic' value.
|
||||
sc Boolean false Effective 'smartcase' value.
|
||||
sl Boolean true True if search pattern comes
|
||||
with a line offset. See
|
||||
sl Boolean true True if search pattern comes
|
||||
with a line offset. See
|
||||
|search-offset|.
|
||||
se Boolean false True if |search-offset|
|
||||
requested to place cursor at
|
||||
(relative to) the end of the
|
||||
se Boolean false True if |search-offset|
|
||||
requested to place cursor at
|
||||
(relative to) the end of the
|
||||
pattern.
|
||||
so Integer 0 Offset value. |search-offset|
|
||||
su Boolean false True if current entry was the
|
||||
su Boolean false True if current entry was the
|
||||
last used search pattern.
|
||||
ss Boolean false True if current entry describes
|
||||
ss Boolean false True if current entry describes
|
||||
|:substitute| pattern.
|
||||
sh Boolean false True if |v:hlsearch| is on.
|
||||
With |shada-h| or 'nohlsearch'
|
||||
With |shada-h| or 'nohlsearch'
|
||||
this key is always false.
|
||||
sp Binary N/A Actual pattern. Required.
|
||||
sb Boolean false True if search direction is
|
||||
sb Boolean false True if search direction is
|
||||
backward.
|
||||
* any none Other keys are allowed for
|
||||
compatibility reasons, see
|
||||
* any none Other keys are allowed for
|
||||
compatibility reasons, see
|
||||
|shada-compatibility|.
|
||||
3 (SubString) Array containing last |:substitute| replacement string.
|
||||
Contains single entry: binary, replacement string used.
|
||||
More entries are allowed for compatibility reasons, see
|
||||
3 (SubString) Array containing last |:substitute| replacement string.
|
||||
Contains single entry: binary, replacement string used.
|
||||
More entries are allowed for compatibility reasons, see
|
||||
|shada-compatibility|.
|
||||
4 (HistoryEntry) Array containing one entry from history. Should have
|
||||
two or three entries. First one is history type
|
||||
(unsigned integer), second is history line (binary),
|
||||
third is the separator character (unsigned integer,
|
||||
must be in interval [0, 255]). Third item is only
|
||||
valid for search history. Possible history types are
|
||||
listed in |hist-names|, here are the corresponding
|
||||
numbers: 0 - cmd, 1 - search, 2 - expr, 3 - input,
|
||||
4 (HistoryEntry) Array containing one entry from history. Should have
|
||||
two or three entries. First one is history type
|
||||
(unsigned integer), second is history line (binary),
|
||||
third is the separator character (unsigned integer,
|
||||
must be in interval [0, 255]). Third item is only
|
||||
valid for search history. Possible history types are
|
||||
listed in |hist-names|, here are the corresponding
|
||||
numbers: 0 - cmd, 1 - search, 2 - expr, 3 - input,
|
||||
4 - debug.
|
||||
5 (Register) Map describing one register (|registers|). If key
|
||||
value is equal to default then it is normally not
|
||||
5 (Register) Map describing one register (|registers|). If key
|
||||
value is equal to default then it is normally not
|
||||
present. Keys:
|
||||
Key Type Def Description ~
|
||||
rt UInteger 0 Register type:
|
||||
@ -1261,12 +1261,12 @@ exactly four MessagePack objects:
|
||||
* any none Other keys are allowed
|
||||
for compatibility reasons,
|
||||
see |shada-compatibility|.
|
||||
6 (Variable) Array containing two items: variable name (binary) and
|
||||
variable value (any object). Values are converted
|
||||
using the same code |msgpackparse()| uses when reading,
|
||||
|msgpackdump()| when writing, so there may appear
|
||||
|msgpack-special-dict|s. If there are more then two
|
||||
entries then the rest are ignored
|
||||
6 (Variable) Array containing two items: variable name (binary) and
|
||||
variable value (any object). Values are converted
|
||||
using the same code |msgpackparse()| uses when reading,
|
||||
|msgpackdump()| when writing, so there may appear
|
||||
|msgpack-special-dict|s. If there are more then two
|
||||
entries then the rest are ignored
|
||||
(|shada-compatibility|).
|
||||
7 (GlobalMark)
|
||||
8 (Jump)
|
||||
@ -1280,57 +1280,57 @@ exactly four MessagePack objects:
|
||||
|
||||
Data contained in the map:
|
||||
Key Type Default Description ~
|
||||
l UInteger 1 Position line number. Must be
|
||||
l UInteger 1 Position line number. Must be
|
||||
greater then zero.
|
||||
c UInteger 0 Position column number.
|
||||
n UInteger 34 ('"') Mark name. Only valid for
|
||||
GlobalMark and LocalMark
|
||||
n UInteger 34 ('"') Mark name. Only valid for
|
||||
GlobalMark and LocalMark
|
||||
entries.
|
||||
f Binary N/A File name. Required.
|
||||
* any none Other keys are allowed for
|
||||
compatibility reasons, see
|
||||
* any none Other keys are allowed for
|
||||
compatibility reasons, see
|
||||
|shada-compatibility|.
|
||||
9 (BufferList) Array containing maps. Each map in the array
|
||||
9 (BufferList) Array containing maps. Each map in the array
|
||||
represents one buffer. Possible keys:
|
||||
Key Type Default Description ~
|
||||
l UInteger 1 Position line number. Must be
|
||||
l UInteger 1 Position line number. Must be
|
||||
greater then zero.
|
||||
c UInteger 0 Position column number.
|
||||
f Binary N/A File name. Required.
|
||||
* any none Other keys are allowed for
|
||||
compatibility reasons, see
|
||||
* any none Other keys are allowed for
|
||||
compatibility reasons, see
|
||||
|shada-compatibility|.
|
||||
* (Unknown) Any other entry type is allowed for compatibility
|
||||
* (Unknown) Any other entry type is allowed for compatibility
|
||||
reasons, see |shada-compatibility|.
|
||||
|
||||
*E575* *E576*
|
||||
Errors in ShaDa file may have two types: E575 used for all “logical” errors
|
||||
and E576 used for all “critical” errors. Critical errors trigger behaviour
|
||||
described in |shada-error-handling| when writing and skipping the rest of the
|
||||
Errors in ShaDa file may have two types: E575 used for all “logical” errors
|
||||
and E576 used for all “critical” errors. Critical errors trigger behaviour
|
||||
described in |shada-error-handling| when writing and skipping the rest of the
|
||||
file when reading and include:
|
||||
*shada-critical-contents-errors*
|
||||
- Any of first three MessagePack objects being not an unsigned integer.
|
||||
- Third object requesting amount of bytes greater then bytes left in the ShaDa
|
||||
- Third object requesting amount of bytes greater then bytes left in the ShaDa
|
||||
file.
|
||||
- Entry with zero type. I.e. first object being equal to zero.
|
||||
- MessagePack parser failing to parse the entry data.
|
||||
- MessagePack parser consuming less or requesting greater bytes then described
|
||||
in the third object for parsing fourth object. I.e. when fourth object
|
||||
either contains more then one MessagePack object or it does not contain
|
||||
- MessagePack parser consuming less or requesting greater bytes then described
|
||||
in the third object for parsing fourth object. I.e. when fourth object
|
||||
either contains more then one MessagePack object or it does not contain
|
||||
complete MessagePack object.
|
||||
|
||||
==============================================================================
|
||||
Standard Paths *standard-path*
|
||||
|
||||
Nvim stores configuration, data, and logs in standard locations. Plugins are
|
||||
strongly encouraged to follow this pattern also. Use |stdpath()| to get the
|
||||
Nvim stores configuration, data, and logs in standard locations. Plugins are
|
||||
strongly encouraged to follow this pattern also. Use |stdpath()| to get the
|
||||
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|.
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
---------------
|
||||
|
@ -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")) {
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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={
|
||||
|
Loading…
Reference in New Issue
Block a user