mirror of
https://github.com/neovim/neovim.git
synced 2026-03-31 04:42:03 +00:00
fix(startup): respect $NVIM_APPNAME in $XDG_CONFIG_DIRS paths
Problem:
$NVIM_APPNAME was not respected when searching $XDG_CONFIG_DIRS for
config files. Nvim hardcoded "nvim" when constructing paths like
`$XDG_CONFIG_DIRS/nvim/init.lua`, ignoring the $NVIM_APPNAME environment
variable.
This meant that config files like `$XDG_CONFIG_DIRS/myapp/init.lua` were
not loaded, even though $NVIM_APPNAME was set to "myapp".
Solution:
Use `get_appname()` instead of hardcoded "nvim" for $XDG_CONFIG_DIRS
paths in `do_system_initialization()` and `do_user_initialization()`.
This makes $XDG_CONFIG_DIRS behave consistently with $XDG_CONFIG_HOME,
which already respected $NVIM_APPNAME.
As documented in `runtime/doc/starting.txt` (L1440-L1441):
"In the help wherever `$XDG_CONFIG_…/nvim` is mentioned it is understood
as `$XDG_CONFIG_…/$NVIM_APPNAME`."
See:
43339dee40/runtime/doc/starting.txt (L1440-L1441)
Relates to #37405
This commit is contained in:
@@ -1981,15 +1981,17 @@ static void exe_commands(mparm_T *parmp)
|
||||
///
|
||||
/// Does one of the following things, stops after whichever succeeds:
|
||||
///
|
||||
/// 1. Source system vimrc file from $XDG_CONFIG_DIRS/nvim/sysinit.vim
|
||||
/// 1. Source system vimrc file from $XDG_CONFIG_DIRS/$NVIM_APPNAME/sysinit.vim
|
||||
/// 2. Source system vimrc file from $VIM
|
||||
static void do_system_initialization(void)
|
||||
{
|
||||
char *const config_dirs = stdpaths_get_xdg_var(kXDGConfigDirs);
|
||||
if (config_dirs != NULL) {
|
||||
const void *iter = NULL;
|
||||
const char path_tail[] = {
|
||||
'n', 'v', 'i', 'm', PATHSEP,
|
||||
const char *appname = get_appname(false);
|
||||
size_t appname_len = strlen(appname);
|
||||
const char sysinit_suffix[] = {
|
||||
PATHSEP,
|
||||
's', 'y', 's', 'i', 'n', 'i', 't', '.', 'v', 'i', 'm', NUL
|
||||
};
|
||||
do {
|
||||
@@ -1999,13 +2001,15 @@ static void do_system_initialization(void)
|
||||
if (dir == NULL || dir_len == 0) {
|
||||
break;
|
||||
}
|
||||
char *vimrc = xmalloc(dir_len + sizeof(path_tail) + 1);
|
||||
size_t path_len = dir_len + 1 + appname_len + sizeof(sysinit_suffix);
|
||||
char *vimrc = xmalloc(path_len);
|
||||
memcpy(vimrc, dir, dir_len);
|
||||
if (vimrc[dir_len - 1] != PATHSEP) {
|
||||
vimrc[dir_len] = PATHSEP;
|
||||
dir_len += 1;
|
||||
}
|
||||
memcpy(vimrc + dir_len, path_tail, sizeof(path_tail));
|
||||
memcpy(vimrc + dir_len, appname, appname_len);
|
||||
memcpy(vimrc + dir_len + appname_len, sysinit_suffix, sizeof(sysinit_suffix));
|
||||
if (do_source(vimrc, false, DOSO_NONE, NULL) != FAIL) {
|
||||
xfree(vimrc);
|
||||
xfree(config_dirs);
|
||||
@@ -2027,8 +2031,8 @@ static void do_system_initialization(void)
|
||||
/// Does one of the following things, stops after whichever succeeds:
|
||||
///
|
||||
/// 1. Execution of VIMINIT environment variable.
|
||||
/// 2. Sourcing user config file ($XDG_CONFIG_HOME/nvim/init.lua or init.vim).
|
||||
/// 3. Sourcing other config files ($XDG_CONFIG_DIRS[1]/nvim/init.lua or init.vim, …).
|
||||
/// 2. Sourcing user config file ($XDG_CONFIG_HOME/$NVIM_APPNAME/init.lua or init.vim).
|
||||
/// 3. Sourcing other config files ($XDG_CONFIG_DIRS[1]/$NVIM_APPNAME/init.lua or init.vim, …).
|
||||
/// 4. Execution of EXINIT environment variable.
|
||||
///
|
||||
/// @return True if it is needed to attempt to source exrc file according to
|
||||
@@ -2072,10 +2076,8 @@ static bool do_user_initialization(void)
|
||||
|
||||
char *const config_dirs = stdpaths_get_xdg_var(kXDGConfigDirs);
|
||||
if (config_dirs != NULL) {
|
||||
const char vim_path_tail[] = { 'n', 'v', 'i', 'm', PATHSEP,
|
||||
'i', 'n', 'i', 't', '.', 'v', 'i', 'm', NUL };
|
||||
const char lua_path_tail[] = { 'n', 'v', 'i', 'm', PATHSEP,
|
||||
'i', 'n', 'i', 't', '.', 'l', 'u', 'a', NUL };
|
||||
const char *appname = get_appname(false);
|
||||
size_t appname_len = strlen(appname);
|
||||
|
||||
const void *iter = NULL;
|
||||
do {
|
||||
@@ -2087,24 +2089,30 @@ static bool do_user_initialization(void)
|
||||
}
|
||||
|
||||
// Build: <xdg_dir>/<appname>/init.lua
|
||||
char *init_lua = xmalloc(dir_len + sizeof(lua_path_tail) + 1);
|
||||
memmove(init_lua, dir, dir_len);
|
||||
const char init_lua_suffix[] = { PATHSEP, 'i', 'n', 'i', 't', '.', 'l', 'u', 'a', NUL };
|
||||
size_t init_lua_len = dir_len + 1 + appname_len + sizeof(init_lua_suffix);
|
||||
char *init_lua = xmalloc(init_lua_len);
|
||||
memcpy(init_lua, dir, dir_len);
|
||||
init_lua[dir_len] = PATHSEP;
|
||||
memmove(init_lua + dir_len + 1, lua_path_tail, sizeof(lua_path_tail));
|
||||
memcpy(init_lua + dir_len + 1, appname, appname_len);
|
||||
memcpy(init_lua + dir_len + 1 + appname_len, init_lua_suffix, sizeof(init_lua_suffix));
|
||||
|
||||
// Build: <xdg_dir>/<appname>/init.vim
|
||||
char *vimrc = xmalloc(dir_len + sizeof(vim_path_tail) + 1);
|
||||
memmove(vimrc, dir, dir_len);
|
||||
vimrc[dir_len] = PATHSEP;
|
||||
memmove(vimrc + dir_len + 1, vim_path_tail, sizeof(vim_path_tail));
|
||||
const char init_vim_suffix[] = { PATHSEP, 'i', 'n', 'i', 't', '.', 'v', 'i', 'm', NUL };
|
||||
size_t init_vim_len = dir_len + 1 + appname_len + sizeof(init_vim_suffix);
|
||||
char *init_vim = xmalloc(init_vim_len);
|
||||
memcpy(init_vim, dir, dir_len);
|
||||
init_vim[dir_len] = PATHSEP;
|
||||
memcpy(init_vim + dir_len + 1, appname, appname_len);
|
||||
memcpy(init_vim + dir_len + 1 + appname_len, init_vim_suffix, sizeof(init_vim_suffix));
|
||||
|
||||
if (os_path_exists(init_lua)
|
||||
&& do_source(init_lua, true, DOSO_VIMRC, NULL)) {
|
||||
if (os_path_exists(vimrc)) {
|
||||
semsg(e_conflicting_configs, init_lua, vimrc);
|
||||
if (os_path_exists(init_vim)) {
|
||||
semsg(e_conflicting_configs, init_lua, init_vim);
|
||||
}
|
||||
|
||||
xfree(vimrc);
|
||||
xfree(init_vim);
|
||||
xfree(init_lua);
|
||||
xfree(config_dirs);
|
||||
do_exrc = p_exrc;
|
||||
@@ -2112,17 +2120,16 @@ static bool do_user_initialization(void)
|
||||
}
|
||||
xfree(init_lua);
|
||||
|
||||
// init.vim
|
||||
if (do_source(vimrc, true, DOSO_VIMRC, NULL) != FAIL) {
|
||||
if (do_source(init_vim, true, DOSO_VIMRC, NULL) != FAIL) {
|
||||
do_exrc = p_exrc;
|
||||
if (do_exrc) {
|
||||
do_exrc = (path_full_compare(VIMRC_FILE, vimrc, false, true) != kEqualFiles);
|
||||
do_exrc = (path_full_compare(VIMRC_FILE, init_vim, false, true) != kEqualFiles);
|
||||
}
|
||||
xfree(vimrc);
|
||||
xfree(init_vim);
|
||||
xfree(config_dirs);
|
||||
return do_exrc;
|
||||
}
|
||||
xfree(vimrc);
|
||||
xfree(init_vim);
|
||||
} while (iter != NULL);
|
||||
xfree(config_dirs);
|
||||
}
|
||||
|
||||
@@ -1192,6 +1192,22 @@ describe('sysinit', function()
|
||||
eval('printf("loaded %d xdg %d vim %d", g:loaded, get(g:, "xdg", 0), get(g:, "vim", 0))')
|
||||
)
|
||||
end)
|
||||
|
||||
it('respects NVIM_APPNAME in XDG_CONFIG_DIRS', function()
|
||||
local appname = 'mysysinitapp'
|
||||
mkdir(xdgdir .. pathsep .. appname)
|
||||
write_file(
|
||||
table.concat({ xdgdir, appname, 'sysinit.vim' }, pathsep),
|
||||
[[let g:appname_sysinit = 1]]
|
||||
)
|
||||
clear {
|
||||
args_rm = { '-u' },
|
||||
env = { HOME = xhome, XDG_CONFIG_DIRS = xdgdir, NVIM_APPNAME = appname },
|
||||
}
|
||||
eq(1, eval('g:appname_sysinit'))
|
||||
-- Should not load from nvim/ subdir (which has the default sysinit.vim from before_each)
|
||||
eq(0, eval('get(g:, "xdg", 0)'))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('user config init', function()
|
||||
@@ -1472,6 +1488,29 @@ describe('user config init', function()
|
||||
}
|
||||
eq(1, eval('g:xdg_vim'))
|
||||
end)
|
||||
|
||||
it('respects NVIM_APPNAME', function()
|
||||
local appname = 'mytestapp'
|
||||
mkdir_p(xdgdir .. pathsep .. appname)
|
||||
-- Also create nvim/ with a config that should NOT be loaded
|
||||
write_file(table.concat({ xdgdir, 'nvim', 'init.lua' }, pathsep), [[vim.g.wrong = 1]])
|
||||
write_file(table.concat({ xdgdir, appname, 'init.lua' }, pathsep), [[vim.g.appname_lua = 1]])
|
||||
clear {
|
||||
args_rm = { '-u' },
|
||||
env = {
|
||||
XDG_CONFIG_HOME = xconfig,
|
||||
XDG_DATA_HOME = xdata,
|
||||
XDG_CONFIG_DIRS = xdgdir,
|
||||
NVIM_APPNAME = appname,
|
||||
},
|
||||
}
|
||||
eq(1, eval('g:appname_lua'))
|
||||
eq(0, eval('get(g:, "wrong", 0)'))
|
||||
eq(
|
||||
fn.fnamemodify(table.concat({ xdgdir, appname, 'init.lua' }, pathsep), ':p'),
|
||||
eval('$MYVIMRC')
|
||||
)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user