aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/lua/executor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/lua/executor.c')
-rw-r--r--src/nvim/lua/executor.c349
1 files changed, 168 insertions, 181 deletions
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 5ffd90fddd..06d16efb05 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -1,12 +1,11 @@
-// This is an open source non-commercial project. Dear PVS-Studio, please check
-// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-
#include <assert.h>
#include <inttypes.h>
#include <lauxlib.h>
#include <lua.h>
#include <lualib.h>
#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <tree_sitter/api.h>
#include <uv.h>
@@ -16,9 +15,9 @@
#include "nvim/api/extmark.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
-#include "nvim/ascii.h"
-#include "nvim/buffer_defs.h"
+#include "nvim/ascii_defs.h"
#include "nvim/change.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/cursor.h"
#include "nvim/drawscreen.h"
#include "nvim/eval.h"
@@ -42,28 +41,28 @@
#include "nvim/lua/executor.h"
#include "nvim/lua/stdlib.h"
#include "nvim/lua/treesitter.h"
-#include "nvim/macros.h"
+#include "nvim/macros_defs.h"
#include "nvim/main.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/msgpack_rpc/channel.h"
-#include "nvim/option_defs.h"
+#include "nvim/option_vars.h"
#include "nvim/os/fileio.h"
#include "nvim/os/os.h"
#include "nvim/path.h"
-#include "nvim/pos.h"
+#include "nvim/pos_defs.h"
#include "nvim/profile.h"
#include "nvim/runtime.h"
#include "nvim/strings.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
#include "nvim/usercmd.h"
-#include "nvim/version.h"
-#include "nvim/vim.h"
+#include "nvim/vim_defs.h"
#include "nvim/window.h"
static int in_fast_callback = 0;
+static bool in_script = false;
// Initialized in nlua_init().
static lua_State *global_lstate = NULL;
@@ -108,11 +107,16 @@ typedef enum luv_err_type {
kThreadCallback,
} luv_err_t;
+lua_State *get_global_lstate(void)
+{
+ return global_lstate;
+}
+
/// Convert lua error into a Vim error message
///
/// @param lstate Lua interpreter state.
-/// @param[in] msg Message base, must contain one `%s`.
-static void nlua_error(lua_State *const lstate, const char *const msg)
+/// @param[in] msg Message base, must contain one `%*s`.
+void nlua_error(lua_State *const lstate, const char *const msg)
FUNC_ATTR_NONNULL_ALL
{
size_t len;
@@ -133,8 +137,13 @@ static void nlua_error(lua_State *const lstate, const char *const msg)
str = lua_tolstring(lstate, -1, &len);
}
- msg_ext_set_kind("lua_error");
- semsg_multiline(msg, (int)len, str);
+ if (in_script) {
+ fprintf(stderr, msg, (int)len, str);
+ fprintf(stderr, "\n");
+ } else {
+ msg_ext_set_kind("lua_error");
+ semsg_multiline(msg, (int)len, str);
+ }
lua_pop(lstate, 1);
}
@@ -144,7 +153,7 @@ static void nlua_error(lua_State *const lstate, const char *const msg)
/// @param lstate Lua interpreter state
/// @param[in] nargs Number of arguments expected by the function being called.
/// @param[in] nresults Number of results the function returns.
-static int nlua_pcall(lua_State *lstate, int nargs, int nresults)
+int nlua_pcall(lua_State *lstate, int nargs, int nresults)
{
lua_getglobal(lstate, "debug");
lua_getfield(lstate, -1, "traceback");
@@ -159,17 +168,6 @@ static int nlua_pcall(lua_State *lstate, int nargs, int nresults)
return status;
}
-/// Gets the version of the current Nvim build.
-///
-/// @param lstate Lua interpreter state.
-static int nlua_nvim_version(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
-{
- Dictionary version = version_dict();
- nlua_push_Dictionary(lstate, version, true);
- api_free_dictionary(version);
- return 1;
-}
-
static void nlua_luv_error_event(void **argv)
{
char *error = (char *)argv[0];
@@ -205,9 +203,7 @@ static int nlua_luv_cfpcall(lua_State *lstate, int nargs, int nresult, int flags
if (status) {
if (status == LUA_ERRMEM && !(flags & LUVF_CALLBACK_NOEXIT)) {
// consider out of memory errors unrecoverable, just like xmalloc()
- os_errmsg(e_outofmem);
- os_errmsg("\n");
- preserve_exit();
+ preserve_exit(e_outofmem);
}
const char *error = lua_tostring(lstate, -1);
@@ -343,7 +339,7 @@ static int nlua_init_argv(lua_State *const L, char **argv, int argc, int lua_arg
lua_pushstring(L, argv[lua_arg0 - 1]);
lua_rawseti(L, -2, 0); // _G.arg[0] = "foo.lua"
- for (; lua_arg0 >= 0 && i + lua_arg0 < argc; i++) {
+ for (; i + lua_arg0 < argc; i++) {
lua_pushstring(L, argv[i + lua_arg0]);
lua_rawseti(L, -2, i + 1); // _G.arg[i+1] = "--foo"
}
@@ -375,6 +371,12 @@ static int nlua_schedule(lua_State *const lstate)
return lua_error(lstate);
}
+ // If main_loop is closing don't schedule tasks to run in the future,
+ // otherwise any refs allocated here will not be cleaned up.
+ if (main_loop.closing) {
+ return 0;
+ }
+
LuaRef cb = nlua_ref_global(lstate, 1);
multiqueue_put(main_loop.events, nlua_schedule_event,
@@ -384,7 +386,8 @@ static int nlua_schedule(lua_State *const lstate)
// Dummy timer callback. Used by f_wait().
static void dummy_timer_due_cb(TimeWatcher *tw, void *data)
-{}
+{
+}
// Dummy timer close callback. Used by f_wait().
static void dummy_timer_close_cb(TimeWatcher *tw, void *data)
@@ -408,6 +411,10 @@ static bool nlua_wait_condition(lua_State *lstate, int *status, bool *callback_r
static int nlua_wait(lua_State *lstate)
FUNC_ATTR_NONNULL_ALL
{
+ if (in_fast_callback) {
+ return luaL_error(lstate, e_luv_api_disabled, "vim.wait");
+ }
+
intptr_t timeout = luaL_checkinteger(lstate, 1);
if (timeout < 0) {
return luaL_error(lstate, "timeout must be >= 0");
@@ -446,8 +453,7 @@ static int nlua_wait(lua_State *lstate)
fast_only = lua_toboolean(lstate, 4);
}
- MultiQueue *loop_events = fast_only || in_fast_callback > 0
- ? main_loop.fast_events : main_loop.events;
+ MultiQueue *loop_events = fast_only ? main_loop.fast_events : main_loop.events;
TimeWatcher *tw = xmalloc(sizeof(TimeWatcher));
@@ -463,12 +469,16 @@ static int nlua_wait(lua_State *lstate)
int pcall_status = 0;
bool callback_result = false;
+ // Flush screen updates before blocking.
+ ui_flush();
+
LOOP_PROCESS_EVENTS_UNTIL(&main_loop,
loop_events,
(int)timeout,
got_int || (is_function ? nlua_wait_condition(lstate,
&pcall_status,
- &callback_result) : false));
+ &callback_result)
+ : false));
// Stop dummy timer
time_watcher_stop(tw);
@@ -534,7 +544,7 @@ int nlua_get_global_ref_count(void)
return nlua_global_refs->ref_count;
}
-static void nlua_common_vim_init(lua_State *lstate, bool is_thread)
+static void nlua_common_vim_init(lua_State *lstate, bool is_thread, bool is_standalone)
FUNC_ATTR_NONNULL_ARG(1)
{
nlua_ref_state_t *ref_state = nlua_new_ref_state(lstate, is_thread);
@@ -566,8 +576,10 @@ static void nlua_common_vim_init(lua_State *lstate, bool is_thread)
lua_setfield(lstate, LUA_REGISTRYINDEX, "mpack.empty_dict");
lua_setfield(lstate, -2, "_empty_dict_mt");
- // vim.loop
- if (is_thread) {
+ // vim.uv
+ if (is_standalone) {
+ // do nothing, use libluv like in a standalone interpreter
+ } else if (is_thread) {
luv_set_callback(lstate, nlua_luv_thread_cb_cfpcall);
luv_set_thread(lstate, nlua_luv_thread_cfpcall);
luv_set_cthread(lstate, nlua_luv_thread_cfcpcall);
@@ -577,9 +589,12 @@ static void nlua_common_vim_init(lua_State *lstate, bool is_thread)
}
luaopen_luv(lstate);
lua_pushvalue(lstate, -1);
- lua_setfield(lstate, -3, "loop");
+ lua_setfield(lstate, -3, "uv");
+
+ lua_pushvalue(lstate, -1);
+ lua_setfield(lstate, -3, "loop"); // deprecated
- // package.loaded.luv = vim.loop
+ // package.loaded.luv = vim.uv
// otherwise luv will be reinitialized when require'luv'
lua_getglobal(lstate, "package");
lua_getfield(lstate, -1, "loaded");
@@ -606,7 +621,7 @@ static int nlua_module_preloader(lua_State *lstate)
return 1;
}
-static bool nlua_init_packages(lua_State *lstate)
+static bool nlua_init_packages(lua_State *lstate, bool is_standalone)
FUNC_ATTR_NONNULL_ALL
{
// put builtin packages in preload
@@ -614,11 +629,11 @@ static bool nlua_init_packages(lua_State *lstate)
lua_getfield(lstate, -1, "preload"); // [package, preload]
for (size_t i = 0; i < ARRAY_SIZE(builtin_modules); i++) {
ModuleDef def = builtin_modules[i];
- lua_pushinteger(lstate, (long)i); // [package, preload, i]
+ lua_pushinteger(lstate, (lua_Integer)i); // [package, preload, i]
lua_pushcclosure(lstate, nlua_module_preloader, 1); // [package, preload, cclosure]
lua_setfield(lstate, -2, def.name); // [package, preload]
- if (nlua_disable_preload && strequal(def.name, "vim.inspect")) {
+ if ((nlua_disable_preload && !is_standalone) && strequal(def.name, "vim.inspect")) {
break;
}
}
@@ -628,7 +643,7 @@ static bool nlua_init_packages(lua_State *lstate)
lua_getglobal(lstate, "require");
lua_pushstring(lstate, "vim._init_packages");
if (nlua_pcall(lstate, 1, 0)) {
- os_errmsg((char *)lua_tostring(lstate, -1));
+ os_errmsg(lua_tostring(lstate, -1));
os_errmsg("\n");
return false;
}
@@ -733,10 +748,6 @@ static bool nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
// vim.types, vim.type_idx, vim.val_idx
nlua_init_types(lstate);
- // neovim version
- lua_pushcfunction(lstate, &nlua_nvim_version);
- lua_setfield(lstate, -2, "version");
-
// schedule
lua_pushcfunction(lstate, &nlua_schedule);
lua_setfield(lstate, -2, "schedule");
@@ -769,7 +780,7 @@ static bool nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
lua_pushcfunction(lstate, &nlua_ui_detach);
lua_setfield(lstate, -2, "ui_detach");
- nlua_common_vim_init(lstate, false);
+ nlua_common_vim_init(lstate, false, false);
// patch require() (only for --startuptime)
if (time_fd != NULL) {
@@ -788,7 +799,7 @@ static bool nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
lua_setglobal(lstate, "vim");
- if (!nlua_init_packages(lstate)) {
+ if (!nlua_init_packages(lstate, false)) {
return false;
}
@@ -813,6 +824,9 @@ void nlua_init(char **argv, int argc, int lua_arg0)
luaL_openlibs(lstate);
if (!nlua_state_init(lstate)) {
os_errmsg(_("E970: Failed to initialize builtin lua modules\n"));
+#ifdef EXITFREE
+ nlua_common_free_all_mem(lstate);
+#endif
os_exit(1);
}
@@ -824,9 +838,28 @@ void nlua_init(char **argv, int argc, int lua_arg0)
static lua_State *nlua_thread_acquire_vm(void)
{
+ return nlua_init_state(true);
+}
+
+void nlua_run_script(char **argv, int argc, int lua_arg0)
+ FUNC_ATTR_NORETURN
+{
+ in_script = true;
+ global_lstate = nlua_init_state(false);
+ luv_set_thread_cb(nlua_thread_acquire_vm, nlua_common_free_all_mem);
+ nlua_init_argv(global_lstate, argv, argc, lua_arg0);
+ bool lua_ok = nlua_exec_file(argv[lua_arg0 - 1]);
+#ifdef EXITFREE
+ nlua_free_all_mem();
+#endif
+ exit(lua_ok ? 0 : 1);
+}
+
+static lua_State *nlua_init_state(bool thread)
+{
// If it is called from the main thread, it will attempt to rebuild the cache.
const uv_thread_t self = uv_thread_self();
- if (uv_thread_equal(&main_thread, &self)) {
+ if (!in_script && uv_thread_equal(&main_thread, &self)) {
runtime_search_path_validate();
}
@@ -835,9 +868,11 @@ static lua_State *nlua_thread_acquire_vm(void)
// Add in the lua standard libraries
luaL_openlibs(lstate);
- // print
- lua_pushcfunction(lstate, &nlua_print);
- lua_setglobal(lstate, "print");
+ if (!in_script) {
+ // print
+ lua_pushcfunction(lstate, &nlua_print);
+ lua_setglobal(lstate, "print");
+ }
lua_pushinteger(lstate, 0);
lua_setfield(lstate, LUA_REGISTRYINDEX, "nlua.refcount");
@@ -845,18 +880,20 @@ static lua_State *nlua_thread_acquire_vm(void)
// vim
lua_newtable(lstate);
- nlua_common_vim_init(lstate, true);
+ nlua_common_vim_init(lstate, thread, in_script);
nlua_state_add_stdlib(lstate, true);
- lua_createtable(lstate, 0, 0);
- lua_pushcfunction(lstate, nlua_thr_api_nvim__get_runtime);
- lua_setfield(lstate, -2, "nvim__get_runtime");
- lua_setfield(lstate, -2, "api");
+ if (!in_script) {
+ lua_createtable(lstate, 0, 0);
+ lua_pushcfunction(lstate, nlua_thr_api_nvim__get_runtime);
+ lua_setfield(lstate, -2, "nvim__get_runtime");
+ lua_setfield(lstate, -2, "api");
+ }
lua_setglobal(lstate, "vim");
- nlua_init_packages(lstate);
+ nlua_init_packages(lstate, in_script);
lua_getglobal(lstate, "package");
lua_getfield(lstate, -1, "loaded");
@@ -892,12 +929,13 @@ static void nlua_common_free_all_mem(lua_State *lstate)
if (nlua_track_refs) {
// in case there are leaked luarefs, leak the associated memory
// to get LeakSanitizer stacktraces on exit
- pmap_destroy(handle_T)(&ref_state->ref_markers);
+ map_destroy(int, &ref_state->ref_markers);
}
#endif
lua_close(lstate);
}
+
static void nlua_print_event(void **argv)
{
char *str = argv[0];
@@ -926,10 +964,13 @@ static void nlua_print_event(void **argv)
}
break;
}
- msg(str + start);
+ msg(str + start, 0);
+ if (msg_silent == 0) {
+ msg_didout = true; // Make blank lines work properly
+ }
}
if (len && str[len - 1] == NUL) { // Last was newline
- msg("");
+ msg("", 0);
}
xfree(str);
}
@@ -1076,7 +1117,7 @@ static int nlua_debug(lua_State *lstate)
.v_type = VAR_UNKNOWN,
},
};
- for (;;) {
+ while (true) {
lua_settop(lstate, 0);
typval_T input;
get_user_input(input_args, &input, false, false);
@@ -1088,7 +1129,7 @@ static int nlua_debug(lua_State *lstate)
tv_clear(&input);
return 0;
}
- if (luaL_loadbuffer(lstate, (const char *)input.vval.v_string,
+ if (luaL_loadbuffer(lstate, input.vval.v_string,
strlen(input.vval.v_string), "=(debug command)")) {
nlua_error(lstate, _("E5115: Error while loading debug string: %.*s"));
} else if (nlua_pcall(lstate, 0, 0)) {
@@ -1111,7 +1152,7 @@ static bool viml_func_is_fast(const char *name)
if (fdef) {
return fdef->fast;
}
- // Not a vimL function
+ // Not a Vimscript function
return false;
}
@@ -1121,7 +1162,7 @@ int nlua_call(lua_State *lstate)
size_t name_len;
const char *name = luaL_checklstring(lstate, 1, &name_len);
if (!nlua_is_deferred_safe() && !viml_func_is_fast(name)) {
- return luaL_error(lstate, e_luv_api_disabled, "vimL function");
+ return luaL_error(lstate, e_luv_api_disabled, "Vimscript function");
}
int nargs = lua_gettop(lstate) - 1;
@@ -1140,28 +1181,29 @@ int nlua_call(lua_State *lstate)
}
}
- TRY_WRAP({
- // TODO(bfredl): this should be simplified in error handling refactor
- force_abort = false;
- suppress_errthrow = false;
- did_throw = false;
- did_emsg = false;
+ // TODO(bfredl): this should be simplified in error handling refactor
+ force_abort = false;
+ suppress_errthrow = false;
+ did_throw = false;
+ did_emsg = false;
- try_start();
- typval_T rettv;
- funcexe_T funcexe = FUNCEXE_INIT;
- funcexe.fe_firstline = curwin->w_cursor.lnum;
- funcexe.fe_lastline = curwin->w_cursor.lnum;
- funcexe.fe_evaluate = true;
+ typval_T rettv;
+ funcexe_T funcexe = FUNCEXE_INIT;
+ funcexe.fe_firstline = curwin->w_cursor.lnum;
+ funcexe.fe_lastline = curwin->w_cursor.lnum;
+ funcexe.fe_evaluate = true;
+
+ TRY_WRAP(&err, {
// call_func() retval is deceptive, ignore it. Instead we set `msg_list`
// (TRY_WRAP) to capture abort-causing non-exception errors.
- (void)call_func((char *)name, (int)name_len, &rettv, nargs, vim_args, &funcexe);
- if (!try_end(&err)) {
- nlua_push_typval(lstate, &rettv, false);
- }
- tv_clear(&rettv);
+ (void)call_func(name, (int)name_len, &rettv, nargs, vim_args, &funcexe);
});
+ if (!ERROR_SET(&err)) {
+ nlua_push_typval(lstate, &rettv, false);
+ }
+ tv_clear(&rettv);
+
free_vim_args:
while (i > 0) {
tv_clear(&vim_args[--i]);
@@ -1266,13 +1308,16 @@ LuaRef nlua_ref(lua_State *lstate, nlua_ref_state_t *ref_state, int index)
#ifdef NLUA_TRACK_REFS
if (nlua_track_refs) {
// dummy allocation to make LeakSanitizer track our luarefs
- pmap_put(handle_T)(&ref_state->ref_markers, ref, xmalloc(3));
+ pmap_put(int)(&ref_state->ref_markers, ref, xmalloc(3));
}
#endif
}
return ref;
}
+// TODO(lewis6991): Currently cannot be run in __gc metamethods as they are
+// invoked in lua_close() which can be invoked after the ref_markers map is
+// destroyed in nlua_common_free_all_mem.
LuaRef nlua_ref_global(lua_State *lstate, int index)
{
return nlua_ref(lstate, nlua_global_refs, index);
@@ -1286,7 +1331,7 @@ void nlua_unref(lua_State *lstate, nlua_ref_state_t *ref_state, LuaRef ref)
#ifdef NLUA_TRACK_REFS
// NB: don't remove entry from map to track double-unref
if (nlua_track_refs) {
- xfree(pmap_get(handle_T)(&ref_state->ref_markers, ref));
+ xfree(pmap_get(int)(&ref_state->ref_markers, ref));
}
#endif
luaL_unref(lstate, LUA_REGISTRYINDEX, ref);
@@ -1459,7 +1504,7 @@ int nlua_source_using_linegetter(LineGetter fgetline, void *cookie, char *name)
/// Call a LuaCallable given some typvals
///
-/// Used to call any lua callable passed from Lua into VimL
+/// Used to call any Lua callable passed from Lua into Vimscript.
///
/// @param[in] lstate Lua State
/// @param[in] lua_cb Lua Callable
@@ -1594,24 +1639,25 @@ bool nlua_is_deferred_safe(void)
///
/// Used for :lua.
///
-/// @param eap VimL command being run.
+/// @param eap Vimscript command being run.
void ex_lua(exarg_T *const eap)
FUNC_ATTR_NONNULL_ALL
{
size_t len;
char *code = script_get(eap, &len);
- if (eap->skip) {
+ if (eap->skip || code == NULL) {
xfree(code);
return;
}
- // When =expr is used transform it to print(vim.inspect(expr))
- if (code[0] == '=') {
- len += sizeof("vim.pretty_print()") - sizeof("=");
+ // When =expr is used transform it to vim.print(expr)
+ if (eap->cmdidx == CMD_equal || code[0] == '=') {
+ size_t off = (eap->cmdidx == CMD_equal) ? 0 : 1;
+ len += sizeof("vim.print()") - 1 - off;
// code_buf needs to be 1 char larger then len for null byte in the end.
// lua nlua_typval_exec doesn't expect null terminated string so len
// needs to end before null byte.
char *code_buf = xmallocz(len);
- vim_snprintf(code_buf, len + 1, "vim.pretty_print(%s)", code + 1);
+ vim_snprintf(code_buf, len + 1, "vim.print(%s)", code + off);
xfree(code);
code = code_buf;
}
@@ -1625,7 +1671,7 @@ void ex_lua(exarg_T *const eap)
///
/// Used for :luado.
///
-/// @param eap VimL command being run.
+/// @param eap Vimscript command being run.
void ex_luado(exarg_T *const eap)
FUNC_ATTR_NONNULL_ALL
{
@@ -1633,7 +1679,7 @@ void ex_luado(exarg_T *const eap)
emsg(_("cannot save undo information"));
return;
}
- const char *const cmd = (const char *)eap->arg;
+ const char *const cmd = eap->arg;
const size_t cmd_len = strlen(cmd);
lua_State *const lstate = global_lstate;
@@ -1674,7 +1720,9 @@ void ex_luado(exarg_T *const eap)
break;
}
lua_pushvalue(lstate, -1);
- const char *old_line = (const char *)ml_get_buf(curbuf, l, false);
+ const char *const old_line = ml_get_buf(curbuf, l);
+ // Get length of old_line here as calling Lua code may free it.
+ const size_t old_line_len = strlen(old_line);
lua_pushstring(lstate, old_line);
lua_pushnumber(lstate, (lua_Number)l);
if (nlua_pcall(lstate, 2, 1)) {
@@ -1682,8 +1730,6 @@ void ex_luado(exarg_T *const eap)
break;
}
if (lua_isstring(lstate, -1)) {
- size_t old_line_len = strlen(old_line);
-
size_t new_line_len;
const char *const new_line = lua_tolstring(lstate, -1, &new_line_len);
char *const new_line_transformed = xmemdupz(new_line, new_line_len);
@@ -1706,11 +1752,11 @@ void ex_luado(exarg_T *const eap)
///
/// Used for :luafile.
///
-/// @param eap VimL command being run.
+/// @param eap Vimscript command being run.
void ex_luafile(exarg_T *const eap)
FUNC_ATTR_NONNULL_ALL
{
- nlua_exec_file((const char *)eap->arg);
+ nlua_exec_file(eap->arg);
}
/// Executes Lua code from a file or "-" (stdin).
@@ -1734,13 +1780,12 @@ bool nlua_exec_file(const char *path)
StringBuilder sb = KV_INITIAL_VALUE;
kv_resize(sb, 64);
- ptrdiff_t read_size = -1;
// Read all input from stdin, unless interrupted (ctrl-c).
while (true) {
if (got_int) { // User canceled.
return false;
}
- read_size = file_read(stdin_dup, IObuff, 64);
+ ptrdiff_t read_size = file_read(stdin_dup, IObuff, 64);
if (read_size < 0) { // Error.
return false;
}
@@ -1842,7 +1887,7 @@ int nlua_expand_pat(expand_T *xp, char *pat, int *num_results, char ***results)
luaL_checktype(lstate, -1, LUA_TFUNCTION);
// [ vim, vim._expand_pat, buf ]
- lua_pushlstring(lstate, (const char *)pat, strlen(pat));
+ lua_pushlstring(lstate, pat, strlen(pat));
if (nlua_pcall(lstate, 1, 2) != 0) {
nlua_error(lstate,
@@ -1961,7 +2006,7 @@ char *nlua_register_table_as_callable(const typval_T *const arg)
void nlua_execute_on_key(int c)
{
char buf[NUMBUFLEN];
- size_t buf_len = special_to_buf(c, mod_mask, false, (char_u *)buf);
+ size_t buf_len = special_to_buf(c, mod_mask, false, buf);
lua_State *const lstate = global_lstate;
@@ -2007,9 +2052,9 @@ void nlua_set_sctx(sctx_T *current)
lua_Debug *info = (lua_Debug *)xmalloc(sizeof(lua_Debug));
// Files where internal wrappers are defined so we can ignore them
- // like vim.o/opt etc are defined in _meta.lua
+ // like vim.o/opt etc are defined in _options.lua
char *ignorelist[] = {
- "vim/_meta.lua",
+ "vim/_options.lua",
"vim/keymap.lua",
};
int ignorelist_size = sizeof(ignorelist) / sizeof(ignorelist[0]);
@@ -2039,10 +2084,15 @@ void nlua_set_sctx(sctx_T *current)
break;
}
char *source_path = fix_fname(info->source + 1);
- get_current_script_id(&source_path, current);
- xfree(source_path);
- current->sc_lnum = info->currentline;
+ int sid = find_script_by_name(source_path);
+ if (sid > 0) {
+ xfree(source_path);
+ } else {
+ new_script_item(source_path, &sid);
+ }
+ current->sc_sid = sid;
current->sc_seq = -1;
+ current->sc_lnum = info->currentline;
cleanup:
xfree(info);
@@ -2069,7 +2119,7 @@ int nlua_do_ucmd(ucmd_T *cmd, exarg_T *eap, bool preview)
lua_setfield(lstate, -2, "line2");
lua_newtable(lstate); // f-args table
- lua_pushstring(lstate, (const char *)eap->arg);
+ lua_pushstring(lstate, eap->arg);
lua_pushvalue(lstate, -1); // Reference for potential use on f-args
lua_setfield(lstate, -4, "args");
@@ -2252,79 +2302,16 @@ plain:
return str.items;
}
-char *nlua_read_secure(const char *path)
-{
- lua_State *const lstate = global_lstate;
- const int top = lua_gettop(lstate);
-
- lua_getglobal(lstate, "vim");
- lua_getfield(lstate, -1, "secure");
- lua_getfield(lstate, -1, "read");
- lua_pushstring(lstate, path);
- if (nlua_pcall(lstate, 1, 1)) {
- nlua_error(lstate, _("Error executing vim.secure.read: %.*s"));
- lua_settop(lstate, top);
- return NULL;
- }
-
- size_t len = 0;
- const char *contents = lua_tolstring(lstate, -1, &len);
- char *buf = NULL;
- if (contents != NULL) {
- // Add one to include trailing null byte
- buf = xcalloc(len + 1, sizeof(char));
- memcpy(buf, contents, len + 1);
- }
-
- lua_settop(lstate, top);
- return buf;
-}
-
-bool nlua_trust(const char *action, const char *path)
+/// Execute the vim._defaults module to set up default mappings and autocommands
+void nlua_init_defaults(void)
{
- lua_State *const lstate = global_lstate;
- const int top = lua_gettop(lstate);
-
- lua_getglobal(lstate, "vim");
- lua_getfield(lstate, -1, "secure");
- lua_getfield(lstate, -1, "trust");
-
- lua_newtable(lstate);
- lua_pushstring(lstate, "action");
- lua_pushstring(lstate, action);
- lua_settable(lstate, -3);
- if (path == NULL) {
- lua_pushstring(lstate, "bufnr");
- lua_pushnumber(lstate, 0);
- lua_settable(lstate, -3);
- } else {
- lua_pushstring(lstate, "path");
- lua_pushstring(lstate, path);
- lua_settable(lstate, -3);
- }
-
- if (nlua_pcall(lstate, 1, 2)) {
- nlua_error(lstate, _("Error executing vim.secure.trust: %.*s"));
- lua_settop(lstate, top);
- return false;
- }
+ lua_State *const L = global_lstate;
+ assert(L);
- bool success = lua_toboolean(lstate, -2);
- const char *msg = lua_tostring(lstate, -1);
- if (msg != NULL) {
- if (success) {
- if (strcmp(action, "allow") == 0) {
- smsg("Allowed \"%s\" in trust database.", msg);
- } else if (strcmp(action, "deny") == 0) {
- smsg("Denied \"%s\" in trust database.", msg);
- } else if (strcmp(action, "remove") == 0) {
- smsg("Removed \"%s\" from trust database.", msg);
- }
- } else {
- semsg(e_trustfile, msg);
- }
+ lua_getglobal(L, "require");
+ lua_pushstring(L, "vim._defaults");
+ if (nlua_pcall(L, 1, 0)) {
+ os_errmsg(lua_tostring(L, -1));
+ os_errmsg("\n");
}
-
- lua_settop(lstate, top);
- return success;
}