Add v:lua.func() vimL syntax for calling lua

Also simplify error messages when calling lua from vimL.
This commit is contained in:
Björn Linse 2019-10-30 20:53:09 +01:00
parent 18096631b1
commit dab40f43b1
10 changed files with 442 additions and 217 deletions

View File

@ -1737,6 +1737,10 @@ v:lnum Line number for the 'foldexpr' |fold-expr|, 'formatexpr' and
expressions is being evaluated. Read-only when in the expressions is being evaluated. Read-only when in the
|sandbox|. |sandbox|.
*v:lua* *lua-variable*
v:lua Prefix for calling lua functions from expressions.
See |v:lua-call| for more information.
*v:mouse_win* *mouse_win-variable* *v:mouse_win* *mouse_win-variable*
v:mouse_win Window number for a mouse click obtained with |getchar()|. v:mouse_win Window number for a mouse click obtained with |getchar()|.
First window has number 1, like with |winnr()|. The value is First window has number 1, like with |winnr()|. The value is

View File

@ -326,6 +326,38 @@ Note: second argument to `luaeval` undergoes VimL to Lua conversion
Return value is also always converted. When converting, Return value is also always converted. When converting,
|msgpack-special-dict|s are treated specially. |msgpack-special-dict|s are treated specially.
==============================================================================
v:lua function calls *v:lua-call*
The special prefix `v:lua` can be used in vimL expressions to call lua
functions which are global or nested inside global tables. The expression
`v:lua.func(arg1, arg2)` is equivalent to executing the lua code
`return func(...)` where the args have been converted to lua values. In addition
`v:lua.somemod.func(args)` will work like `return somemod.func(...)` .
`v:lua` can also be used in function options like 'omnifunc'. As an
example, consider the following lua implementation of an omnifunc: >
function mymod.omnifunc(findstart, base)
if findstart == 1 then
return 0
else
return {'stuff', 'steam', 'strange things'}
end
end
vim.api.nvim_buf_set_option(0, 'omnifunc', 'v:lua.mymod.omnifunc')
A limitation is that the plugin module ("mymod" in this case) must
be made available as a global.
Note: `v:lua` without a call is not allowed in a vimL expression. Funcrefs
to lua functions cannot be created. The following are errors: >
let g:Myvar = v:lua.myfunc
call SomeFunc(v:lua.mycallback)
let g:foo = v:lua
let g:foo = v:['lua']
============================================================================== ==============================================================================
Lua standard modules *lua-stdlib* Lua standard modules *lua-stdlib*

View File

