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:
shadmansaleh
2021-05-31 17:35:13 +06:00
parent 1df8a34a7b
commit 687eb0b39f
7 changed files with 103 additions and 21 deletions

View File

@ -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'.

View File

@ -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:

View File

@ -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");
}
}

View File

@ -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()

View File

@ -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()

View File

@ -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)

View File

@ -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