-
-
Notifications
You must be signed in to change notification settings - Fork 5.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add XDG_BASE_DIR support #14182
Add XDG_BASE_DIR support #14182
Changes from all commits
1b69a9a
54ed71e
fc6605a
37ded4a
a2a413e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
*freedesktop.txt* For Vim version 9.1. Last change: 2024 Mar 20 | ||
|
||
|
||
VIM REFERENCE MANUAL by Bram Moolenaar | ||
|
||
|
||
*freedesktop* *X-desktop-group* *xdg* | ||
This file contains some information on what it is freedesktop and the XDG | ||
families of specifications. | ||
|
||
Freedesktop is a project aiming to develop specifications to enable | ||
interoperability between Unix-like operating systems. | ||
|
||
Vim tries to conform, for some extent, to the specifications made by | ||
freedesktop (see |xdg-base-dir|). | ||
|
||
============================================================================== | ||
XDG Base Directory Specification *xdg-base-dir* *$XDG_CONFIG_HOME* | ||
|
||
The XDG Base Directory Specification aim to define standard locations for the | ||
multilple data e configuration files used by applications. In order to divide | ||
this files by their use and not by application. This is mainly done to go | ||
against the legacy behavior of dumping everything in the home directory. | ||
|
||
This directories should be overwritable by the user, using environment | ||
variable but should also give fallback in case those variables weren't set. | ||
|
||
This is a not exhaustive of those directories: | ||
XDG_CACHE_HOME HOME/.cache Ephemiral data files | ||
XDG_CONFIG_HOME HOME/.config Configuration files | ||
XDG_DATA_HOME HOME/.local/share Persistent data files | ||
XDG_STATE_HOME HOME/.local/state State data files | ||
|
||
*xdg-vimrc* | ||
Vim, on Unix systems, will look at `$XDG_CONFIG_HOME/vim/vimrc` for | ||
configuration (see |vimrc|) but it will source it only if no other rc is found | ||
in `$HOME` or `$HOME/vim`. | ||
|
||
*xdg-runtime* | ||
When the |xdg-vimrc| is used the |'runtimepath'| will be modified accordingly | ||
to respect the |xdg-base-dir|: > | ||
|
||
"$XDG_CONFIG_HOME/vim,$VIMRUNTIME,/after,$XDG_CONFIG_HOME/vim/after" | ||
< | ||
|
||
vim:tw=78:ts=8:noet:ft=help:norl: |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -809,7 +809,8 @@ accordingly. Vim proceeds in this order: | |
name. Also see |vimrc-intro|. | ||
|
||
Places for your personal initializations: | ||
Unix $HOME/.vimrc or $HOME/.vim/vimrc | ||
Unix $HOME/.vimrc, $HOME/.vim/vimrc | ||
or $XDG_CONFIG_HOME/vim/vimrc | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you are changing also changing 'runtimepath' and 'packpath'. That should also be documented. |
||
MS-Windows $HOME/_vimrc, $HOME/vimfiles/vimrc | ||
or $VIM/_vimrc | ||
Amiga s:.vimrc, home:.vimrc, home:vimfiles:vimrc | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -364,6 +364,66 @@ set_init_clean_rtp(void) | |
} | ||
#endif | ||
|
||
#ifdef UNIX | ||
/* | ||
* Change 'runtimepath' and 'packdir' to '$XDG_CONFIG_HOME/vim' if the only | ||
* vimrc found is located in '$XDG_CONFIG_HOME/vim/vimrc'. | ||
* In case the '$XDG_CONFIG_HOME' variable is not set, '$HOME/.config' is used | ||
* as a fallback as is defined in the XDG base dir specification: | ||
* <https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html> | ||
*/ | ||
static void | ||
set_init_xdg_rtp(void) | ||
{ | ||
int opt_idx; | ||
int has_xdg_env = TRUE; | ||
int should_free_xdg_dir = FALSE; | ||
char_u *vimrc1 = NULL; | ||
char_u *vimrc2 = NULL; | ||
char_u *xdg_dir = NULL; | ||
char_u *xdg_rtp = NULL; | ||
char_u *vimrc_xdg = NULL; | ||
|
||
vimrc1 = expand_env_save((char_u *)USR_VIMRC_FILE); | ||
vimrc2 = expand_env_save((char_u *)USR_VIMRC_FILE2); | ||
|
||
xdg_dir = mch_getenv("XDG_CONFIG_HOME"); | ||
if (!xdg_dir) | ||
{ | ||
xdg_dir = expand_env_save((char_u *)"~/.config"); | ||
should_free_xdg_dir = TRUE; | ||
has_xdg_env = FALSE; | ||
} | ||
vimrc_xdg = concat_fnames(xdg_dir, (char_u *)"vim/vimrc", TRUE); | ||
|
||
if (file_is_readable(vimrc1) || file_is_readable(vimrc2) || | ||
!file_is_readable(vimrc_xdg)) | ||
goto theend; | ||
|
||
xdg_rtp = has_xdg_env ? (char_u *)XDG_RUNTIMEPATH | ||
: (char_u *)XDG_RUNTIMEPATH_FB; | ||
|
||
if ((opt_idx = findoption((char_u *)"runtimepath")) < 0) | ||
goto theend; | ||
|
||
options[opt_idx].def_val[VI_DEFAULT] = xdg_rtp; | ||
p_rtp = xdg_rtp; | ||
|
||
if ((opt_idx = findoption((char_u *)"packpath")) < 0) | ||
goto theend; | ||
|
||
options[opt_idx].def_val[VI_DEFAULT] = xdg_rtp; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This just overrides the default, right? I guess, this is not needed or is it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 'packpath' defaults to // src/os_unix.h
# ifdef RUNTIME_GLOBAL
# ifdef RUNTIME_GLOBAL_AFTER
# define DFLT_RUNTIMEPATH "~/.vim," RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL_AFTER ",~/.vim/after"
# define XDG_RUNTIMEPATH "$XDG_CONFIG_HOME/vim," RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL_AFTER "/after,$XDG_CONFIG_HOME/vim/after"
# define XDG_RUNTIMEPATH_FB "~/.config/vim," RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL_AFTER "/after,~/.config/vim/after"
# define CLEAN_RUNTIMEPATH RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL_AFTER
# else
# define DFLT_RUNTIMEPATH "~/.vim," RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL "/after,~/.vim/after"
# define XDG_RUNTIMEPATH "$XDG_CONFIG_HOME/vim," RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL "/after,$XDG_CONFIG_HOME/vim/after"
# define XDG_RUNTIMEPATH_FB "~/.config/vim," RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL "/after,~/.config/vim/after"
# define CLEAN_RUNTIMEPATH RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL "/after"
# endif
# else
# define DFLT_RUNTIMEPATH "~/.vim,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after,~/.vim/after"
# define XDG_RUNTIMEPATH "$XDG_CONFIG_HOME/vim,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after,$XDG_CONFIG_HOME/vim/after"
# define XDG_RUNTIMEPATH_FB "~/.config/vim,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after,~/.config/vim/after"
# define CLEAN_RUNTIMEPATH "$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after"
# endif // src/optiondefs.h
{"packpath", "pp", P_STRING|P_VI_DEF|P_EXPAND|P_ONECOMMA|P_NODUP
|P_SECURE,
(char_u *)&p_pp, PV_NONE, NULL, NULL,
{(char_u *)DFLT_RUNTIMEPATH, (char_u *)0L}
SCTX_INIT}, It should be need it unless I do the checks when initializing the options. But I don't know if there is a benefit or not There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes I know. I was just wondering if we need to override the default or if simply setting the option pointer is enough. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you want There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah, yes makes sense. Thanks |
||
p_pp = xdg_rtp; | ||
|
||
theend: | ||
vim_free(vimrc1); | ||
vim_free(vimrc2); | ||
vim_free(vimrc_xdg); | ||
if (should_free_xdg_dir) | ||
vim_free(xdg_dir); | ||
} | ||
#endif | ||
|
||
/* | ||
* Expand environment variables and things like "~" for the defaults. | ||
* If option_expand() returns non-NULL the variable is expanded. This can | ||
|
@@ -588,6 +648,7 @@ set_init_1(int clean_arg) | |
set_options_default(0); | ||
|
||
#ifdef UNIX | ||
set_init_xdg_rtp(); | ||
set_init_restricted_mode(); | ||
#endif | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -236,7 +236,7 @@ typedef struct dsc$descriptor DESC; | |
# ifdef VMS | ||
# define USR_VIMRC_FILE "sys$login:.vimrc" | ||
# else | ||
# define USR_VIMRC_FILE "$HOME/.vimrc" | ||
# define USR_VIMRC_FILE "~/.vimrc" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why this change? That seems unrelated There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I got a strange bug where it did expanded correctly (I was probably doing something wrong). Also is more consistent between other prepocessor variables. I can adress it in another PR if you want to. |
||
# endif | ||
#endif | ||
|
||
|
@@ -249,6 +249,12 @@ typedef struct dsc$descriptor DESC; | |
# endif | ||
#endif | ||
|
||
#ifndef XDG_VIMRC_FILE | ||
# define XDG_VIMRC_FILE mch_getenv("XDG_CONFIG_HOME") \ | ||
? (char_u *)"$XDG_CONFIG_HOME/vim/vimrc" \ | ||
: (char_u *)"~/.config/vim/vimrc" | ||
#endif | ||
|
||
#if !defined(USR_VIMRC_FILE3) && defined(VMS) | ||
# define USR_VIMRC_FILE3 "sys$login:_vimrc" | ||
#endif | ||
|
@@ -349,13 +355,19 @@ typedef struct dsc$descriptor DESC; | |
# ifdef RUNTIME_GLOBAL | ||
# ifdef RUNTIME_GLOBAL_AFTER | ||
# define DFLT_RUNTIMEPATH "~/.vim," RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL_AFTER ",~/.vim/after" | ||
# define XDG_RUNTIMEPATH "$XDG_CONFIG_HOME/vim," RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL_AFTER "/after,$XDG_CONFIG_HOME/vim/after" | ||
# define XDG_RUNTIMEPATH_FB "~/.config/vim," RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL_AFTER "/after,~/.config/vim/after" | ||
# define CLEAN_RUNTIMEPATH RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL_AFTER | ||
# else | ||
# define DFLT_RUNTIMEPATH "~/.vim," RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL "/after,~/.vim/after" | ||
# define XDG_RUNTIMEPATH "$XDG_CONFIG_HOME/vim," RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL "/after,$XDG_CONFIG_HOME/vim/after" | ||
# define XDG_RUNTIMEPATH_FB "~/.config/vim," RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL "/after,~/.config/vim/after" | ||
# define CLEAN_RUNTIMEPATH RUNTIME_GLOBAL ",$VIMRUNTIME," RUNTIME_GLOBAL "/after" | ||
# endif | ||
# else | ||
# define DFLT_RUNTIMEPATH "~/.vim,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after,~/.vim/after" | ||
# define XDG_RUNTIMEPATH "$XDG_CONFIG_HOME/vim,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after,$XDG_CONFIG_HOME/vim/after" | ||
# define XDG_RUNTIMEPATH_FB "~/.config/vim,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after,~/.config/vim/after" | ||
# define CLEAN_RUNTIMEPATH "$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after" | ||
# endif | ||
# endif | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
func s:get_rcs() | ||
let rcs = { | ||
\ 'file1': { 'path': '~/.vimrc' }, | ||
\ 'file2': { 'path': '~/.vim/vimrc' }, | ||
\ 'xdg': { 'path': exists('$XDG_CONFIG_HOME') ? '$XDG_CONFIG_HOME' : "~/.config" }, | ||
\} | ||
for v in values(rcs) | ||
let v.exists = filereadable(expand(v.path)) | ||
endfor | ||
return rcs | ||
endfunc | ||
|
||
func Test_xdg_rc_detection() | ||
if !has('unix') | ||
return v:false | ||
endif | ||
let rc = s:get_rcs() | ||
let before =<< trim CODE | ||
call writefile([expand('$MYVIMRC')], "XMY_VIMRC") | ||
quit! | ||
CODE | ||
call RunVim(before, [], "") | ||
let my_rc = readfile("XMY_VIMRC") | ||
if rc.file1.exists | ||
call assert_equal(rc.file1.path, my_rc) | ||
elseif !rc.file1.exists && rc.file2.exists | ||
call assert_equal(rc.file2.path, my_rc) | ||
elseif !rc.file1.exists && !rc.file2.exists && rc.xdg.exists | ||
call assert_equal(rc.xdg.path, my_rc) | ||
endif | ||
call delete("XMY_VIMRC") | ||
endfunc | ||
|
||
" vim: shiftwidth=2 sts=2 expandtab |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fixed those when merging. You should probably compare against what was committed instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chrisbra #14559