@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user