diff --git a/tests/test_tui_gateway_server.py b/tests/test_tui_gateway_server.py index 7d70214a74..0fd5cb7db2 100644 --- a/tests/test_tui_gateway_server.py +++ b/tests/test_tui_gateway_server.py @@ -371,6 +371,7 @@ def test_complete_slash_details_args(): ) assert resp_root["result"]["replace_from"] == len("/details") + assert any(item["text"] == " thinking" for item in resp_root["result"]["items"]) assert any(item["text"] == "thinking" for item in resp_section["result"]["items"]) assert any(item["text"] == "expanded" for item in resp_mode["result"]["items"]) diff --git a/tui_gateway/server.py b/tui_gateway/server.py index 5cfc38fab2..397f4f17d1 100644 --- a/tui_gateway/server.py +++ b/tui_gateway/server.py @@ -3692,6 +3692,13 @@ def _details_completion_item(value: str, meta: str = "") -> dict: return {"text": value, "display": value, "meta": meta} +def _details_root_completion_item(value: str, meta: str, needs_leading_space: bool) -> dict: + return _details_completion_item( + f" {value}" if needs_leading_space else value, + meta, + ) + + def _details_completions(text: str) -> list[dict] | None: if not text.lower().startswith("/details"): return None @@ -3710,9 +3717,15 @@ def _details_completions(text: str) -> list[dict] | None: if not body or (len(parts) == 0 and has_trailing_space): return [ - *[_details_completion_item(mode, "global mode") for mode in modes], - _details_completion_item("cycle", "cycle global mode"), - *[_details_completion_item(section, "section override") for section in sections], + *[ + _details_root_completion_item(mode, "global mode", not has_trailing_space) + for mode in modes + ], + _details_root_completion_item("cycle", "cycle global mode", not has_trailing_space), + *[ + _details_root_completion_item(section, "section override", not has_trailing_space) + for section in sections + ], ] if len(parts) == 1 and not has_trailing_space: diff --git a/ui-tui/src/components/textInput.tsx b/ui-tui/src/components/textInput.tsx index 9f8b299424..b31f86e73e 100644 --- a/ui-tui/src/components/textInput.tsx +++ b/ui-tui/src/components/textInput.tsx @@ -472,7 +472,14 @@ export function TextInput({ return stringWidth(current.slice(prevPos(current, cursor), cursor)) === 1 } - const commit = (next: string, nextCur: number, track = true, syncParent = true, syncLocal = true) => { + const commit = ( + next: string, + nextCur: number, + track = true, + syncParent = true, + syncLocal = true, + nextLineWidth?: number + ) => { const prev = vRef.current const c = snapPos(next, nextCur) editVersionRef.current += 1 @@ -501,7 +508,7 @@ export function TextInput({ curRef.current = c vRef.current = next - lineWidthRef.current = stringWidth(next.includes('\n') ? next.slice(next.lastIndexOf('\n') + 1) : next) + lineWidthRef.current = nextLineWidth ?? stringWidth(next.includes('\n') ? next.slice(next.lastIndexOf('\n') + 1) : next) if (next !== prev) { if (syncParent) { @@ -509,6 +516,7 @@ export function TextInput({ self.current = true cbChange.current(next) } else { + self.current = true scheduleParentChange(next) } } @@ -768,7 +776,7 @@ export function TextInput({ v = v.slice(0, t) + v.slice(c) c = t stdout!.write('\b \b') - commit(v, c, true, false, false) + commit(v, c, true, false, false, Math.max(0, lineWidthRef.current - 1)) return } else { @@ -855,7 +863,7 @@ export function TextInput({ if (simpleAppend) { stdout!.write(text) - commit(v, c, true, false, false) + commit(v, c, true, false, false, lineWidthRef.current + stringWidth(text)) return }