aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorluukvbaal <luukvbaal@gmail.com>2024-01-27 02:00:50 +0100
committerGitHub <noreply@github.com>2024-01-26 17:00:50 -0800
commitc2433589dca022a7f40cdcbd0cd1ad8aba6ee4a9 (patch)
tree4ec42e5d42d7c0bb5e674af2e94e1fe3eac2c837
parent0892c080d16776366a2fe289f9083cdc532ec56c (diff)
downloadrneovim-c2433589dca022a7f40cdcbd0cd1ad8aba6ee4a9.tar.gz
rneovim-c2433589dca022a7f40cdcbd0cd1ad8aba6ee4a9.tar.bz2
rneovim-c2433589dca022a7f40cdcbd0cd1ad8aba6ee4a9.zip
feat(ex_cmds): ranged :lua #27167
:{range}lua executes the specified lines in the current buffer as Lua code, regardless of its extension or 'filetype'. Close #27103
-rw-r--r--runtime/doc/lua.txt5
-rw-r--r--runtime/doc/news.txt3
-rw-r--r--src/nvim/ex_cmds.lua2
-rw-r--r--src/nvim/lua/executor.c9
-rw-r--r--src/nvim/runtime.c9
-rw-r--r--test/functional/lua/commands_spec.lua25
6 files changed, 48 insertions, 5 deletions
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index 433a9fc266..fecdfd9bd0 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -254,6 +254,11 @@ arguments separated by " " (space) instead of "\t" (tab).
< To see the LuaJIT version: >vim
:lua =jit.version
<
+:{range}lua
+ Executes the |[range]| in the current buffer as Lua code. Unlike |:source|,
+ this will execute the specified lines regardless of the extension or
+ |'filetype'| of the buffer.
+
*:lua-heredoc*
:lua << [trim] [{endmarker}]
{script}
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
index 2212b9910b..40717f8ecf 100644
--- a/runtime/doc/news.txt
+++ b/runtime/doc/news.txt
@@ -340,6 +340,9 @@ The following changes to existing APIs or features add new behavior.
• |:source| without arguments treats a buffer with its 'filetype' set to "lua"
as Lua code regardless of its extension.
+• |:lua| with a |[range]| executes that range in the current buffer as Lua code
+ regardless of its extension.
+
• |:checkhealth| buffer now implements |folding|. The initial folding status is
defined by the 'foldenable' option.
diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua
index 551d228862..1318eda5eb 100644
--- a/src/nvim/ex_cmds.lua
+++ b/src/nvim/ex_cmds.lua
@@ -1612,7 +1612,7 @@ module.cmds = {
},
{
command = 'lua',
- flags = bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK),
+ flags = bit.bor(RANGE, EXTRA, CMDWIN, LOCK_OK),
addr_type = 'ADDR_LINES',
func = 'ex_lua',
},
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index f48cab6739..3139e924a1 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -1649,6 +1649,15 @@ bool nlua_is_deferred_safe(void)
void ex_lua(exarg_T *const eap)
FUNC_ATTR_NONNULL_ALL
{
+ if (eap->addr_count > 0 || *eap->arg == NUL) {
+ if (eap->addr_count > 0 && *eap->arg == NUL) {
+ cmd_source_buffer(eap, true);
+ } else {
+ semsg(_(e_invarg2), "exactly one of {chunk} and {range} required");
+ }
+ return;
+ }
+
size_t len;
char *code = script_get(eap, &len);
if (eap->skip || code == NULL) {
diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c
index 3f8e467118..77a22b6fd1 100644
--- a/src/nvim/runtime.c
+++ b/src/nvim/runtime.c
@@ -1779,7 +1779,7 @@ freeall:
static void cmd_source(char *fname, exarg_T *eap)
{
if (eap != NULL && *fname == NUL) {
- cmd_source_buffer(eap);
+ cmd_source_buffer(eap, false);
} else if (eap != NULL && eap->forceit) {
// ":source!": read Normal mode commands
// Need to execute the commands directly. This is required at least
@@ -1989,7 +1989,7 @@ static int source_using_linegetter(void *cookie, LineGetter fgetline, const char
return retval;
}
-static void cmd_source_buffer(const exarg_T *const eap)
+void cmd_source_buffer(const exarg_T *const eap, bool ex_lua)
FUNC_ATTR_NONNULL_ALL
{
if (curbuf == NULL) {
@@ -2012,9 +2012,10 @@ static void cmd_source_buffer(const exarg_T *const eap)
.buf = ga.ga_data,
.offset = 0,
};
- if (strequal(curbuf->b_p_ft, "lua")
+ if (ex_lua || strequal(curbuf->b_p_ft, "lua")
|| (curbuf->b_fname && path_with_extension(curbuf->b_fname, "lua"))) {
- nlua_source_using_linegetter(get_str_line, (void *)&cookie, ":source (no file)");
+ char *name = ex_lua ? ":lua (no file)" : ":source (no file)";
+ nlua_source_using_linegetter(get_str_line, (void *)&cookie, name);
} else {
source_using_linegetter((void *)&cookie, get_str_line, ":source (no file)");
}
diff --git a/test/functional/lua/commands_spec.lua b/test/functional/lua/commands_spec.lua
index 28a99a86f8..083f6f3541 100644
--- a/test/functional/lua/commands_spec.lua
+++ b/test/functional/lua/commands_spec.lua
@@ -55,6 +55,12 @@ describe(':lua command', function()
)
end)
it('throws catchable errors', function()
+ for _, cmd in ipairs({ 'lua', '1lua chunk' }) do
+ eq(
+ 'Vim(lua):E475: Invalid argument: exactly one of {chunk} and {range} required',
+ pcall_err(command, cmd)
+ )
+ end
eq(
[[Vim(lua):E5107: Error loading lua [string ":lua"]:0: unexpected symbol near ')']],
pcall_err(command, 'lua ()')
@@ -192,6 +198,25 @@ describe(':lua command', function()
exec_capture('=x(false)')
)
end)
+
+ it('works with range in current buffer', function()
+ local screen = Screen.new(40, 10)
+ screen:attach()
+ api.nvim_buf_set_lines(0, 0, 0, 0, { 'function x() print "hello" end', 'x()' })
+ feed(':1,2lua<CR>')
+ screen:expect {
+ grid = [[
+ function x() print "hello" end |
+ x() |
+ ^ |
+ {1:~ }|*6
+ hello |
+ ]],
+ attr_ids = {
+ [1] = { foreground = Screen.colors.Blue, bold = true },
+ },
+ }
+ end)
end)
describe(':luado command', function()