mirror of
https://github.com/neovim/neovim
synced 2025-07-17 01:31:48 +00:00
feat(startup): Source runtime/plugin/**/*.lua at startup
For opt plugins these files are sourced on `:packadd` * `:runtime` Now can exexute lua files
This commit is contained in:
@ -187,8 +187,10 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|.
|
||||
|
||||
*:ru* *:runtime*
|
||||
:ru[ntime][!] [where] {file} ..
|
||||
Read Ex commands from {file} in each directory given
|
||||
by 'runtimepath' and/or 'packpath'. There is no error
|
||||
Source vim/lua {file} in each directory given by
|
||||
'runtimepath' and/or 'packpath'. The vim files are
|
||||
executed in same mannar as |:source| and lua files
|
||||
similarly as |:luafile|. There is no error
|
||||
for non-existing files.
|
||||
|
||||
Example: >
|
||||
@ -244,6 +246,8 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|.
|
||||
Note that {name} is the directory name, not the name
|
||||
of the .vim file. All the files matching the pattern
|
||||
pack/*/opt/{name}/plugin/**/*.vim ~
|
||||
and
|
||||
pack/*/opt/{name}/plugin/**/*.lua ~
|
||||
will be sourced. This allows for using subdirectories
|
||||
below "plugin", just like with plugins in
|
||||
'runtimepath'.
|
||||
|
@ -469,10 +469,15 @@ accordingly. Vim proceeds in this order:
|
||||
7. Load the plugin scripts. *load-plugins*
|
||||
This does the same as the command: >
|
||||
:runtime! plugin/**/*.vim
|
||||
:runtime! plugin/**/*.lua
|
||||
< The result is that all directories in the 'runtimepath' option will be
|
||||
searched for the "plugin" sub-directory and all files ending in ".vim"
|
||||
will be sourced (in alphabetical order per directory), also in
|
||||
subdirectories.
|
||||
and ".lua" will be sourced (in alphabetical order per directory),
|
||||
also in subdirectories. First all the "*.vim" files will be sourced and
|
||||
then all the "*.lua" files will be sourced. If two files with same
|
||||
name but different extensions exists they will be treated in same
|
||||
manner. For example when both "foo.vim" and "foo.lua" exists then
|
||||
first "foo.vim" will be sourced then "foo.lua" will be ran.
|
||||
However, directories in 'runtimepath' ending in "after" are skipped
|
||||
here and only loaded after packages, see below.
|
||||
Loading plugins won't be done when:
|
||||
|
@ -1367,7 +1367,8 @@ static void load_plugins(void)
|
||||
{
|
||||
if (p_lpl) {
|
||||
char_u *rtp_copy = NULL;
|
||||
char_u *const plugin_pattern = (char_u *)"plugin/**/*.vim"; // NOLINT
|
||||
char_u *const plugin_pattern_vim = (char_u *)"plugin/**/*.vim"; // NOLINT
|
||||
char_u *const plugin_pattern_lua = (char_u *)"plugin/**/*.lua"; // NOLINT
|
||||
|
||||
// First add all package directories to 'runtimepath', so that their
|
||||
// autoload directories can be found. Only if not done already with a
|
||||
@ -1380,7 +1381,10 @@ static void load_plugins(void)
|
||||
}
|
||||
|
||||
source_in_path(rtp_copy == NULL ? p_rtp : rtp_copy,
|
||||
plugin_pattern,
|
||||
plugin_pattern_vim,
|
||||
DIP_ALL | DIP_NOAFTER);
|
||||
source_in_path(rtp_copy == NULL ? p_rtp : rtp_copy,
|
||||
plugin_pattern_lua,
|
||||
DIP_ALL | DIP_NOAFTER);
|
||||
TIME_MSG("loading plugins");
|
||||
xfree(rtp_copy);
|
||||
@ -1392,7 +1396,8 @@ static void load_plugins(void)
|
||||
}
|
||||
TIME_MSG("loading packages");
|
||||
|
||||
source_runtime(plugin_pattern, DIP_ALL | DIP_AFTER);
|
||||
source_runtime(plugin_pattern_vim, DIP_ALL | DIP_AFTER);
|
||||
source_runtime(plugin_pattern_lua, DIP_ALL | DIP_AFTER);
|
||||
TIME_MSG("loading after plugins");
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "nvim/misc1.h"
|
||||
#include "nvim/os/os.h"
|
||||
#include "nvim/runtime.h"
|
||||
#include "nvim/lua/executor.h"
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "runtime.c.generated.h"
|
||||
@ -49,7 +50,11 @@ void ex_runtime(exarg_T *eap)
|
||||
|
||||
static void source_callback(char_u *fname, void *cookie)
|
||||
{
|
||||
(void)do_source(fname, false, DOSO_NONE);
|
||||
if (path_with_extension((const char *)fname, "lua")) {
|
||||
nlua_exec_file((const char *)fname);
|
||||
} else {
|
||||
(void)do_source(fname, false, DOSO_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
/// Find the file "name" in all directories in "path" and invoke
|
||||
@ -245,7 +250,8 @@ int source_in_path(char_u *path, char_u *name, int flags)
|
||||
return do_in_path_and_pp(path, name, flags, source_callback, NULL);
|
||||
}
|
||||
|
||||
// Expand wildcards in "pat" and invoke do_source() for each match.
|
||||
// Expand wildcards in "pat" and invoke do_source()/nlua_exec_file()
|
||||
// for each match.
|
||||
static void source_all_matches(char_u *pat)
|
||||
{
|
||||
int num_files;
|
||||
@ -253,7 +259,11 @@ static void source_all_matches(char_u *pat)
|
||||
|
||||
if (gen_expand_wildcards(1, &pat, &num_files, &files, EW_FILE) == OK) {
|
||||
for (int i = 0; i < num_files; i++) {
|
||||
(void)do_source(files[i], false, DOSO_NONE);
|
||||
if (path_with_extension((const char *)files[i], "lua")) {
|
||||
nlua_exec_file((const char *)files[i]);
|
||||
} else {
|
||||
(void)do_source(files[i], false, DOSO_NONE);
|
||||
}
|
||||
}
|
||||
FreeWild(num_files, files);
|
||||
}
|
||||
@ -405,17 +415,15 @@ theend:
|
||||
/// Load scripts in "plugin" and "ftdetect" directories of the package.
|
||||
static int load_pack_plugin(char_u *fname)
|
||||
{
|
||||
static const char *plugpat = "%s/plugin/**/*.vim"; // NOLINT
|
||||
static const char *ftpat = "%s/ftdetect/*.vim"; // NOLINT
|
||||
|
||||
int retval = FAIL;
|
||||
char *const ffname = fix_fname((char *)fname);
|
||||
size_t len = strlen(ffname) + STRLEN(ftpat);
|
||||
char_u *pat = try_malloc(len + 1);
|
||||
if (pat == NULL) {
|
||||
goto theend;
|
||||
}
|
||||
vim_snprintf((char *)pat, len, plugpat, ffname);
|
||||
char_u *pat = xmallocz(len);
|
||||
|
||||
vim_snprintf((char *)pat, len, "%s/plugin/**/*.vim", ffname);
|
||||
source_all_matches(pat);
|
||||
vim_snprintf((char *)pat, len, "%s/plugin/**/*.lua", ffname);
|
||||
source_all_matches(pat);
|
||||
|
||||
char_u *cmd = vim_strsave((char_u *)"g:did_load_filetypes");
|
||||
@ -430,12 +438,9 @@ static int load_pack_plugin(char_u *fname)
|
||||
}
|
||||
xfree(cmd);
|
||||
xfree(pat);
|
||||
retval = OK;
|
||||
|
||||
theend:
|
||||
xfree(ffname);
|
||||
|
||||
return retval;
|
||||
return OK;
|
||||
}
|
||||
|
||||
// used for "cookie" of add_pack_plugin()
|
||||
|
@ -11,6 +11,7 @@ local exec_lua = helpers.exec_lua
|
||||
local feed = helpers.feed
|
||||
local funcs = helpers.funcs
|
||||
local mkdir = helpers.mkdir
|
||||
local mkdir_p = helpers.mkdir_p
|
||||
local nvim_prog = helpers.nvim_prog
|
||||
local nvim_set = helpers.nvim_set
|
||||
local read_file = helpers.read_file
|
||||
@ -494,6 +495,53 @@ describe('user config init', function()
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('runtime/plugin', function()
|
||||
local xhome = 'Xhome'
|
||||
local pathsep = helpers.get_pathsep()
|
||||
local xconfig = xhome .. pathsep .. 'Xconfig'
|
||||
|
||||
before_each(function()
|
||||
mkdir_p(xconfig .. pathsep .. 'nvim')
|
||||
end)
|
||||
|
||||
after_each(function()
|
||||
rmdir(xhome)
|
||||
end)
|
||||
|
||||
it('loads plugin/*.lua from XDG config home', function()
|
||||
local plugin_folder_path = table.concat({xconfig, 'nvim', 'plugin'}, pathsep)
|
||||
local plugin_file_path = table.concat({plugin_folder_path, 'plugin.lua'}, pathsep)
|
||||
mkdir_p(plugin_folder_path)
|
||||
write_file(plugin_file_path, [[
|
||||
vim.g.lua_plugin = 1
|
||||
]])
|
||||
|
||||
clear{ args_rm={'-u' }, env={ XDG_CONFIG_HOME=xconfig }}
|
||||
|
||||
eq(1, eval('g:lua_plugin'))
|
||||
rmdir(plugin_folder_path)
|
||||
end)
|
||||
|
||||
|
||||
it('loads plugin/*.lua from start plugins', function()
|
||||
local plugin_path = table.concat({xconfig, 'nvim', 'pack', 'catagory',
|
||||
'start', 'test_plugin'}, pathsep)
|
||||
local plugin_folder_path = table.concat({plugin_path, 'plugin'}, pathsep)
|
||||
local plugin_file_path = table.concat({plugin_folder_path, 'plugin.lua'},
|
||||
pathsep)
|
||||
mkdir_p(plugin_folder_path)
|
||||
write_file(plugin_file_path, [[
|
||||
vim.g.lua_plugin = 2
|
||||
]])
|
||||
|
||||
clear{ args_rm={'-u' }, env={ XDG_CONFIG_HOME=xconfig }}
|
||||
|
||||
eq(2, eval('g:lua_plugin'))
|
||||
rmdir(plugin_path)
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
describe('user session', function()
|
||||
local xhome = 'Xhome'
|
||||
local pathsep = helpers.get_pathsep()
|
||||
|
@ -878,6 +878,11 @@ function module.os_kill(pid)
|
||||
or 'kill -9 '..pid..' > /dev/null'))
|
||||
end
|
||||
|
||||
-- Create directories with non exsisting intermidiate directories
|
||||
function module.mkdir_p(path)
|
||||
return module.meths.call_function('mkdir', {path, 'p'})
|
||||
end
|
||||
|
||||
module = global_helpers.tbl_extend('error', module, global_helpers)
|
||||
|
||||
return function(after_each)
|
||||
|
@ -101,9 +101,14 @@ describe('packadd', function()
|
||||
call setline(1, 'let g:plugin_works = 24')
|
||||
wq
|
||||
|
||||
exe 'split ' . plugdir . '/plugin/test.lua'
|
||||
call setline(1, 'vim.g.plugin_lua_works = 24')
|
||||
wq
|
||||
|
||||
packadd other
|
||||
|
||||
call assert_equal(24, g:plugin_works)
|
||||
call assert_equal(24, g:plugin_lua_works)
|
||||
call assert_true(len(&rtp) > len(rtp))
|
||||
call assert_match(Escape(plugdir) . '\($\|,\)', &rtp)
|
||||
endfunc
|
||||
@ -117,13 +122,18 @@ describe('packadd', function()
|
||||
exe 'split ' . s:plugdir . '/plugin/test.vim'
|
||||
call setline(1, 'let g:plugin_works = 42')
|
||||
wq
|
||||
exe 'split ' . s:plugdir . '/plugin/test.lua'
|
||||
call setline(1, 'let g:plugin_lua_works = 42')
|
||||
wq
|
||||
let g:plugin_works = 0
|
||||
let g:plugin_lua_works = 0
|
||||
|
||||
packadd! mytest
|
||||
|
||||
call assert_true(len(&rtp) > len(rtp))
|
||||
call assert_match(Escape(s:plugdir) . '\($\|,\)', &rtp)
|
||||
call assert_equal(0, g:plugin_works)
|
||||
call assert_equal(0, g:plugin_lua_works)
|
||||
|
||||
" check the path is not added twice
|
||||
let new_rtp = &rtp
|
||||
|
Reference in New Issue
Block a user