From 289ae8aa3f07567e92d535bed41a3c60e4ecda6c Mon Sep 17 00:00:00 2001 From: Horizontal42 <75383519+Horizontal42@users.noreply.github.com> Date: Wed, 19 Aug 2026 16:35:21 +0300 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20[perf:=20avoid=20expensive=20doc=20?= =?UTF-8?q?stringification=20for=20autocomplete]=20(#102)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf: avoid expensive doc stringification for autocomplete Refactored the autocomplete variable matching logic in `src/ui/editor.ts` to iterate through document lines using CodeMirror's `iterLines()` instead of allocating the entire document string in memory with `toString()`. Also pulled the regex up and introduced a quick `.includes("=")` bailout to skip the regex engine completely for most lines. Co-authored-by: Horizontal42 <75383519+Horizontal42@users.noreply.github.com> * drop stray benchmark script --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- src/ui/editor.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/ui/editor.ts b/src/ui/editor.ts index 8d5ca57..dea37c8 100644 --- a/src/ui/editor.ts +++ b/src/ui/editor.ts @@ -170,6 +170,7 @@ export class SumEditor { this.resultsEl = resultsEl; let engineOptions: { label: string; type: string; detail?: string }[] | null = null; + const varPattern = /^\s*([\p{L}_][\p{L}\d_]*)\s*=/u; const completionSource = (ctx: CompletionContext): CompletionResult | null => { const word = ctx.matchBefore(/[\p{L}_]+$/u); if (!word || (word.from === word.to && !ctx.explicit)) return null; @@ -182,9 +183,15 @@ export class SumEditor { })); const options = [...engineOptions]; // document variables - const text = ctx.state.doc.toString(); - for (const m of text.matchAll(/^\s*([\p{L}_][\p{L}\d_]*)\s*=/gmu)) { - options.push({ label: m[1], type: "variable" }); + const iter = ctx.state.doc.iterLines(); + for (let next = iter.next(); !next.done; next = iter.next()) { + const line = next.value; + if (line.includes("=")) { + const m = varPattern.exec(line); + if (m) { + options.push({ label: m[1], type: "variable" }); + } + } } return { from: word.from, options, validFor: /^[\p{L}_]*$/u }; };