From c96fae90c08cd2c7c6efc933770a6345696c0bdd Mon Sep 17 00:00:00 2001 From: Cormac Shannon <> Date: Thu, 5 Mar 2026 00:13:34 +0000 Subject: [PATCH] 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 ${...}. --- issues/19-nested-commands-prompt2.md | 2 +- llex.c | 2 ++ llex.h | 1 + testes/lush/interactive.lua | 8 ++++++++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/issues/19-nested-commands-prompt2.md b/issues/19-nested-commands-prompt2.md index 056f9061..d67d0765 100644 --- a/issues/19-nested-commands-prompt2.md +++ b/issues/19-nested-commands-prompt2.md @@ -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: diff --git a/llex.c b/llex.c index 77e70f1e..b6dc50b2 100644 --- a/llex.c +++ b/llex.c @@ -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; diff --git a/llex.h b/llex.h index 33fb09d0..566032b1 100644 --- a/llex.h +++ b/llex.h @@ -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; diff --git a/testes/lush/interactive.lua b/testes/lush/interactive.lua index 04f680ee..30ee964f 100644 --- a/testes/lush/interactive.lua +++ b/testes/lush/interactive.lua @@ -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