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
This commit is contained in:
shadmansaleh 2021-06-03 07:07:51 +06:00
parent 92b6b3764c
commit e1edc079dd
7 changed files with 89 additions and 28 deletions

View File

@ -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

View File

@ -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:

View File

@ -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;

View File

@ -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

View File

@ -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) {

View File

@ -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);
}

View File

@ -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)