Skip to content

Commit

Permalink
patch 9.1.0327: No support for using $XDG_CONFIG_HOME
Browse files Browse the repository at this point in the history
Problem:  No support for using $XDG_CONFIG_HOME
Solution: optionally source $XDG_CONFIG_HOME/vim/vimrc
          (Luca Saccarola)

fixes: #2034
closes: #14182

Signed-off-by: Luca Saccarola <github.e41mv@aleeas.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
  • Loading branch information
saccarosium authored and chrisbra committed Apr 14, 2024
1 parent f9f5424 commit c9df1fb
Show file tree
Hide file tree
Showing 13 changed files with 359 additions and 12 deletions.
62 changes: 51 additions & 11 deletions runtime/doc/starting.txt
@@ -1,4 +1,4 @@
*starting.txt* For Vim version 9.1. Last change: 2024 Mar 13
*starting.txt* For Vim version 9.1. Last change: 2024 Apr 14


VIM REFERENCE MANUAL by Bram Moolenaar
Expand Down Expand Up @@ -811,7 +811,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
MS-Windows $HOME/_vimrc, $HOME/vimfiles/vimrc
or $VIM/_vimrc
Amiga s:.vimrc, home:.vimrc, home:vimfiles:vimrc
Expand Down Expand Up @@ -853,15 +854,16 @@ accordingly. Vim proceeds in this order:
I The environment variable VIMINIT (see also |compatible-default|) (*)
The value of $VIMINIT is used as an Ex command line.
II The user vimrc file(s):
"$HOME/.vimrc" (for Unix) (*)
"$HOME/.vim/vimrc" (for Unix) (*)
"s:.vimrc" (for Amiga) (*)
"home:.vimrc" (for Amiga) (*)
"home:vimfiles:vimrc" (for Amiga) (*)
"$VIM/.vimrc" (for Amiga) (*)
"$HOME/_vimrc" (for Win32) (*)
"$HOME/vimfiles/vimrc" (for Win32) (*)
"$VIM/_vimrc" (for Win32) (*)
"$HOME/.vimrc" (for Unix) (*)
"$HOME/.vim/vimrc" (for Unix) (*)
"$HOME/.config/vim/vimrc" (for Unix) (*)
"s:.vimrc" (for Amiga) (*)
"home:.vimrc" (for Amiga) (*)
"home:vimfiles:vimrc" (for Amiga) (*)
"$VIM/.vimrc" (for Amiga) (*)
"$HOME/_vimrc" (for Win32) (*)
"$HOME/vimfiles/vimrc" (for Win32) (*)
"$VIM/_vimrc" (for Win32) (*)
"$HOME/config/settings/vim/vimrc" (for Haiku) (*)

Note: For Unix and Amiga, when ".vimrc" does not exist,
Expand Down Expand Up @@ -1085,6 +1087,44 @@ defaults.vim from your .vimrc, first unlet skip_defaults_vim, as in the
example above.


*xdg-base-dir* *$XDG_CONFIG_HOME*
XDG Base Directory Specification ~

The XDG Base Directory Specification aims to define a standard location for
configuration files used by applications. This is mainly done to prevent
the legacy behavior of dumping everything into the users home directory.
The specification can be found online at
https://specifications.freedesktop.org/basedir-spec/latest/

The location of this standard configuration directory is configurable by the
user, using environment variable but should also give fallback in case those
variables weren't set.

