mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge #7880 'lua/executor: Remove lightuserdata'
This commit is contained in:
commit
ada1956206
@ -40,66 +40,6 @@ typedef struct {
|
|||||||
/// Name of the run code for use in messages
|
/// Name of the run code for use in messages
|
||||||
#define NLUA_EVAL_NAME "<VimL compiled string>"
|
#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
|
/// Convert lua error into a Vim error message
|
||||||
///
|
///
|
||||||
/// @param lstate Lua interpreter state.
|
/// @param lstate Lua interpreter state.
|
||||||
@ -163,123 +103,6 @@ static int nlua_stricmp(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
|
|||||||
return 1;
|
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
|
/// Initialize lua interpreter state
|
||||||
///
|
///
|
||||||
/// Called by lua interpreter itself to initialize state.
|
/// Called by lua interpreter itself to initialize state.
|
||||||
@ -327,7 +150,7 @@ static lua_State *nlua_init(void)
|
|||||||
preserve_exit();
|
preserve_exit();
|
||||||
}
|
}
|
||||||
luaL_openlibs(lstate);
|
luaL_openlibs(lstate);
|
||||||
NLUA_CALL_C_FUNCTION_0(lstate, nlua_state_init, 0);
|
nlua_state_init(lstate);
|
||||||
return 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)
|
void executor_exec_lua(const String str, typval_T *const ret_tv)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
NLUA_CALL_C_FUNCTION_2(nlua_enter(), nlua_exec_lua_string, 0,
|
lua_State *const lstate = nlua_enter();
|
||||||
(void *)&str, ret_tv);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Evaluate lua string
|
if (luaL_loadbuffer(lstate, str.data, str.size, NLUA_EVAL_NAME)) {
|
||||||
///
|
nlua_error(lstate, _("E5104: Error while creating lua chunk: %.*s"));
|
||||||
/// Used for luaeval(). Expects three values on the stack:
|
return;
|
||||||
///
|
|
||||||
/// 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);
|
if (lua_pcall(lstate, 0, 1, 0)) {
|
||||||
memcpy(lcmd + sizeof(EVALHEADER) - 1, str->data, str->size);
|
nlua_error(lstate, _("E5105: Error while calling lua chunk: %.*s"));
|
||||||
lcmd[lcmd_len - 1] = ')';
|
return;
|
||||||
#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) {
|
nlua_pop_typval(lstate, ret_tv);
|
||||||
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 (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;
|
|
||||||
}
|
|
||||||
|
|
||||||
*retval = nlua_pop_Object(lstate, err);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print as a Vim message
|
/// 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)
|
typval_T *const ret_tv)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
NLUA_CALL_C_FUNCTION_3(nlua_enter(), nlua_eval_lua_string, 0,
|
lua_State *const lstate = nlua_enter();
|
||||||
(void *)&str, arg, ret_tv);
|
|
||||||
|
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
|
/// Execute lua string
|
||||||
@ -632,10 +403,29 @@ void executor_eval_lua(const String str, typval_T *const arg,
|
|||||||
/// @return Return value of the execution.
|
/// @return Return value of the execution.
|
||||||
Object executor_exec_lua_api(const String str, const Array args, Error *err)
|
Object executor_exec_lua_api(const String str, const Array args, Error *err)
|
||||||
{
|
{
|
||||||
Object retval = NIL;
|
lua_State *const lstate = nlua_enter();
|
||||||
NLUA_CALL_C_FUNCTION_4(nlua_enter(), nlua_exec_lua_string_api, 0,
|
|
||||||
(void *)&str, (void *)&args, &retval, err);
|
if (luaL_loadbuffer(lstate, str.data, str.size, "<nvim>")) {
|
||||||
return retval;
|
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"));
|
EMSG(_("cannot save undo information"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const String cmd = {
|
const char *const cmd = (const char *)eap->arg;
|
||||||
.size = STRLEN(eap->arg),
|
const size_t cmd_len = strlen(cmd);
|
||||||
.data = (char *)eap->arg,
|
|
||||||
};
|
lua_State *const lstate = nlua_enter();
|
||||||
const linenr_T range[] = { eap->line1, eap->line2 };
|
|
||||||
NLUA_CALL_C_FUNCTION_2(nlua_enter(), nlua_exec_luado_string, 0,
|
#define DOSTART "return function(line, linenr) "
|
||||||
(void *)&cmd, (void *)range);
|
#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
|
/// Run lua file
|
||||||
@ -688,6 +535,15 @@ void ex_luado(exarg_T *const eap)
|
|||||||
void ex_luafile(exarg_T *const eap)
|
void ex_luafile(exarg_T *const eap)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
NLUA_CALL_C_FUNCTION_1(nlua_enter(), nlua_exec_lua_file, 0,
|
lua_State *const lstate = nlua_enter();
|
||||||
(void *)eap->arg);
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user