From 6b4275da08c21f980a2dcdc3cbe6fad1cd8626fb Mon Sep 17 00:00:00 2001 From: Filip Noetzel Date: Tue, 10 Jun 2025 11:52:39 +0200 Subject: [PATCH] Extract buildDecorationsFromMatches function from ratingViewPlugin.ts --- .../buildDecorationsFromMatches.ts | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/editor-extension/ratingViewPlugin/buildDecorationsFromMatches.ts diff --git a/src/editor-extension/ratingViewPlugin/buildDecorationsFromMatches.ts b/src/editor-extension/ratingViewPlugin/buildDecorationsFromMatches.ts new file mode 100644 index 0000000..8bbc8e4 --- /dev/null +++ b/src/editor-extension/ratingViewPlugin/buildDecorationsFromMatches.ts @@ -0,0 +1,64 @@ +import { Decoration, RangeSetBuilder } from "@codemirror/view"; +import { getUnicodeCharLength } from '../../utils/getUnicodeCharLength'; +import { isFullOnlySymbol } from '../../utils/isFullOnlySymbol'; +import { LOGGING_ENABLED } from '../../constants'; +import { RatingMatch } from '../RatingMatch'; +import { RatingWidget } from '../RatingWidget/RatingWidget'; + +/** + * Build decorations from filtered matches, skipping those near the cursor + */ +export function buildDecorationsFromMatches( + matches: RatingMatch[], + cursorPos: number, + builder: RangeSetBuilder +): void { + // Add decorations in sorted order, but skip if cursor is nearby + for (const match of matches) { + // Skip creating widget if cursor is near this rating + if (cursorPos >= match.start - 1 && cursorPos <= match.end + 1) { + if (LOGGING_ENABLED) { + console.debug('[InteractiveRatings] Skipping widget creation due to nearby cursor', { + cursorPos, + ratingStart: match.start, + ratingEnd: match.end + }); + } + continue; + } + + const decoration = Decoration.replace({ + widget: new RatingWidget( + match.pattern, + match.rating, + match.symbolSet, + match.start, + match.end, + match.ratingText + ), + inclusive: false + }); + + builder.add(match.start, match.end, decoration); + } + + if (LOGGING_ENABLED && matches.length > 0) { + const skippedCount = matches.filter(m => + cursorPos >= m.start - 1 && cursorPos <= m.end + 1 + ).length; + const fullOnlyCount = matches.filter(m => isFullOnlySymbol(m.symbolSet)).length; + const commentCount = matches.filter(m => m.ratingText && m.ratingText.format === 'comment-fraction').length; + const autoAddCandidates = matches.filter(m => isFullOnlySymbol(m.symbolSet) && !m.ratingText).length; + const shortPatternCount = matches.filter(m => getUnicodeCharLength(m.pattern) < 3).length; + console.debug(`[InteractiveRatings] Built ${matches.length - skippedCount}/${matches.length} rating decorations (${skippedCount} skipped due to cursor proximity)`, { + cursorPos, + withRatingText: matches.filter(m => m.ratingText).length, + symbolsOnly: matches.filter(m => !m.ratingText).length, + withHalfSymbols: matches.filter(m => m.symbolSet.half).length, + fullOnlySymbols: fullOnlyCount, + commentFormatSymbols: commentCount, + autoAddCandidates, + shortPatterns: shortPatternCount + }); + } +} \ No newline at end of file