aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/lua
diff options
context:
space:
mode:
authorb-r-o-c-k <brockmammen@gmail.com>2018-04-14 14:17:51 -0500
committerb-r-o-c-k <brockmammen@gmail.com>2018-04-14 14:17:51 -0500
commitad999eaa775d7d4b0cacedb30c6ea3a0ee699a6f (patch)
tree92de2079e80f5f289dd87a54af123cb7d90c3058 /src/nvim/lua
parent78bc52ea5397c092d01cd08296fe1dc85d998329 (diff)
parentef4feab0e75be19c5f41d70a001db980b72090f5 (diff)
downloadrneovim-ad999eaa775d7d4b0cacedb30c6ea3a0ee699a6f.tar.gz
rneovim-ad999eaa775d7d4b0cacedb30c6ea3a0ee699a6f.tar.bz2
rneovim-ad999eaa775d7d4b0cacedb30c6ea3a0ee699a6f.zip
Merge branch 'master' into s-dash-stdin
Diffstat (limited to 'src/nvim/lua')
-rw-r--r--src/nvim/lua/converter.c51
-rw-r--r--src/nvim/lua/executor.c438
-rw-r--r--src/nvim/lua/vim.lua68
3 files changed, 247 insertions, 310 deletions
diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c
index cacba3ce87..5da6d2c0a0 100644
--- a/src/nvim/lua/converter.c
+++ b/src/nvim/lua/converter.c
@@ -211,20 +211,28 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
size_t len;
const char *s = lua_tolstring(lstate, -2, &len);
if (cur.special) {
- list_T *const kv_pair = tv_list_alloc();
- tv_list_append_list(cur.tv->vval.v_list, kv_pair);
- listitem_T *const key = tv_list_item_alloc();
- key->li_tv = decode_string(s, len, kTrue, false, false);
- tv_list_append(kv_pair, key);
- if (key->li_tv.v_type == VAR_UNKNOWN) {
+ list_T *const kv_pair = tv_list_alloc(2);
+
+ typval_T s_tv = decode_string(s, len, kTrue, false, false);
+ if (s_tv.v_type == VAR_UNKNOWN) {
ret = false;
tv_list_unref(kv_pair);
continue;
}
- listitem_T *const val = tv_list_item_alloc();
- tv_list_append(kv_pair, val);
+ tv_list_append_owned_tv(kv_pair, s_tv);
+
+ // Value: not populated yet, need to create list item to push.
+ tv_list_append_owned_tv(kv_pair, (typval_T) {
+ .v_type = VAR_UNKNOWN,
+ });
kv_push(stack, cur);
- cur = (TVPopStackItem) { &val->li_tv, false, false, 0 };
+ tv_list_append_list(cur.tv->vval.v_list, kv_pair);
+ cur = (TVPopStackItem) {
+ .tv = TV_LIST_ITEM_TV(tv_list_last(kv_pair)),
+ .container = false,
+ .special = false,
+ .idx = 0,
+ };
} else {
dictitem_T *const di = tv_dict_item_alloc_len(s, len);
if (tv_dict_add(cur.tv->vval.v_dict, di) == FAIL) {
@@ -239,15 +247,23 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
}
} else {
assert(cur.tv->v_type == VAR_LIST);
- lua_rawgeti(lstate, -1, cur.tv->vval.v_list->lv_len + 1);
+ lua_rawgeti(lstate, -1, tv_list_len(cur.tv->vval.v_list) + 1);
if (lua_isnil(lstate, -1)) {
lua_pop(lstate, 2);
continue;
}
- listitem_T *const li = tv_list_item_alloc();
- tv_list_append(cur.tv->vval.v_list, li);
+ // Not populated yet, need to create list item to push.
+ tv_list_append_owned_tv(cur.tv->vval.v_list, (typval_T) {
+ .v_type = VAR_UNKNOWN,
+ });
kv_push(stack, cur);
- cur = (TVPopStackItem) { &li->li_tv, false, false, 0 };
+ // TODO(ZyX-I): Use indexes, here list item *will* be reallocated.
+ cur = (TVPopStackItem) {
+ .tv = TV_LIST_ITEM_TV(tv_list_last(cur.tv->vval.v_list)),
+ .container = false,
+ .special = false,
+ .idx = 0,
+ };
}
}
assert(!cur.container);
@@ -305,8 +321,8 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
switch (table_props.type) {
case kObjectTypeArray: {
cur.tv->v_type = VAR_LIST;
- cur.tv->vval.v_list = tv_list_alloc();
- cur.tv->vval.v_list->lv_refcount++;
+ cur.tv->vval.v_list = tv_list_alloc((ptrdiff_t)table_props.maxidx);
+ tv_list_ref(cur.tv->vval.v_list);
if (table_props.maxidx != 0) {
cur.container = true;
cur.idx = lua_gettop(lstate);
@@ -322,7 +338,8 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
} else {
cur.special = table_props.has_string_with_nul;
if (table_props.has_string_with_nul) {
- decode_create_map_special_dict(cur.tv);
+ decode_create_map_special_dict(
+ cur.tv, (ptrdiff_t)table_props.string_keys_num);
assert(cur.tv->v_type == VAR_DICT);
dictitem_T *const val_di = tv_dict_find(cur.tv->vval.v_dict,
S_LEN("_VAL"));
@@ -406,7 +423,7 @@ nlua_pop_typval_table_processing_end:
#define TYPVAL_ENCODE_CONV_STR_STRING TYPVAL_ENCODE_CONV_STRING
#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, str, len, type) \
- TYPVAL_ENCODE_CONV_NIL()
+ TYPVAL_ENCODE_CONV_NIL(tv)
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
do { \
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 8e7b8a1824..02eabb9c89 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -40,66 +40,6 @@ typedef struct {
/// Name of the run code for use in messages
#define NLUA_EVAL_NAME "<VimL compiled string>"
-/// Call C function which does not expect any arguments
-///
-/// @param function Called function
-/// @param numret Number of returned arguments
-#define NLUA_CALL_C_FUNCTION_0(lstate, function, numret) \
- do { \
- lua_pushcfunction(lstate, &function); \
- lua_call(lstate, 0, numret); \
- } while (0)
-/// Call C function which expects one argument
-///
-/// @param function Called function
-/// @param numret Number of returned arguments
-/// @param a… Supplied argument (should be a void* pointer)
-#define NLUA_CALL_C_FUNCTION_1(lstate, function, numret, a1) \
- do { \
- lua_pushcfunction(lstate, &function); \
- lua_pushlightuserdata(lstate, a1); \
- lua_call(lstate, 1, numret); \
- } while (0)
-/// Call C function which expects two arguments
-///
-/// @param function Called function
-/// @param numret Number of returned arguments
-/// @param a… Supplied argument (should be a void* pointer)
-#define NLUA_CALL_C_FUNCTION_2(lstate, function, numret, a1, a2) \
- do { \
- lua_pushcfunction(lstate, &function); \
- lua_pushlightuserdata(lstate, a1); \
- lua_pushlightuserdata(lstate, a2); \
- lua_call(lstate, 2, numret); \
- } while (0)
-/// Call C function which expects three arguments
-///
-/// @param function Called function
-/// @param numret Number of returned arguments
-/// @param a… Supplied argument (should be a void* pointer)
-#define NLUA_CALL_C_FUNCTION_3(lstate, function, numret, a1, a2, a3) \
- do { \
- lua_pushcfunction(lstate, &function); \
- lua_pushlightuserdata(lstate, a1); \
- lua_pushlightuserdata(lstate, a2); \
- lua_pushlightuserdata(lstate, a3); \
- lua_call(lstate, 3, numret); \
- } while (0)
-/// Call C function which expects five arguments
-///
-/// @param function Called function
-/// @param numret Number of returned arguments
-/// @param a… Supplied argument (should be a void* pointer)
-#define NLUA_CALL_C_FUNCTION_4(lstate, function, numret, a1, a2, a3, a4) \
- do { \
- lua_pushcfunction(lstate, &function); \
- lua_pushlightuserdata(lstate, a1); \
- lua_pushlightuserdata(lstate, a2); \
- lua_pushlightuserdata(lstate, a3); \
- lua_pushlightuserdata(lstate, a4); \
- lua_call(lstate, 4, numret); \
- } while (0)
-
/// Convert lua error into a Vim error message
///
/// @param lstate Lua interpreter state.
@@ -163,123 +103,6 @@ static int nlua_stricmp(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
return 1;
}
-/// Evaluate lua string
-///
-/// Expects two values on the stack: string to evaluate, pointer to the
-/// location where result is saved. Always returns nothing (from the lua point
-/// of view).
-static int nlua_exec_lua_string(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
-{
- const String *const str = (const String *)lua_touserdata(lstate, 1);
- typval_T *const ret_tv = (typval_T *)lua_touserdata(lstate, 2);
- lua_pop(lstate, 2);
-
- if (luaL_loadbuffer(lstate, str->data, str->size, NLUA_EVAL_NAME)) {
- nlua_error(lstate, _("E5104: Error while creating lua chunk: %.*s"));
- return 0;
- }
- if (lua_pcall(lstate, 0, 1, 0)) {
- nlua_error(lstate, _("E5105: Error while calling lua chunk: %.*s"));
- return 0;
- }
- if (!nlua_pop_typval(lstate, ret_tv)) {
- return 0;
- }
- return 0;
-}
-
-/// Evaluate lua string for each line in range
-///
-/// Expects two values on the stack: string to evaluate and pointer to integer
-/// array with line range. Always returns nothing (from the lua point of view).
-static int nlua_exec_luado_string(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
-{
- const String *const str = (const String *)lua_touserdata(lstate, 1);
- const linenr_T *const range = (const linenr_T *)lua_touserdata(lstate, 2);
- lua_pop(lstate, 2);
-
-#define DOSTART "return function(line, linenr) "
-#define DOEND " end"
- const size_t lcmd_len = (str->size
- + (sizeof(DOSTART) - 1)
- + (sizeof(DOEND) - 1));
- char *lcmd;
- if (lcmd_len < IOSIZE) {
- lcmd = (char *)IObuff;
- } else {
- lcmd = xmalloc(lcmd_len + 1);
- }
- memcpy(lcmd, DOSTART, sizeof(DOSTART) - 1);
- memcpy(lcmd + sizeof(DOSTART) - 1, str->data, str->size);
- memcpy(lcmd + sizeof(DOSTART) - 1 + str->size, DOEND, sizeof(DOEND) - 1);
-#undef DOSTART
-#undef DOEND
-
- if (luaL_loadbuffer(lstate, lcmd, lcmd_len, NLUA_EVAL_NAME)) {
- nlua_error(lstate, _("E5109: Error while creating lua chunk: %.*s"));
- if (lcmd_len >= IOSIZE) {
- xfree(lcmd);
- }
- return 0;
- }
- if (lcmd_len >= IOSIZE) {
- xfree(lcmd);
- }
- if (lua_pcall(lstate, 0, 1, 0)) {
- nlua_error(lstate, _("E5110: Error while creating lua function: %.*s"));
- return 0;
- }
- for (linenr_T l = range[0]; l <= range[1]; l++) {
- if (l > curbuf->b_ml.ml_line_count) {
- break;
- }
- lua_pushvalue(lstate, -1);
- lua_pushstring(lstate, (const char *)ml_get_buf(curbuf, l, false));
- lua_pushnumber(lstate, (lua_Number)l);
- if (lua_pcall(lstate, 2, 1, 0)) {
- nlua_error(lstate, _("E5111: Error while calling lua function: %.*s"));
- break;
- }
- if (lua_isstring(lstate, -1)) {
- 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);
- for (size_t i = 0; i < new_line_len; i++) {
- if (new_line_transformed[i] == NUL) {
- new_line_transformed[i] = '\n';
- }
- }
- ml_replace(l, (char_u *)new_line_transformed, false);
- changed_bytes(l, 0);
- }
- lua_pop(lstate, 1);
- }
- lua_pop(lstate, 1);
- check_cursor();
- update_screen(NOT_VALID);
- return 0;
-}
-
-/// Evaluate lua file
-///
-/// Expects one value on the stack: file to evaluate. Always returns nothing
-/// (from the lua point of view).
-static int nlua_exec_lua_file(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
-{
- const char *const filename = (const char *)lua_touserdata(lstate, 1);
- lua_pop(lstate, 1);
-
- if (luaL_loadfile(lstate, filename)) {
- nlua_error(lstate, _("E5112: Error while creating lua chunk: %.*s"));
- return 0;
- }
- if (lua_pcall(lstate, 0, 0, 0)) {
- nlua_error(lstate, _("E5113: Error while calling lua chunk: %.*s"));
- return 0;
- }
- return 0;
-}
-
/// Initialize lua interpreter state
///
/// Called by lua interpreter itself to initialize state.
@@ -327,7 +150,7 @@ static lua_State *nlua_init(void)
preserve_exit();
}
luaL_openlibs(lstate);
- NLUA_CALL_C_FUNCTION_0(lstate, nlua_state_init, 0);
+ nlua_state_init(lstate);
return lstate;
}
@@ -378,108 +201,18 @@ static lua_State *nlua_enter(void)
void executor_exec_lua(const String str, typval_T *const ret_tv)
FUNC_ATTR_NONNULL_ALL
{
- NLUA_CALL_C_FUNCTION_2(nlua_enter(), nlua_exec_lua_string, 0,
- (void *)&str, ret_tv);
-}
+ lua_State *const lstate = nlua_enter();
-/// Evaluate lua string
-///
-/// Used for luaeval(). Expects three values on the stack:
-///
-/// 1. String to evaluate.
-/// 2. _A value.
-/// 3. Pointer to location where result is saved.
-///
-/// @param[in,out] lstate Lua interpreter state.
-static int nlua_eval_lua_string(lua_State *const lstate)
- FUNC_ATTR_NONNULL_ALL
-{
- const String *const str = (const String *)lua_touserdata(lstate, 1);
- typval_T *const arg = (typval_T *)lua_touserdata(lstate, 2);
- typval_T *const ret_tv = (typval_T *)lua_touserdata(lstate, 3);
- lua_pop(lstate, 3);
-
- garray_T str_ga;
- ga_init(&str_ga, 1, 80);
-#define EVALHEADER "local _A=select(1,...) return ("
- const size_t lcmd_len = sizeof(EVALHEADER) - 1 + str->size + 1;
- char *lcmd;
- if (lcmd_len < IOSIZE) {
- lcmd = (char *)IObuff;
- } else {
- lcmd = xmalloc(lcmd_len);
- }
- memcpy(lcmd, EVALHEADER, sizeof(EVALHEADER) - 1);
- memcpy(lcmd + sizeof(EVALHEADER) - 1, str->data, str->size);
- lcmd[lcmd_len - 1] = ')';
-#undef EVALHEADER
- if (luaL_loadbuffer(lstate, lcmd, lcmd_len, NLUA_EVAL_NAME)) {
- nlua_error(lstate,
- _("E5107: Error while creating lua chunk for luaeval(): %.*s"));
- if (lcmd != (char *)IObuff) {
- xfree(lcmd);
- }
- return 0;
- }
- if (lcmd != (char *)IObuff) {
- xfree(lcmd);
- }
-
- if (arg == NULL || arg->v_type == VAR_UNKNOWN) {
- lua_pushnil(lstate);
- } else {
- nlua_push_typval(lstate, arg);
- }
- if (lua_pcall(lstate, 1, 1, 0)) {
- nlua_error(lstate,
- _("E5108: Error while calling lua chunk for luaeval(): %.*s"));
- return 0;
- }
- if (!nlua_pop_typval(lstate, ret_tv)) {
- return 0;
- }
-
- 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, 4);
-
- if (luaL_loadbuffer(lstate, str->data, str->size, "<nvim>")) {
- size_t len;
- const char *str = lua_tolstring(lstate, -1, &len);
- api_set_error(err, kErrorTypeValidation,
- "Error loading lua: %.*s", (int)len, str);
- return 0;
- }
-
- for (size_t i = 0; i < args->size; i++) {
- nlua_push_Object(lstate, args->items[i]);
+ if (luaL_loadbuffer(lstate, str.data, str.size, NLUA_EVAL_NAME)) {
+ nlua_error(lstate, _("E5104: Error while creating lua chunk: %.*s"));
+ return;
}
-
- if (lua_pcall(lstate, (int)args->size, 1, 0)) {
- size_t len;
- const char *str = lua_tolstring(lstate, -1, &len);
- api_set_error(err, kErrorTypeException,
- "Error executing lua: %.*s", (int)len, str);
- return 0;
+ if (lua_pcall(lstate, 0, 1, 0)) {
+ nlua_error(lstate, _("E5105: Error while calling lua chunk: %.*s"));
+ return;
}
- *retval = nlua_pop_Object(lstate, err);
-
- return 0;
+ nlua_pop_typval(lstate, ret_tv);
}
/// Print as a Vim message
@@ -617,8 +350,46 @@ void executor_eval_lua(const String str, typval_T *const arg,
typval_T *const ret_tv)
FUNC_ATTR_NONNULL_ALL
{
- NLUA_CALL_C_FUNCTION_3(nlua_enter(), nlua_eval_lua_string, 0,
- (void *)&str, arg, ret_tv);
+ lua_State *const lstate = nlua_enter();
+
+ garray_T str_ga;
+ ga_init(&str_ga, 1, 80);
+#define EVALHEADER "local _A=select(1,...) return ("
+ const size_t lcmd_len = sizeof(EVALHEADER) - 1 + str.size + 1;
+ char *lcmd;
+ if (lcmd_len < IOSIZE) {
+ lcmd = (char *)IObuff;
+ } else {
+ lcmd = xmalloc(lcmd_len);
+ }
+ memcpy(lcmd, EVALHEADER, sizeof(EVALHEADER) - 1);
+ memcpy(lcmd + sizeof(EVALHEADER) - 1, str.data, str.size);
+ lcmd[lcmd_len - 1] = ')';
+#undef EVALHEADER
+ if (luaL_loadbuffer(lstate, lcmd, lcmd_len, NLUA_EVAL_NAME)) {
+ nlua_error(lstate,
+ _("E5107: Error while creating lua chunk for luaeval(): %.*s"));
+ if (lcmd != (char *)IObuff) {
+ xfree(lcmd);
+ }
+ return;
+ }
+ if (lcmd != (char *)IObuff) {
+ xfree(lcmd);
+ }
+
+ if (arg->v_type == VAR_UNKNOWN) {
+ lua_pushnil(lstate);
+ } else {
+ nlua_push_typval(lstate, arg);
+ }
+ if (lua_pcall(lstate, 1, 1, 0)) {
+ nlua_error(lstate,
+ _("E5108: Error while calling lua chunk for luaeval(): %.*s"));
+ return;
+ }
+
+ nlua_pop_typval(lstate, ret_tv);
}
/// Execute lua string
@@ -632,10 +403,29 @@ void executor_eval_lua(const String str, typval_T *const arg,
/// @return Return value of the execution.
Object executor_exec_lua_api(const String str, const Array args, Error *err)
{
- Object retval = NIL;
- NLUA_CALL_C_FUNCTION_4(nlua_enter(), nlua_exec_lua_string_api, 0,
- (void *)&str, (void *)&args, &retval, err);
- return retval;
+ lua_State *const lstate = nlua_enter();
+
+ if (luaL_loadbuffer(lstate, str.data, str.size, "<nvim>")) {
+ size_t len;
+ const char *errstr = lua_tolstring(lstate, -1, &len);
+ api_set_error(err, kErrorTypeValidation,
+ "Error loading lua: %.*s", (int)len, errstr);
+ return NIL;
+ }
+
+ for (size_t i = 0; i < args.size; i++) {
+ nlua_push_Object(lstate, args.items[i]);
+ }
+
+ if (lua_pcall(lstate, (int)args.size, 1, 0)) {
+ size_t len;
+ const char *errstr = lua_tolstring(lstate, -1, &len);
+ api_set_error(err, kErrorTypeException,
+ "Error executing lua: %.*s", (int)len, errstr);
+ return NIL;
+ }
+
+ return nlua_pop_Object(lstate, err);
}
@@ -671,13 +461,70 @@ void ex_luado(exarg_T *const eap)
EMSG(_("cannot save undo information"));
return;
}
- const String cmd = {
- .size = STRLEN(eap->arg),
- .data = (char *)eap->arg,
- };
- const linenr_T range[] = { eap->line1, eap->line2 };
- NLUA_CALL_C_FUNCTION_2(nlua_enter(), nlua_exec_luado_string, 0,
- (void *)&cmd, (void *)range);
+ const char *const cmd = (const char *)eap->arg;
+ const size_t cmd_len = strlen(cmd);
+
+ lua_State *const lstate = nlua_enter();
+
+#define DOSTART "return function(line, linenr) "
+#define DOEND " end"
+ const size_t lcmd_len = (cmd_len
+ + (sizeof(DOSTART) - 1)
+ + (sizeof(DOEND) - 1));
+ char *lcmd;
+ if (lcmd_len < IOSIZE) {
+ lcmd = (char *)IObuff;
+ } else {
+ lcmd = xmalloc(lcmd_len + 1);
+ }
+ memcpy(lcmd, DOSTART, sizeof(DOSTART) - 1);
+ memcpy(lcmd + sizeof(DOSTART) - 1, cmd, cmd_len);
+ memcpy(lcmd + sizeof(DOSTART) - 1 + cmd_len, DOEND, sizeof(DOEND) - 1);
+#undef DOSTART
+#undef DOEND
+
+ if (luaL_loadbuffer(lstate, lcmd, lcmd_len, NLUA_EVAL_NAME)) {
+ nlua_error(lstate, _("E5109: Error while creating lua chunk: %.*s"));
+ if (lcmd_len >= IOSIZE) {
+ xfree(lcmd);
+ }
+ return;
+ }
+ if (lcmd_len >= IOSIZE) {
+ xfree(lcmd);
+ }
+ if (lua_pcall(lstate, 0, 1, 0)) {
+ nlua_error(lstate, _("E5110: Error while creating lua function: %.*s"));
+ return;
+ }
+ for (linenr_T l = eap->line1; l <= eap->line2; l++) {
+ if (l > curbuf->b_ml.ml_line_count) {
+ break;
+ }
+ lua_pushvalue(lstate, -1);
+ lua_pushstring(lstate, (const char *)ml_get_buf(curbuf, l, false));
+ lua_pushnumber(lstate, (lua_Number)l);
+ if (lua_pcall(lstate, 2, 1, 0)) {
+ nlua_error(lstate, _("E5111: Error while calling lua function: %.*s"));
+ break;
+ }
+ if (lua_isstring(lstate, -1)) {
+ 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);
+ for (size_t i = 0; i < new_line_len; i++) {
+ if (new_line_transformed[i] == NUL) {
+ new_line_transformed[i] = '\n';
+ }
+ }
+ ml_replace(l, (char_u *)new_line_transformed, false);
+ changed_bytes(l, 0);
+ }
+ lua_pop(lstate, 1);
+ }
+ lua_pop(lstate, 1);
+ check_cursor();
+ update_screen(NOT_VALID);
}
/// Run lua file
@@ -688,6 +535,15 @@ void ex_luado(exarg_T *const eap)
void ex_luafile(exarg_T *const eap)
FUNC_ATTR_NONNULL_ALL
{
- NLUA_CALL_C_FUNCTION_1(nlua_enter(), nlua_exec_lua_file, 0,
- (void *)eap->arg);
+ lua_State *const lstate = nlua_enter();
+
+ if (luaL_loadfile(lstate, (const char *)eap->arg)) {
+ nlua_error(lstate, _("E5112: Error while creating lua chunk: %.*s"));
+ return;
+ }
+
+ if (lua_pcall(lstate, 0, 0, 0)) {
+ nlua_error(lstate, _("E5113: Error while calling lua chunk: %.*s"));
+ return;
+ }
}
diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua
index c7952520b0..e1bbb03d3f 100644
--- a/src/nvim/lua/vim.lua
+++ b/src/nvim/lua/vim.lua
@@ -1,3 +1,62 @@
+-- Internal-only until comments in #8107 are addressed.
+-- Returns:
+-- {errcode}, {output}
+local function _system(cmd)
+ local out = vim.api.nvim_call_function('system', { cmd })
+ local err = vim.api.nvim_get_vvar('shell_error')
+ return err, out
+end
+
+-- Gets process info from the `ps` command.
+-- Used by nvim_get_proc() as a fallback.
+local function _os_proc_info(pid)
+ if pid == nil or pid <= 0 or type(pid) ~= 'number' then
+ error('invalid pid')
+ end
+ local cmd = { 'ps', '-p', pid, '-o', 'ucomm=', }
+ local err, name = _system(cmd)
+ if 1 == err and string.gsub(name, '%s*', '') == '' then
+ return {} -- Process not found.
+ elseif 0 ~= err then
+ local args_str = vim.api.nvim_call_function('string', { cmd })
+ error('command failed: '..args_str)
+ end
+ local _, ppid = _system({ 'ps', '-p', pid, '-o', 'ppid=', })
+ -- Remove trailing whitespace.
+ name = string.gsub(name, '%s+$', '')
+ ppid = string.gsub(ppid, '%s+$', '')
+ ppid = tonumber(ppid) == nil and -1 or tonumber(ppid)
+ return {
+ name = name,
+ pid = pid,
+ ppid = ppid,
+ }
+end
+
+-- Gets process children from the `pgrep` command.
+-- Used by nvim_get_proc_children() as a fallback.
+local function _os_proc_children(ppid)
+ if ppid == nil or ppid <= 0 or type(ppid) ~= 'number' then
+ error('invalid ppid')
+ end
+ local cmd = { 'pgrep', '-P', ppid, }
+ local err, rv = _system(cmd)
+ if 1 == err and string.gsub(rv, '%s*', '') == '' then
+ return {} -- Process not found.
+ elseif 0 ~= err then
+ local args_str = vim.api.nvim_call_function('string', { cmd })
+ error('command failed: '..args_str)
+ end
+ local children = {}
+ for s in string.gmatch(rv, '%S+') do
+ local i = tonumber(s)
+ if i ~= nil then
+ table.insert(children, i)
+ end
+ end
+ return children
+end
+
-- TODO(ZyX-I): Create compatibility layer.
--{{{1 package.path updater function
-- Last inserted paths. Used to clear out items from package.[c]path when they
@@ -58,7 +117,12 @@ local function _update_package_paths()
end
last_nvim_paths = cur_nvim_paths
end
---{{{1 Module definition
-return {
+
+local module = {
_update_package_paths = _update_package_paths,
+ _os_proc_children = _os_proc_children,
+ _os_proc_info = _os_proc_info,
+ _system = _system,
}
+
+return module