fix(app): incremental scrollback search

Search only ran on Enter; typing merely reset the counter to 0/0, so a
visible term showed no matches until the user pressed Enter. run() now takes
an optional query override and onChange fires it on every keystroke for
search-as-you-type, while Enter/Shift+Enter still navigate matches.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-14 08:00:45 +07:00
parent 21180ae9e0
commit 89373676e8
+13 -7
View File
@@ -45,16 +45,17 @@ export function SearchBar({
}; };
}, [surfaceId]); }, [surfaceId]);
function run(forward: boolean) { function run(forward: boolean, override?: string) {
if (!surfaceId) return; if (!surfaceId) return;
const addon = getSearch(surfaceId); const addon = getSearch(surfaceId);
if (!addon || !term) { const query = override ?? term;
if (!addon || !query) {
addon?.clearDecorations(); addon?.clearDecorations();
setCount({ index: -1, total: 0 }); setCount({ index: -1, total: 0 });
return; return;
} }
if (forward) addon.findNext(term, SEARCH_OPTS); if (forward) addon.findNext(query, SEARCH_OPTS);
else addon.findPrevious(term, SEARCH_OPTS); else addon.findPrevious(query, SEARCH_OPTS);
} }
return ( return (
@@ -79,9 +80,14 @@ export function SearchBar({
ref={inputRef} ref={inputRef}
value={term} value={term}
onChange={(e) => { onChange={(e) => {
setTerm(e.target.value); const value = e.target.value;
setCount({ index: -1, total: 0 }); setTerm(value);
if (surfaceId) getSearch(surfaceId)?.clearDecorations(); if (!value) {
setCount({ index: -1, total: 0 });
if (surfaceId) getSearch(surfaceId)?.clearDecorations();
} else {
run(true, value); // search-as-you-type
}
}} }}
onKeyDown={(e) => { onKeyDown={(e) => {
if (e.key === "Enter") { if (e.key === "Enter") {