aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames McCoy <jamessan@jamessan.com>2018-12-16 13:20:54 -0500
committerGitHub <noreply@github.com>2018-12-16 13:20:54 -0500
commit7a8dadbedb0ba15e67b198774bb87caad1e22828 (patch)
tree9748153d46706a868a1ce39a4912e79b1643c8ce
parentb48efd9ba7bf1d317dcf231e3e595988537a5cf9 (diff)
parent314f6ea3678c09f9824242a10abbe4a2fb2ccff3 (diff)
downloadrneovim-7a8dadbedb0ba15e67b198774bb87caad1e22828.tar.gz
rneovim-7a8dadbedb0ba15e67b198774bb87caad1e22828.tar.bz2
rneovim-7a8dadbedb0ba15e67b198774bb87caad1e22828.zip
Merge pull request #9077 from jamessan/xdg-sysinit
startup: Use $XDG_CONFIG_DIRS/nvim/sysinit.vim if it exists
-rw-r--r--runtime/doc/starting.txt9
-rw-r--r--src/nvim/main.c47
-rw-r--r--test/functional/core/startup_spec.lua59
3 files changed, 107 insertions, 8 deletions
diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt
index 450d2967b4..82e73035d8 100644
--- a/runtime/doc/starting.txt
+++ b/runtime/doc/starting.txt
@@ -436,10 +436,11 @@ accordingly. Vim proceeds in this order:
If Vim was started in Ex mode with the "-s" argument, all following
initializations until 4. are skipped. Only the "-u" option is
interpreted.
- *system-vimrc*
- a. For Unix, MS-Windows, and Macintosh, the system vimrc file is read for
- initializations. The path of this file is shown with the
- ":version" command. Mostly it's "$VIM/vimrc".
+ *system-vimrc* *sysinit.vim*
+ a. The system vimrc file is read for initializations. If
+ nvim/sysinit.vim file exists in one of $XDG_CONFIG_DIRS, it will be
+ used. Otherwise, the system vimrc file is used. The path of this file
+ is shown with the ":version" command. Mostly it's "$VIM/sysinit.vim".
*VIMINIT* *EXINIT* *$MYVIMRC*
b. Four places are searched for initializations. The first that exists
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 911e51407d..8a40577e8f 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -1722,6 +1722,48 @@ static void exe_commands(mparm_T *parmp)
TIME_MSG("executing command arguments");
}
+/// Source system-wide vimrc if built with one defined
+///
+/// Does one of the following things, stops after whichever succeeds:
+///
+/// 1. Source system vimrc file from $XDG_CONFIG_DIRS/nvim/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,
+ 's', 'y', 's', 'i', 'n', 'i', 't', '.', 'v', 'i', 'm', NUL
+ };
+ do {
+ const char *dir;
+ size_t dir_len;
+ iter = vim_env_iter(':', config_dirs, iter, &dir, &dir_len);
+ if (dir == NULL || dir_len == 0) {
+ break;
+ }
+ char *vimrc = xmalloc(dir_len + sizeof(path_tail) + 1);
+ memcpy(vimrc, dir, dir_len);
+ vimrc[dir_len] = PATHSEP;
+ memcpy(vimrc + dir_len + 1, path_tail, sizeof(path_tail));
+ if (do_source((char_u *)vimrc, false, DOSO_NONE) != FAIL) {
+ xfree(vimrc);
+ xfree(config_dirs);
+ return;
+ }
+ xfree(vimrc);
+ } while (iter != NULL);
+ xfree(config_dirs);
+ }
+
+#ifdef SYS_VIMRC_FILE
+ // Get system wide defaults, if the file name is defined.
+ (void)do_source((char_u *)SYS_VIMRC_FILE, false, DOSO_NONE);
+#endif
+}
+
/// Source vimrc or do other user initialization
///
/// Does one of the following things, stops after whichever succeeds:
@@ -1804,10 +1846,7 @@ static void source_startup_scripts(const mparm_T *const parmp)
}
}
} else if (!silent_mode) {
-#ifdef SYS_VIMRC_FILE
- // Get system wide defaults, if the file name is defined.
- (void) do_source((char_u *)SYS_VIMRC_FILE, false, DOSO_NONE);
-#endif
+ do_system_initialization();
if (do_user_initialization()) {
// Read initialization commands from ".vimrc" or ".exrc" in current
diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua
index 15121261c7..8edb8fc014 100644
--- a/test/functional/core/startup_spec.lua
+++ b/test/functional/core/startup_spec.lua
@@ -7,12 +7,17 @@ local eq = helpers.eq
local eval = helpers.eval
local feed = helpers.feed
local funcs = helpers.funcs
+local mkdir = helpers.mkdir
local nvim_prog = helpers.nvim_prog
local nvim_set = helpers.nvim_set
local read_file = helpers.read_file
local retry = helpers.retry
+local rmdir = helpers.rmdir
+local set_session = helpers.set_session
local sleep = helpers.sleep
+local spawn = helpers.spawn
local iswin = helpers.iswin
+local write_file = helpers.write_file
describe('startup', function()
before_each(function()
@@ -204,3 +209,57 @@ describe('startup', function()
end)
end)
+describe('sysinit', function()
+ local xdgdir = 'Xxdg'
+ local vimdir = 'Xvim'
+ local xhome = 'Xhome'
+ local pathsep = helpers.get_pathsep()
+ local argv = {
+ nvim_prog, '--headless', '--embed', '-i', 'NONE', '-n',
+ '--cmd', 'set nomore undodir=. directory=. belloff='
+ }
+
+ before_each(function()
+ rmdir(xdgdir)
+ rmdir(vimdir)
+ rmdir(xhome)
+
+ mkdir(xdgdir)
+ mkdir(xdgdir .. pathsep .. 'nvim')
+ write_file(table.concat({xdgdir, 'nvim', 'sysinit.vim'}, pathsep), [[
+ let g:loaded = get(g:, "loaded", 0) + 1
+ let g:xdg = 1
+ ]])
+
+ mkdir(vimdir)
+ write_file(table.concat({vimdir, 'sysinit.vim'}, pathsep), [[
+ let g:loaded = get(g:, "loaded", 0) + 1
+ let g:vim = 1
+ ]])
+
+ mkdir(xhome)
+ end)
+ after_each(function()
+ rmdir(xdgdir)
+ rmdir(vimdir)
+ rmdir(xhome)
+ end)
+
+ it('prefers XDG_CONFIG_DIRS over VIM', function()
+ set_session(spawn(argv, nil,
+ { 'HOME='..xhome,
+ 'XDG_CONFIG_DIRS='..xdgdir,
+ 'VIM='..vimdir }))
+ eq('loaded 1 xdg 1 vim 0',
+ eval('printf("loaded %d xdg %d vim %d", g:loaded, get(g:, "xdg", 0), get(g:, "vim", 0))'))
+ end)
+
+ it('uses VIM if XDG_CONFIG_DIRS unset', function()
+ set_session(spawn(argv, nil,
+ { 'HOME='..xhome,
+ 'XDG_CONFIG_DIRS=',
+ 'VIM='..vimdir }))
+ eq('loaded 1 xdg 0 vim 1',
+ eval('printf("loaded %d xdg %d vim %d", g:loaded, get(g:, "xdg", 0), get(g:, "vim", 0))'))
+ end)
+end)