From 54cd0f6656d661309ceb51124f1be732d77ac9f7 Mon Sep 17 00:00:00 2001 From: Jared Miller Date: Mon, 9 Feb 2026 17:35:32 -0500 Subject: [PATCH] Strip dfrotz prompt even without preceding newline --- justfile | 2 +- src/mudlib/if_session.py | 20 +++++++++++++++++--- tests/test_if_session.py | 4 ++-- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/justfile b/justfile index a4bb791..17b3112 100644 --- a/justfile +++ b/justfile @@ -6,7 +6,7 @@ typecheck: uvx ty check test: - uv run pytest -n auto --testmon + uv run pytest -n auto --no-testmon check: lint typecheck test diff --git a/src/mudlib/if_session.py b/src/mudlib/if_session.py index 669eb6c..c50dce9 100644 --- a/src/mudlib/if_session.py +++ b/src/mudlib/if_session.py @@ -203,20 +203,34 @@ class IFSession: buf += chunk # Check for prompt at end of buffer - # dfrotz prompt is "\n> " (with trailing space) - text = buf.decode("latin-1").rstrip() + # dfrotz prompt is always "> " (with trailing space/newline) + raw = buf.decode("latin-1") + has_prompt = ( + raw.endswith("> ") or raw.endswith(">\n") or raw.endswith(">\r\n") + ) + text = raw.rstrip() + # \n> is always the dfrotz prompt — strip unconditionally if text.endswith("\n>"): return text[:-2].rstrip() if text == ">": return "" + # bare > (no preceding newline) — only strip when raw confirms prompt + if has_prompt and text.endswith(">"): + return text[:-1].rstrip() except TimeoutError: pass - text = buf.decode("latin-1").rstrip() + raw = buf.decode("latin-1") + has_prompt = raw.endswith("> ") or raw.endswith(">\n") or raw.endswith(">\r\n") + text = raw.rstrip() + # \n> is always the dfrotz prompt — strip unconditionally if text.endswith("\n>"): return text[:-2].rstrip() if text == ">": return "" + # bare > (no preceding newline) — only strip when raw confirms prompt + if has_prompt and text.endswith(">"): + return text[:-1].rstrip() return text diff --git a/tests/test_if_session.py b/tests/test_if_session.py index a105c65..f363246 100644 --- a/tests/test_if_session.py +++ b/tests/test_if_session.py @@ -52,7 +52,7 @@ async def test_start_spawns_subprocess_and_returns_intro(): mock_process.stdout = AsyncMock() mock_process.stdin = AsyncMock() - # Simulate dfrotz output: intro text followed by ">" prompt + # Simulate dfrotz output: intro text followed by "\n>" prompt intro_bytes = b"Welcome to the story!\nYou are in a room.\n>" async def read_side_effect(n): @@ -599,7 +599,7 @@ async def test_quit_then_stop_does_not_double_save(tmp_path): session.process = mock_process # Simulate dfrotz save responses (only expect one save) - responses = [b"Enter saved game: \n>", b"Ok.\n>"] + responses = [b"Enter saved game: \n> ", b"Ok.\n> "] response_data = b"".join(responses) async def read_side_effect(n):