diff --git a/man/nvim.1 b/man/nvim.1 index 43dfc21dc7..9f35014ee8 100644 --- a/man/nvim.1 +++ b/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 diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index 3f0d0770bf..d197a2c62c 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -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") diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 1109056d47..4d6f589714 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -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 diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt index 1d3fa6c2ca..f542f33451 100644 --- a/runtime/doc/starting.txt +++ b/runtime/doc/starting.txt @@ -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|. diff --git a/runtime/doc/usr_21.txt b/runtime/doc/usr_21.txt index 44d653a1a7..add5d48073 100644 --- a/runtime/doc/usr_21.txt +++ b/runtime/doc/usr_21.txt @@ -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 diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index e24dd46f49..1a3d6022ca 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -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 diff --git a/runtime/lua/vim/lsp/log.lua b/runtime/lua/vim/lsp/log.lua index 66e82ecfeb..29cb27d373 100644 --- a/runtime/lua/vim/lsp/log.lua +++ b/runtime/lua/vim/lsp/log.lua @@ -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 diff --git a/src/nvim/README.md b/src/nvim/README.md index c7cb233c73..9417629691 100644 --- a/src/nvim/README.md +++ b/src/nvim/README.md @@ -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 --------------- diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 520137af0a..282c7cffc9 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -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")) { diff --git a/src/nvim/log.c b/src/nvim/log.c index 7d50ecf69e..815d53b570 100644 --- a/src/nvim/log.c +++ b/src/nvim/log.c @@ -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 diff --git a/src/nvim/option.c b/src/nvim/option.c index b5c9dfee87..940570b134 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -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. diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c index 5b824d23f4..5d6ffc1db1 100644 --- a/src/nvim/os/stdpaths.c +++ b/src/nvim/os/stdpaths.c @@ -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) { diff --git a/src/nvim/os/stdpaths_defs.h b/src/nvim/os/stdpaths_defs.h index 44c30df373..f94c511fe7 100644 --- a/src/nvim/os/stdpaths_defs.h +++ b/src/nvim/os/stdpaths_defs.h @@ -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 diff --git a/src/nvim/shada.c b/src/nvim/shada.c index a3d88a4963..abb6c68474 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -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; diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua index 6620c9acef..36a53d8d26 100644 --- a/test/functional/options/defaults_spec.lua +++ b/test/functional/options/defaults_spec.lua @@ -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={