mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +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
	 shadmansaleh
					shadmansaleh