Implement variable highlighting in Compose.vue

Added a variable highlighting feature to the editor using CodeMirror.
This commit is contained in:
cmcooper1980
2026-04-12 03:02:44 -05:00
committed by GitHub
parent b02f5e092e
commit ca9c8b4ba1

View File

@@ -252,7 +252,8 @@ import { python } from "@codemirror/lang-python";
import { dracula as editorTheme } from "thememirror"; import { dracula as editorTheme } from "thememirror";
import { lineNumbers, EditorView } from "@codemirror/view"; import { lineNumbers, EditorView } from "@codemirror/view";
import { parseDocument, Document } from "yaml"; import { parseDocument, Document } from "yaml";
import { Decoration, ViewPlugin } from "@codemirror/view";
import { RangeSetBuilder } from "@codemirror/state";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { import {
COMBINED_TERMINAL_COLS, 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 { export default {
components: { components: {
NetworkInput, NetworkInput,
@@ -312,6 +350,7 @@ export default {
const extensions = [ const extensions = [
editorTheme, editorTheme,
yaml(), yaml(),
variableHighlight,
lineNumbers(), lineNumbers(),
EditorView.focusChangeEffect.of(focusEffectHandler) EditorView.focusChangeEffect.of(focusEffectHandler)
]; ];
@@ -319,6 +358,7 @@ export default {
const extensionsEnv = [ const extensionsEnv = [
editorTheme, editorTheme,
python(), python(),
variableHighlight,
lineNumbers(), lineNumbers(),
EditorView.focusChangeEffect.of(focusEffectHandler) EditorView.focusChangeEffect.of(focusEffectHandler)
]; ];
@@ -858,6 +898,11 @@ export default {
height: 200px; height: 200px;
} }
:deep(.cm-variable-highlight) {
color: #fe6000;
font-weight: 600;
}
.editor-box { .editor-box {
font-family: 'JetBrains Mono', monospace; font-family: 'JetBrains Mono', monospace;
font-size: 14px; font-size: 14px;