aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/quickfix.txt4
-rw-r--r--runtime/doc/repeat.txt14
-rw-r--r--runtime/doc/starting.txt9
-rw-r--r--runtime/doc/syntax.txt3
-rw-r--r--runtime/doc/usr_05.txt2
-rw-r--r--runtime/filetype.vim1
-rw-r--r--runtime/ftplugin.vim4
-rw-r--r--runtime/indent.vim3
-rw-r--r--runtime/syntax/synload.vim3
-rw-r--r--src/nvim/ex_cmds2.c25
-rw-r--r--src/nvim/ex_getln.c32
-rw-r--r--src/nvim/lua/executor.c18
-rw-r--r--src/nvim/main.c25
-rw-r--r--src/nvim/runtime.c22
-rw-r--r--src/nvim/syntax.c4
-rw-r--r--src/nvim/vim.h1
-rw-r--r--test/functional/core/startup_spec.lua57
-rw-r--r--test/functional/ex_cmds/source_spec.lua46
-rw-r--r--test/functional/helpers.lua5
-rw-r--r--test/functional/legacy/packadd_spec.lua10
-rw-r--r--test/functional/lua/runtime_spec.lua141
21 files changed, 382 insertions, 47 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/runtime/doc/repeat.txt b/runtime/doc/repeat.txt
index dd05084652..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
@@ -187,8 +189,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 +248,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..2110b88330 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 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/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/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 <filetype> 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 <name>
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/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/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/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/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/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 56a14887df..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.
@@ -2421,6 +2423,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 +2448,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);
@@ -2656,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.
@@ -2769,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!
///
@@ -2796,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/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/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 56cd97f133..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 {
@@ -1367,7 +1363,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 +1377,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 +1392,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");
}
}
@@ -1883,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 1fb7e3b434..c3cd210538 100644
--- a/src/nvim/runtime.c
+++ b/src/nvim/runtime.c
@@ -245,7 +245,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;
@@ -405,17 +406,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); // NOLINT
+ source_all_matches(pat);
+ 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");
@@ -426,16 +425,15 @@ 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);
xfree(pat);
- retval = OK;
-
-theend:
xfree(ffname);
- return retval;
+ return OK;
}
// used for "cookie" of add_pack_plugin()
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/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
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/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)
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
diff --git a/test/functional/lua/runtime_spec.lua b/test/functional/lua/runtime_spec.lua
new file mode 100644
index 0000000000..e9c34c9228
--- /dev/null
+++ b/test/functional/lua/runtime_spec.lua
@@ -0,0 +1,141 @@
+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 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)
+
+ teardown(function()
+ os.remove(init)
+ end)
+
+ before_each(function()
+ mkdir_p(plug_dir)
+ end)
+
+ after_each(function()
+ rmdir(plug_dir)
+ end)
+
+ describe('colors', function()
+ local colorscheme_folder = plug_dir .. sep .. 'colors'
+
+ it('loads lua colorscheme', function()
+ local colorscheme_file = colorscheme_folder .. sep .. 'new_colorscheme.lua'
+ mkdir_p(colorscheme_folder)
+ write_file(colorscheme_file, [[vim.g.lua_colorscheme = 1]])
+
+ 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_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']])
+
+ exec('colorscheme new_colorscheme')
+
+ eq('vim', eval('g:colorscheme'))
+ rmdir(colorscheme_folder)
+ end)
+ end)
+
+ describe('compiler', function()
+ local compiler_folder = plug_dir .. sep .. 'compiler'
+
+ it('loads lua compilers', function()
+ local compiler_file = compiler_folder .. sep .. 'new_compiler.lua'
+ mkdir_p(compiler_folder)
+ write_file(compiler_file, [[vim.g.lua_compiler = 1]])
+
+ 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 = 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']])
+
+ exec('compiler new_compiler')
+
+ eq('vim', eval('g:compiler'))
+ rmdir(compiler_folder)
+ end)
+ end)
+
+ describe('ftplugin', function()
+ local ftplugin_folder = table.concat({plug_dir, 'ftplugin'}, sep)
+
+ it('loads lua ftplugins', function()
+ local ftplugin_file = table.concat({ftplugin_folder , 'new-ft.lua'}, sep)
+ mkdir_p(ftplugin_folder)
+ write_file(ftplugin_file , [[vim.g.lua_ftplugin = 1]])
+
+ exec [[set filetype=new-ft]]
+ eq(1, eval('g:lua_ftplugin'))
+ rmdir(ftplugin_folder)
+ end)
+ end)
+
+ describe('indent', function()
+ local indent_folder = table.concat({plug_dir, 'indent'}, sep)
+
+ it('loads lua indents', function()
+ local indent_file = table.concat({indent_folder , 'new-ft.lua'}, sep)
+ mkdir_p(indent_folder)
+ write_file(indent_file , [[vim.g.lua_indent = 1]])
+
+ exec [[set filetype=new-ft]]
+ eq(1, eval('g:lua_indent'))
+ rmdir(indent_folder)
+ end)
+ end)
+
+ describe('syntax', function()
+ 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'}, sep)
+ mkdir_p(syntax_folder)
+ write_file(syntax_file , [[vim.g.lua_syntax = 1]])
+
+ 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'}, sep)
+ mkdir_p(syntax_folder)
+ write_file(syntax_file , [[vim.g.lua_syntax = 5]])
+
+ exec('set syntax=my-lang')
+ eq(5, eval('g:lua_syntax'))
+ rmdir(syntax_folder)
+ end)
+ end)
+
+end)
+