From 687eb0b39f3bcad9566198b4c60bbd2755032991 Mon Sep 17 00:00:00 2001 From: shadmansaleh Date: Mon, 31 May 2021 17:35:13 +0600 Subject: feat(startup): Source runtime/plugin/**/*.lua at startup For opt plugins these files are sourced on `:packadd` * `:runtime` Now can exexute lua files --- runtime/doc/repeat.txt | 8 ++++-- runtime/doc/starting.txt | 9 +++++-- src/nvim/main.c | 11 +++++--- src/nvim/runtime.c | 33 +++++++++++++---------- test/functional/core/startup_spec.lua | 48 +++++++++++++++++++++++++++++++++ test/functional/helpers.lua | 5 ++++ test/functional/legacy/packadd_spec.lua | 10 +++++++ 7 files changed, 103 insertions(+), 21 deletions(-) diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt index dd05084652..c7806398d8 100644 --- a/runtime/doc/repeat.txt +++ b/runtime/doc/repeat.txt @@ -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'. diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt index ae9022c56c..3a3caea126 100644 --- a/runtime/doc/starting.txt +++ b/runtime/doc/starting.txt @@ -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: diff --git a/src/nvim/main.c b/src/nvim/main.c index 56cd97f133..e626ad03db 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -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"); } } diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 1fb7e3b434..dadff42456 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -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() diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua index d5f03db03a..258fea85e4 100644 --- a/test/functional/core/startup_spec.lua +++ b/test/functional/core/startup_spec.lua @@ -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() diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index 4acb1a7d8d..08ca14c3df 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -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) diff --git a/test/functional/legacy/packadd_spec.lua b/test/functional/legacy/packadd_spec.lua index 486a1fe471..48cd3ef9f8 100644 --- a/test/functional/legacy/packadd_spec.lua +++ b/test/functional/legacy/packadd_spec.lua @@ -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 -- cgit From 1e6c02510afd79659519f2a69075b36784134322 Mon Sep 17 00:00:00 2001 From: shadmansaleh Date: Wed, 2 Jun 2021 09:32:37 +0600 Subject: feat(runtime): Allow lua to be used in colorschemes * tests(runtime): move runtime/plugin tests to functional/lua/runtime_spec --- runtime/doc/syntax.txt | 3 +- src/nvim/syntax.c | 4 ++ test/functional/core/startup_spec.lua | 48 ------------------- test/functional/lua/runtime_spec.lua | 89 +++++++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 49 deletions(-) create mode 100644 test/functional/lua/runtime_spec.lua diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt index b159f655fa..bf649b5940 100644 --- a/runtime/doc/syntax.txt +++ b/runtime/doc/syntax.txt @@ -4749,8 +4749,9 @@ in their own color. feature it will output "unknown". :colo[rscheme] {name} Load color scheme {name}. This searches 'runtimepath' - for the file "colors/{name}.vim". The first one that + for the file "colors/{name}.(vim|lua)". The first one that is found is loaded. + Note: "colors/{name}.vim" is tried first. Also searches all plugins in 'packpath', first below "start" and then under "opt". diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index ed886ab7f9..ce81f26d38 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -6438,6 +6438,10 @@ int load_colors(char_u *name) apply_autocmds(EVENT_COLORSCHEMEPRE, name, curbuf->b_fname, false, curbuf); snprintf((char *)buf, buflen, "colors/%s.vim", name); retval = source_runtime(buf, DIP_START + DIP_OPT); + if (retval == FAIL) { + snprintf((char *)buf, buflen, "colors/%s.lua", name); + retval = source_runtime(buf, DIP_START + DIP_OPT); + } xfree(buf); apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, FALSE, curbuf); diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua index 258fea85e4..d5f03db03a 100644 --- a/test/functional/core/startup_spec.lua +++ b/test/functional/core/startup_spec.lua @@ -11,7 +11,6 @@ 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 @@ -495,53 +494,6 @@ 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() diff --git a/test/functional/lua/runtime_spec.lua b/test/functional/lua/runtime_spec.lua new file mode 100644 index 0000000000..a37570e4a4 --- /dev/null +++ b/test/functional/lua/runtime_spec.lua @@ -0,0 +1,89 @@ +local helpers = require('test.functional.helpers')(after_each) + +local clear = helpers.clear +local eq = helpers.eq +local eval = helpers.eval +local exec = helpers.exec +local mkdir_p = helpers.mkdir_p +local rmdir = helpers.rmdir +local write_file = helpers.write_file + +describe('runtime:', function() + local xhome = 'Xhome' + local pathsep = helpers.get_pathsep() + local xconfig = xhome .. pathsep .. 'Xconfig' + + before_each(function() + clear() + mkdir_p(xconfig .. pathsep .. 'nvim') + end) + + after_each(function() + rmdir(xhome) + end) + + describe('plugin', function() + 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('colors', function() + it('loads lua colorscheme', function() + local colorscheme_folder = table.concat({xconfig, 'nvim', 'colors'}, + pathsep) + local colorscheme_file = table.concat({colorscheme_folder, 'new_colorscheme.lua'}, + pathsep) + mkdir_p(colorscheme_folder) + write_file(colorscheme_file, [[vim.g.lua_colorscheme = 1]]) + + clear{ args_rm={'-' }, env={ XDG_CONFIG_HOME=xconfig }} + exec('colorscheme new_colorscheme') + + eq(1, eval('g:lua_colorscheme')) + rmdir(colorscheme_folder) + end) + + it('loads vim colorscheme when both lua and vim version exist', function() + local colorscheme_folder = table.concat({xconfig, 'nvim', 'colors'}, + pathsep) + local colorscheme_file = table.concat({colorscheme_folder, 'new_colorscheme'}, + pathsep) + mkdir_p(colorscheme_folder) + write_file(colorscheme_file..'.vim', [[let g:colorscheme = 'vim']]) + write_file(colorscheme_file..'.lua', [[vim.g.colorscheme = 'lua']]) + + clear{ args_rm={'-u' }, env={ XDG_CONFIG_HOME=xconfig }} + exec('colorscheme new_colorscheme') + + eq('vim', eval('g:colorscheme')) + rmdir(colorscheme_folder) + end) + end) + +end) + -- cgit From 68be8b99cfb1ab6105c48707986ce409ca38dd35 Mon Sep 17 00:00:00 2001 From: shadmansaleh Date: Wed, 2 Jun 2021 13:48:13 +0600 Subject: feat(runtime): Allow lua to be used in compiler --- runtime/doc/quickfix.txt | 4 ++-- src/nvim/ex_cmds2.c | 7 ++++++- test/functional/lua/runtime_spec.lua | 30 ++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/runtime/doc/quickfix.txt b/runtime/doc/quickfix.txt index a937cfee98..ebc7e2a1b4 100644 --- a/runtime/doc/quickfix.txt +++ b/runtime/doc/quickfix.txt @@ -1208,8 +1208,8 @@ not "b:current_compiler". What the command actually does is the following: - Delete the "current_compiler" and "b:current_compiler" variables. - Define the "CompilerSet" user command. With "!" it does ":set", without "!" it does ":setlocal". -- Execute ":runtime! compiler/{name}.vim". The plugins are expected to set - options with "CompilerSet" and set the "current_compiler" variable to the +- Execute ":runtime! compiler/{name}.(vim|lua)". The plugins are expected to + set options with "CompilerSet" and set the "current_compiler" variable to the name of the compiler. - Delete the "CompilerSet" user command. - Set "b:current_compiler" to the value of "current_compiler". diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 56a14887df..3f35c41e7a 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -2421,6 +2421,7 @@ void ex_compiler(exarg_T *eap) if (*eap->arg == NUL) { // List all compiler scripts. do_cmdline_cmd("echo globpath(&rtp, 'compiler/*.vim')"); // NOLINT + do_cmdline_cmd("echo globpath(&rtp, 'compiler/*.lua')"); // NOLINT } else { size_t bufsize = STRLEN(eap->arg) + 14; buf = xmalloc(bufsize); @@ -2445,7 +2446,11 @@ void ex_compiler(exarg_T *eap) snprintf((char *)buf, bufsize, "compiler/%s.vim", eap->arg); if (source_in_path(p_rtp, buf, DIP_ALL) == FAIL) { - EMSG2(_("E666: compiler not supported: %s"), eap->arg); + // Try lua compiler + snprintf((char *)buf, bufsize, "compiler/%s.lua", eap->arg); + if (source_in_path(p_rtp, buf, DIP_ALL) == FAIL) { + EMSG2(_("E666: compiler not supported: %s"), eap->arg); + } } xfree(buf); diff --git a/test/functional/lua/runtime_spec.lua b/test/functional/lua/runtime_spec.lua index a37570e4a4..11407ad19c 100644 --- a/test/functional/lua/runtime_spec.lua +++ b/test/functional/lua/runtime_spec.lua @@ -85,5 +85,35 @@ describe('runtime:', function() end) end) + describe('compiler', function() + local compiler_folder = table.concat({xconfig, 'nvim', 'compiler'}, pathsep) + + it('loads lua compilers', function() + local compiler_file = table.concat({compiler_folder, 'new_compiler.lua'}, + pathsep) + mkdir_p(compiler_folder) + write_file(compiler_file, [[vim.g.lua_compiler = 1]]) + + clear{ args_rm={'-' }, env={ XDG_CONFIG_HOME=xconfig }} + exec('compiler new_compiler') + + eq(1, eval('g:lua_compiler')) + rmdir(compiler_folder) + end) + + it('loads vim compilers when both lua and vim version exist', function() + local compiler_file = table.concat({compiler_folder, 'new_compiler'}, + pathsep) + mkdir_p(compiler_folder) + write_file(compiler_file..'.vim', [[let g:compiler = 'vim']]) + write_file(compiler_file..'.lua', [[vim.g.compiler = 'lua']]) + + clear{ args_rm={'-u' }, env={ XDG_CONFIG_HOME=xconfig }} + exec('compiler new_compiler') + + eq('vim', eval('g:compiler')) + rmdir(compiler_folder) + end) + end) end) -- cgit From fd5e5d2715d264447d94d7253f3c78bd7003a472 Mon Sep 17 00:00:00 2001 From: shadmansaleh Date: Wed, 2 Jun 2021 16:25:50 +0600 Subject: feat(runtime): Allow lua to be used in ftplugin --- runtime/doc/usr_05.txt | 2 +- runtime/ftplugin.vim | 4 +++- test/functional/lua/runtime_spec.lua | 21 +++++++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/runtime/doc/usr_05.txt b/runtime/doc/usr_05.txt index d8634ac6ed..d0206ba82d 100644 --- a/runtime/doc/usr_05.txt +++ b/runtime/doc/usr_05.txt @@ -411,7 +411,7 @@ Examples for the "stuff" filetype on Unix: > The part is the name of the filetype the plugin is to be used for. Only files of this filetype will use the settings from the plugin. The part of the plugin file doesn't matter, you can use it to have several plugins -for the same filetype. Note that it must end in ".vim". +for the same filetype. Note that it must end in ".vim" or ".lua". Further reading: diff --git a/runtime/ftplugin.vim b/runtime/ftplugin.vim index a434b9372b..feef949dba 100644 --- a/runtime/ftplugin.vim +++ b/runtime/ftplugin.vim @@ -28,7 +28,9 @@ augroup filetypeplugin " When there is a dot it is used to separate filetype names. Thus for " "aaa.bbb" load "aaa" and then "bbb". for name in split(s, '\.') - exe 'runtime! ftplugin/' . name . '.vim ftplugin/' . name . '_*.vim ftplugin/' . name . '/*.vim' + exe 'runtime! ftplugin/' . name . '.vim ftplugin/' . name . '_*.vim ftplugin/' . name . '/*.vim' + " Load lua ftplugins + exe printf('runtime! ftplugin/%s.lua ftplugin/%s_*.lua ftplugin/%s/*.lua', name, name, name) endfor endif endfunc diff --git a/test/functional/lua/runtime_spec.lua b/test/functional/lua/runtime_spec.lua index 11407ad19c..b55141f427 100644 --- a/test/functional/lua/runtime_spec.lua +++ b/test/functional/lua/runtime_spec.lua @@ -23,6 +23,7 @@ describe('runtime:', function() end) describe('plugin', function() + before_each(clear) 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) @@ -53,6 +54,7 @@ describe('runtime:', function() end) describe('colors', function() + before_each(clear) it('loads lua colorscheme', function() local colorscheme_folder = table.concat({xconfig, 'nvim', 'colors'}, pathsep) @@ -87,6 +89,7 @@ describe('runtime:', function() describe('compiler', function() local compiler_folder = table.concat({xconfig, 'nvim', 'compiler'}, pathsep) + before_each(clear) it('loads lua compilers', function() local compiler_file = table.concat({compiler_folder, 'new_compiler.lua'}, @@ -115,5 +118,23 @@ describe('runtime:', function() rmdir(compiler_folder) end) end) + + describe('ftplugin', function() + local ftplugin_folder = table.concat({xconfig, 'nvim', 'ftplugin'}, pathsep) + + before_each(clear) + + it('loads lua ftplugins', function() + local ftplugin_file = table.concat({ftplugin_folder , 'new-ft.lua'}, pathsep) + mkdir_p(ftplugin_folder) + write_file(ftplugin_file , [[ vim.g.lua_ftplugin = 1 ]]) + + clear{ args_rm={'-u' }, env={ XDG_CONFIG_HOME=xconfig, VIMRUNTIME='runtime/' }} + + exec [[set filetype=new-ft]] + eq(1, eval('g:lua_ftplugin')) + rmdir(ftplugin_folder) + end) + end) end) -- cgit From 4dffe1ff2f284fbd4d2bdb6a0f3997e21f9c0c6c Mon Sep 17 00:00:00 2001 From: shadmansaleh Date: Wed, 2 Jun 2021 16:33:40 +0600 Subject: feat(runtime): Allow lua to be used in indent --- runtime/indent.vim | 3 ++- test/functional/lua/runtime_spec.lua | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/runtime/indent.vim b/runtime/indent.vim index 12f03648ca..2b64dd44b9 100644 --- a/runtime/indent.vim +++ b/runtime/indent.vim @@ -24,7 +24,8 @@ augroup filetypeindent " When there is a dot it is used to separate filetype names. Thus for " "aaa.bbb" load "indent/aaa.vim" and then "indent/bbb.vim". for name in split(s, '\.') - exe 'runtime! indent/' . name . '.vim' + exe 'runtime! indent/' . name . '.vim' + exe 'runtime! indent/' . name . '.lua' endfor endif endfunc diff --git a/test/functional/lua/runtime_spec.lua b/test/functional/lua/runtime_spec.lua index b55141f427..cd554d6bea 100644 --- a/test/functional/lua/runtime_spec.lua +++ b/test/functional/lua/runtime_spec.lua @@ -136,5 +136,24 @@ describe('runtime:', function() rmdir(ftplugin_folder) end) end) + + describe('indent', function() + local indent_folder = table.concat({xconfig, 'nvim', 'indent'}, pathsep) + + before_each(clear) + + it('loads lua indents', function() + local indent_file = table.concat({indent_folder , 'new-ft.lua'}, pathsep) + mkdir_p(indent_folder) + write_file(indent_file , [[ vim.g.lua_indent = 1 ]]) + + clear{ args_rm={'-u' }, env={ XDG_CONFIG_HOME=xconfig, VIMRUNTIME='runtime/' }} + + exec [[set filetype=new-ft]] + eq(1, eval('g:lua_indent')) + rmdir(indent_folder) + end) + end) + end) -- cgit From f256a18fefeebe76edcca42f530b238e95bc25b6 Mon Sep 17 00:00:00 2001 From: shadmansaleh Date: Wed, 2 Jun 2021 17:04:42 +0600 Subject: feat(runtime): Allow lua to be used in ftdetect --- runtime/filetype.vim | 1 + src/nvim/runtime.c | 6 ++++-- test/functional/lua/runtime_spec.lua | 21 +++++++++++++++++++-- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/runtime/filetype.vim b/runtime/filetype.vim index ed70ac5ce8..89cc1a8fc5 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -2303,6 +2303,7 @@ au BufNewFile,BufRead *.txt " Use the filetype detect plugins. They may overrule any of the previously " detected filetypes. runtime! ftdetect/*.vim +runtime! ftdetect/*.lua " NOTE: The above command could have ended the filetypedetect autocmd group " and started another one. Let's make sure it has ended to get to a consistent diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index dadff42456..22df4d985b 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -421,9 +421,9 @@ static int load_pack_plugin(char_u *fname) size_t len = strlen(ffname) + STRLEN(ftpat); char_u *pat = xmallocz(len); - vim_snprintf((char *)pat, len, "%s/plugin/**/*.vim", ffname); + vim_snprintf((char *)pat, len, "%s/plugin/**/*.vim", ffname); // NOLINT source_all_matches(pat); - vim_snprintf((char *)pat, len, "%s/plugin/**/*.lua", ffname); + vim_snprintf((char *)pat, len, "%s/plugin/**/*.lua", ffname); // NOLINT source_all_matches(pat); char_u *cmd = vim_strsave((char_u *)"g:did_load_filetypes"); @@ -434,6 +434,8 @@ static int load_pack_plugin(char_u *fname) do_cmdline_cmd("augroup filetypedetect"); vim_snprintf((char *)pat, len, ftpat, ffname); source_all_matches(pat); + vim_snprintf((char *)pat, len, "%s/ftdetect/*.lua", ffname); // NOLINT + source_all_matches(pat); do_cmdline_cmd("augroup END"); } xfree(cmd); diff --git a/test/functional/lua/runtime_spec.lua b/test/functional/lua/runtime_spec.lua index cd554d6bea..7286e89c76 100644 --- a/test/functional/lua/runtime_spec.lua +++ b/test/functional/lua/runtime_spec.lua @@ -127,7 +127,7 @@ describe('runtime:', function() it('loads lua ftplugins', function() local ftplugin_file = table.concat({ftplugin_folder , 'new-ft.lua'}, pathsep) mkdir_p(ftplugin_folder) - write_file(ftplugin_file , [[ vim.g.lua_ftplugin = 1 ]]) + write_file(ftplugin_file , [[vim.g.lua_ftplugin = 1]]) clear{ args_rm={'-u' }, env={ XDG_CONFIG_HOME=xconfig, VIMRUNTIME='runtime/' }} @@ -145,7 +145,7 @@ describe('runtime:', function() it('loads lua indents', function() local indent_file = table.concat({indent_folder , 'new-ft.lua'}, pathsep) mkdir_p(indent_folder) - write_file(indent_file , [[ vim.g.lua_indent = 1 ]]) + write_file(indent_file , [[vim.g.lua_indent = 1]]) clear{ args_rm={'-u' }, env={ XDG_CONFIG_HOME=xconfig, VIMRUNTIME='runtime/' }} @@ -155,5 +155,22 @@ describe('runtime:', function() end) end) + describe('ftdetect', function() + local ftdetect_folder = table.concat({xconfig, 'nvim', 'ftdetect'}, pathsep) + + before_each(clear) + + it('loads lua ftdetects', function() + local ftdetect_file = table.concat({ftdetect_folder , 'new-ft.lua'}, pathsep) + mkdir_p(ftdetect_folder) + write_file(ftdetect_file , [[vim.g.lua_ftdetect = 1]]) + + clear{ args_rm={'-u' }, env={ XDG_CONFIG_HOME=xconfig, VIMRUNTIME='runtime/' }} + + eq(1, eval('g:lua_ftdetect')) + rmdir(ftdetect_folder) + end) + end) + end) -- cgit From f000251e087637d1add3678184ada80bef432fa9 Mon Sep 17 00:00:00 2001 From: shadmansaleh Date: Wed, 2 Jun 2021 21:08:28 +0600 Subject: feat(runtime): Allow lua to be used in syntax --- runtime/syntax/synload.vim | 3 ++- test/functional/lua/runtime_spec.lua | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/runtime/syntax/synload.vim b/runtime/syntax/synload.vim index f373161c7c..3863a84c1a 100644 --- a/runtime/syntax/synload.vim +++ b/runtime/syntax/synload.vim @@ -55,7 +55,8 @@ fun! s:SynSet() " load each in sequence. Skip empty entries. for name in split(s, '\.') if !empty(name) - exe "runtime! syntax/" . name . ".vim syntax/" . name . "/*.vim" + exe "runtime! syntax/" . name . ".vim syntax/" . name . "/*.vim" + exe "runtime! syntax/" . name . ".lua syntax/" . name . "/*.lua" endif endfor endif diff --git a/test/functional/lua/runtime_spec.lua b/test/functional/lua/runtime_spec.lua index 7286e89c76..cbdc6fa184 100644 --- a/test/functional/lua/runtime_spec.lua +++ b/test/functional/lua/runtime_spec.lua @@ -172,5 +172,35 @@ describe('runtime:', function() end) end) + describe('syntax', function() + local syntax_folder = table.concat({xconfig, 'nvim', 'syntax'}, pathsep) + + before_each(clear) + + it('loads lua syntaxes on filetype change', function() + local syntax_file = table.concat({syntax_folder , 'my-lang.lua'}, pathsep) + mkdir_p(syntax_folder) + write_file(syntax_file , [[vim.g.lua_syntax = 1]]) + + clear{ args_rm={'-u' }, env={ XDG_CONFIG_HOME=xconfig, VIMRUNTIME='runtime/' }} + + exec('set filetype=my-lang') + eq(1, eval('g:lua_syntax')) + rmdir(syntax_folder) + end) + + it('loads lua syntaxes on syntax change', function() + local syntax_file = table.concat({syntax_folder , 'my-lang.lua'}, pathsep) + mkdir_p(syntax_folder) + write_file(syntax_file , [[vim.g.lua_syntax = 5]]) + + clear{ args_rm={'-u' }, env={ XDG_CONFIG_HOME=xconfig, VIMRUNTIME='runtime/' }} + + exec('set syntax=my-lang') + eq(5, eval('g:lua_syntax')) + rmdir(syntax_folder) + end) + end) + end) -- cgit From 07c9b20c75d318dcdee9e5196bca12ee66d041ba Mon Sep 17 00:00:00 2001 From: shadmansaleh Date: Wed, 2 Jun 2021 19:39:24 +0600 Subject: enhance(runtime): Enable completion for lua files Enabled for `:colorscheme` `:compiler` filetype --- src/nvim/ex_getln.c | 32 ++++++++++++++++++++++++++++---- src/nvim/vim.h | 1 + 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 75ed5dc0e5..f63987136f 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -5115,11 +5115,12 @@ ExpandFromContext ( } if (xp->xp_context == EXPAND_COLORS) { char *directories[] = { "colors", NULL }; - return ExpandRTDir(pat, DIP_START + DIP_OPT, num_file, file, directories); + return ExpandRTDir(pat, DIP_START + DIP_OPT + DIP_LUA, num_file, file, + directories); } if (xp->xp_context == EXPAND_COMPILER) { char *directories[] = { "compiler", NULL }; - return ExpandRTDir(pat, 0, num_file, file, directories); + return ExpandRTDir(pat, DIP_LUA, num_file, file, directories); } if (xp->xp_context == EXPAND_OWNSYNTAX) { char *directories[] = { "syntax", NULL }; @@ -5127,7 +5128,7 @@ ExpandFromContext ( } if (xp->xp_context == EXPAND_FILETYPE) { char *directories[] = { "syntax", "indent", "ftplugin", NULL }; - return ExpandRTDir(pat, 0, num_file, file, directories); + return ExpandRTDir(pat, DIP_LUA, num_file, file, directories); } if (xp->xp_context == EXPAND_CHECKHEALTH) { char *directories[] = { "autoload/health", NULL }; @@ -5567,6 +5568,7 @@ static int ExpandUserList(expand_T *xp, int *num_file, char_u ***file) /// 'packpath'/pack/ * /start/ * /{dirnames}/{pat}.vim /// When "flags" has DIP_OPT: search also from 'opt' of 'packpath': /// 'packpath'/pack/ * /opt/ * /{dirnames}/{pat}.vim +/// When "flags" has DIP_LUA: search also performed for .lua files /// "dirnames" is an array with one or more directory names. static int ExpandRTDir(char_u *pat, int flags, int *num_file, char_u ***file, char *dirnames[]) @@ -5584,6 +5586,10 @@ static int ExpandRTDir(char_u *pat, int flags, int *num_file, char_u ***file, char_u *s = xmalloc(size); snprintf((char *)s, size, "%s/%s*.vim", dirnames[i], pat); globpath(p_rtp, s, &ga, 0); + if (flags & DIP_LUA) { + snprintf((char *)s, size, "%s/%s*.lua", dirnames[i], pat); + globpath(p_rtp, s, &ga, 0); + } xfree(s); } @@ -5593,6 +5599,10 @@ static int ExpandRTDir(char_u *pat, int flags, int *num_file, char_u ***file, char_u *s = xmalloc(size); snprintf((char *)s, size, "pack/*/start/*/%s/%s*.vim", dirnames[i], pat); // NOLINT globpath(p_pp, s, &ga, 0); + if (flags & DIP_LUA) { + snprintf((char *)s, size, "pack/*/start/*/%s/%s*.lua", dirnames[i], pat); // NOLINT + globpath(p_pp, s, &ga, 0); + } xfree(s); } @@ -5601,6 +5611,10 @@ static int ExpandRTDir(char_u *pat, int flags, int *num_file, char_u ***file, char_u *s = xmalloc(size); snprintf((char *)s, size, "start/*/%s/%s*.vim", dirnames[i], pat); // NOLINT globpath(p_pp, s, &ga, 0); + if (flags & DIP_LUA) { + snprintf((char *)s, size, "start/*/%s/%s*.lua", dirnames[i], pat); // NOLINT + globpath(p_pp, s, &ga, 0); + } xfree(s); } } @@ -5611,6 +5625,10 @@ static int ExpandRTDir(char_u *pat, int flags, int *num_file, char_u ***file, char_u *s = xmalloc(size); snprintf((char *)s, size, "pack/*/opt/*/%s/%s*.vim", dirnames[i], pat); // NOLINT globpath(p_pp, s, &ga, 0); + if (flags & DIP_LUA) { + snprintf((char *)s, size, "pack/*/opt/*/%s/%s*.lua", dirnames[i], pat); // NOLINT + globpath(p_pp, s, &ga, 0); + } xfree(s); } @@ -5619,6 +5637,10 @@ static int ExpandRTDir(char_u *pat, int flags, int *num_file, char_u ***file, char_u *s = xmalloc(size); snprintf((char *)s, size, "opt/*/%s/%s*.vim", dirnames[i], pat); // NOLINT globpath(p_pp, s, &ga, 0); + if (flags & DIP_LUA) { + snprintf((char *)s, size, "opt/*/%s/%s*.lua", dirnames[i], pat); // NOLINT + globpath(p_pp, s, &ga, 0); + } xfree(s); } } @@ -5627,7 +5649,9 @@ static int ExpandRTDir(char_u *pat, int flags, int *num_file, char_u ***file, char_u *match = ((char_u **)ga.ga_data)[i]; char_u *s = match; char_u *e = s + STRLEN(s); - if (e - s > 4 && STRNICMP(e - 4, ".vim", 4) == 0) { + if (e - s > 4 && (STRNICMP(e - 4, ".vim", 4) == 0 + || ((flags & DIP_LUA) + && STRNICMP(e - 4, ".lua", 4) == 0))) { e -= 4; for (s = e; s > match; MB_PTR_BACK(match, s)) { if (vim_ispathsep(*s)) { diff --git a/src/nvim/vim.h b/src/nvim/vim.h index 0245c472ef..df4ab04eb6 100644 --- a/src/nvim/vim.h +++ b/src/nvim/vim.h @@ -313,6 +313,7 @@ enum { FOLD_TEXT_LEN = 51 }; //!< buffer size for get_foldtext() #define DIP_NORTP 0x20 // do not use 'runtimepath' #define DIP_NOAFTER 0x40 // skip "after" directories #define DIP_AFTER 0x80 // only use "after" directories +#define DIP_LUA 0x100 // also use ".lua" files // Lowest number used for window ID. Cannot have this many windows per tab. #define LOWEST_WIN_ID 1000 -- cgit From 92b6b3764cf75d01bcbf04fcf598140fc01e7902 Mon Sep 17 00:00:00 2001 From: shadmansaleh Date: Wed, 2 Jun 2021 22:46:25 +0600 Subject: refactor(tests): Simplify tests at functional/lua/runtime_spec --- test/functional/core/startup_spec.lua | 57 ++++++++++++++++ test/functional/lua/runtime_spec.lua | 123 ++++++++-------------------------- 2 files changed, 86 insertions(+), 94 deletions(-) diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua index d5f03db03a..30c0758446 100644 --- a/test/functional/core/startup_spec.lua +++ b/test/functional/core/startup_spec.lua @@ -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,62 @@ describe('user config init', function() end) end) +describe('runtime:', function() + local xhome = 'Xhome' + local pathsep = helpers.get_pathsep() + local xconfig = xhome .. pathsep .. 'Xconfig' + + setup(function() + mkdir_p(xconfig .. pathsep .. 'nvim') + end) + + teardown(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) + + it('loads ftdetect/*.lua', function() + local ftdetect_folder = table.concat({xconfig, 'nvim', 'ftdetect'}, pathsep) + local ftdetect_file = table.concat({ftdetect_folder , 'new-ft.lua'}, pathsep) + mkdir_p(ftdetect_folder) + write_file(ftdetect_file , [[vim.g.lua_ftdetect = 1]]) + + -- TODO(shadmansaleh): Figure out why this test fails without + -- setting VIMRUNTIME + clear{ args_rm={'-u'}, env={XDG_CONFIG_HOME=xconfig, + VIMRUNTIME='runtime/'}} + + eq(1, eval('g:lua_ftdetect')) + rmdir(ftdetect_folder) + end) +end) + describe('user session', function() local xhome = 'Xhome' local pathsep = helpers.get_pathsep() diff --git a/test/functional/lua/runtime_spec.lua b/test/functional/lua/runtime_spec.lua index cbdc6fa184..e9c34c9228 100644 --- a/test/functional/lua/runtime_spec.lua +++ b/test/functional/lua/runtime_spec.lua @@ -9,61 +9,36 @@ local rmdir = helpers.rmdir local write_file = helpers.write_file describe('runtime:', function() - local xhome = 'Xhome' - local pathsep = helpers.get_pathsep() - local xconfig = xhome .. pathsep .. 'Xconfig' - - before_each(function() - clear() - mkdir_p(xconfig .. pathsep .. 'nvim') + local plug_dir = 'Test_Plugin' + local sep = helpers.get_pathsep() + local init = 'dummy_init.lua' + + setup(function() + io.open(init, 'w'):close() -- touch init file + clear{args = {'-u', init}} + exec('set rtp+=' .. plug_dir) end) - after_each(function() - rmdir(xhome) + teardown(function() + os.remove(init) end) - describe('plugin', function() - before_each(clear) - 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 }} + before_each(function() + mkdir_p(plug_dir) + end) - eq(2, eval('g:lua_plugin')) - rmdir(plugin_path) - end) + after_each(function() + rmdir(plug_dir) end) describe('colors', function() - before_each(clear) + local colorscheme_folder = plug_dir .. sep .. 'colors' + it('loads lua colorscheme', function() - local colorscheme_folder = table.concat({xconfig, 'nvim', 'colors'}, - pathsep) - local colorscheme_file = table.concat({colorscheme_folder, 'new_colorscheme.lua'}, - pathsep) + local colorscheme_file = colorscheme_folder .. sep .. 'new_colorscheme.lua' mkdir_p(colorscheme_folder) write_file(colorscheme_file, [[vim.g.lua_colorscheme = 1]]) - clear{ args_rm={'-' }, env={ XDG_CONFIG_HOME=xconfig }} exec('colorscheme new_colorscheme') eq(1, eval('g:lua_colorscheme')) @@ -71,15 +46,11 @@ describe('runtime:', function() end) it('loads vim colorscheme when both lua and vim version exist', function() - local colorscheme_folder = table.concat({xconfig, 'nvim', 'colors'}, - pathsep) - local colorscheme_file = table.concat({colorscheme_folder, 'new_colorscheme'}, - pathsep) + local colorscheme_file = colorscheme_folder .. sep .. 'new_colorscheme' mkdir_p(colorscheme_folder) write_file(colorscheme_file..'.vim', [[let g:colorscheme = 'vim']]) write_file(colorscheme_file..'.lua', [[vim.g.colorscheme = 'lua']]) - clear{ args_rm={'-u' }, env={ XDG_CONFIG_HOME=xconfig }} exec('colorscheme new_colorscheme') eq('vim', eval('g:colorscheme')) @@ -88,16 +59,13 @@ describe('runtime:', function() end) describe('compiler', function() - local compiler_folder = table.concat({xconfig, 'nvim', 'compiler'}, pathsep) - before_each(clear) + local compiler_folder = plug_dir .. sep .. 'compiler' it('loads lua compilers', function() - local compiler_file = table.concat({compiler_folder, 'new_compiler.lua'}, - pathsep) + local compiler_file = compiler_folder .. sep .. 'new_compiler.lua' mkdir_p(compiler_folder) write_file(compiler_file, [[vim.g.lua_compiler = 1]]) - clear{ args_rm={'-' }, env={ XDG_CONFIG_HOME=xconfig }} exec('compiler new_compiler') eq(1, eval('g:lua_compiler')) @@ -105,13 +73,11 @@ describe('runtime:', function() end) it('loads vim compilers when both lua and vim version exist', function() - local compiler_file = table.concat({compiler_folder, 'new_compiler'}, - pathsep) + local compiler_file = compiler_folder .. sep .. 'new_compiler' mkdir_p(compiler_folder) write_file(compiler_file..'.vim', [[let g:compiler = 'vim']]) write_file(compiler_file..'.lua', [[vim.g.compiler = 'lua']]) - clear{ args_rm={'-u' }, env={ XDG_CONFIG_HOME=xconfig }} exec('compiler new_compiler') eq('vim', eval('g:compiler')) @@ -120,17 +86,13 @@ describe('runtime:', function() end) describe('ftplugin', function() - local ftplugin_folder = table.concat({xconfig, 'nvim', 'ftplugin'}, pathsep) - - before_each(clear) + local ftplugin_folder = table.concat({plug_dir, 'ftplugin'}, sep) it('loads lua ftplugins', function() - local ftplugin_file = table.concat({ftplugin_folder , 'new-ft.lua'}, pathsep) + local ftplugin_file = table.concat({ftplugin_folder , 'new-ft.lua'}, sep) mkdir_p(ftplugin_folder) write_file(ftplugin_file , [[vim.g.lua_ftplugin = 1]]) - clear{ args_rm={'-u' }, env={ XDG_CONFIG_HOME=xconfig, VIMRUNTIME='runtime/' }} - exec [[set filetype=new-ft]] eq(1, eval('g:lua_ftplugin')) rmdir(ftplugin_folder) @@ -138,64 +100,37 @@ describe('runtime:', function() end) describe('indent', function() - local indent_folder = table.concat({xconfig, 'nvim', 'indent'}, pathsep) - - before_each(clear) + local indent_folder = table.concat({plug_dir, 'indent'}, sep) it('loads lua indents', function() - local indent_file = table.concat({indent_folder , 'new-ft.lua'}, pathsep) + local indent_file = table.concat({indent_folder , 'new-ft.lua'}, sep) mkdir_p(indent_folder) write_file(indent_file , [[vim.g.lua_indent = 1]]) - clear{ args_rm={'-u' }, env={ XDG_CONFIG_HOME=xconfig, VIMRUNTIME='runtime/' }} - exec [[set filetype=new-ft]] eq(1, eval('g:lua_indent')) rmdir(indent_folder) end) end) - describe('ftdetect', function() - local ftdetect_folder = table.concat({xconfig, 'nvim', 'ftdetect'}, pathsep) - - before_each(clear) - - it('loads lua ftdetects', function() - local ftdetect_file = table.concat({ftdetect_folder , 'new-ft.lua'}, pathsep) - mkdir_p(ftdetect_folder) - write_file(ftdetect_file , [[vim.g.lua_ftdetect = 1]]) - - clear{ args_rm={'-u' }, env={ XDG_CONFIG_HOME=xconfig, VIMRUNTIME='runtime/' }} - - eq(1, eval('g:lua_ftdetect')) - rmdir(ftdetect_folder) - end) - end) - describe('syntax', function() - local syntax_folder = table.concat({xconfig, 'nvim', 'syntax'}, pathsep) - - before_each(clear) + local syntax_folder = table.concat({plug_dir, 'syntax'}, sep) it('loads lua syntaxes on filetype change', function() - local syntax_file = table.concat({syntax_folder , 'my-lang.lua'}, pathsep) + local syntax_file = table.concat({syntax_folder , 'my-lang.lua'}, sep) mkdir_p(syntax_folder) write_file(syntax_file , [[vim.g.lua_syntax = 1]]) - clear{ args_rm={'-u' }, env={ XDG_CONFIG_HOME=xconfig, VIMRUNTIME='runtime/' }} - exec('set filetype=my-lang') eq(1, eval('g:lua_syntax')) rmdir(syntax_folder) end) it('loads lua syntaxes on syntax change', function() - local syntax_file = table.concat({syntax_folder , 'my-lang.lua'}, pathsep) + local syntax_file = table.concat({syntax_folder , 'my-lang.lua'}, sep) mkdir_p(syntax_folder) write_file(syntax_file , [[vim.g.lua_syntax = 5]]) - clear{ args_rm={'-u' }, env={ XDG_CONFIG_HOME=xconfig, VIMRUNTIME='runtime/' }} - exec('set syntax=my-lang') eq(5, eval('g:lua_syntax')) rmdir(syntax_folder) -- cgit From e1edc079dd0d0cb4a53e5998086568cf9d10a26a Mon Sep 17 00:00:00 2001 From: shadmansaleh Date: Thu, 3 Jun 2021 07:07:51 +0600 Subject: refactor(source): Move lua file detection to do_source So now :source can run lua files too :) * feat: Add support for :[ranged]source for lua files --- runtime/doc/repeat.txt | 6 +++-- runtime/doc/starting.txt | 2 +- src/nvim/ex_cmds2.c | 18 ++++++++++--- src/nvim/lua/executor.c | 18 +++++++++++++ src/nvim/main.c | 14 +++------- src/nvim/runtime.c | 13 ++-------- test/functional/ex_cmds/source_spec.lua | 46 +++++++++++++++++++++++++++++++++ 7 files changed, 89 insertions(+), 28 deletions(-) diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt index c7806398d8..6755747dcf 100644 --- a/runtime/doc/repeat.txt +++ b/runtime/doc/repeat.txt @@ -172,9 +172,11 @@ Using Vim scripts *using-scripts* For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|. *:so* *:source* *load-vim-script* -:so[urce] {file} Read Ex commands from {file}. These are commands that - start with a ":". +:so[urce] {file} Runs vim or lua {file} Triggers the |SourcePre| autocommand. + + Note: Only files ending with `.lua` is sourced as + lua file. Anything else is assumed to be vimscript. *:source!* :so[urce]! {file} Read Vim commands from {file}. These are commands that are executed from Normal mode, like you type diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt index 3a3caea126..2110b88330 100644 --- a/runtime/doc/starting.txt +++ b/runtime/doc/starting.txt @@ -477,7 +477,7 @@ accordingly. Vim proceeds in this order: 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. + first "foo.vim" will be sourced then "foo.lua" will be sourced. However, directories in 'runtimepath' ending in "after" are skipped here and only loaded after packages, see below. Loading plugins won't be done when: diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 3f35c41e7a..4798e93b91 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -27,6 +27,7 @@ #include "nvim/ex_getln.h" #include "nvim/fileio.h" #include "nvim/getchar.h" +#include "nvim/globals.h" #include "nvim/mark.h" #include "nvim/mbyte.h" #include "nvim/memline.h" @@ -53,6 +54,7 @@ #include "nvim/os/fs_defs.h" #include "nvim/api/private/helpers.h" #include "nvim/api/private/defs.h" +#include "nvim/lua/executor.h" /// Growarray to store info about already sourced scripts. @@ -2661,8 +2663,13 @@ static void cmd_source_buffer(const exarg_T *eap) .curr_lnum = eap->line1, .final_lnum = eap->line2, }; - source_using_linegetter((void *)&cookie, get_buffer_line, - ":source (no file)"); + if (curbuf != NULL && curbuf->b_fname + && path_with_extension((const char *)curbuf->b_fname, "lua")) { + nlua_source_using_linegetter(get_buffer_line, (void *)&cookie, ":source"); + } else { + source_using_linegetter((void *)&cookie, get_buffer_line, + ":source (no file)"); + } } /// ":source" and associated commands. @@ -2774,7 +2781,8 @@ int do_source_str(const char *cmd, const char *traceback_name) return source_using_linegetter((void *)&cookie, get_str_line, traceback_name); } -/// Reads the file `fname` and executes its lines as Ex commands. +/// When fname is a 'lua' file nlua_exec_file() is invoked to source it. +/// Otherwise reads the file `fname` and executes its lines as Ex commands. /// /// This function may be called recursively! /// @@ -2801,6 +2809,10 @@ int do_source(char_u *fname, int check_other, int is_vimrc) proftime_T wait_start; bool trigger_source_post = false; + if (path_with_extension((const char *)fname, "lua")) { + return (int)nlua_exec_file((const char *)fname); + } + p = expand_env_save(fname); if (p == NULL) { return retval; diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 0a52cc16cb..afc387ef38 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -1161,6 +1161,24 @@ static void nlua_typval_exec(const char *lcmd, size_t lcmd_len, } } +int nlua_source_using_linegetter(LineGetter fgetline, + void *cookie, char *name) +{ + garray_T ga; + char_u *line = NULL; + + ga_init(&ga, (int)sizeof(char_u *), 10); + while ((line = fgetline(0, cookie, 0, false)) != NULL) { + GA_APPEND(char_u *, &ga, line); + } + char *code = (char *)ga_concat_strings_sep(&ga, "\n"); + size_t len = strlen(code); + nlua_typval_exec(code, len, name, NULL, 0, false, NULL); + ga_clear_strings(&ga); + xfree(code); + return OK; +} + /// Call a LuaCallable given some typvals /// /// Used to call any lua callable passed from Lua into VimL diff --git a/src/nvim/main.c b/src/nvim/main.c index e626ad03db..53043d293e 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1101,11 +1101,7 @@ static void command_line_scan(mparm_T *parmp) size_t s_size = STRLEN(a) + 9; char *s = xmalloc(s_size); - if (path_with_extension(a, "lua")) { - snprintf(s, s_size, "luafile %s", a); - } else { - snprintf(s, s_size, "so %s", a); - } + snprintf(s, s_size, "so %s", a); parmp->cmds_tofree[parmp->n_commands] = true; parmp->commands[parmp->n_commands++] = s; } else { @@ -1888,12 +1884,8 @@ static void source_startup_scripts(const mparm_T *const parmp) || strequal(parmp->use_vimrc, "NORC")) { // Do nothing. } else { - if (path_with_extension(parmp->use_vimrc, "lua")) { - 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); - } + 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) { diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 22df4d985b..c3cd210538 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -15,7 +15,6 @@ #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" @@ -50,11 +49,7 @@ void ex_runtime(exarg_T *eap) static void source_callback(char_u *fname, void *cookie) { - if (path_with_extension((const char *)fname, "lua")) { - nlua_exec_file((const char *)fname); - } else { - (void)do_source(fname, false, DOSO_NONE); - } + (void)do_source(fname, false, DOSO_NONE); } /// Find the file "name" in all directories in "path" and invoke @@ -259,11 +254,7 @@ 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++) { - 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); - } + (void)do_source(files[i], false, DOSO_NONE); } FreeWild(num_files, files); } diff --git a/test/functional/ex_cmds/source_spec.lua b/test/functional/ex_cmds/source_spec.lua index 16d0dfb6a1..a03e1ae9ce 100644 --- a/test/functional/ex_cmds/source_spec.lua +++ b/test/functional/ex_cmds/source_spec.lua @@ -6,6 +6,9 @@ local clear = helpers.clear local meths = helpers.meths local feed = helpers.feed local feed_command = helpers.feed_command +local write_file = helpers.write_file +local exec = helpers.exec +local eval = helpers.eval describe(':source', function() before_each(function() @@ -44,4 +47,47 @@ describe(':source', function() command('source') eq('4', meths.exec('echo luaeval("y")', true)) end) + + it('can source lua files', function() + local test_file = 'test.lua' + write_file (test_file, [[vim.g.sourced_lua = 1]]) + + exec('source ' .. test_file) + + eq(1, eval('g:sourced_lua')) + os.remove(test_file) + end) + + it('can source selected region in lua file', function() + local test_file = 'test.lua' + + write_file (test_file, [[ + vim.g.b = 5 + vim.g.b = 6 + vim.g.b = 7 + ]]) + + command('edit '..test_file) + feed('ggjV') + feed_command(':source') + + eq(6, eval('g:b')) + os.remove(test_file) + end) + + it('can source current lua buffer without argument', function() + local test_file = 'test.lua' + + write_file (test_file, [[ + vim.g.c = 10 + vim.g.c = 11 + vim.g.c = 12 + ]]) + + command('edit '..test_file) + feed_command(':source') + + eq(12, eval('g:c')) + os.remove(test_file) + end) end) -- cgit