New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] execute lua directly from the remote API #6704
Conversation
src/nvim/lua/executor.c
Outdated
} | ||
|
||
if (lua_pcall(lstate, (int)args->size, 1, 0)) { | ||
api_set_error(err, kErrorTypeException, "Error while calling lua chunk"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing error string, it is on top of the stack: see nlua_error
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks, fixed.
20b6216
to
408fa77
Compare
added docs and tests, marking RFC. |
test/functional/api/vim_spec.lua
Outdated
end) | ||
|
||
it('reports errors', function() | ||
meths.execute_lua('vim.api.nvim_set_var("test", 3)', {}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed
eq({false, 'Error executing lua: [string "<nvim>"]:1: '.. | ||
"attempt to call global 'bork' (a nil value)"}, | ||
meth_pcall(meths.execute_lua, 'bork()', {})) | ||
end) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe test an arity error or some other error involving the args array.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what error? lua just adds or subtracts nil
as it sees fit. Maybe, if there any valid msgpack Object that can't be translated to valid lua, but I can't think of any...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
meth_pcall(meths.execute_lua, '(function() return "foo" end)()', {42, 'baz'}))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that doesn't even use the arguments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was intentional...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so what would the test test? A nested function that takes no arguments and gets no arguments? That is not an error.
@@ -81,6 +81,26 @@ describe('api', function() | |||
end) | |||
end) | |||
|
|||
describe('nvim_execute_lua', function() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it worth testing with call_atomic ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why? how behaves it differently with call_atomic? Also this is to some extent intended as an alternative to call_atomic in cases it is too primitive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know, it depends on interactions that I didn't evaluate. Also, adding test coverage exercises future accidental interactions.
Also this is to some extent intended as an alternative to call_atomic in cases it is too primitive.
My intention is to recommend Lua for any server-side coordination logic, who knows what kind of things will be batched in call_atomic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By that argument we could test any api function through call_atomic. Why do we expect execute_lua to have any special "interactions"?
If lua is used for batching and coordination, then how is call_atomic needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If lua is used for batching and coordination, then how is call_atomic needed?
I think that's a good observation. It's usually good to have a single (powerful) way to do things. If one has both, users/script writers will often think about which is best/most efficient/... for their situation, perhaps spending needless time on this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, for instance for add_highlight I will probably recommend lua over call_atomic. There should probably be a standard runtime lua function for "append some text to a buffer with certain highlights" instead of every rplugin maintaining an output buffer needs to reimplement it.
What happens to NUL bytes in the |
Re: #6704 (comment) Where are the docs? |
I would expect |
Do we have any reason to add luaeval-like API function? If not we should stick to API conventions rather than lua conventions. |
it executes a block of code, it does not eval an expression. |
@fmoralesc in |
It happens whatever luajit decides to do. Messing with linelists in the api does not help. But a test would be good. |
Doesn't it? What does |
nil |
@bfredl |
@ZyX-I the point was: it does not return 3. |
@bfredl My point is: it may not return 3, yet it is not a correct statement, it is only a correct expression. |
it won't return the value of an correct expression either (not sure why lua makes a difference), for that one needs |
@ZyX-I makes a good point, it will avoid confusion if we raise an error for invalid statements, I would guess people might try |
but that is what lua does for us... |
Ok, I made a wrong assumption then, because the tests cover |
but a test would be good, and a note in the docs. |
But I expect that to error out, like from the command-line, not return nil. I am not sure what is the cause here, I do not see you doing something wrong. |
And With one exception: I have two arguments and do |
src/nvim/lua/executor.c
Outdated
Object *retval = (Object *)lua_touserdata(lstate, 3); | ||
Error *err = (Error *)lua_touserdata(lstate, 4); | ||
|
||
lua_pop(lstate, 3); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be 4
.
It does behave constitently. I just guessed nil because I didn't know an
arbitrary subset of expressions are not statements.
Den 11 maj 2017 11:38 fm skrev "Nikolai Aleksandrovich Pavlov" <
notifications@github.com>:
… ***@***.**** commented on this pull request.
------------------------------
In src/nvim/lua/executor.c
<#6704 (comment)>:
> @@ -373,6 +373,46 @@ static int nlua_eval_lua_string(lua_State *const lstate)
return 0;
}
+/// Evaluate lua string
+///
+/// Expects four values on the stack: string to evaluate, pointer to args array,
+/// and locations where result and error are saved, respectively. Always
+/// returns nothing (from the lua point of view).
+static int nlua_exec_lua_string_api(lua_State *const lstate)
+ FUNC_ATTR_NONNULL_ALL
+{
+ const String *str = (const String *)lua_touserdata(lstate, 1);
+ const Array *args = (const Array *)lua_touserdata(lstate, 2);
+ Object *retval = (Object *)lua_touserdata(lstate, 3);
+ Error *err = (Error *)lua_touserdata(lstate, 4);
+
+ lua_pop(lstate, 3);
This should be 4.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#6704 (review)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABTMoJKm8Pwz8WkMjLeVbzwyRWFbsGaVks5r4tccgaJpZM4NU5hw>
.
|
src/nvim/api/vim.c
Outdated
@@ -254,6 +255,25 @@ Object nvim_call_function(String fname, Array args, Error *err) | |||
return rv; | |||
} | |||
|
|||
/// Execute lua code. Parameters might be passed, they are available inside | |||
/// the chunk as `...`. They chunk can return a value. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"They chunk" => "The chunk"
src/nvim/api/vim.c
Outdated
/// the chunk as `...`. They chunk can return a value. | ||
/// | ||
/// To evaluate an expression, it must be prefixed with "return ". | ||
/// For instance, to call a lua function with arguments and return value, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"return value" => "return a value"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe "return its' value" ? (it being the function's result...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"arguments and return value" should have been a noun phrase, but as was ambiguous (even if both readings kinda make sense, as you see) I will rewrite it
coredump in oldtests test 17, probably unrelated:
|
b6e0bea
to
b0b242a
Compare
Any objection to naming it simply |
methods should be preferably be verb pharses. lua is not a verb. |
FEATURES: 0e873a3 Lua(Jit) built-in neovim#4411 5b32bce Windows: `:terminal` neovim#7007 7b0ceb3 UI/API: externalize cmdline neovim#7173 b67f58b UI/API: externalize wildmenu neovim#7454 b23aa1c UI: 'winhighlight' neovim#6597 17531ed UI: command-line coloring (`:help input()-highlight`) neovim#6364 244a1f9 API: execute lua directly from the remote api neovim#6704 45626de API: `get_keymap()` neovim#6236 db99982 API: `nvim_get_hl_by_name()`, `nvim_get_hl_by_id()` neovim#7082 dc68538 menu_get() function neovim#6322 9db42d4 :cquit : take an error code argument neovim#7336 9cc185d job-control: serverstart(): support ipv6 neovim#6680 1b7a9bf job-control: sockopen() neovim#6594 6efe84a clipboard: fallback to tmux clipboard neovim#6894 6016ac2 clipboard: customize clipboard with `g:clipboard` neovim#6030 3a86dd5 ruby: override ruby host via `g:ruby_host_prog` neovim#6841 16cce1a debug: $NVIM_LOG_FILE neovim#6827 0cba3da `:checkhealth` built-in, validates $VIMRUNTIME neovim#7399 FIXES: 105d680 TUI: more terminals, improve scroll/resize neovim#6816 cb912a3 :terminal : handle F1-F12, other keys neovim#7241 619838f inccommand: improve performance neovim#6949 04b3c32 inccommand: Fix matches for zero-width neovim#7487 60b1e8a inccommand: multiline, other fixes neovim#7315 f1f7f3b inccommand: Ignore leading modifiers in the command neovim#6967 1551f71 inccommand: fix 'gdefault' lockup neovim#7262 6338199 API: bufhl: support creating new groups neovim#7414 541dde3 API: allow K_EVENT during operator-pending 8c732f7 terminal: adjust for 'number' neovim#7440 5bec946 UI: preserve wildmenu during jobs/events neovim#7110 c349083 UI: disable 'lazyredraw' during ui_refresh. neovim#6259 51808a2 send FocusGained/FocusLost event instead of pseudokey neovim#7221 133f8bc shada: preserve unnamed register on restart neovim#4700 1b70a1d shada: avoid assertion on corrupt shada file neovim#6958 9f534f3 mksession: Restore tab-local working directory neovim#6859 de1084f fix buf_write() crash neovim#7140 7f76986 syntax: register 'Normal' highlight group neovim#6973 6e7a8c3 RPC: close channel if stream was closed neovim#7081 85f3084 clipboard: disallow recursion; show hint only once neovim#7203 8d1ccb6 clipboard: performance, avoid weird edge-cases neovim#7193 01487d4 'titleold' neovim#7358 01e53a5 Windows: better path-handling, separator (slash) hygiene neovim#7349 0f2873c Windows: multibyte startup arguments neovim#7060 CHANGES: 9ff0cc7 :terminal : start in normal-mode neovim#6808 032b088 lower priority of 'cursorcolumn', 'colorcolumn' neovim#7364 2a3bcd1 RPC: Don't delay notifications when request is pending neovim#6544 023f67c :terminal : Do not change 'number', 'relativenumber' neovim#6796 1ef2d76 socket.c: Disable Nagle's algorithm on TCP sockets neovim#6915 6720fe2 help: `K` tries Vim help instead of manpage neovim#3104 7068370 help, man.vim: change "outline" map to `gO` neovim#7405
As discussed in #4411 (comment) .
Should be NOEVAL, but is not yet to facilitate quick testing.