The Lua interpreter can save typed lines. But when a partial line is written the saved history is not exactly what was typed. This is most apparent when the line is an expression that has to be rewritten as a valid statement.
This patch will save the original line as typed in the history. It is written agains Lua 5.3.0. It is not needed in Lua 5.3.1.
A full-featured interactive Lua frontend can be had with luaprompt. No patching necessary.
diff --git a/src/lua.c b/src/lua.c index 34a3900..d007d34 100644 --- a/src/lua.c +++ b/src/lua.c @@ -327,19 +327,23 @@ static int pushline (lua_State *L, int firstline) { /* ** Try to compile line on the stack as 'return <line>'; on return, stack -** has either compiled chunk or original line (if compilation failed). +** has either compiled chunk or error message (if compilation failed). +** The original line remains on the stack. */ -static int addreturn (lua_State *L) { +static int addreturn (lua_State *L, int idx) { int status; size_t len; const char *line; lua_pushliteral(L, "return "); - lua_pushvalue(L, -2); /* duplicate line */ + lua_pushvalue(L, idx); /* duplicate line */ lua_concat(L, 2); /* new line is "return ..." */ line = lua_tolstring(L, -1, &len); - if ((status = luaL_loadbuffer(L, line, len, "=stdin")) == LUA_OK) - lua_remove(L, -3); /* remove original line */ - else + if ((status = luaL_loadbuffer(L, line, len, "=stdin")) == LUA_OK) + lua_remove(L, -2); /* remove new line */ + else { lua_pop(L, 2); /* remove result from 'luaL_loadbuffer' and new line */ + line = lua_tolstring(L, idx, &len); /* get what it has */ + status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */ + } return status; } @@ -349,9 +353,7 @@ static int addreturn (lua_State *L) { */ static int multiline (lua_State *L) { for (;;) { /* repeat until gets a complete statement */ - size_t len; - const char *line = lua_tolstring(L, 1, &len); /* get what it has */ - int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */ + int status = addreturn(L, 1); if (!incomplete(L, status) || !pushline(L, 0)) return status; /* cannot or should not try to add continuation line */ lua_pushliteral(L, "\n"); /* add newline... */ @@ -372,8 +374,7 @@ static int loadline (lua_State *L) { lua_settop(L, 0); if (!pushline(L, 1)) return -1; /* no input */ - if ((status = addreturn(L)) != LUA_OK) /* 'return ...' did not work? */ - status = multiline(L); /* try as command, maybe with continuation lines */ + status = multiline(L); /* try as command, maybe with continuation lines */ lua_saveline(L, 1); /* keep history */ lua_remove(L, 1); /* remove line from the stack */ lua_assert(lua_gettop(L) == 1);