MCPcopy Create free account
hub / github.com/claude-code-best/claude-code / handleQueryChange

Function handleQueryChange

src/components/GlobalSearchDialog.tsx:97–188  ·  view source on GitHub ↗
(q: string)

Source from the content-addressed store, hash-verified

95 }, [focused]);
96
97 const handleQueryChange = (q: string) => {
98 setQuery(q);
99 if (timeoutRef.current) clearTimeout(timeoutRef.current);
100 abortRef.current?.abort();
101
102 if (!q.trim()) {
103 setMatches(m => (m.length ? [] : m));
104 setIsSearching(false);
105 setTruncated(false);
106 return;
107 }
108 const controller = new AbortController();
109 abortRef.current = controller;
110 setIsSearching(true);
111 setTruncated(false);
112 // Client-filter existing results while rg walks — keeps something on
113 // screen instead of flashing blank. rg results are merged in (deduped by
114 // file:line) rather than replaced, so the count is monotonic within a
115 // query: it only grows as rg streams, never dips to the first chunk's
116 // size. Narrowing (new query extends old): filter is exact — any line
117 // that matched the old -F -i literal contains the new one iff its text
118 // includes the new query lowered. Non-narrowing (broadening/different):
119 // filter is best-effort — may briefly show a subset until rg fills in
120 // the rest.
121 const queryLower = q.toLowerCase();
122 setMatches(m => {
123 const filtered = m.filter(match => match.text.toLowerCase().includes(queryLower));
124 return filtered.length === m.length ? m : filtered;
125 });
126
127 timeoutRef.current = setTimeout(
128 (query, controller, setMatches, setTruncated, setIsSearching) => {
129 // ripgrep outputs absolute paths when given an absolute target, so
130 // relativize against cwd to preserve directory context in the truncated
131 // display (otherwise the cwd prefix eats the width budget).
132 // relativePath() returns POSIX-normalized output so truncatePathMiddle
133 // (which uses lastIndexOf('/')) works on Windows too.
134 const cwd = getCwd();
135 let collected = 0;
136 void ripGrepStream(
137 // -e disambiguates pattern from options when the query starts with '-'
138 // (e.g. searching for "--verbose" or "-rf"). See GrepTool.ts for the
139 // same precaution.
140 ['-n', '--no-heading', '-i', '-m', String(MAX_MATCHES_PER_FILE), '-F', '-e', query],
141 cwd,
142 controller.signal,
143 lines => {
144 if (controller.signal.aborted) return;
145 const parsed: Match[] = [];
146 for (const line of lines) {
147 const m = parseRipgrepLine(line);
148 if (!m) continue;
149 const rel = relativePath(cwd, m.file);
150 parsed.push({ ...m, file: rel.startsWith('..') ? m.file : rel });
151 }
152 if (!parsed.length) return;
153 collected += parsed.length;
154 setMatches(prev => {

Callers

nothing calls this directly

Calls 8

getCwdFunction · 0.85
ripGrepStreamFunction · 0.85
parseRipgrepLineFunction · 0.85
relativePathFunction · 0.85
matchKeyFunction · 0.85
abortMethod · 0.65
pushMethod · 0.45
hasMethod · 0.45

Tested by

no test coverage detected