This is a not an exhaustive list of those directories:
Environment var default location Description ~
`$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

Vim will only care of the `$XDG_CONFIG_HOME` directory, the others are not
(yet) used for its various configuration and state files.

*xdg-vimrc*
Vim, on Unix systems, will look at `$XDG_CONFIG_HOME/vim/vimrc` for its
configuration (see |vimrc|) but it will source it only if no other
initialization file is found in `$HOME` or `$HOME/.vim` (thus making this
feature backward compatible). However, if you want to migrate to use
`$XDG_CONFIG_HOME/vim/` directory, you will have to move away your `~/.vimrc`
and `~/.vim/vimrc` file.

*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"
<

Avoiding trojan horses ~
*trojan-horse*
While reading the "vimrc" or the "exrc" file in the current directory, some
Expand Down
4 changes: 4 additions & 0 deletions runtime/doc/tags
Expand Up @@ -12,6 +12,7 @@ $VIM starting.txt /*$VIM*
$VIM-use version5.txt /*$VIM-use*
$VIMRUNTIME starting.txt /*$VIMRUNTIME*
$VIM_POSIX vi_diff.txt /*$VIM_POSIX*
$XDG_CONFIG_HOME starting.txt /*$XDG_CONFIG_HOME*
$quote eval.txt /*$quote*
% motion.txt /*%*
%:. cmdline.txt /*%:.*
Expand Down Expand Up @@ -11371,6 +11372,9 @@ x11-clientserver remote.txt /*x11-clientserver*
x11-cut-buffer gui_x11.txt /*x11-cut-buffer*
x11-selection gui_x11.txt /*x11-selection*
xattr editing.txt /*xattr*
xdg-base-dir starting.txt /*xdg-base-dir*
xdg-runtime starting.txt /*xdg-runtime*
xdg-vimrc starting.txt /*xdg-vimrc*
xf86conf.vim syntax.txt /*xf86conf.vim*
xfontset mbyte.txt /*xfontset*
xfree-xterm syntax.txt /*xfree-xterm*
Expand Down
2 changes: 2 additions & 0 deletions runtime/doc/version9.txt
Expand Up @@ -41543,6 +41543,8 @@ and is a work in progress.

Support for Wayland UI.

Support for the XDG Desktop Specification |xdg-base-dir|

Vim9 script
-----------
Add support for internal builtin functions with vim9 objects, see
Expand Down
4 changes: 4 additions & 0 deletions src/main.c
Expand Up @@ -3276,6 +3276,10 @@ source_startup_scripts(mparm_T *parmp)
&& do_source((char_u *)USR_VIMRC_FILE2, TRUE,
DOSO_VIMRC, NULL) == FAIL
#endif
#ifdef XDG_VIMRC_FILE
&& do_source((char_u *)XDG_VIMRC_FILE, TRUE,
DOSO_VIMRC, NULL) == FAIL
#endif
#ifdef USR_VIMRC_FILE3
&& do_source((char_u *)USR_VIMRC_FILE3, TRUE,
DOSO_VIMRC, NULL) == FAIL
Expand Down
61 changes: 61 additions & 0 deletions src/option.c
Expand Up @@ -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;
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
Expand Down Expand Up @@ -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

Expand Down
14 changes: 13 additions & 1 deletion src/os_unix.h
Expand Up @@ -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"
# endif
#endif

Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions src/testdir/Make_all.mak
Expand Up @@ -331,6 +331,7 @@ NEW_TESTS = \
test_wnext \
test_wordcount \
test_writefile \
test_xdg \
test_xxd \
test_alot_latin \
test_alot_utf8 \
Expand Down Expand Up @@ -564,6 +565,7 @@ NEW_TESTS_RES = \
test_winfixbuf.res \
test_wordcount.res \
test_writefile.res \
test_xdg.res \
test_xxd.res \
test_alot_latin.res \
test_alot_utf8.res \
Expand Down
20 changes: 20 additions & 0 deletions src/testdir/dumps/Test_xdg_1.dump
@@ -0,0 +1,20 @@
|~+0#4040ff13#ffffff0| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|r+0#0000000&|c|_|o|n|e| @16|o|n|e| @48
|r|c| @20|.|v|i|m|r|c| @45
|P+0#00e0003&|r|e|s@1| |E|N|T|E|R| |o|r| |t|y|p|e| |c|o|m@1|a|n|d| |t|o| |c|o|n|t|i|n|u|e> +0#0000000&@35
20 changes: 20 additions & 0 deletions src/testdir/dumps/Test_xdg_2.dump
@@ -0,0 +1,20 @@
|~+0#4040ff13#ffffff0| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|r+0#0000000&|c|_|t|w|o| @16|t|w|o| @48
|r|c| @20|.|v|i|m|/|v|i|m|r|c| @41
|P+0#00e0003&|r|e|s@1| |E|N|T|E|R| |o|r| |t|y|p|e| |c|o|m@1|a|n|d| |t|o| |c|o|n|t|i|n|u|e> +0#0000000&@35
20 changes: 20 additions & 0 deletions src/testdir/dumps/Test_xdg_3.dump
@@ -0,0 +1,20 @@
|~+0#4040ff13#ffffff0| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|r+0#0000000&|c|_|t|h|r|e@1| @14|t|h|r|e@1| @46
|r|c| @20|.|c|o|n|f|i|g|/|v|i|m|/|v|i|m|r|c| @34
|P+0#00e0003&|r|e|s@1| |E|N|T|E|R| |o|r| |t|y|p|e| |c|o|m@1|a|n|d| |t|o| |c|o|n|t|i|n|u|e> +0#0000000&@35
20 changes: 20 additions & 0 deletions src/testdir/dumps/Test_xdg_4.dump
@@ -0,0 +1,20 @@
|~+0#4040ff13#ffffff0| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|r+0#0000000&|c|_|f|o|u|r| @15|f|o|u|r| @47
|r|c| @20|x|d|g|/|v|i|m|/|v|i|m|r|c| @38
|P+0#00e0003&|r|e|s@1| |E|N|T|E|R| |o|r| |t|y|p|e| |c|o|m@1|a|n|d| |t|o| |c|o|n|t|i|n|u|e> +0#0000000&@35

0 comments on commit c9df1fb

Please sign in to comment.