add: 将loadTheme抽象到外部模块,使用DEFAULT_EDITOR_SETTINGS默认值,增加老的配置项迁移

This commit is contained in:
rarnu
2026-05-02 17:19:34 +08:00
parent e5f3f3bad8
commit 4d2c34ecb1
4 changed files with 110 additions and 122 deletions
+18 -72
View File
@@ -1,7 +1,6 @@
<script setup lang="ts">
import { ref, watch, shallowRef, computed } from "vue";
import type { EditorView as EditorViewType } from "@codemirror/view";
import type { Extension } from "@codemirror/state";
import { useI18n } from "vue-i18n";
import { Settings } from "lucide-vue-next";
import { Button } from "@/components/ui/button";
@@ -13,7 +12,10 @@ import {
Select, SelectContent, SelectItem, SelectTrigger, SelectValue,
} from "@/components/ui/select";
import { Separator } from "@/components/ui/separator";
import { useSettingsStore, EDITOR_THEMES, FONT_FAMILIES, type EditorTheme } from "@/stores/settingsStore";
import {
useSettingsStore, EDITOR_THEMES, FONT_FAMILIES, DEFAULT_EDITOR_SETTINGS,
} from "@/stores/settingsStore";
import { loadEditorTheme, editorFontTheme } from "@/lib/editorThemes";
const { t } = useI18n();
const settingsStore = useSettingsStore();
@@ -58,9 +60,9 @@ function applySettings() {
}
function resetDefaults() {
editFontFamily.value = "'JetBrains Mono', 'Fira Code', monospace";
editFontSize.value = 13;
editTheme.value = "one-dark";
editFontFamily.value = DEFAULT_EDITOR_SETTINGS.fontFamily;
editFontSize.value = DEFAULT_EDITOR_SETTINGS.fontSize;
editTheme.value = DEFAULT_EDITOR_SETTINGS.theme;
}
function onFontFamilyChange(v: any) {
@@ -68,78 +70,36 @@ function onFontFamilyChange(v: any) {
}
function onThemeChange(v: any) {
if (typeof v === 'string') editTheme.value = v as EditorTheme;
if (typeof v === 'string') editTheme.value = v as typeof DEFAULT_EDITOR_SETTINGS.theme;
}
// ---------- CodeMirror preview ----------
const previewRef = ref<HTMLDivElement>();
const previewView = shallowRef<EditorViewType | null>(null);
// Reactive settings computed for the preview
const previewSettings = computed(() => ({
fontFamily: editFontFamily.value,
fontSize: editFontSize.value,
theme: editTheme.value,
}));
async function loadTheme(theme: EditorTheme): Promise<Extension> {
switch (theme) {
case "one-dark":
return (await import("@codemirror/theme-one-dark")).oneDark;
case "vscode-dark":
return (await import("@uiw/codemirror-theme-vscode")).vscodeDark;
case "vscode-light":
return (await import("@uiw/codemirror-theme-vscode")).vscodeLight;
case "nord":
return (await import("@uiw/codemirror-theme-nord")).nord;
case "okaidia":
return (await import("@uiw/codemirror-theme-okaidia")).okaidia;
case "material":
return (await import("@uiw/codemirror-theme-material")).materialDark;
case "duotone-light":
return (await import("@uiw/codemirror-theme-duotone")).duotoneLight;
case "duotone-dark":
return (await import("@uiw/codemirror-theme-duotone")).duotoneDark;
case "xcode":
return (await import("@uiw/codemirror-theme-xcode")).xcodeLight;
default:
return (await import("@codemirror/theme-one-dark")).oneDark;
}
}
const previewSql = `SELECT u.id, u.name
FROM users u
ORDER BY u.id LIMIT 5;`;
let fontSizeComp: import("@codemirror/state").Compartment | null = null;
let fontFamilyComp: import("@codemirror/state").Compartment | null = null;
let fontThemeComp: import("@codemirror/state").Compartment | null = null;
let themeComp: import("@codemirror/state").Compartment | null = null;
let editorViewModule: typeof import("@codemirror/view") | null = null;
watch(previewSettings, async (ss) => {
if (
!previewView.value ||
!fontSizeComp ||
!fontFamilyComp ||
!themeComp ||
!editorViewModule
) return;
if (!previewView.value || !fontThemeComp || !themeComp || !editorViewModule) return;
const themeExt = await loadTheme(ss.theme);
const themeExt = await loadEditorTheme(ss.theme);
previewView.value.dispatch({
effects: [
themeComp.reconfigure(themeExt),
fontFamilyComp.reconfigure(
editorViewModule.EditorView.theme({
"&": { fontSize: `${ss.fontSize}px` },
".cm-content": { fontFamily: ss.fontFamily },
})
),
fontSizeComp.reconfigure(
editorViewModule.EditorView.theme({
"&": { fontSize: `${ss.fontSize}px` },
".cm-content": { fontFamily: ss.fontFamily },
})
fontThemeComp.reconfigure(
editorFontTheme(editorViewModule.EditorView, ss.fontSize, ss.fontFamily)
),
],
});
@@ -165,12 +125,11 @@ watch(previewRef, async (el) => {
]);
editorViewModule = { EditorView } as typeof import("@codemirror/view");
fontSizeComp = new Compartment();
fontFamilyComp = new Compartment();
fontThemeComp = new Compartment();
themeComp = new Compartment();
const ss = previewSettings.value;
const themeExt = await loadTheme(ss.theme);
const themeExt = await loadEditorTheme(ss.theme);
const state = EditorState.create({
doc: previewSql,
@@ -178,22 +137,10 @@ watch(previewRef, async (el) => {
basicSetup,
sql({ dialect: MySQL }),
themeComp.of(themeExt),
fontSizeComp.of(
EditorView.theme({
"&": { fontSize: `${ss.fontSize}px` },
".cm-scroller": { overflow: "auto" },
".cm-content": { fontFamily: ss.fontFamily },
})
),
fontFamilyComp.of(
EditorView.theme({
"&": { fontSize: `${ss.fontSize}px` },
".cm-scroller": { overflow: "auto" },
".cm-content": { fontFamily: ss.fontFamily },
})
fontThemeComp.of(
editorFontTheme(EditorView, ss.fontSize, ss.fontFamily)
),
],
// readOnly: true,
});
previewView.value = new EditorView({ state, parent: previewRef.value });
@@ -204,8 +151,7 @@ watch(() => props.open, (open) => {
previewView.value.destroy();
previewView.value = null;
previewInitialized = false;
fontSizeComp = null;
fontFamilyComp = null;
fontThemeComp = null;
themeComp = null;
editorViewModule = null;
}
+26 -49
View File
@@ -2,15 +2,15 @@
import { ref, onMounted, onBeforeUnmount, watch, shallowRef } from "vue";
import type { CompletionContext } from "@codemirror/autocomplete";
import type { EditorView as EditorViewType } from "@codemirror/view";
import type { Extension } from "@codemirror/state";
import { resolveExecutableSql } from "@/lib/sqlExecutionTarget";
import { formatSqlText, type SqlFormatDialect } from "@/lib/sqlFormatter";
import { useConnectionStore } from "@/stores/connectionStore";
import { useSettingsStore, type EditorTheme } from "@/stores/settingsStore";
import { useSettingsStore } from "@/stores/settingsStore";
import {
buildSqlCompletionItemsFromContext,
getSqlCompletionContext,
} from "@/lib/sqlCompletion";
import { loadEditorTheme, editorFontTheme } from "@/lib/editorThemes";
const props = defineProps<{
modelValue: string;
@@ -35,53 +35,23 @@ const settingsStore = useSettingsStore();
const MIN_FONT_SIZE = 10;
const MAX_FONT_SIZE = 24;
let editorViewModule: typeof import("@codemirror/view") | null = null;
let fontSizeTheme: import("@codemirror/state").Compartment | null = null;
let fontFamilyTheme: import("@codemirror/state").Compartment | null = null;
let fontThemeComp: import("@codemirror/state").Compartment | null = null;
let codeMirrorTheme: import("@codemirror/state").Compartment | null = null;
async function loadTheme(theme: EditorTheme): Promise<Extension> {
switch (theme) {
case "one-dark":
return (await import("@codemirror/theme-one-dark")).oneDark;
case "vscode-dark":
return (await import("@uiw/codemirror-theme-vscode")).vscodeDark;
case "vscode-light":
return (await import("@uiw/codemirror-theme-vscode")).vscodeLight;
case "nord":
return (await import("@uiw/codemirror-theme-nord")).nord;
case "okaidia":
return (await import("@uiw/codemirror-theme-okaidia")).okaidia;
case "material":
return (await import("@uiw/codemirror-theme-material")).materialDark;
case "duotone-light":
return (await import("@uiw/codemirror-theme-duotone")).duotoneLight;
case "duotone-dark":
return (await import("@uiw/codemirror-theme-duotone")).duotoneDark;
case "xcode":
return (await import("@uiw/codemirror-theme-xcode")).xcodeLight;
default:
return (await import("@codemirror/theme-one-dark")).oneDark;
}
}
function fontTheme(EditorView: typeof import("@codemirror/view").EditorView, size: number, family: string) {
return EditorView.theme({
"&": { height: "100%", fontSize: `${size}px` },
".cm-scroller": { overflow: "auto" },
".cm-content": { fontFamily: family },
});
}
function setFontSize(size: number) {
const next = Math.min(MAX_FONT_SIZE, Math.max(MIN_FONT_SIZE, size));
const ss = settingsStore.editorSettings;
ss.fontSize = next;
settingsStore.updateEditorSettings({ fontSize: next });
if (view.value && fontSizeTheme && fontFamilyTheme && editorViewModule) {
if (view.value && fontThemeComp && editorViewModule) {
view.value.dispatch({
effects: [
fontSizeTheme.reconfigure(fontTheme(editorViewModule.EditorView, next, ss.fontFamily)),
fontFamilyTheme.reconfigure(fontTheme(editorViewModule.EditorView, next, ss.fontFamily)),
fontThemeComp.reconfigure(
editorFontTheme(editorViewModule.EditorView, next, ss.fontFamily, {
fixedHeight: true,
scrollable: true,
})
),
],
});
}
@@ -197,8 +167,7 @@ onMounted(async () => {
import("@codemirror/autocomplete"),
]);
editorViewModule = { EditorView, keymap } as typeof import("@codemirror/view");
fontSizeTheme = new Compartment();
fontFamilyTheme = new Compartment();
fontThemeComp = new Compartment();
codeMirrorTheme = new Compartment();
const ss = settingsStore.editorSettings;
@@ -248,7 +217,7 @@ onMounted(async () => {
},
]);
const theme = await loadTheme(ss.theme);
const theme = await loadEditorTheme(ss.theme);
const state = EditorState.create({
doc: props.modelValue,
@@ -278,8 +247,12 @@ onMounted(async () => {
emit("selectionChange", selectedSqlFromView(update.view));
}
}),
fontSizeTheme.of(fontTheme(EditorView, ss.fontSize, ss.fontFamily)),
fontFamilyTheme.of(fontTheme(EditorView, ss.fontSize, ss.fontFamily)),
fontThemeComp.of(
editorFontTheme(EditorView, ss.fontSize, ss.fontFamily, {
fixedHeight: true,
scrollable: true,
})
),
EditorView.domEventHandlers({
wheel(event) {
if (!event.metaKey && !event.ctrlKey) return false;
@@ -317,13 +290,17 @@ watch(
watch(
() => settingsStore.editorSettings,
async (ss) => {
if (!view.value || !codeMirrorTheme || !fontFamilyTheme || !fontSizeTheme || !editorViewModule) return;
const themeExt = await loadTheme(ss.theme);
if (!view.value || !codeMirrorTheme || !fontThemeComp || !editorViewModule) return;
const themeExt = await loadEditorTheme(ss.theme);
view.value.dispatch({
effects: [
codeMirrorTheme.reconfigure(themeExt),
fontFamilyTheme.reconfigure(fontTheme(editorViewModule.EditorView, ss.fontSize, ss.fontFamily)),
fontSizeTheme.reconfigure(fontTheme(editorViewModule.EditorView, ss.fontSize, ss.fontFamily)),
fontThemeComp.reconfigure(
editorFontTheme(editorViewModule.EditorView, ss.fontSize, ss.fontFamily, {
fixedHeight: true,
scrollable: true,
})
),
],
});
},