@ -422,6 +422,7 @@ static struct vimvar {
VV(VV_TYPE_BOOL, "t_bool", VAR_NUMBER, VV_RO), VV(VV_TYPE_BOOL, "t_bool", VAR_NUMBER, VV_RO),
VV(VV_ECHOSPACE, "echospace", VAR_NUMBER, VV_RO), VV(VV_ECHOSPACE, "echospace", VAR_NUMBER, VV_RO),
VV(VV_EXITING, "exiting", VAR_NUMBER, VV_RO), VV(VV_EXITING, "exiting", VAR_NUMBER, VV_RO),
VV(VV_LUA, "lua", VAR_PARTIAL, VV_RO),
}; };
#undef VV #undef VV
@ -433,11 +434,14 @@ static struct vimvar {
#define vv_str vv_di.di_tv.vval.v_string #define vv_str vv_di.di_tv.vval.v_string
#define vv_list vv_di.di_tv.vval.v_list #define vv_list vv_di.di_tv.vval.v_list
#define vv_dict vv_di.di_tv.vval.v_dict #define vv_dict vv_di.di_tv.vval.v_dict
#define vv_partial vv_di.di_tv.vval.v_partial
#define vv_tv vv_di.di_tv #define vv_tv vv_di.di_tv
/// Variable used for v: /// Variable used for v:
static ScopeDictDictItem vimvars_var; static ScopeDictDictItem vimvars_var;
static partial_T *vvlua_partial;
/// v: hashtab /// v: hashtab
#define vimvarht vimvardict.dv_hashtab #define vimvarht vimvardict.dv_hashtab
@ -639,6 +643,13 @@ void eval_init(void)
set_vim_var_nr(VV_ECHOSPACE, sc_col - 1); set_vim_var_nr(VV_ECHOSPACE, sc_col - 1);
vimvars[VV_LUA].vv_type = VAR_PARTIAL;
vvlua_partial = xcalloc(1, sizeof(partial_T));
vimvars[VV_LUA].vv_partial = vvlua_partial;
// this value shouldn't be printed, but if it is, do not crash
vvlua_partial->pt_name = xmallocz(0);
vvlua_partial->pt_refcount++;
set_reg_var(0); // default for v:register is not 0 but '"' set_reg_var(0); // default for v:register is not 0 but '"'
} }
@ -1313,12 +1324,25 @@ int call_vim_function(
{ {
int doesrange; int doesrange;
int ret; int ret;
int len = (int)STRLEN(func);
partial_T *pt = NULL;
if (len >= 6 && !memcmp(func, "v:lua.", 6)) {
func += 6;
len = check_luafunc_name((const char *)func, false);
if (len == 0) {
ret = FAIL;
goto fail;
}
pt = vvlua_partial;
}
rettv->v_type = VAR_UNKNOWN; // tv_clear() uses this. rettv->v_type = VAR_UNKNOWN; // tv_clear() uses this.
ret = call_func(func, (int)STRLEN(func), rettv, argc, argv, NULL, ret = call_func(func, len, rettv, argc, argv, NULL,
curwin->w_cursor.lnum, curwin->w_cursor.lnum, curwin->w_cursor.lnum, curwin->w_cursor.lnum,
&doesrange, true, NULL, NULL); &doesrange, true, pt, NULL);
fail:
if (ret == FAIL) { if (ret == FAIL) {
tv_clear(rettv); tv_clear(rettv);
} }
@ -2462,6 +2486,13 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv,
} }
} }
if (lp->ll_di != NULL && tv_is_luafunc(&lp->ll_di->di_tv)
&& len == -1 && rettv == NULL) {
tv_clear(&var1);
EMSG2(e_illvar, "v:['lua']");
return NULL;
}
if (lp->ll_di == NULL) { if (lp->ll_di == NULL) {
// Can't add "v:" or "a:" variable. // Can't add "v:" or "a:" variable.
if (lp->ll_dict == &vimvardict if (lp->ll_dict == &vimvardict
@ -4699,7 +4730,7 @@ eval_index(
if (evaluate) { if (evaluate) {
n1 = 0; n1 = 0;
if (!empty1 && rettv->v_type != VAR_DICT) { if (!empty1 && rettv->v_type != VAR_DICT && !tv_is_luafunc(rettv)) {
n1 = tv_get_number(&var1); n1 = tv_get_number(&var1);
tv_clear(&var1); tv_clear(&var1);
} }
@ -4823,7 +4854,7 @@ eval_index(
if (len == -1) { if (len == -1) {
tv_clear(&var1); tv_clear(&var1);
} }
if (item == NULL) { if (item == NULL || tv_is_luafunc(&item->di_tv)) {
return FAIL; return FAIL;
} }
@ -6334,7 +6365,7 @@ static char_u *deref_func_name(const char *name, int *lenp,
*/ */
static int static int
get_func_tv( get_func_tv(
char_u *name, // name of the function const char_u *name, // name of the function
int len, // length of "name" int len, // length of "name"
typval_T *rettv, typval_T *rettv,
char_u **arg, // argument, pointing to the '(' char_u **arg, // argument, pointing to the '('
@ -6590,7 +6621,15 @@ call_func(
rettv->vval.v_number = 0; rettv->vval.v_number = 0;
error = ERROR_UNKNOWN; error = ERROR_UNKNOWN;
if (!builtin_function((const char *)rfname, -1)) { if (partial == vvlua_partial) {
if (len > 0) {
error = ERROR_NONE;
executor_call_lua((const char *)funcname, len,
argvars, argcount, rettv);
} else {
error = ERROR_UNKNOWN;
}
} else if (!builtin_function((const char *)rfname, -1)) {
// User defined function. // User defined function.
if (partial != NULL && partial->pt_func != NULL) { if (partial != NULL && partial->pt_func != NULL) {
fp = partial->pt_func; fp = partial->pt_func;
@ -6707,14 +6746,14 @@ call_func(
/// ///
/// @param ermsg must be passed without translation (use N_() instead of _()). /// @param ermsg must be passed without translation (use N_() instead of _()).
/// @param name function name /// @param name function name
static void emsg_funcname(char *ermsg, char_u *name) static void emsg_funcname(char *ermsg, const char_u *name)
{ {
char_u *p; char_u *p;
if (*name == K_SPECIAL) { if (*name == K_SPECIAL) {
p = concat_str((char_u *)"<SNR>", name + 3); p = concat_str((char_u *)"<SNR>", name + 3);
} else { } else {
p = name; p = (char_u *)name;
} }
EMSG2(_(ermsg), p); EMSG2(_(ermsg), p);
@ -20168,6 +20207,26 @@ static void check_vars(const char *name, size_t len)
} }
} }
/// check if special v:lua value for calling lua functions
static bool tv_is_luafunc(typval_T *tv)
{
return tv->v_type == VAR_PARTIAL && tv->vval.v_partial == vvlua_partial;
}
/// check the function name after "v:lua."
static int check_luafunc_name(const char *str, bool paren)
{
const char *p = str;
while (ASCII_ISALNUM(*p) || *p == '_' || *p == '.') {
p++;
}
if (*p != (paren ? '(' : NUL)) {
return 0;
} else {
return (int)(p-str);
}
}
/// Handle expr[expr], expr[expr:expr] subscript and .name lookup. /// Handle expr[expr], expr[expr:expr] subscript and .name lookup.
/// Also handle function call with Funcref variable: func(expr) /// Also handle function call with Funcref variable: func(expr)
/// Can all be combined: dict.func(expr)[idx]['func'](expr) /// Can all be combined: dict.func(expr)[idx]['func'](expr)
@ -20181,9 +20240,30 @@ handle_subscript(
{ {
int ret = OK; int ret = OK;
dict_T *selfdict = NULL; dict_T *selfdict = NULL;
char_u *s; const char_u *s;
int len; int len;
typval_T functv; typval_T functv;
int slen = 0;
bool lua = false;
if (tv_is_luafunc(rettv)) {
if (**arg != '.') {
tv_clear(rettv);
ret = FAIL;
} else {
(*arg)++;
lua = true;
s = (char_u *)(*arg);
slen = check_luafunc_name(*arg, true);
if (slen == 0) {
tv_clear(rettv);
ret = FAIL;
}
(*arg) += slen;
}
}
while (ret == OK while (ret == OK
&& (**arg == '[' && (**arg == '['
@ -20200,14 +20280,16 @@ handle_subscript(
// Invoke the function. Recursive! // Invoke the function. Recursive!
if (functv.v_type == VAR_PARTIAL) { if (functv.v_type == VAR_PARTIAL) {
pt = functv.vval.v_partial; pt = functv.vval.v_partial;
s = partial_name(pt); if (!lua) {
s = partial_name(pt);
}
} else { } else {
s = functv.vval.v_string; s = functv.vval.v_string;
} }
} else { } else {
s = (char_u *)""; s = (char_u *)"";
} }
ret = get_func_tv(s, (int)STRLEN(s), rettv, (char_u **)arg, ret = get_func_tv(s, lua ? slen : (int)STRLEN(s), rettv, (char_u **)arg,
curwin->w_cursor.lnum, curwin->w_cursor.lnum, curwin->w_cursor.lnum, curwin->w_cursor.lnum,
&len, evaluate, pt, selfdict); &len, evaluate, pt, selfdict);
@ -22039,8 +22121,19 @@ trans_function_name(
*pp = (char_u *)end; *pp = (char_u *)end;
} else if (lv.ll_tv->v_type == VAR_PARTIAL } else if (lv.ll_tv->v_type == VAR_PARTIAL
&& lv.ll_tv->vval.v_partial != NULL) { && lv.ll_tv->vval.v_partial != NULL) {
name = vim_strsave(partial_name(lv.ll_tv->vval.v_partial)); if (lv.ll_tv->vval.v_partial == vvlua_partial && *end == '.') {
*pp = (char_u *)end; len = check_luafunc_name((const char *)end+1, true);
if (len == 0) {
EMSG2(e_invexpr2, "v:lua");
goto theend;
}
name = xmallocz(len);
memcpy(name, end+1, len);
*pp = (char_u *)end+1+len;
} else {
name = vim_strsave(partial_name(lv.ll_tv->vval.v_partial));
*pp = (char_u *)end;
}
if (partial != NULL) { if (partial != NULL) {
*partial = lv.ll_tv->vval.v_partial; *partial = lv.ll_tv->vval.v_partial;
} }

View File

@ -117,6 +117,7 @@ typedef enum {
VV_TYPE_BOOL, VV_TYPE_BOOL,
VV_ECHOSPACE, VV_ECHOSPACE,
VV_EXITING, VV_EXITING,
VV_LUA,
} VimVarIndex; } VimVarIndex;
/// All recognized msgpack types /// All recognized msgpack types

View File

@ -48,9 +48,6 @@ typedef struct {
# include "lua/executor.c.generated.h" # include "lua/executor.c.generated.h"
#endif #endif
/// Name of the run code for use in messages
#define NLUA_EVAL_NAME "<VimL compiled string>"
/// 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.
@ -397,29 +394,6 @@ static lua_State *nlua_enter(void)
return lstate; return lstate;
} }
/// Execute lua string
///
/// @param[in] str String to execute.
/// @param[out] ret_tv Location where result will be saved.
///
/// @return Result of the execution.
void executor_exec_lua(const String str, typval_T *const ret_tv)
FUNC_ATTR_NONNULL_ALL
{
lua_State *const lstate = nlua_enter();
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, 0, 1, 0)) {
nlua_error(lstate, _("E5105: Error while calling lua chunk: %.*s"));
return;
}
nlua_pop_typval(lstate, ret_tv);
}
static void nlua_print_event(void **argv) static void nlua_print_event(void **argv)
{ {
char *str = argv[0]; char *str = argv[0];
@ -732,10 +706,6 @@ 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
{ {
lua_State *const lstate = nlua_enter();
garray_T str_ga;
ga_init(&str_ga, 1, 80);
#define EVALHEADER "local _A=select(1,...) return (" #define EVALHEADER "local _A=select(1,...) return ("
const size_t lcmd_len = sizeof(EVALHEADER) - 1 + str.size + 1; const size_t lcmd_len = sizeof(EVALHEADER) - 1 + str.size + 1;
char *lcmd; char *lcmd;
@ -748,30 +718,71 @@ void executor_eval_lua(const String str, typval_T *const arg,
memcpy(lcmd + sizeof(EVALHEADER) - 1, str.data, str.size); memcpy(lcmd + sizeof(EVALHEADER) - 1, str.data, str.size);
lcmd[lcmd_len - 1] = ')'; lcmd[lcmd_len - 1] = ')';
#undef EVALHEADER #undef EVALHEADER
if (luaL_loadbuffer(lstate, lcmd, lcmd_len, NLUA_EVAL_NAME)) { typval_exec_lua(lcmd, lcmd_len, "luaeval()", arg, 1, true, ret_tv);
nlua_error(lstate,
_("E5107: Error while creating lua chunk for luaeval(): %.*s"));
if (lcmd != (char *)IObuff) {
xfree(lcmd);
}
return;
}
if (lcmd != (char *)IObuff) { if (lcmd != (char *)IObuff) {
xfree(lcmd); xfree(lcmd);
} }
}
if (arg->v_type == VAR_UNKNOWN) { void executor_call_lua(const char *str, size_t len, typval_T *const args,
lua_pushnil(lstate); int argcount, typval_T *ret_tv)
FUNC_ATTR_NONNULL_ALL
{
#define CALLHEADER "return "
#define CALLSUFFIX "(...)"
const size_t lcmd_len = sizeof(CALLHEADER) - 1 + len + sizeof(CALLSUFFIX) - 1;
char *lcmd;
if (lcmd_len < IOSIZE) {
lcmd = (char *)IObuff;
} else { } else {
nlua_push_typval(lstate, arg, true); lcmd = xmalloc(lcmd_len);
} }
if (lua_pcall(lstate, 1, 1, 0)) { memcpy(lcmd, CALLHEADER, sizeof(CALLHEADER) - 1);
nlua_error(lstate, memcpy(lcmd + sizeof(CALLHEADER) - 1, str, len);
_("E5108: Error while calling lua chunk for luaeval(): %.*s")); memcpy(lcmd + sizeof(CALLHEADER) - 1 + len, CALLSUFFIX,
sizeof(CALLSUFFIX) - 1);
#undef CALLHEADER
#undef CALLSUFFIX
typval_exec_lua(lcmd, lcmd_len, "v:lua", args, argcount, false, ret_tv);
if (lcmd != (char *)IObuff) {
xfree(lcmd);
}
}
static void typval_exec_lua(const char *lcmd, size_t lcmd_len, const char *name,
typval_T *const args, int argcount, bool special,
typval_T *ret_tv)
{
if (check_restricted() || check_secure()) {
ret_tv->v_type = VAR_NUMBER;
ret_tv->vval.v_number = 0;
return; return;
} }
nlua_pop_typval(lstate, ret_tv); lua_State *const lstate = nlua_enter();
if (luaL_loadbuffer(lstate, lcmd, lcmd_len, name)) {
nlua_error(lstate, _("E5107: Error loading lua %.*s"));
return;
}
for (int i = 0; i < argcount; i++) {
if (args[i].v_type == VAR_UNKNOWN) {
lua_pushnil(lstate);
} else {
nlua_push_typval(lstate, &args[i], special);
}
}
if (lua_pcall(lstate, argcount, ret_tv ? 1 : 0, 0)) {
nlua_error(lstate, _("E5108: Error executing lua %.*s"));
return;
}
if (ret_tv) {
nlua_pop_typval(lstate, ret_tv);
}
} }
/// Execute lua string /// Execute lua string
@ -857,9 +868,8 @@ void ex_lua(exarg_T *const eap)
xfree(code); xfree(code);
return; return;
} }
typval_T tv = { .v_type = VAR_UNKNOWN }; typval_exec_lua(code, len, ":lua", NULL, 0, false, NULL);
executor_exec_lua((String) { .data = code, .size = len }, &tv);
tv_clear(&tv);
xfree(code); xfree(code);
} }
@ -897,8 +907,8 @@ void ex_luado(exarg_T *const eap)
#undef DOSTART #undef DOSTART
#undef DOEND #undef DOEND
if (luaL_loadbuffer(lstate, lcmd, lcmd_len, NLUA_EVAL_NAME)) { if (luaL_loadbuffer(lstate, lcmd, lcmd_len, ":luado")) {
nlua_error(lstate, _("E5109: Error while creating lua chunk: %.*s")); nlua_error(lstate, _("E5109: Error loading lua: %.*s"));
if (lcmd_len >= IOSIZE) { if (lcmd_len >= IOSIZE) {
xfree(lcmd); xfree(lcmd);
} }
@ -908,7 +918,7 @@ void ex_luado(exarg_T *const eap)
xfree(lcmd); xfree(lcmd);
} }
if (lua_pcall(lstate, 0, 1, 0)) { if (lua_pcall(lstate, 0, 1, 0)) {
nlua_error(lstate, _("E5110: Error while creating lua function: %.*s")); nlua_error(lstate, _("E5110: Error executing lua: %.*s"));
return; return;
} }
for (linenr_T l = eap->line1; l <= eap->line2; l++) { for (linenr_T l = eap->line1; l <= eap->line2; l++) {
@ -919,7 +929,7 @@ void ex_luado(exarg_T *const eap)
lua_pushstring(lstate, (const char *)ml_get_buf(curbuf, l, false)); lua_pushstring(lstate, (const char *)ml_get_buf(curbuf, l, false));
lua_pushnumber(lstate, (lua_Number)l); lua_pushnumber(lstate, (lua_Number)l);
if (lua_pcall(lstate, 2, 1, 0)) { if (lua_pcall(lstate, 2, 1, 0)) {
nlua_error(lstate, _("E5111: Error while calling lua function: %.*s")); nlua_error(lstate, _("E5111: Error calling lua: %.*s"));
break; break;
} }
if (lua_isstring(lstate, -1)) { if (lua_isstring(lstate, -1)) {

View File

@ -155,41 +155,41 @@ describe('luaeval(vim.api.…)', function()
it('errors out correctly when working with API', function() it('errors out correctly when working with API', function()
-- Conversion errors -- Conversion errors
eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Cannot convert given lua type', eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Cannot convert given lua type',
exc_exec([[call luaeval("vim.api.nvim__id(vim.api.nvim__id)")]])) exc_exec([[call luaeval("vim.api.nvim__id(vim.api.nvim__id)")]]))
eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Cannot convert given lua table', eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Cannot convert given lua table',
exc_exec([[call luaeval("vim.api.nvim__id({1, foo=42})")]])) exc_exec([[call luaeval("vim.api.nvim__id({1, foo=42})")]]))
eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Cannot convert given lua type', eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Cannot convert given lua type',
exc_exec([[call luaeval("vim.api.nvim__id({42, vim.api.nvim__id})")]])) exc_exec([[call luaeval("vim.api.nvim__id({42, vim.api.nvim__id})")]]))
-- Errors in number of arguments -- Errors in number of arguments
eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Expected 1 argument', eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected 1 argument',
exc_exec([[call luaeval("vim.api.nvim__id()")]])) exc_exec([[call luaeval("vim.api.nvim__id()")]]))
eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Expected 1 argument', eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected 1 argument',
exc_exec([[call luaeval("vim.api.nvim__id(1, 2)")]])) exc_exec([[call luaeval("vim.api.nvim__id(1, 2)")]]))
eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Expected 2 arguments', eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected 2 arguments',
exc_exec([[call luaeval("vim.api.nvim_set_var(1, 2, 3)")]])) exc_exec([[call luaeval("vim.api.nvim_set_var(1, 2, 3)")]]))
-- Error in argument types -- Error in argument types
eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Expected lua string', eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected lua string',
exc_exec([[call luaeval("vim.api.nvim_set_var(1, 2)")]])) exc_exec([[call luaeval("vim.api.nvim_set_var(1, 2)")]]))
eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Expected lua number', eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected lua number',
exc_exec([[call luaeval("vim.api.nvim_buf_get_lines(0, 'test', 1, false)")]])) exc_exec([[call luaeval("vim.api.nvim_buf_get_lines(0, 'test', 1, false)")]]))
eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Number is not integral', eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Number is not integral',
exc_exec([[call luaeval("vim.api.nvim_buf_get_lines(0, 1.5, 1, false)")]])) exc_exec([[call luaeval("vim.api.nvim_buf_get_lines(0, 1.5, 1, false)")]]))
eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Expected lua table', eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected lua table',
exc_exec([[call luaeval("vim.api.nvim__id_float('test')")]])) exc_exec([[call luaeval("vim.api.nvim__id_float('test')")]]))
eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Unexpected type', eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Unexpected type',
exc_exec([[call luaeval("vim.api.nvim__id_float({[vim.type_idx]=vim.types.dictionary})")]])) exc_exec([[call luaeval("vim.api.nvim__id_float({[vim.type_idx]=vim.types.dictionary})")]]))
eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Expected lua table', eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected lua table',
exc_exec([[call luaeval("vim.api.nvim__id_array(1)")]])) exc_exec([[call luaeval("vim.api.nvim__id_array(1)")]]))
eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Unexpected type', eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Unexpected type',
exc_exec([[call luaeval("vim.api.nvim__id_array({[vim.type_idx]=vim.types.dictionary})")]])) exc_exec([[call luaeval("vim.api.nvim__id_array({[vim.type_idx]=vim.types.dictionary})")]]))
eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Expected lua table', eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected lua table',
exc_exec([[call luaeval("vim.api.nvim__id_dictionary(1)")]])) exc_exec([[call luaeval("vim.api.nvim__id_dictionary(1)")]]))
eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Unexpected type', eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Unexpected type',
exc_exec([[call luaeval("vim.api.nvim__id_dictionary({[vim.type_idx]=vim.types.array})")]])) exc_exec([[call luaeval("vim.api.nvim__id_dictionary({[vim.type_idx]=vim.types.array})")]]))
-- TODO: check for errors with Tabpage argument -- TODO: check for errors with Tabpage argument
-- TODO: check for errors with Window argument -- TODO: check for errors with Window argument

