fix(tui): clear reference token on escape

ISSUES CLOSED: #6450
This commit is contained in:
2026-04-10 19:39:16 +00:00
committed by Forgejo
parent ed973575b1
commit 1809df9609
3 changed files with 58 additions and 0 deletions
+17
View File
@@ -143,3 +143,20 @@ def step_run_fallback_tui_app(context: Context) -> None:
def step_fallback_tui_fails(context: Context, message: str) -> None:
assert context.tui_fallback_error is not None
assert message in str(context.tui_fallback_error)
@given('a TUI prompt value "{value}"')
def step_set_tui_prompt_value(context: Context, value: str) -> None:
context.tui_prompt_value = value
@when("I clear pending TUI reference token via escape")
def step_clear_pending_reference(context: Context) -> None:
cleanup = getattr(tui_app_module, "_strip_pending_reference_token")
assert callable(cleanup)
context.tui_prompt_value = cleanup(context.tui_prompt_value)
@then('the TUI prompt value should be "{expected}"')
def step_assert_tui_prompt_value(context: Context, expected: str) -> None:
assert context.tui_prompt_value == expected
+5
View File
@@ -37,3 +37,8 @@ Feature: TUI input modes
Then TUI textual availability should be boolean
When I run fallback TUI app
Then fallback TUI app should fail with "Textual dependency missing."
Scenario: Escape removes pending reference trigger from prompt
Given a TUI prompt value "inspect @reso"
When I clear pending TUI reference token via escape
Then the TUI prompt value should be "inspect"
+36
View File
@@ -189,6 +189,35 @@ class SessionView:
transcript: list[str] = field(default_factory=list)
def _strip_pending_reference_token(value: str) -> str:
"""Remove the trailing @ reference trigger (if any).
This trims whitespace and drops the last token that begins with ``@`` when the
token does not contain any embedded whitespace. Escaped triggers (``\\@``)
remain untouched.
"""
if not isinstance(value, str):
return ""
candidate = value.rstrip()
if "@" not in candidate:
return candidate
last_at = candidate.rfind("@")
if last_at == -1:
return candidate
if last_at > 0 and candidate[last_at - 1] == "\\":
return candidate
suffix = candidate[last_at:]
if any(ch.isspace() for ch in suffix):
return candidate
return candidate[:last_at].rstrip()
class _CommandRouter(Protocol):
"""Router protocol used by the TUI input-mode command handler."""
@@ -331,6 +360,13 @@ if _TEXTUAL_AVAILABLE:
if getattr(ref_picker, "visible", False):
self._remove_reference_trigger(prompt)
ref_picker.hide()
prompt = self.query_one("#prompt", PromptInput)
prompt_value = getattr(prompt, "value", "")
if isinstance(prompt_value, str):
prompt.value = _strip_pending_reference_token(prompt_value)
focus_method = getattr(prompt, "focus", None)
if callable(focus_method):
focus_method()
return
focus_method = getattr(prompt, "focus", None)