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* *:runtime*
:ru[ntime][!] [where] {file} .. :ru[ntime][!] [where] {file} ..
Read Ex commands from {file} in each directory given Source vim/lua {file} in each directory given by
by 'runtimepath' and/or 'packpath'. There is no error '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. for non-existing files.
Example: > 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 Note that {name} is the directory name, not the name
of the .vim file. All the files matching the pattern of the .vim file. All the files matching the pattern
pack/*/opt/{name}/plugin/**/*.vim ~ pack/*/opt/{name}/plugin/**/*.vim ~
and
pack/*/opt/{name}/plugin/**/*.lua ~
will be sourced. This allows for using subdirectories will be sourced. This allows for using subdirectories
below "plugin", just like with plugins in below "plugin", just like with plugins in
'runtimepath'. 'runtimepath'.

View File

@@ -469,10 +469,15 @@ accordingly. Vim proceeds in this order:
7. Load the plugin scripts. *load-plugins* 7. Load the plugin scripts. *load-plugins*
This does the same as the command: > This does the same as the command: >
:runtime! plugin/**/*.vim :runtime! plugin/**/*.vim
:runtime! plugin/**/*.lua
< The result is that all directories in the 'runtimepath' option will be < The result is that all directories in the 'runtimepath' option will be
searched for the "plugin" sub-directory and all files ending in ".vim" searched for the "plugin" sub-directory and all files ending in ".vim"
will be sourced (in alphabetical order per directory), also in and ".lua" will be sourced (in alphabetical order per directory),
subdirectories. 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 However, directories in 'runtimepath' ending in "after" are skipped
here and only loaded after packages, see below. here and only loaded after packages, see below.
Loading plugins won't be done when: Loading plugins won't be done when:

View File

@@ -1367,7 +1367,8 @@ static void load_plugins(void)
{ {
if (p_lpl) { if (p_lpl) {
char_u *rtp_copy = NULL; 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 // First add all package directories to 'runtimepath', so that their
// autoload directories can be found. Only if not done already with a // 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, 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); DIP_ALL | DIP_NOAFTER);
TIME_MSG("loading plugins"); TIME_MSG("loading plugins");
xfree(rtp_copy); xfree(rtp_copy);
@@ -1392,7 +1396,8 @@ static void load_plugins(void)
} }
TIME_MSG("loading packages"); 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"); TIME_MSG("loading after plugins");
} }
} }

View File

@@ -15,6 +15,7 @@
#include "nvim/misc1.h" #include "nvim/misc1.h"
#include "nvim/os/os.h" #include "nvim/os/os.h"
#include "nvim/runtime.h" #include "nvim/runtime.h"
#include "nvim/lua/executor.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "runtime.c.generated.h" # include "runtime.c.generated.h"
@@ -49,7 +50,11 @@ void ex_runtime(exarg_T *eap)
static void source_callback(char_u *fname, void *cookie) 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 /// 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); 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) static void source_all_matches(char_u *pat)
{ {
int num_files; 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) { if (gen_expand_wildcards(1, &pat, &num_files, &files, EW_FILE) == OK) {
for (int i = 0; i < num_files; i++) { 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); FreeWild(num_files, files);
} }
@@ -405,17 +415,15 @@ theend:
/// Load scripts in "plugin" and "ftdetect" directories of the package. /// Load scripts in "plugin" and "ftdetect" directories of the package.
static int load_pack_plugin(char_u *fname) static int load_pack_plugin(char_u *fname)
{ {
static const char *plugpat = "%s/plugin/**/*.vim"; // NOLINT
static const char *ftpat = "%s/ftdetect/*.vim"; // NOLINT static const char *ftpat = "%s/ftdetect/*.vim"; // NOLINT
int retval = FAIL;
char *const ffname = fix_fname((char *)fname); char *const ffname = fix_fname((char *)fname);
size_t len = strlen(ffname) + STRLEN(ftpat); size_t len = strlen(ffname) + STRLEN(ftpat);
char_u *pat = try_malloc(len + 1); char_u *pat = xmallocz(len);
if (pat == NULL) {
goto theend; vim_snprintf((char *)pat, len, "%s/plugin/**/*.vim", ffname);
} source_all_matches(pat);
vim_snprintf((char *)pat, len, plugpat, ffname); vim_snprintf((char *)pat, len, "%s/plugin/**/*.lua", ffname);
source_all_matches(pat); source_all_matches(pat);
char_u *cmd = vim_strsave((char_u *)"g:did_load_filetypes"); 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(cmd);
xfree(pat); xfree(pat);
retval = OK;
theend:
xfree(ffname); xfree(ffname);
return retval; return OK;
} }
// used for "cookie" of add_pack_plugin() // used for "cookie" of add_pack_plugin()

View File

@@ -11,6 +11,7 @@ local exec_lua = helpers.exec_lua
local feed = helpers.feed local feed = helpers.feed
local funcs = helpers.funcs local funcs = helpers.funcs
local mkdir = helpers.mkdir local mkdir = helpers.mkdir
local mkdir_p = helpers.mkdir_p
local nvim_prog = helpers.nvim_prog local nvim_prog = helpers.nvim_prog
local nvim_set = helpers.nvim_set local nvim_set = helpers.nvim_set
local read_file = helpers.read_file local read_file = helpers.read_file
@@ -494,6 +495,53 @@ describe('user config init', function()
end) end)
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() describe('user session', function()
local xhome = 'Xhome' local xhome = 'Xhome'
local pathsep = helpers.get_pathsep() local pathsep = helpers.get_pathsep()

View File

@@ -878,6 +878,11 @@ function module.os_kill(pid)
or 'kill -9 '..pid..' > /dev/null')) or 'kill -9 '..pid..' > /dev/null'))
end 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) module = global_helpers.tbl_extend('error', module, global_helpers)
return function(after_each) return function(after_each)

View File

@@ -101,9 +101,14 @@ describe('packadd', function()
call setline(1, 'let g:plugin_works = 24') call setline(1, 'let g:plugin_works = 24')
wq wq
exe 'split ' . plugdir . '/plugin/test.lua'
call setline(1, 'vim.g.plugin_lua_works = 24')
wq
packadd other packadd other
call assert_equal(24, g:plugin_works) call assert_equal(24, g:plugin_works)
call assert_equal(24, g:plugin_lua_works)
call assert_true(len(&rtp) > len(rtp)) call assert_true(len(&rtp) > len(rtp))
call assert_match(Escape(plugdir) . '\($\|,\)', &rtp) call assert_match(Escape(plugdir) . '\($\|,\)', &rtp)
endfunc endfunc
@@ -117,13 +122,18 @@ describe('packadd', function()
exe 'split ' . s:plugdir . '/plugin/test.vim' exe 'split ' . s:plugdir . '/plugin/test.vim'
call setline(1, 'let g:plugin_works = 42') call setline(1, 'let g:plugin_works = 42')
wq 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_works = 0
let g:plugin_lua_works = 0
packadd! mytest packadd! mytest
call assert_true(len(&rtp) > len(rtp)) call assert_true(len(&rtp) > len(rtp))
call assert_match(Escape(s:plugdir) . '\($\|,\)', &rtp) call assert_match(Escape(s:plugdir) . '\($\|,\)', &rtp)
call assert_equal(0, g:plugin_works) call assert_equal(0, g:plugin_works)
call assert_equal(0, g:plugin_lua_works)
" check the path is not added twice " check the path is not added twice
let new_rtp = &rtp let new_rtp = &rtp