View File

@ -13,6 +13,7 @@ local source = helpers.source
local dedent = helpers.dedent local dedent = helpers.dedent
local command = helpers.command local command = helpers.command
local exc_exec = helpers.exc_exec local exc_exec = helpers.exc_exec
local pcall_err = helpers.pcall_err
local write_file = helpers.write_file local write_file = helpers.write_file
local redir_exec = helpers.redir_exec local redir_exec = helpers.redir_exec
local curbufmeths = helpers.curbufmeths local curbufmeths = helpers.curbufmeths
@ -42,16 +43,16 @@ describe(':lua command', function()
eq({'', 'ETTS', 'TTSE', 'STTE'}, curbufmeths.get_lines(0, 100, false)) eq({'', 'ETTS', 'TTSE', 'STTE'}, curbufmeths.get_lines(0, 100, false))
end) end)
it('throws catchable errors', function() it('throws catchable errors', function()
eq([[Vim(lua):E5104: Error while creating lua chunk: [string "<VimL compiled string>"]:1: unexpected symbol near ')']], eq([[Vim(lua):E5107: Error loading lua [string ":lua"]:1: unexpected symbol near ')']],
exc_exec('lua ()')) pcall_err(command, 'lua ()'))
eq([[Vim(lua):E5105: Error while calling lua chunk: [string "<VimL compiled string>"]:1: TEST]], eq([[Vim(lua):E5108: Error executing lua [string ":lua"]:1: TEST]],
exc_exec('lua error("TEST")')) exc_exec('lua error("TEST")'))
eq([[Vim(lua):E5105: Error while calling lua chunk: [string "<VimL compiled string>"]:1: Invalid buffer id]], eq([[Vim(lua):E5108: Error executing lua [string ":lua"]:1: Invalid buffer id]],
exc_exec('lua vim.api.nvim_buf_set_lines(-10, 1, 1, false, {"TEST"})')) exc_exec('lua vim.api.nvim_buf_set_lines(-10, 1, 1, false, {"TEST"})'))
eq({''}, curbufmeths.get_lines(0, 100, false)) eq({''}, curbufmeths.get_lines(0, 100, false))
end) end)
it('works with NULL errors', function() it('works with NULL errors', function()
eq([=[Vim(lua):E5105: Error while calling lua chunk: [NULL]]=], eq([=[Vim(lua):E5108: Error executing lua [NULL]]=],
exc_exec('lua error(nil)')) exc_exec('lua error(nil)'))
end) end)
it('accepts embedded NLs without heredoc', function() it('accepts embedded NLs without heredoc', function()
@ -74,7 +75,7 @@ describe(':lua command', function()
it('works with long strings', function() it('works with long strings', function()
local s = ('x'):rep(100500) local s = ('x'):rep(100500)
eq('\nE5104: Error while creating lua chunk: [string "<VimL compiled string>"]:1: unfinished string near \'<eof>\'', redir_exec(('lua vim.api.nvim_buf_set_lines(1, 1, 2, false, {"%s})'):format(s))) eq('\nE5107: Error loading lua [string ":lua"]:1: unfinished string near \'<eof>\'', redir_exec(('lua vim.api.nvim_buf_set_lines(1, 1, 2, false, {"%s})'):format(s)))
eq({''}, curbufmeths.get_lines(0, -1, false)) eq({''}, curbufmeths.get_lines(0, -1, false))
eq('', redir_exec(('lua vim.api.nvim_buf_set_lines(1, 1, 2, false, {"%s"})'):format(s))) eq('', redir_exec(('lua vim.api.nvim_buf_set_lines(1, 1, 2, false, {"%s"})'):format(s)))
@ -82,7 +83,7 @@ describe(':lua command', function()
end) end)
it('can show multiline error messages', function() it('can show multiline error messages', function()
local screen = Screen.new(50,10) local screen = Screen.new(40,10)
screen:attach() screen:attach()
screen:set_default_attr_ids({ screen:set_default_attr_ids({
[1] = {bold = true, foreground = Screen.colors.Blue1}, [1] = {bold = true, foreground = Screen.colors.Blue1},
@ -92,51 +93,51 @@ describe(':lua command', function()
}) })
feed(':lua error("fail\\nmuch error\\nsuch details")<cr>') feed(':lua error("fail\\nmuch error\\nsuch details")<cr>')
screen:expect([[ screen:expect{grid=[[
| |
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
{2: }| {2: }|
{3:E5105: Error while calling lua chunk: [string "<Vi}| {3:E5108: Error executing lua [string ":lua}|
{3:mL compiled string>"]:1: fail} | {3:"]:1: fail} |
{3:much error} | {3:much error} |
{3:such details} | {3:such details} |
{4:Press ENTER or type command to continue}^ | {4:Press ENTER or type command to continue}^ |
]]) ]]}
feed('<cr>') feed('<cr>')
screen:expect([[ screen:expect{grid=[[
^ | ^ |
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
| |
]]) ]]}
eq('E5105: Error while calling lua chunk: [string "<VimL compiled string>"]:1: fail\nmuch error\nsuch details', eval('v:errmsg')) eq('E5108: Error executing lua [string ":lua"]:1: fail\nmuch error\nsuch details', eval('v:errmsg'))
local status, err = pcall(command,'lua error("some error\\nin a\\nAPI command")') local status, err = pcall(command,'lua error("some error\\nin a\\nAPI command")')
local expected = 'Vim(lua):E5105: Error while calling lua chunk: [string "<VimL compiled string>"]:1: some error\nin a\nAPI command' local expected = 'Vim(lua):E5108: Error executing lua [string ":lua"]:1: some error\nin a\nAPI command'
eq(false, status) eq(false, status)
eq(expected, string.sub(err, -string.len(expected))) eq(expected, string.sub(err, -string.len(expected)))
feed(':messages<cr>') feed(':messages<cr>')
screen:expect([[ screen:expect{grid=[[
| |
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
{2: }| {2: }|
{3:E5105: Error while calling lua chunk: [string "<Vi}| {3:E5108: Error executing lua [string ":lua}|
{3:mL compiled string>"]:1: fail} | {3:"]:1: fail} |
{3:much error} | {3:much error} |
{3:such details} | {3:such details} |
{4:Press ENTER or type command to continue}^ | {4:Press ENTER or type command to continue}^ |
]]) ]]}
end) end)
end) end)
@ -167,13 +168,13 @@ describe(':luado command', function()
eq({''}, curbufmeths.get_lines(0, -1, false)) eq({''}, curbufmeths.get_lines(0, -1, false))
end) end)
it('fails on errors', function() it('fails on errors', function()
eq([[Vim(luado):E5109: Error while creating lua chunk: [string "<VimL compiled string>"]:1: unexpected symbol near ')']], eq([[Vim(luado):E5109: Error loading lua: [string ":luado"]:1: unexpected symbol near ')']],
exc_exec('luado ()')) exc_exec('luado ()'))
eq([[Vim(luado):E5111: Error while calling lua function: [string "<VimL compiled string>"]:1: attempt to perform arithmetic on global 'liness' (a nil value)]], eq([[Vim(luado):E5111: Error calling lua: [string ":luado"]:1: attempt to perform arithmetic on global 'liness' (a nil value)]],
exc_exec('luado return liness + 1')) exc_exec('luado return liness + 1'))
end) end)
it('works with NULL errors', function() it('works with NULL errors', function()
eq([=[Vim(luado):E5111: Error while calling lua function: [NULL]]=], eq([=[Vim(luado):E5111: Error calling lua: [NULL]]=],
exc_exec('luado error(nil)')) exc_exec('luado error(nil)'))
end) end)
it('fails in sandbox when needed', function() it('fails in sandbox when needed', function()
@ -185,7 +186,7 @@ describe(':luado command', function()
it('works with long strings', function() it('works with long strings', function()
local s = ('x'):rep(100500) local s = ('x'):rep(100500)
eq('\nE5109: Error while creating lua chunk: [string "<VimL compiled string>"]:1: unfinished string near \'<eof>\'', redir_exec(('luado return "%s'):format(s))) eq('\nE5109: Error loading lua: [string ":luado"]:1: unfinished string near \'<eof>\'', redir_exec(('luado return "%s'):format(s)))
eq({''}, curbufmeths.get_lines(0, -1, false)) eq({''}, curbufmeths.get_lines(0, -1, false))
eq('', redir_exec(('luado return "%s"'):format(s))) eq('', redir_exec(('luado return "%s"'):format(s)))

View File

@ -1,13 +1,17 @@
-- Test suite for testing luaeval() function -- Test suite for testing luaeval() function
local helpers = require('test.functional.helpers')(after_each) local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local redir_exec = helpers.redir_exec local redir_exec = helpers.redir_exec
local pcall_err = helpers.pcall_err
local exc_exec = helpers.exc_exec local exc_exec = helpers.exc_exec
local exec_lua = helpers.exec_lua
local command = helpers.command local command = helpers.command
local meths = helpers.meths local meths = helpers.meths
local funcs = helpers.funcs local funcs = helpers.funcs
local clear = helpers.clear local clear = helpers.clear
local eval = helpers.eval local eval = helpers.eval
local feed = helpers.feed
local NIL = helpers.NIL local NIL = helpers.NIL
local eq = helpers.eq local eq = helpers.eq
@ -186,9 +190,9 @@ describe('luaeval()', function()
exc_exec('call luaeval("{1, foo=2}")')) exc_exec('call luaeval("{1, foo=2}")'))
eq("Vim(call):E5101: Cannot convert given lua type", eq("Vim(call):E5101: Cannot convert given lua type",
exc_exec('call luaeval("vim.api.nvim_buf_get_lines")')) exc_exec('call luaeval("vim.api.nvim_buf_get_lines")'))
startswith("Vim(call):E5107: Error while creating lua chunk for luaeval(): ", startswith("Vim(call):E5107: Error loading lua [string \"luaeval()\"]:",
exc_exec('call luaeval("1, 2, 3")')) exc_exec('call luaeval("1, 2, 3")'))
startswith("Vim(call):E5108: Error while calling lua chunk for luaeval(): ", startswith("Vim(call):E5108: Error executing lua [string \"luaeval()\"]:",
exc_exec('call luaeval("(nil)()")')) exc_exec('call luaeval("(nil)()")'))
eq("Vim(call):E5101: Cannot convert given lua type", eq("Vim(call):E5101: Cannot convert given lua type",
exc_exec('call luaeval("{42, vim.api}")')) exc_exec('call luaeval("{42, vim.api}")'))
@ -237,19 +241,99 @@ describe('luaeval()', function()
it('errors out correctly when doing incorrect things in lua', function() it('errors out correctly when doing incorrect things in lua', function()
-- Conversion errors -- Conversion errors
eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: attempt to call field \'xxx_nonexistent_key_xxx\' (a nil value)', eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: attempt to call field \'xxx_nonexistent_key_xxx\' (a nil value)',
exc_exec([[call luaeval("vim.xxx_nonexistent_key_xxx()")]])) exc_exec([[call luaeval("vim.xxx_nonexistent_key_xxx()")]]))
eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: ERROR', eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: ERROR',
exc_exec([[call luaeval("error('ERROR')")]])) exc_exec([[call luaeval("error('ERROR')")]]))
eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [NULL]', eq('Vim(call):E5108: Error executing lua [NULL]',
exc_exec([[call luaeval("error(nil)")]])) exc_exec([[call luaeval("error(nil)")]]))
end) end)
it('does not leak memory when called with too long line', it('does not leak memory when called with too long line',
function() function()
local s = ('x'):rep(65536) local s = ('x'):rep(65536)
eq('Vim(call):E5107: Error while creating lua chunk for luaeval(): [string "<VimL compiled string>"]:1: unexpected symbol near \')\'', eq('Vim(call):E5107: Error loading lua [string "luaeval()"]:1: unexpected symbol near \')\'',
exc_exec([[call luaeval("(']] .. s ..[[' + )")]])) exc_exec([[call luaeval("(']] .. s ..[[' + )")]]))
eq(s, funcs.luaeval('"' .. s .. '"')) eq(s, funcs.luaeval('"' .. s .. '"'))
end) end)
end) end)
describe('v:lua', function()
before_each(function()
exec_lua([[
function _G.foo(a,b,n)
_G.val = n
return a+b
end
mymod = {}
function mymod.noisy(name)
vim.api.nvim_set_current_line("hey "..name)
end
function mymod.crashy()
nonexistent()
end
function mymod.omni(findstart, base)
if findstart == 1 then
return 5
else
if base == 'st' then
return {'stuff', 'steam', 'strange things'}
end
end
end
vim.api.nvim_buf_set_option(0, 'omnifunc', 'v:lua.mymod.omni')
]])
end)
it('works in expressions', function()
eq(7, eval('v:lua.foo(3,4,v:null)'))
eq(true, exec_lua([[return _G.val == vim.NIL]]))
eq(NIL, eval('v:lua.mymod.noisy("eval")'))
eq("hey eval", meths.get_current_line())
eq("Vim:E5108: Error executing lua [string \"<nvim>\"]:10: attempt to call global 'nonexistent' (a nil value)",
pcall_err(eval, 'v:lua.mymod.crashy()'))
end)
it('works in :call', function()
command(":call v:lua.mymod.noisy('command')")
eq("hey command", meths.get_current_line())
eq("Vim(call):E5108: Error executing lua [string \"<nvim>\"]:10: attempt to call global 'nonexistent' (a nil value)",
pcall_err(command, 'call v:lua.mymod.crashy()'))
end)
it('works in func options', function()
local screen = Screen.new(60, 8)
screen:set_default_attr_ids({
[1] = {bold = true, foreground = Screen.colors.Blue1},
[2] = {background = Screen.colors.WebGray},
[3] = {background = Screen.colors.LightMagenta},
[4] = {bold = true},
[5] = {bold = true, foreground = Screen.colors.SeaGreen4},
})
screen:attach()
feed('isome st<c-x><c-o>')
screen:expect{grid=[[
some stuff^ |
{1:~ }{2: stuff }{1: }|
{1:~ }{3: steam }{1: }|
{1:~ }{3: strange things }{1: }|
{1:~ }|
{1:~ }|
{1:~ }|
{4:-- Omni completion (^O^N^P) }{5:match 1 of 3} |
]]}
end)
it('throw errors for invalid use', function()
eq('Vim(let):E15: Invalid expression: v:lua.func', pcall_err(command, "let g:Func = v:lua.func"))
eq('Vim(let):E15: Invalid expression: v:lua', pcall_err(command, "let g:Func = v:lua"))
eq("Vim(let):E15: Invalid expression: v:['lua']", pcall_err(command, "let g:Func = v:['lua']"))
eq("Vim:E15: Invalid expression: v:['lua'].foo()", pcall_err(eval, "v:['lua'].foo()"))
eq("Vim(call):E461: Illegal variable name: v:['lua']", pcall_err(command, "call v:['lua'].baar()"))
eq("Vim(let):E46: Cannot change read-only variable \"v:['lua']\"", pcall_err(command, "let v:['lua'] = 'xx'"))
eq("Vim(let):E46: Cannot change read-only variable \"v:lua\"", pcall_err(command, "let v:lua = 'xx'"))
end)
end)

