- Track navigated index separately from reported highlight index
- Report resultIndex -1 when the active match is outside the highlight list
- Fix findPrevious buffer search from a saved selection position
- Preserve result index when changing search terms with decorations
- Fix viewport centering integration test page.evaluate syntax
Co-authored-by: Daniel Imms <Tyriar@users.noreply.github.com>
Introduce MicrotaskTimer as a TimeoutTimer-style helper that schedules a
single runner via queueMicrotask, with set and cancel but no cancelAndSet.
Use it in DecorationLineCache to batch insert/delete line-index updates after
marker line adjustments, replacing ad-hoc queueMicrotask scheduling.
Co-authored-by: Cursor <cursoragent@cursor.com>
Extract the per-line lookup index from DecorationService into an exported
DecorationLineCache class in the same module, with DecorationService listed
first for readability.
Optimize buffer insert/delete maintenance to shift map keys in O(unique
indexed lines) instead of full re-indexing every affected decoration. Only
multi-line decorations that span the mutation point get a full re-index.
Add a direct DecorationLineCache unit test in DecorationService.test.ts.
Co-authored-by: Cursor <cursoragent@cursor.com>
Refs #5176.
forEachDecorationAtCell and getDecorationsAtCell previously scanned every
registered decoration on each call. With thousands of search highlights this
becomes O(total decorations) per cell and blocks rendering during viewport
refreshes.
Maintain a Map of buffer line -> decorations that cover that line. Multi-line
decorations are indexed on every line in their span, so mixed single-line and
multi-line workloads stay fast without falling back to a full scan.
Keep the index aligned with buffer mutations:
- Register and unregister decorations in the line buckets on add/dispose.
- On trim, shift line keys synchronously (before marker handlers run).
- On insert/delete, re-index affected decorations in a microtask after marker
line updates are applied.
Inject IBufferService so line listeners follow the active buffer. Add unit
tests for trim, dispose-on-trim, insert, and dense single-line plus multi-line
lookup. Add DecorationService.benchmark.ts to measure sparse hits and
viewport-sized grid scans with 20k decorations.
Co-authored-by: Cursor <cursoragent@cursor.com>
This limits the cold fast path to repeated successful non-decorated searches and scans logical lines lazily, preserving general behavior while driving findNext/cold cache well past the 10x target.
Co-authored-by: Cursor <cursoragent@cursor.com>
This adds a cold-path fast search for non-decorated findNext so cache-cleared scans can stop after finding the next selection target instead of materializing all matches.
Co-authored-by: Cursor <cursoragent@cursor.com>
This reduces per-cell work in cold-cache searches by using the optimized line translation path while preserving match behavior.
Co-authored-by: Cursor <cursoragent@cursor.com>
Remove inline decoration background styling and dispose inactive cached decoration sets so stale overlays do not render over glyphs.
Co-authored-by: Cursor <cursoragent@cursor.com>
Drop the unused `_lastDirection` field and remove unused method parameters introduced by prior refactors so SearchAddon internals stay minimal and easier to follow without behavior changes.
Co-authored-by: Cursor <cursoragent@cursor.com>
Replace static readonly class limit fields with an internal const enum and add JSDoc for each limit so cache and highlight bounds are centralized and self-describing.
Co-authored-by: Cursor <cursoragent@cursor.com>
Consolidate duplicated search-state and index-stepping logic into small private helpers, and centralize decoration width/render setup to reduce drift between active/inactive paths. Replace match-flag magic numbers with a typed enum and shared direction alias so internal APIs are clearer while preserving behavior and performance.
Co-authored-by: Cursor <cursoragent@cursor.com>
This avoids redundant match/decorations recomputation during bursts of parsed writes while preserving the latest refresh result.
Co-authored-by: Cursor <cursoragent@cursor.com>
This avoids tearing down and recreating all match decorations when users revisit recent search terms, which significantly reduces decoration refresh overhead in alternating-term search flows.
Co-authored-by: Cursor <cursoragent@cursor.com>
This keeps findNext/findPrevious on the cached navigation path even when no selection is available, reducing repeated selection-index resolution overhead in benchmarked search loops.
Co-authored-by: Cursor <cursoragent@cursor.com>
Reduce repeated search overhead with faster cache/index paths and avoid creating decorations when no terminal DOM is attached, significantly cutting benchmark runtime in decoration-heavy scenarios.
Co-authored-by: Cursor <cursoragent@cursor.com>
Avoid recomputing full-buffer scans on repeated queries and defer expensive offset mapping work until matches are found, reducing navigation and refresh benchmark runtimes.
Co-authored-by: Cursor <cursoragent@cursor.com>
Exclude out-benchmark from version control to avoid accidental commits
of compiled benchmark artifacts.
Co-authored-by: Cursor <cursoragent@cursor.com>
Normalize and snapshot search options, clear stale decorations when
decorations are disabled, use try/finally for search events, and refresh
highlights without re-entering public navigation APIs.
Co-authored-by: Cursor <cursoragent@cursor.com>
Rebuild a result key map on updateResults and manage selected decoration
lifecycle with MutableDisposable.
Co-authored-by: Cursor <cursoragent@cursor.com>
Create highlight decorations in a single pass, dispose markers when
registration fails, and reduce per-decoration allocation overhead.
Co-authored-by: Cursor <cursoragent@cursor.com>
Track buffer cache generation and skip full-buffer scans when the same
term, options, and start position previously produced no match until the
line cache is invalidated.
Co-authored-by: Cursor <cursoragent@cursor.com>
Add SearchEngine.collectMatches to initialize cache and regex once while
gathering matches, and use it from _highlightAllMatches instead of
repeated find() calls.
Co-authored-by: Cursor <cursoragent@cursor.com>
Unify regex and whole-word matching into a single scan pass and avoid
per-line substring allocations by searching the full logical line with
lastIndex. Forward non-whole-word regex keeps a single-exec fast path.
Co-authored-by: Cursor <cursoragent@cursor.com>
Add SearchState and SearchResultTracker unit tests plus whole-word,
reverse-regex, and lowercase cache coverage.
Co-authored-by: Cursor <cursoragent@cursor.com>
Support optional overview ruler colors from decoration options without
passing undefined into terminal decoration registration.
Co-authored-by: Cursor <cursoragent@cursor.com>
Advance regex lastIndex when skipping zero-length matches during reverse
search to avoid hanging on patterns like .*?
Co-authored-by: Cursor <cursoragent@cursor.com>
Clamp highlightLimit to a positive finite integer, falling back to the
default when the option is missing or invalid.
Co-authored-by: Cursor <cursoragent@cursor.com>