aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/lua/executor.c
diff options
context:
space:
mode:
authorBjörn Linse <bjorn.linse@gmail.com>2019-06-29 20:15:12 +0200
committerBjörn Linse <bjorn.linse@gmail.com>2019-08-05 13:19:44 +0200
commitd3a7bdefb0782179433f42f8be8a35816a04f68e (patch)
treedf8992fbe0d92ba525166f436bf625e44a6c37c8 /src/nvim/lua/executor.c
parent4c35e6fe6734050b2e633aba330b0e389835fbc4 (diff)
downloadrneovim-d3a7bdefb0782179433f42f8be8a35816a04f68e.tar.gz
rneovim-d3a7bdefb0782179433f42f8be8a35816a04f68e.tar.bz2
rneovim-d3a7bdefb0782179433f42f8be8a35816a04f68e.zip
lua: immediate-callback safe print()
Diffstat (limited to 'src/nvim/lua/executor.c')
-rw-r--r--src/nvim/lua/executor.c85
1 files changed, 49 insertions, 36 deletions
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 3fd1620845..44d56e770c 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -323,6 +323,42 @@ void executor_exec_lua(const String str, typval_T *const ret_tv)
nlua_pop_typval(lstate, ret_tv);
}
+static void nlua_print_event(void **argv)
+{
+ char *str = argv[0];
+ const size_t len = (size_t)(intptr_t)argv[1]-1; // exclude final NUL
+
+ for (size_t i = 0; i < len;) {
+ const size_t start = i;
+ while (i < len) {
+ switch (str[i]) {
+ case NUL: {
+ str[i] = NL;
+ i++;
+ continue;
+ }
+ case NL: {
+ // TODO(bfredl): use proper multiline msg? Probably should implement
+ // print() in lua in terms of nvim_message(), when it is available.
+ str[i] = NUL;
+ i++;
+ break;
+ }
+ default: {
+ i++;
+ continue;
+ }
+ }
+ break;
+ }
+ msg((char_u *)str + start);
+ }
+ if (len && str[len - 1] == NUL) { // Last was newline
+ msg((char_u *)"");
+ }
+ xfree(str);
+}
+
/// Print as a Vim message
///
/// @param lstate Lua interpreter state.
@@ -362,47 +398,24 @@ static int nlua_print(lua_State *const lstate)
lua_pop(lstate, 1);
}
#undef PRINT_ERROR
- lua_pop(lstate, nargs + 1);
ga_append(&msg_ga, NUL);
- {
- const size_t len = (size_t)msg_ga.ga_len - 1;
- char *const str = (char *)msg_ga.ga_data;
-
- for (size_t i = 0; i < len;) {
- const size_t start = i;
- while (i < len) {
- switch (str[i]) {
- case NUL: {
- str[i] = NL;
- i++;
- continue;
- }
- case NL: {
- str[i] = NUL;
- i++;
- break;
- }
- default: {
- i++;
- continue;
- }
- }
- break;
- }
- msg((char_u *)str + start);
- }
- if (len && str[len - 1] == NUL) { // Last was newline
- msg((char_u *)"");
- }
+
+ if (in_fast_callback) {
+ multiqueue_put(main_loop.events, nlua_print_event,
+ 2, msg_ga.ga_data, msg_ga.ga_len);
+ } else {
+ nlua_print_event((void *[]){ msg_ga.ga_data,
+ (void *)(intptr_t)msg_ga.ga_len });
}
- ga_clear(&msg_ga);
return 0;
+
nlua_print_error:
- emsgf(_("E5114: Error while converting print argument #%i: %.*s"),
- curargidx, (int)errmsg_len, errmsg);
ga_clear(&msg_ga);
- lua_pop(lstate, lua_gettop(lstate));
- return 0;
+ const char *fmt = _("E5114: Error while converting print argument #%i: %.*s");
+ size_t len = (size_t)vim_snprintf((char *)IObuff, IOSIZE, fmt, curargidx,
+ (int)errmsg_len, errmsg);
+ lua_pushlstring(lstate, (char *)IObuff, len);
+ return lua_error(lstate);
}
/// debug.debug: interaction with user while debugging.