Merge pull request #12235 from dm1try/add_init_lua

add init.lua as an alternative user config
This commit is contained in:
Björn Linse
2020-12-01 18:54:50 +01:00
committed by GitHub
6 changed files with 176 additions and 26 deletions

View File

@@ -104,7 +104,7 @@ argument.
--startuptime {fname} *--startuptime* --startuptime {fname} *--startuptime*
During startup write timing messages to the file {fname}. During startup write timing messages to the file {fname}.
This can be used to find out where time is spent while loading This can be used to find out where time is spent while loading
your |init.vim|, plugins and opening the first file. your |config|, plugins and opening the first file.
When {fname} already exists new messages are appended. When {fname} already exists new messages are appended.
(Only available when compiled with the |+startuptime| (Only available when compiled with the |+startuptime|
feature). feature).
@@ -211,7 +211,7 @@ argument.
When 'verbose' is set messages are printed to stderr. > When 'verbose' is set messages are printed to stderr. >
echo foo | nvim -V1 -es echo foo | nvim -V1 -es
< User |init.vim| is skipped (unless given with |-u|). < User |config| is skipped (unless given with |-u|).
Swap file is skipped (like |-n|). Swap file is skipped (like |-n|).
User |shada| is loaded (unless "-i NONE" is given). User |shada| is loaded (unless "-i NONE" is given).
@@ -406,12 +406,14 @@ accordingly. Vim proceeds in this order:
proceeding to load user configuration. proceeding to load user configuration.
4. Load user config (execute Ex commands from files, environment, …). 4. Load user config (execute Ex commands from files, environment, …).
$VIMINIT environment variable is read as one Ex command line (separate An environment variable (e.g. $VIMINIT) is read as one Ex command
multiple commands with '|' or <NL>). line, where multiple commands must be separated with '|' or <NL>.
*config* *init.vim* *vimrc* *exrc* *config* *init.vim* *init.lua* *vimrc* *exrc*
A file containing init commands is generically called a "vimrc" or A file that contains initialization commands is generically called
"config". Each line in such a file is executed as an Ex command. a "vimrc" or config file. It can be a Vimscript or Lua file named
|vimrc-intro| |base-directories| "init.vim" or "init.lua" respectively. It is an error to use both at
the same time. Each line in a "init.vim" is executed as an Ex command
line. See also |vimrc-intro| and |base-directories|.
The Nvim config file is "init.vim", located at: The Nvim config file is "init.vim", located at:
Unix ~/.config/nvim/init.vim Unix ~/.config/nvim/init.vim
@@ -578,7 +580,7 @@ The extreme flexibility of editors like Vim and Emacs means that any plugin or
setting can affect the entire editor in ways that are not initially obvious. setting can affect the entire editor in ways that are not initially obvious.
To find the cause of a problem in your config, you must "bisect" it: To find the cause of a problem in your config, you must "bisect" it:
1. Remove or disable half of your `init.vim`. 1. Remove or disable half of your |config|.
2. Restart Nvim. 2. Restart Nvim.
3. If the problem still occurs, goto 1. 3. If the problem still occurs, goto 1.
4. If the problem is gone, restore half of the removed lines. 4. If the problem is gone, restore half of the removed lines.
@@ -597,7 +599,7 @@ to 'shortmess'.
$VIM and $VIMRUNTIME $VIM and $VIMRUNTIME
*$VIM* *$VIM*
The environment variable "$VIM" is used to locate various user files for Nvim, The environment variable "$VIM" is used to locate various user files for Nvim,
such as the user startup script |init.vim|. This depends on the system, see such as the user |config|. This depends on the system, see
|startup|. |startup|.
Nvim will try to get the value for $VIM in this order: Nvim will try to get the value for $VIM in this order:
@@ -709,11 +711,11 @@ can be used with different terminals.
Only global mappings are stored, not mappings local to a buffer. Only global mappings are stored, not mappings local to a buffer.
A common method is to use a default |init.vim| file, make some modifications A common method is to use a default |config| file, make some modifications
with ":map" and ":set" commands and write the modified file. First read the with ":map" and ":set" commands and write the modified file. First read the
default vimrc in with a command like ":source ~piet/.vimrc.Cprogs", change default vimrc in with a command like ":source ~piet/.vimrc.Cprogs", change
the settings and then save them in the current directory with ":mkvimrc!". If the settings and then save them in the current directory with ":mkvimrc!". If
you want to make this file your default |init.vim|, move it to you want to make this file your default |config|, move it to
$XDG_CONFIG_HOME/nvim. You could also use autocommands |autocommand| and/or $XDG_CONFIG_HOME/nvim. You could also use autocommands |autocommand| and/or
modelines |modeline|. modelines |modeline|.
@@ -1065,7 +1067,7 @@ do this. This can be useful in order to create a second file, say
"~/.my.shada" which could contain certain settings that you always want when "~/.my.shada" which could contain certain settings that you always want when
you first start Neovim. For example, you can preload registers with you first start Neovim. For example, you can preload registers with
particular data, or put certain commands in the command line history. A line particular data, or put certain commands in the command line history. A line
in your |init.vim| file like > in your |config| file like >
:rshada! ~/.my.shada :rshada! ~/.my.shada
can be used to load this information. You could even have different ShaDa can be used to load this information. You could even have different ShaDa
files for different types of files (e.g., C code) and load them based on the files for different types of files (e.g., C code) and load them based on the

