MCPcopy Create free account
hub / github.com/codeaashu/claude-code / extractCompletionToken

Function extractCompletionToken

src/hooks/useTypeahead.tsx:261–325  ·  view source on GitHub ↗
(text: string, cursorPos: number, includeAtSymbol = false)

Source from the content-addressed store, hash-verified

259 * @returns The completable token and its start position, or null if not found
260 */
261export function extractCompletionToken(text: string, cursorPos: number, includeAtSymbol = false): {
262 token: string;
263 startPos: number;
264 isQuoted?: boolean;
265} | null {
266 // Empty input check
267 if (!text) return null;
268
269 // Get text up to cursor
270 const textBeforeCursor = text.substring(0, cursorPos);
271
272 // Check for quoted @ mention first (e.g., @"my file with spaces")
273 if (includeAtSymbol) {
274 const quotedAtRegex = /@"([^"]*)"?$/;
275 const quotedMatch = textBeforeCursor.match(quotedAtRegex);
276 if (quotedMatch && quotedMatch.index !== undefined) {
277 // Include any remaining quoted content after cursor until closing quote or end
278 const textAfterCursor = text.substring(cursorPos);
279 const afterQuotedMatch = textAfterCursor.match(/^[^"]*"?/);
280 const quotedSuffix = afterQuotedMatch ? afterQuotedMatch[0] : '';
281 return {
282 token: quotedMatch[0] + quotedSuffix,
283 startPos: quotedMatch.index,
284 isQuoted: true
285 };
286 }
287 }
288
289 // Fast path for @ tokens: use lastIndexOf to avoid expensive $ anchor scan
290 if (includeAtSymbol) {
291 const atIdx = textBeforeCursor.lastIndexOf('@');
292 if (atIdx >= 0 && (atIdx === 0 || /\s/.test(textBeforeCursor[atIdx - 1]!))) {
293 const fromAt = textBeforeCursor.substring(atIdx);
294 const atHeadMatch = fromAt.match(AT_TOKEN_HEAD_RE);
295 if (atHeadMatch && atHeadMatch[0].length === fromAt.length) {
296 const textAfterCursor = text.substring(cursorPos);
297 const afterMatch = textAfterCursor.match(PATH_CHAR_HEAD_RE);
298 const tokenSuffix = afterMatch ? afterMatch[0] : '';
299 return {
300 token: atHeadMatch[0] + tokenSuffix,
301 startPos: atIdx,
302 isQuoted: false
303 };
304 }
305 }
306 }
307
308 // Non-@ token or cursor outside @ token — use $ anchor on (short) tail
309 const tokenRegex = includeAtSymbol ? TOKEN_WITH_AT_RE : TOKEN_WITHOUT_AT_RE;
310 const match = textBeforeCursor.match(tokenRegex);
311 if (!match || match.index === undefined) {
312 return null;
313 }
314
315 // Check if cursor is in the MIDDLE of a token (more word characters after cursor)
316 // If so, extend the token to include all characters until whitespace or end of string
317 const textAfterCursor = text.substring(cursorPos);
318 const afterMatch = textAfterCursor.match(PATH_CHAR_HEAD_RE);

Callers 1

useTypeaheadFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected