From ca9c8b4ba1692ca468612335d73c0549a6f72d1d Mon Sep 17 00:00:00 2001 From: cmcooper1980 <31871143+cmcooper1980@users.noreply.github.com> Date: Sun, 12 Apr 2026 03:02:44 -0500 Subject: [PATCH] Implement variable highlighting in Compose.vue Added a variable highlighting feature to the editor using CodeMirror. --- frontend/src/pages/Compose.vue | 47 +++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/frontend/src/pages/Compose.vue b/frontend/src/pages/Compose.vue index 41834bf..92f782c 100644 --- a/frontend/src/pages/Compose.vue +++ b/frontend/src/pages/Compose.vue @@ -252,7 +252,8 @@ import { python } from "@codemirror/lang-python"; import { dracula as editorTheme } from "thememirror"; import { lineNumbers, EditorView } from "@codemirror/view"; import { parseDocument, Document } from "yaml"; - +import { Decoration, ViewPlugin } from "@codemirror/view"; +import { RangeSetBuilder } from "@codemirror/state"; import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; import { COMBINED_TERMINAL_COLS, @@ -288,6 +289,43 @@ let prismjsSymbolDefinition = { } }; +// Highlight $VAR and ${VAR} +const variableHighlight = ViewPlugin.fromClass(class { + constructor(view) { + this.decorations = this.buildDecorations(view); + } + + update(update) { + if (update.docChanged || update.viewportChanged) { + this.decorations = this.buildDecorations(update.view); + } + } + + buildDecorations(view) { + const builder = new RangeSetBuilder(); + + for (const { from, to } of view.visibleRanges) { + const text = view.state.doc.sliceString(from, to); + const variableRegex = /\$\{?[A-Za-z0-9_]+\}?/g; + let match; + while ((match = variableRegex.exec(text)) !== null) { + const start = from + match.index; + const end = start + match[0].length; + + builder.add( + start, + end, + Decoration.mark({ class: "cm-variable-highlight" }) + ); + } + } + + return builder.finish(); + } +}, { + decorations: v => v.decorations +}); + export default { components: { NetworkInput, @@ -312,6 +350,7 @@ export default { const extensions = [ editorTheme, yaml(), + variableHighlight, lineNumbers(), EditorView.focusChangeEffect.of(focusEffectHandler) ]; @@ -319,6 +358,7 @@ export default { const extensionsEnv = [ editorTheme, python(), + variableHighlight, lineNumbers(), EditorView.focusChangeEffect.of(focusEffectHandler) ]; @@ -858,6 +898,11 @@ export default { height: 200px; } +:deep(.cm-variable-highlight) { + color: #fe6000; + font-weight: 600; +} + .editor-box { font-family: 'JetBrains Mono', monospace; font-size: 14px;