fix(explore): accurately resolve query file paths and find camelCase symbols
Previously, `codegraph_explore` queries explicitly naming files by path (e.g., `src/routes/m/projects/[id]/runs/[runId]/+page.svelte`) were shredded. Bracketed path segments exploded into "named symbol" seeds, and FTS on fragments like `page` or `runs` admitted every sibling file, starving the user's intended target. This change introduces: - **Query path pinning:** File paths named in a query are now resolved against the index, "pinned," and stripped from the query. Pinned files are guaranteed inclusion, top ranking, and fair allocation. Unresolvable path-like spans are reported. - **Segment vocabulary supplement:** Natural language query terms (e.g., "auto-scroll to bottom") can now reach camelCase identifiers (e.g., `pinFeedIfNearBottom`, `feedAtBottom`) by matching against their constituent segments. - **Variable seeding:** `variable` and `constant` node kinds are now included in identifier seeding, improving recall for `$state`-style variables common in frameworks like Svelte.
This commit is contained in:
@@ -2,6 +2,7 @@ import { describe, it, expect } from 'vitest';
|
||||
import {
|
||||
splitIdentifierSegments,
|
||||
extractProseCandidates,
|
||||
extractSegmentSearchWords,
|
||||
normalizeProseWord,
|
||||
segmentLookupVariants,
|
||||
} from '../src/search/identifier-segments';
|
||||
@@ -101,3 +102,32 @@ describe('segmentLookupVariants — light plural folding', () => {
|
||||
expect(segmentLookupVariants('boxes')).toEqual(['boxes']); // -es strip would go sub-minimum
|
||||
});
|
||||
});
|
||||
|
||||
describe('extractSegmentSearchWords — query words for the search-side vocab supplement', () => {
|
||||
it('keeps prose words and adds camel-token segments', () => {
|
||||
const words = extractSegmentSearchWords('auto-scroll to bottom — atBottom tracking');
|
||||
// Prose candidates survive as before…
|
||||
expect(words).toContain('scroll');
|
||||
expect(words).toContain('bottom');
|
||||
expect(words).toContain('tracking');
|
||||
// …and the camel token contributed its ≥4-char segments ("at" is under
|
||||
// the prose minimum; "bottom" arrives from the split even when the prose
|
||||
// pass missed it).
|
||||
expect(extractSegmentSearchWords('where is atBottom set')).toContain('bottom');
|
||||
});
|
||||
|
||||
it('splits multi-hump tokens into every usable segment', () => {
|
||||
const words = extractSegmentSearchWords('trace pinFeedIfNearBottom please');
|
||||
expect(words).toEqual(expect.arrayContaining(['feed', 'near', 'bottom']));
|
||||
});
|
||||
|
||||
it('does not invent segments for plain prose', () => {
|
||||
const words = extractSegmentSearchWords('how does checkout work');
|
||||
expect(words).toContain('checkout');
|
||||
expect(words).not.toContain('check');
|
||||
});
|
||||
|
||||
it('returns nothing for an empty query', () => {
|
||||
expect(extractSegmentSearchWords('')).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user