fix(nacos): build syntax tree before config editor paint

This commit is contained in:
Melody Ruch authored and GitHub committed 2026-08-15 18:40:24 +08:00
1 parent 405bdb295c
commit d782667b22
1 file changed
+62 -63
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, nextTick, onBeforeUnmount, onMounted, ref, shallowRef, useId, watch } from "vue";
import { Compartment, type Extension } from "@codemirror/state";
import { StreamLanguage } from "@codemirror/language";
import { StreamLanguage, ensureSyntaxTree } from "@codemirror/language";
import type { EditorView } from "@codemirror/view";
import { Archive, ArrowLeftRight, CheckCircle2, ChevronDown, ChevronLeft, ChevronRight, Clipboard, Columns3, Download, FileClock, FileInput, FileText, Loader2, Network, Plus, RefreshCw, Save, Search, Send, Server, Trash2, X } from "@lucide/vue";
import { Button } from "@/components/ui/button";
@@ -518,69 +518,68 @@ async function mountConfigEditor() {
configEditorFontSize.value = clampEditorFontSize(editorSettings.fontSize);
const theme = await loadEditorTheme(editorSettings.theme, editorThemeAppearance(), currentCustomThemeColors(), themePalette.value);
if (generation !== configEditorGeneration || editorSessionId !== configEditorSessionId || host !== configEditorHost.value || configEditorView.value || !selectedConfig.value) return;
const view = new EditorView({
parent: host,
state: EditorState.create({
doc: content,
extensions: [
cmSearch({
top: true,
createPanel: () => {
const dom = document.createElement("span");
dom.style.display = "none";
return { dom };
},
}),
basicSetup,
EditorState.allowMultipleSelections.of(true),
trimmedSelectionLayer(),
Prec.highest(keymap.of([{ key: "Mod-f", run: () => configSearchPanelRef.value?.openSearch() ?? false, preventDefault: true }, { key: "Mod-h", run: () => configSearchPanelRef.value?.openReplace() ?? false, preventDefault: true }, indentWithTab])),
keymap.of([...defaultKeymap, ...historyKeymap]),
EditorView.domEventHandlers({
wheel(event, eventView) {
if (!event.metaKey && !event.ctrlKey) return false;
event.preventDefault();
const next = fontSizeFromWheelDelta(configEditorFontSize.value, event.deltaY);
if (next !== configEditorFontSize.value) {
configEditorFontSize.value = next;
eventView.dispatch({
effects: configEditorFontTheme.reconfigure(editorFontTheme(EditorView, next, settingsStore.editorSettings.fontFamily, { fixedHeight: true, scrollable: true })),
});
}
configEditorZoomCommitScheduler.schedule(next);
return true;
},
}),
configEditorLanguage.of(language),
configEditorTheme.of(theme),
configEditorFontTheme.of(editorFontTheme(EditorView, editorSettings.fontSize, editorSettings.fontFamily, { fixedHeight: true, scrollable: true })),
configEditorWordWrap.of(editorSettings.wordWrap ? EditorView.lineWrapping : []),
EditorState.readOnly.of(!!props.readOnly),
EditorView.editable.of(!props.readOnly),
EditorView.updateListener.of((update) => {
if (!update.docChanged || generation !== configEditorGeneration || editorSessionId !== configEditorSessionId) return;
configContent.value = update.state.doc.toString();
configSaveNotice.value = "";
}),
EditorView.theme({
"&": {
height: "100%",
},
".cm-scroller": {
overflow: "auto",
},
".cm-content": {
minHeight: "100%",
userSelect: "text",
WebkitUserSelect: "text",
},
".cm-lineNumbers .cm-gutterElement": {
padding: "0 10px 0 8px",
},
}),
],
}),
const state = EditorState.create({
doc: content,
extensions: [
cmSearch({
top: true,
createPanel: () => {
const dom = document.createElement("span");
dom.style.display = "none";
return { dom };
},
}),
basicSetup,
EditorState.allowMultipleSelections.of(true),
trimmedSelectionLayer(),
Prec.highest(keymap.of([{ key: "Mod-f", run: () => configSearchPanelRef.value?.openSearch() ?? false, preventDefault: true }, { key: "Mod-h", run: () => configSearchPanelRef.value?.openReplace() ?? false, preventDefault: true }, indentWithTab])),
keymap.of([...defaultKeymap, ...historyKeymap]),
EditorView.domEventHandlers({
wheel(event, eventView) {
if (!event.metaKey && !event.ctrlKey) return false;
event.preventDefault();
const next = fontSizeFromWheelDelta(configEditorFontSize.value, event.deltaY);
if (next !== configEditorFontSize.value) {
configEditorFontSize.value = next;
eventView.dispatch({
effects: configEditorFontTheme.reconfigure(editorFontTheme(EditorView, next, settingsStore.editorSettings.fontFamily, { fixedHeight: true, scrollable: true })),
});
}
configEditorZoomCommitScheduler.schedule(next);
return true;
},
}),
configEditorLanguage.of(language),
configEditorTheme.of(theme),
configEditorFontTheme.of(editorFontTheme(EditorView, editorSettings.fontSize, editorSettings.fontFamily, { fixedHeight: true, scrollable: true })),
configEditorWordWrap.of(editorSettings.wordWrap ? EditorView.lineWrapping : []),
EditorState.readOnly.of(!!props.readOnly),
EditorView.editable.of(!props.readOnly),
EditorView.updateListener.of((update) => {
if (!update.docChanged || generation !== configEditorGeneration || editorSessionId !== configEditorSessionId) return;
configContent.value = update.state.doc.toString();
configSaveNotice.value = "";
}),
EditorView.theme({
"&": {
height: "100%",
},
".cm-scroller": {
overflow: "auto",
},
".cm-content": {
minHeight: "100%",
userSelect: "text",
WebkitUserSelect: "text",
},
".cm-lineNumbers .cm-gutterElement": {
padding: "0 10px 0 8px",
},
}),
],
});
ensureSyntaxTree(state, content.length, 500);
const view = new EditorView({ parent: host, state });
if (generation !== configEditorGeneration || editorSessionId !== configEditorSessionId || host !== configEditorHost.value) {
view.destroy();
return;