0
0
mirror of https://github.com/vim/vim.git synced 2025-09-26 04:04:07 -04:00

patch 9.1.0327: No support for using $XDG_CONFIG_HOME

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>
This commit is contained in:
Luca Saccarola
2024-04-14 22:53:22 +02:00
committed by Christian Brabandt
parent f9f5424d3e
commit c9df1fb35a
13 changed files with 359 additions and 12 deletions

View File

@@ -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

View File

@@ -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
@@ -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

View File

@@ -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
@@ -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

View File

@@ -331,6 +331,7 @@ NEW_TESTS = \
test_wnext \
test_wordcount \
test_writefile \
test_xdg \
test_xxd \
test_alot_latin \
test_alot_utf8 \
@@ -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 \

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

140
src/testdir/test_xdg.vim Normal file
View File

@@ -0,0 +1,140 @@
" Tests for the XDG feature
source check.vim
CheckFeature terminal
source shared.vim
source screendump.vim
source mouse.vim
source term_util.vim
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()
CheckUnix
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
func Test_xdg_runtime_files()
" This tests, that the initialization file from
" ~/.vimrc, ~/.vim/vimrc and ~/.config/vim/vimrc (or
" $XDG_HOMECONFIG/vim/vimrc) are sourced in that order
CheckUnix
call mkdir(expand('~/.vim/'), 'pD')
call mkdir(expand('~/.config/vim/'), 'pD')
call mkdir(expand('~/xdg/vim/'), 'pD')
let rc1=expand('~/.vimrc')
let rc2=expand('~/.vim/vimrc')
let rc3=expand('~/.config/vim/vimrc')
let rc4=expand('~/xdg/vim/vimrc')
" g:rc_one|two|three|four is to verify, that the other
" init files are not source
" g:rc is to verify which rc file has been loaded.
let file1 =<< trim CODE
let g:rc_one = 'one'
let g:rc = '.vimrc'
CODE
let file2 =<< trim CODE
let g:rc_two = 'two'
let g:rc = '.vim/vimrc'
CODE
let file3 =<< trim CODE
let g:rc_three = 'three'
let g:rc = '.config/vim/vimrc'
CODE
let file4 =<< trim CODE
let g:rc_four = 'four'
let g:rc = 'xdg/vim/vimrc'
CODE
call writefile(file1, rc1)
call writefile(file2, rc2)
call writefile(file3, rc3)
call writefile(file4, rc4)
let rows = 20
let buf = RunVimInTerminal('', #{rows: rows, no_clean: 1})
call TermWait(buf)
call term_sendkeys(buf, ":echo \$MYVIMRC\<cr>")
call WaitForAssert({-> assert_match('XfakeHOME/\.vimrc', term_getline(buf, rows))})
call term_sendkeys(buf, ":call filter(g:, {idx, _ -> idx =~ '^rc'})\<cr>")
call TermWait(buf)
call term_sendkeys(buf, ":redraw!\<cr>")
call TermWait(buf)
call term_sendkeys(buf, ":let g:\<cr>")
call VerifyScreenDump(buf, 'Test_xdg_1', {})
call StopVimInTerminal(buf)
call delete(rc1)
bw
let buf = RunVimInTerminal('', #{rows: rows, no_clean: 1})
call TermWait(buf)
call term_sendkeys(buf, ":echo \$MYVIMRC\<cr>")
call WaitForAssert({-> assert_match('XfakeHOME/\.vim/vimrc', term_getline(buf, rows))})
call term_sendkeys(buf, ":call filter(g:, {idx, _ -> idx =~ '^rc'})\<cr>")
call TermWait(buf)
call term_sendkeys(buf, ":redraw!\<cr>")
call TermWait(buf)
call term_sendkeys(buf, ":let g:\<cr>")
call VerifyScreenDump(buf, 'Test_xdg_2', {})
call StopVimInTerminal(buf)
call delete(rc2)
bw
let buf = RunVimInTerminal('', #{rows: rows, no_clean: 1})
call TermWait(buf)
call term_sendkeys(buf, ":echo \$MYVIMRC\<cr>")
call WaitForAssert({-> assert_match('XfakeHOME/\.config/vim/vimrc', term_getline(buf, rows))})
call term_sendkeys(buf, ":call filter(g:, {idx, _ -> idx =~ '^rc'})\<cr>")
call TermWait(buf)
call term_sendkeys(buf, ":redraw!\<cr>")
call TermWait(buf)
call term_sendkeys(buf, ":let g:\<cr>")
call VerifyScreenDump(buf, 'Test_xdg_3', {})
call StopVimInTerminal(buf)
call delete(rc3)
bw
let $XDG_CONFIG_HOME=expand('~/xdg/')
let buf = RunVimInTerminal('', #{rows: rows, no_clean: 1})
call TermWait(buf)
call term_sendkeys(buf, ":redraw!\<cr>")
call TermWait(buf)
call term_sendkeys(buf, ":echo \$MYVIMRC\<cr>")
call WaitForAssert({-> assert_match('xdg/vim/vimrc', term_getline(buf, rows))})
call term_sendkeys(buf, ":call filter(g:, {idx, _ -> idx =~ '^rc'})\<cr>")
call TermWait(buf)
call term_sendkeys(buf, ":let g:\<cr>")
call VerifyScreenDump(buf, 'Test_xdg_4', {})
call StopVimInTerminal(buf)
call delete(rc4)
bw
unlet $XDG_CONFIG_HOME
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
327,
/**/
326,
/**/