Fix nested commands in interactive mode triggering prompt2 (issue #19)

Save and restore cmd_mode across interpolation parsing so that
luaX_readcommandcont resumes in the correct mode after a nested
backtick command inside ${...}.
This commit is contained in:
Cormac Shannon
2026-03-05 00:13:34 +00:00
parent b3aa1d9c63
commit c96fae90c0
4 changed files with 12 additions and 1 deletions

View File

@@ -1,6 +1,6 @@
# 19 — Nested commands in interactive mode trigger prompt2
**Status:** open
**Status:** done
Running nested commands in an interactive command drops into prompt2 when it shouldn't:

2
llex.c
View File

@@ -512,6 +512,7 @@ static int read_command_body (LexState *ls, SemInfo *seminfo) {
/* store fragment so far */
seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
luaZ_bufflen(ls->buff));
ls->saved_cmd_mode = ls->cmd_mode; /* save for readcommandcont */
return interactive ? TK_INTERACTIVE_INTERP : TK_COMMAND_INTERP;
}
else {
@@ -571,6 +572,7 @@ static int read_command (LexState *ls, SemInfo *seminfo) {
** consumed the '}' that closes an interpolated ${expr}.
*/
int luaX_readcommandcont (LexState *ls) {
ls->cmd_mode = ls->saved_cmd_mode; /* restore mode from before interpolation */
int tk = read_command_body(ls, &ls->t.seminfo);
ls->t.token = tk;
return tk;

1
llex.h
View File

@@ -83,6 +83,7 @@ typedef struct LexState {
TString *brkn; /* "break" name (used as a label) */
TString *glbn; /* "global" name (when not a reserved word) */
lu_byte cmd_mode; /* 0=normal, 1=backtick command, 2=interactive command */
lu_byte saved_cmd_mode; /* cmd_mode to restore after interpolation */
} LexState;

View File

@@ -86,6 +86,14 @@ do
assert(run_cmd() == 0)
end
-- ===== NESTED BACKTICK IN INTERPOLATION (issue #19) =====
do
local result = `echo hello`
!echo ${result.stdout}
assert(_.code == 0)
end
-- ===== EMPTY COMMAND (just whitespace after !) =====
do