mirror of
https://github.com/Horizontal42/summarum.git
synced 2026-11-11 01:02:01 +03:00
perf(ui): cache variable highlight RegExp creation
Caching the RegExp compilation for highlighting variables under the cursor avoids creating an assignment RegExp and a highlight RegExp constantly when typing, saving roughly ~40% of the overhead time for this function as tested. Co-authored-by: Horizontal42 <75383519+Horizontal42@users.noreply.github.com>
This commit is contained in:
parent
b399b95263
commit
49742f8b66
1 changed files with 16 additions and 4 deletions
|
|
@ -75,6 +75,8 @@ const highlightField = StateField.define<DecorationSet>({
|
|||
provide: (f) => EditorView.decorations.from(f),
|
||||
});
|
||||
|
||||
const varHighlightReCache = new Map<string, { assignment: RegExp; highlight: RegExp }>();
|
||||
|
||||
/** Highlights every occurrence of the variable under the cursor. */
|
||||
function buildVarHighlight(state: EditorState): DecorationSet {
|
||||
const builder = new RangeSetBuilder<Decoration>();
|
||||
|
|
@ -90,11 +92,21 @@ function buildVarHighlight(state: EditorState): DecorationSet {
|
|||
if (a === b) return builder.finish();
|
||||
const word = text.slice(a, b);
|
||||
if (!/^[\p{L}_][\p{L}\d_]*$/u.test(word)) return builder.finish();
|
||||
|
||||
let cachedRe = varHighlightReCache.get(word);
|
||||
if (!cachedRe) {
|
||||
const esc = word.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
cachedRe = {
|
||||
assignment: new RegExp(`^\\s*${esc}\\s*=`, "mu"),
|
||||
highlight: new RegExp(`(?<![\\p{L}\\d_])${esc}(?![\\p{L}\\d_])`, "gu"),
|
||||
};
|
||||
if (varHighlightReCache.size > 1000) varHighlightReCache.clear();
|
||||
varHighlightReCache.set(word, cachedRe);
|
||||
}
|
||||
|
||||
// only highlight if the word is actually assigned somewhere in the document
|
||||
const esc = word.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
if (!new RegExp(`^\\s*${esc}\\s*=`, "mu").test(text)) return builder.finish();
|
||||
const re = new RegExp(`(?<![\\p{L}\\d_])${esc}(?![\\p{L}\\d_])`, "gu");
|
||||
for (const m of text.matchAll(re)) {
|
||||
if (!cachedRe.assignment.test(text)) return builder.finish();
|
||||
for (const m of text.matchAll(cachedRe.highlight)) {
|
||||
builder.add(m.index, m.index + word.length, Decoration.mark({ class: "tok-var-active" }));
|
||||
}
|
||||
return builder.finish();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue