aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/repeat.txt6
-rw-r--r--runtime/doc/starting.txt2
-rw-r--r--src/nvim/ex_cmds2.c18
-rw-r--r--src/nvim/lua/executor.c18
-rw-r--r--src/nvim/main.c14
-rw-r--r--src/nvim/runtime.c13
-rw-r--r--test/functional/ex_cmds/source_spec.lua46
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)