View File

@ -54,11 +54,12 @@ describe('print', function()
v_tblout = setmetatable({}, meta_tblout) v_tblout = setmetatable({}, meta_tblout)
]]) ]])
eq('', redir_exec('luafile ' .. fname)) eq('', redir_exec('luafile ' .. fname))
eq('\nE5105: Error while calling lua chunk: E5114: Error while converting print argument #2: [NULL]', -- TODO(bfredl): these look weird, print() should not use "E5114:" style errors..
eq('\nE5108: Error executing lua E5114: Error while converting print argument #2: [NULL]',
redir_exec('lua print("foo", v_nilerr, "bar")')) redir_exec('lua print("foo", v_nilerr, "bar")'))
eq('\nE5105: Error while calling lua chunk: E5114: Error while converting print argument #2: Xtest-functional-lua-overrides-luafile:2: abc', eq('\nE5108: Error executing lua E5114: Error while converting print argument #2: Xtest-functional-lua-overrides-luafile:2: abc',
redir_exec('lua print("foo", v_abcerr, "bar")')) redir_exec('lua print("foo", v_abcerr, "bar")'))
eq('\nE5105: Error while calling lua chunk: E5114: Error while converting print argument #2: <Unknown error: lua_tolstring returned NULL for tostring result>', eq('\nE5108: Error executing lua E5114: Error while converting print argument #2: <Unknown error: lua_tolstring returned NULL for tostring result>',
redir_exec('lua print("foo", v_tblout, "bar")')) redir_exec('lua print("foo", v_tblout, "bar")'))
end) end)
it('prints strings with NULs and NLs correctly', function() it('prints strings with NULs and NLs correctly', function()
@ -156,7 +157,8 @@ describe('debug.debug', function()
lua_debug> ^ | lua_debug> ^ |
]]) ]])
feed('<C-c>') feed('<C-c>')
screen:expect([[ screen:expect{grid=[[
{0:~ }|
{0:~ }| {0:~ }|
{0:~ }| {0:~ }|
{0:~ }| {0:~ }|
@ -167,11 +169,10 @@ describe('debug.debug', function()
lua_debug> print("TEST") | lua_debug> print("TEST") |
TEST | TEST |
| |
{E:E5105: Error while calling lua chunk: [string "<VimL }| {E:E5108: Error executing lua [string ":lua"]:5: attempt}|
{E:compiled string>"]:5: attempt to perform arithmetic o}| {E: to perform arithmetic on local 'a' (a nil value)} |
{E:n local 'a' (a nil value)} |
Interrupt: {cr:Press ENTER or type command to continue}^ | Interrupt: {cr:Press ENTER or type command to continue}^ |
]]) ]]}
feed('<C-l>:lua Test()\n') feed('<C-l>:lua Test()\n')
screen:expect([[ screen:expect([[
{0:~ }| {0:~ }|
@ -190,7 +191,8 @@ describe('debug.debug', function()
lua_debug> ^ | lua_debug> ^ |
]]) ]])
feed('\n') feed('\n')
screen:expect([[ screen:expect{grid=[[
{0:~ }|
{0:~ }| {0:~ }|
{0:~ }| {0:~ }|
{0:~ }| {0:~ }|
@ -201,11 +203,10 @@ describe('debug.debug', function()
{0:~ }| {0:~ }|
nil | nil |
lua_debug> | lua_debug> |
{E:E5105: Error while calling lua chunk: [string "<VimL }| {E:E5108: Error executing lua [string ":lua"]:5: attempt}|
{E:compiled string>"]:5: attempt to perform arithmetic o}| {E: to perform arithmetic on local 'a' (a nil value)} |
{E:n local 'a' (a nil value)} |
{cr:Press ENTER or type command to continue}^ | {cr:Press ENTER or type command to continue}^ |
]]) ]]}
end) end)
it("can be safely exited with 'cont'", function() it("can be safely exited with 'cont'", function()

View File

@ -747,7 +747,7 @@ describe('ui/ext_messages', function()
{1:~ }| {1:~ }|
{1:~ }| {1:~ }|
]], messages={{ ]], messages={{
content = {{'E5105: Error while calling lua chunk: [string "<VimL compiled string>"]:1: such\nmultiline\nerror', 2}}, content = {{'E5108: Error executing lua [string ":lua"]:1: such\nmultiline\nerror', 2}},
kind = "lua_error" kind = "lua_error"
}}} }}}
end) end)
@ -1146,97 +1146,96 @@ aliquip ex ea commodo consequat.]])
it('handles wrapped lines with line scroll', function() it('handles wrapped lines with line scroll', function()
feed(':lua error(_G.x)<cr>') feed(':lua error(_G.x)<cr>')
screen:expect{grid=[[ screen:expect{grid=[[
{2:E5105: Error while calling lua chun}| {2:E5108: Error executing lua [string }|
{2:k: [string "<VimL compiled string>"}| {2:":lua"]:1: Lorem ipsum dolor sit am}|
{2:]:1: Lorem ipsum dolor sit amet, co}| {2:et, consectetur} |
{2:nsectetur} |
{2:adipisicing elit, sed do eiusmod te}| {2:adipisicing elit, sed do eiusmod te}|
{2:mpor} | {2:mpor} |
{2:incididunt ut labore et dolore magn}| {2:incididunt ut labore et dolore magn}|
{2:a aliqua.} |
{4:-- More --}^ | {4:-- More --}^ |
]]} ]]}
feed('j') feed('j')
screen:expect{grid=[[ screen:expect{grid=[[
{2:k: [string "<VimL compiled string>"}| {2:":lua"]:1: Lorem ipsum dolor sit am}|
{2:]:1: Lorem ipsum dolor sit amet, co}| {2:et, consectetur} |
{2:nsectetur} |
{2:adipisicing elit, sed do eiusmod te}| {2:adipisicing elit, sed do eiusmod te}|
{2:mpor} | {2:mpor} |
{2:incididunt ut labore et dolore magn}| {2:incididunt ut labore et dolore magn}|
{2:a aliqua.} | {2:a aliqua.} |
{2:Ut enim ad minim veniam, quis nostr}|
{4:-- More --}^ | {4:-- More --}^ |
]]} ]]}
feed('k') feed('k')
screen:expect{grid=[[ screen:expect{grid=[[
{2:E5105: Error while calling lua chun}| {2:E5108: Error executing lua [string }|
{2:k: [string "<VimL compiled string>"}| {2:":lua"]:1: Lorem ipsum dolor sit am}|
{2:]:1: Lorem ipsum dolor sit amet, co}| {2:et, consectetur} |
{2:nsectetur} |
{2:adipisicing elit, sed do eiusmod te}| {2:adipisicing elit, sed do eiusmod te}|
{2:mpor} | {2:mpor} |
{2:incididunt ut labore et dolore magn}| {2:incididunt ut labore et dolore magn}|
{2:a aliqua.} |
{4:-- More --}^ | {4:-- More --}^ |
]]} ]]}
feed('j') feed('j')
screen:expect{grid=[[ screen:expect{grid=[[
{2:k: [string "<VimL compiled string>"}| {2:":lua"]:1: Lorem ipsum dolor sit am}|
{2:]:1: Lorem ipsum dolor sit amet, co}| {2:et, consectetur} |
{2:nsectetur} |
{2:adipisicing elit, sed do eiusmod te}| {2:adipisicing elit, sed do eiusmod te}|
{2:mpor} | {2:mpor} |
{2:incididunt ut labore et dolore magn}| {2:incididunt ut labore et dolore magn}|
{2:a aliqua.} | {2:a aliqua.} |
{2:Ut enim ad minim veniam, quis nostr}|
{4:-- More --}^ | {4:-- More --}^ |
]]} ]]}
end) end)
it('handles wrapped lines with page scroll', function() it('handles wrapped lines with page scroll', function()
feed(':lua error(_G.x)<cr>') feed(':lua error(_G.x)<cr>')
screen:expect{grid=[[ screen:expect{grid=[[
{2:E5105: Error while calling lua chun}| {2:E5108: Error executing lua [string }|
{2:k: [string "<VimL compiled string>"}| {2:":lua"]:1: Lorem ipsum dolor sit am}|
{2:]:1: Lorem ipsum dolor sit amet, co}| {2:et, consectetur} |
{2:nsectetur} |
{2:adipisicing elit, sed do eiusmod te}| {2:adipisicing elit, sed do eiusmod te}|
{2:mpor} | {2:mpor} |
{2:incididunt ut labore et dolore magn}| {2:incididunt ut labore et dolore magn}|
{2:a aliqua.} |
{4:-- More --}^ | {4:-- More --}^ |
]]} ]]}
feed('d') feed('d')
screen:expect{grid=[[ screen:expect{grid=[[
{2:adipisicing elit, sed do eiusmod te}|
{2:mpor} |
{2:incididunt ut labore et dolore magn}| {2:incididunt ut labore et dolore magn}|
{2:a aliqua.} | {2:a aliqua.} |
{2:Ut enim ad minim veniam, quis nostr}| {2:Ut enim ad minim veniam, quis nostr}|
{2:ud xercitation} | {2:ud xercitation} |
{2:ullamco laboris nisi ut} | {2:ullamco laboris nisi ut} |
{4:-- More --}^ | {2:aliquip ex ea commodo consequat.} |
{4:Press ENTER or type command to cont}|
{4:inue}^ |
]]} ]]}
feed('u') feed('u')
screen:expect{grid=[[ screen:expect{grid=[[
{2:E5105: Error while calling lua chun}| {2:E5108: Error executing lua [string }|
{2:k: [string "<VimL compiled string>"}| {2:":lua"]:1: Lorem ipsum dolor sit am}|
{2:]:1: Lorem ipsum dolor sit amet, co}| {2:et, consectetur} |
{2:nsectetur} |
{2:adipisicing elit, sed do eiusmod te}| {2:adipisicing elit, sed do eiusmod te}|
{2:mpor} | {2:mpor} |
{2:incididunt ut labore et dolore magn}| {2:incididunt ut labore et dolore magn}|
{2:a aliqua.} |
{4:-- More --}^ | {4:-- More --}^ |
]]} ]]}
feed('d') feed('d')
screen:expect{grid=[[ screen:expect{grid=[[
{2:adipisicing elit, sed do eiusmod te}|
{2:mpor} | {2:mpor} |
{2:incididunt ut labore et dolore magn}| {2:incididunt ut labore et dolore magn}|
{2:a aliqua.} | {2:a aliqua.} |
{2:Ut enim ad minim veniam, quis nostr}| {2:Ut enim ad minim veniam, quis nostr}|
{2:ud xercitation} | {2:ud xercitation} |
{2:ullamco laboris nisi ut} | {2:ullamco laboris nisi ut} |
{2:aliquip ex ea commodo consequat.} |
{4:-- More --}^ | {4:-- More --}^ |
]]} ]]}
end) end)
@ -1246,49 +1245,49 @@ aliquip ex ea commodo consequat.]])
feed(':lua error(_G.x)<cr>') feed(':lua error(_G.x)<cr>')
screen:expect{grid=[[ screen:expect{grid=[[
{3:E5105: Error while calling lua chun}| {3:E5108: Error executing lua [string }|
{3:k: [string "<VimL compiled string>"}| {3:":lua"]:1: Lorem ipsum dolor sit am}|
{3:]:1: Lorem ipsum dolor sit amet, co}| {3:et, consectetur}{5: }|
{3:nsectetur}{5: }|
{3:adipisicing elit, sed do eiusmod te}| {3:adipisicing elit, sed do eiusmod te}|
{3:mpor}{5: }| {3:mpor}{5: }|
{3:incididunt ut labore et dolore magn}| {3:incididunt ut labore et dolore magn}|
{3:a aliqua.}{5: }|
{6:-- More --}{5:^ }| {6:-- More --}{5:^ }|
]]} ]]}
feed('j') feed('j')
screen:expect{grid=[[ screen:expect{grid=[[
{3:k: [string "<VimL compiled string>"}| {3:":lua"]:1: Lorem ipsum dolor sit am}|
{3:]:1: Lorem ipsum dolor sit amet, co}| {3:et, consectetur}{5: }|
{3:nsectetur}{5: }|
{3:adipisicing elit, sed do eiusmod te}| {3:adipisicing elit, sed do eiusmod te}|
{3:mpor}{5: }| {3:mpor}{5: }|
{3:incididunt ut labore et dolore magn}| {3:incididunt ut labore et dolore magn}|
{3:a aliqua.}{5: }| {3:a aliqua.}{5: }|
{3:Ut enim ad minim veniam, quis nostr}|
{6:-- More --}{5:^ }| {6:-- More --}{5:^ }|
]]} ]]}
feed('k') feed('k')
screen:expect{grid=[[ screen:expect{grid=[[
{3:E5105: Error while calling lua chun}| {3:E5108: Error executing lua [string }|
{3:k: [string "<VimL compiled string>"}| {3:":lua"]:1: Lorem ipsum dolor sit am}|
{3:]:1: Lorem ipsum dolor sit amet, co}| {3:et, consectetur}{5: }|
{3:nsectetur}{5: }|
{3:adipisicing elit, sed do eiusmod te}| {3:adipisicing elit, sed do eiusmod te}|
{3:mpor}{5: }| {3:mpor}{5: }|
{3:incididunt ut labore et dolore magn}| {3:incididunt ut labore et dolore magn}|
{3:a aliqua.}{5: }|
{6:-- More --}{5:^ }| {6:-- More --}{5:^ }|
]]} ]]}
feed('j') feed('j')
screen:expect{grid=[[ screen:expect{grid=[[
{3:k: [string "<VimL compiled string>"}| {3:":lua"]:1: Lorem ipsum dolor sit am}|
{3:]:1: Lorem ipsum dolor sit amet, co}| {3:et, consectetur}{5: }|
{3:nsectetur}{5: }|
{3:adipisicing elit, sed do eiusmod te}| {3:adipisicing elit, sed do eiusmod te}|
{3:mpor}{5: }| {3:mpor}{5: }|
{3:incididunt ut labore et dolore magn}| {3:incididunt ut labore et dolore magn}|
{3:a aliqua.}{5: }| {3:a aliqua.}{5: }|
{3:Ut enim ad minim veniam, quis nostr}|
{6:-- More --}{5:^ }| {6:-- More --}{5:^ }|
]]} ]]}
end) end)
@ -1297,46 +1296,46 @@ aliquip ex ea commodo consequat.]])
command("hi MsgArea guisp=Yellow") command("hi MsgArea guisp=Yellow")
feed(':lua error(_G.x)<cr>') feed(':lua error(_G.x)<cr>')
screen:expect{grid=[[ screen:expect{grid=[[
{3:E5105: Error while calling lua chun}| {3:E5108: Error executing lua [string }|
{3:k: [string "<VimL compiled string>"}| {3:":lua"]:1: Lorem ipsum dolor sit am}|
{3:]:1: Lorem ipsum dolor sit amet, co}| {3:et, consectetur}{5: }|
{3:nsectetur}{5: }|
{3:adipisicing elit, sed do eiusmod te}| {3:adipisicing elit, sed do eiusmod te}|
{3:mpor}{5: }| {3:mpor}{5: }|
{3:incididunt ut labore et dolore magn}| {3:incididunt ut labore et dolore magn}|
{3:a aliqua.}{5: }|
{6:-- More --}{5:^ }| {6:-- More --}{5:^ }|
]]} ]]}
feed('d') feed('d')
screen:expect{grid=[[ screen:expect{grid=[[
{3:adipisicing elit, sed do eiusmod te}|
{3:mpor}{5: }|
{3:incididunt ut labore et dolore magn}| {3:incididunt ut labore et dolore magn}|
{3:a aliqua.}{5: }| {3:a aliqua.}{5: }|
{3:Ut enim ad minim veniam, quis nostr}| {3:Ut enim ad minim veniam, quis nostr}|
{3:ud xercitation}{5: }| {3:ud xercitation}{5: }|
{3:ullamco laboris nisi ut}{5: }| {3:ullamco laboris nisi ut}{5: }|
{6:-- More --}{5:^ }| {3:aliquip ex ea commodo consequat.}{5: }|
{6:Press ENTER or type command to cont}|
{6:inue}{5:^ }|
]]} ]]}
feed('u') feed('u')
screen:expect{grid=[[ screen:expect{grid=[[
{3:E5105: Error while calling lua chun}| {3:E5108: Error executing lua [string }|
{3:k: [string "<VimL compiled string>"}| {3:":lua"]:1: Lorem ipsum dolor sit am}|
{3:]:1: Lorem ipsum dolor sit amet, co}| {3:et, consectetur}{5: }|
{3:nsectetur}{5: }|
{3:adipisicing elit, sed do eiusmod te}| {3:adipisicing elit, sed do eiusmod te}|
{3:mpor}{5: }| {3:mpor}{5: }|
{3:incididunt ut labore et dolore magn}| {3:incididunt ut labore et dolore magn}|
{3:a aliqua.}{5: }|
{6:-- More --}{5:^ }| {6:-- More --}{5:^ }|
]]} ]]}
feed('d') feed('d')
screen:expect{grid=[[ screen:expect{grid=[[
{3:adipisicing elit, sed do eiusmod te}|
{3:mpor}{5: }| {3:mpor}{5: }|
{3:incididunt ut labore et dolore magn}| {3:incididunt ut labore et dolore magn}|
{3:a aliqua.}{5: }| {3:a aliqua.}{5: }|
{3:Ut enim ad minim veniam, quis nostr}| {3:Ut enim ad minim veniam, quis nostr}|
{3:ud xercitation}{5: }| {3:ud xercitation}{5: }|
{3:ullamco laboris nisi ut}{5: }| {3:ullamco laboris nisi ut}{5: }|
{3:aliquip ex ea commodo consequat.}{5: }|
{6:-- More --}{5:^ }| {6:-- More --}{5:^ }|
]]} ]]}
end) end)
@ -1473,23 +1472,23 @@ aliquip ex ea commodo consequat.]])
it('can be resized', function() it('can be resized', function()
feed(':lua error(_G.x)<cr>') feed(':lua error(_G.x)<cr>')
screen:expect{grid=[[ screen:expect{grid=[[
{2:E5105: Error while calling lua chun}| {2:E5108: Error executing lua [string }|
{2:k: [string "<VimL compiled string>"}| {2:":lua"]:1: Lorem ipsum dolor sit am}|
{2:]:1: Lorem ipsum dolor sit amet, co}| {2:et, consectetur} |
{2:nsectetur} |
{2:adipisicing elit, sed do eiusmod te}| {2:adipisicing elit, sed do eiusmod te}|
{2:mpor} | {2:mpor} |
{2:incididunt ut labore et dolore magn}| {2:incididunt ut labore et dolore magn}|
{2:a aliqua.} |
{4:-- More --}^ | {4:-- More --}^ |
]]} ]]}
-- responds to resize, but text is not reflown -- responds to resize, but text is not reflown
screen:try_resize(45, 5) screen:try_resize(45, 5)
screen:expect{grid=[[ screen:expect{grid=[[
{2:nsectetur} |
{2:adipisicing elit, sed do eiusmod te} | {2:adipisicing elit, sed do eiusmod te} |
{2:mpor} | {2:mpor} |
{2:incididunt ut labore et dolore magn} | {2:incididunt ut labore et dolore magn} |
{2:a aliqua.} |
{4:-- More --}^ | {4:-- More --}^ |
]]} ]]}
@ -1497,14 +1496,14 @@ aliquip ex ea commodo consequat.]])
-- text is not reflown; existing lines get cut -- text is not reflown; existing lines get cut
screen:try_resize(30, 12) screen:try_resize(30, 12)
screen:expect{grid=[[ screen:expect{grid=[[
{2:E5105: Error while calling lua}| {2:E5108: Error executing lua [st}|
{2:k: [string "<VimL compiled str}| {2:":lua"]:1: Lorem ipsum dolor s}|
{2:]:1: Lorem ipsum dolor sit ame}| {2:et, consectetur} |
{2:nsectetur} |
{2:adipisicing elit, sed do eiusm}| {2:adipisicing elit, sed do eiusm}|
{2:mpore} | {2:mpore} |
{2:incididunt ut labore et dolore}| {2:incididunt ut labore et dolore}|
{2: magn} | {2:a aliqua.} |
|
| |
| |
| |
@ -1515,18 +1514,18 @@ aliquip ex ea commodo consequat.]])
-- wrapped at the new screen size. -- wrapped at the new screen size.
feed('<cr>') feed('<cr>')
screen:expect{grid=[[ screen:expect{grid=[[
{2:k: [string "<VimL compiled str}| {2:et, consectetur} |
{2:]:1: Lorem ipsum dolor sit ame}|
{2:nsectetur} |
{2:adipisicing elit, sed do eiusm}| {2:adipisicing elit, sed do eiusm}|
{2:mpore} | {2:mpore} |
{2:incididunt ut labore et dolore}| {2:incididunt ut labore et dolore}|
{2: magna aliqua.} | {2:a aliqua.} |
{2:Ut enim ad minim veniam, quis }| {2:Ut enim ad minim veniam, quis }|
{2:nostrud xercitation} | {2:nostrud xercitation} |
{2:ullamco laboris nisi ut} | {2:ullamco laboris nisi ut} |
{2:aliquip ex ea commodo consequa}| {2:aliquip ex ea commodo consequa}|
{4:-- More --}^ | {2:t.} |
{4:Press ENTER or type command to}|
{4: continue}^ |
]]} ]]}
feed('q') feed('q')