View File

@@ -927,7 +927,7 @@ void nlua_typval_eval(const String str, typval_T *const arg,
memcpy(lcmd + sizeof(EVALHEADER) - 1, str.data, str.size); memcpy(lcmd + sizeof(EVALHEADER) - 1, str.data, str.size);
lcmd[lcmd_len - 1] = ')'; lcmd[lcmd_len - 1] = ')';
#undef EVALHEADER #undef EVALHEADER
typval_exec_lua(lcmd, lcmd_len, "luaeval()", arg, 1, true, ret_tv); nlua_typval_exec(lcmd, lcmd_len, "luaeval()", arg, 1, true, ret_tv);
if (lcmd != (char *)IObuff) { if (lcmd != (char *)IObuff) {
xfree(lcmd); xfree(lcmd);
@@ -954,16 +954,16 @@ void nlua_typval_call(const char *str, size_t len, typval_T *const args,
#undef CALLHEADER #undef CALLHEADER
#undef CALLSUFFIX #undef CALLSUFFIX
typval_exec_lua(lcmd, lcmd_len, "v:lua", args, argcount, false, ret_tv); nlua_typval_exec(lcmd, lcmd_len, "v:lua", args, argcount, false, ret_tv);
if (lcmd != (char *)IObuff) { if (lcmd != (char *)IObuff) {
xfree(lcmd); xfree(lcmd);
} }
} }
static void typval_exec_lua(const char *lcmd, size_t lcmd_len, const char *name, static void nlua_typval_exec(const char *lcmd, size_t lcmd_len,
typval_T *const args, int argcount, bool special, const char *name, typval_T *const args,
typval_T *ret_tv) int argcount, bool special, typval_T *ret_tv)
{ {
if (check_secure()) { if (check_secure()) {
if (ret_tv) { if (ret_tv) {
@@ -1140,7 +1140,7 @@ void ex_lua(exarg_T *const eap)
xfree(code); xfree(code);
return; return;
} }
typval_exec_lua(code, len, ":lua", NULL, 0, false, NULL); nlua_typval_exec(code, len, ":lua", NULL, 0, false, NULL);
xfree(code); xfree(code);
} }
@@ -1230,18 +1230,31 @@ void ex_luado(exarg_T *const eap)
/// @param eap VimL command being run. /// @param eap VimL command being run.
void ex_luafile(exarg_T *const eap) void ex_luafile(exarg_T *const eap)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{
nlua_exec_file((const char *)eap->arg);
}
/// execute lua code from a file.
///
/// @param path path of the file
///
/// @return true if everything ok, false if there was an error (echoed)
bool nlua_exec_file(const char *path)
FUNC_ATTR_NONNULL_ALL
{ {
lua_State *const lstate = nlua_enter(); lua_State *const lstate = nlua_enter();
if (luaL_loadfile(lstate, (const char *)eap->arg)) { if (luaL_loadfile(lstate, path)) {
nlua_error(lstate, _("E5112: Error while creating lua chunk: %.*s")); nlua_error(lstate, _("E5112: Error while creating lua chunk: %.*s"));
return; return false;
} }
if (lua_pcall(lstate, 0, 0, 0)) { if (lua_pcall(lstate, 0, 0, 0)) {
nlua_error(lstate, _("E5113: Error while calling lua chunk: %.*s")); nlua_error(lstate, _("E5113: Error while calling lua chunk: %.*s"));
return; return false;
} }
return true;
} }
static void nlua_add_treesitter(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL static void nlua_add_treesitter(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL

View File

@@ -1069,9 +1069,14 @@ static void command_line_scan(mparm_T *parmp)
} else { } else {
a = argv[0]; a = argv[0];
} }
size_t s_size = STRLEN(a) + 4;
size_t s_size = STRLEN(a) + 9;
char *s = xmalloc(s_size); char *s = xmalloc(s_size);
if (path_with_extension(a, "lua")) {
snprintf(s, s_size, "luafile %s", a);
} else {
snprintf(s, s_size, "so %s", a); snprintf(s, s_size, "so %s", a);
}
parmp->cmds_tofree[parmp->n_commands] = true; parmp->cmds_tofree[parmp->n_commands] = true;
parmp->commands[parmp->n_commands++] = s; parmp->commands[parmp->n_commands++] = s;
} else { } else {
@@ -1770,6 +1775,23 @@ static bool do_user_initialization(void)
do_exrc = p_exrc; do_exrc = p_exrc;
return do_exrc; return do_exrc;
} }
char_u *init_lua_path = (char_u *)stdpaths_user_conf_subpath("init.lua");
if (os_path_exists(init_lua_path)
&& nlua_exec_file((const char *)init_lua_path)) {
os_setenv("MYVIMRC", (const char *)init_lua_path, 1);
char_u *vimrc_path = (char_u *)stdpaths_user_conf_subpath("init.vim");
if (os_path_exists(vimrc_path)) {
EMSG3(_("Conflicting configs: \"%s\" \"%s\""), init_lua_path, vimrc_path);
}
xfree(vimrc_path);
xfree(init_lua_path);
return false;
}
xfree(init_lua_path);
char_u *user_vimrc = (char_u *)stdpaths_user_conf_subpath("init.vim"); char_u *user_vimrc = (char_u *)stdpaths_user_conf_subpath("init.vim");
if (do_source(user_vimrc, true, DOSO_VIMRC) != FAIL) { if (do_source(user_vimrc, true, DOSO_VIMRC) != FAIL) {
do_exrc = p_exrc; do_exrc = p_exrc;
@@ -1828,11 +1850,15 @@ static void source_startup_scripts(const mparm_T *const parmp)
if (strequal(parmp->use_vimrc, "NONE") if (strequal(parmp->use_vimrc, "NONE")
|| strequal(parmp->use_vimrc, "NORC")) { || strequal(parmp->use_vimrc, "NORC")) {
// Do nothing. // Do nothing.
} else {
if (path_with_extension(parmp->use_vimrc, "lua")) {
nlua_exec_file(parmp->use_vimrc);
} else { } else {
if (do_source((char_u *)parmp->use_vimrc, false, DOSO_NONE) != OK) { if (do_source((char_u *)parmp->use_vimrc, false, DOSO_NONE) != OK) {
EMSG2(_("E282: Cannot read from \"%s\""), parmp->use_vimrc); EMSG2(_("E282: Cannot read from \"%s\""), parmp->use_vimrc);
} }
} }
}
} else if (!silent_mode) { } else if (!silent_mode) {
do_system_initialization(); do_system_initialization();

View File

@@ -1704,6 +1704,13 @@ int path_with_url(const char *fname)
return path_is_url(p); return path_is_url(p);
} }
bool path_with_extension(const char *path, const char *extension)
{
const char *last_dot = strrchr(path, '.');
if (!last_dot) { return false; }
return strcmp(last_dot + 1, extension) == 0;
}
/* /*
* Return TRUE if "name" is a full (absolute) path name or URL. * Return TRUE if "name" is a full (absolute) path name or URL.
*/ */

View File

@@ -432,3 +432,88 @@ describe('clean', function()
clear('--clean') clear('--clean')
ok(string.match(meths.get_option('runtimepath'), funcs.stdpath('config')) == nil) ok(string.match(meths.get_option('runtimepath'), funcs.stdpath('config')) == nil)
end) end)
describe('user config init', function()
local xhome = 'Xhome'
local pathsep = helpers.get_pathsep()
local xconfig = xhome .. pathsep .. 'Xconfig'
local init_lua_path = table.concat({xconfig, 'nvim', 'init.lua'}, pathsep)
before_each(function()
rmdir(xhome)
-- TODO, make mkdir_p helper
mkdir(xhome)
mkdir(xconfig)
mkdir(xconfig .. pathsep .. 'nvim')
write_file(init_lua_path, [[
vim.g.lua_rc = 1
]])
end)
after_each(function()
rmdir(xhome)
end)
it('loads init.lua from XDG config home by default', function()
clear{ args_rm={'-u' }, env={ XDG_CONFIG_HOME=xconfig }}
eq(1, eval('g:lua_rc'))
eq(init_lua_path, eval('$MYVIMRC'))
end)
describe 'with explicitly provided config'(function()
local custom_lua_path = table.concat({xhome, 'custom.lua'}, pathsep)
before_each(function()
write_file(custom_lua_path, [[
vim.g.custom_lua_rc = 1
]])
end)
it('loads custom lua config and does not set $MYVIMRC', function()
clear{ args={'-u', custom_lua_path }, env={ XDG_CONFIG_HOME=xconfig }}
eq(1, eval('g:custom_lua_rc'))
eq('', eval('$MYVIMRC'))
end)
end)
describe 'VIMRC also exists'(function()
before_each(function()
write_file(table.concat({xconfig, 'nvim', 'init.vim'}, pathsep), [[
let g:vim_rc = 1
]])
end)
it('loads default lua config, but shows an error', function()
clear{ args_rm={'-u'}, env={ XDG_CONFIG_HOME=xconfig }}
feed('<cr>') -- TODO check this, test execution is blocked without it
eq(1, eval('g:lua_rc'))
matches('Conflicting configs', meths.exec('messages', true))
end)
end)
end)
describe('user session', function()
local xhome = 'Xhome'
local pathsep = helpers.get_pathsep()
local session_file = table.concat({xhome, 'session.lua'}, pathsep)
before_each(function()
rmdir(xhome)
mkdir(xhome)
write_file(session_file, [[
vim.g.lua_session = 1
]])
end)
after_each(function()
rmdir(xhome)
end)
it('loads session from the provided lua file', function()
clear{ args={'-S', session_file }, env={ HOME=xhome }}
eq(1, eval('g:lua_session'))
end)
end)

View File

@@ -603,4 +603,21 @@ describe('path.c', function()
eq(FAIL, path_is_absolute('not/in/my/home~/directory')) eq(FAIL, path_is_absolute('not/in/my/home~/directory'))
end) end)
end) end)
describe('path_with_extension', function()
local function path_with_extension(filename, extension)
local c_filename = to_cstr(filename)
local c_extension = to_cstr(extension)
return cimp.path_with_extension(c_filename, c_extension)
end
itp('returns true if filename includes a provided extension', function()
eq(true, path_with_extension('/some/path/file.lua', 'lua'))
end)
itp('returns false if filename does not include a provided extension', function()
eq(false, path_with_extension('/some/path/file.vim', 'lua'))
eq(false, path_with_extension('/some/path/file', 'lua'))
end)
end)
end) end)