mirror of
https://github.com/neovim/neovim.git
synced 2025-10-04 17:06:30 +00:00
Merge pull request #12235 from dm1try/add_init_lua
add init.lua as an alternative user config
This commit is contained in:
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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);
|
||||||
snprintf(s, s_size, "so %s", a);
|
if (path_with_extension(a, "lua")) {
|
||||||
|
snprintf(s, s_size, "luafile %s", a);
|
||||||
|
} else {
|
||||||
|
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;
|
||||||
@@ -1829,8 +1851,12 @@ static void source_startup_scripts(const mparm_T *const parmp)
|
|||||||
|| strequal(parmp->use_vimrc, "NORC")) {
|
|| strequal(parmp->use_vimrc, "NORC")) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
} else {
|
} else {
|
||||||
if (do_source((char_u *)parmp->use_vimrc, false, DOSO_NONE) != OK) {
|
if (path_with_extension(parmp->use_vimrc, "lua")) {
|
||||||
EMSG2(_("E282: Cannot read from \"%s\""), parmp->use_vimrc);
|
nlua_exec_file(parmp->use_vimrc);
|
||||||
|
} else {
|
||||||
|
if (do_source((char_u *)parmp->use_vimrc, false, DOSO_NONE) != OK) {
|
||||||
|
EMSG2(_("E282: Cannot read from \"%s\""), parmp->use_vimrc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!silent_mode) {
|
} else if (!silent_mode) {
|
||||||
|
@@ -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.
|
||||||
*/
|
*/
|
||||||
|
@@ -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)
|
||||||
|
@@ -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)
|
||||||
|
Reference in New Issue
Block a user