fix(settings): sync live preview line numbers

This commit is contained in:
t8y2
2026-08-25 10:31:46 +08:00
parent 7686d7dc13
commit 418951c1e2
2 changed files with 32 additions and 3 deletions
@@ -108,6 +108,7 @@ import { formatShortcutDisplay } from "@/lib/editor/shortcutDisplay";
import { normalizeSidebarHiddenTablePrefixes } from "@/lib/sidebar/sidebarTableNameDisplay";
import { currentStatementFrameRangeTo } from "@/lib/sql/currentStatementFrame";
import { currentStatementFrameLayer } from "@/lib/editor/codemirrorCurrentStatementFrameLayer";
import { buildQueryEditorLineNumbersExtension } from "@/lib/editor/queryEditorLineNumbers";
import { normalizeSqlFormatterSettings, type SqlFormatterSettings } from "@/lib/sql/sqlFormatterConfig";
import { validateConfigName, generateId, type AiConfigItem, type ConfigNameValidationResult } from "@/lib/ai/aiConfigList";
import { currentExecutableStatementRange, type SqlTextRange } from "@/lib/sql/sqlStatementRanges";
@@ -3409,6 +3410,7 @@ const previewSettings = computed<{
appPalette: AppThemePalette;
customColors?: CustomThemeColors;
showStatementRunButtons: boolean;
showLineNumbers: boolean;
showCurrentStatementFrame: boolean;
}>(() => ({
fontFamily: editFontFamily.value,
@@ -3418,6 +3420,7 @@ const previewSettings = computed<{
appPalette: themePalette.value,
customColors: getPreviewCustomThemeColors(),
showStatementRunButtons: editShowStatementRunButtons.value,
showLineNumbers: editShowLineNumbers.value,
showCurrentStatementFrame: editShowCurrentStatementFrame.value,
}));
@@ -3440,7 +3443,9 @@ let fontThemeComp: import("@codemirror/state").Compartment | null = null;
let themeComp: import("@codemirror/state").Compartment | null = null;
let diagnosticComp: import("@codemirror/state").Compartment | null = null;
let previewRunGutterComp: import("@codemirror/state").Compartment | null = null;
let previewLineNumbersComp: import("@codemirror/state").Compartment | null = null;
let currentStatementFrameComp: import("@codemirror/state").Compartment | null = null;
let previewLineNumbersFactory: typeof import("@codemirror/view").lineNumbers | null = null;
let setPreviewDiagnosticsEffect: import("@codemirror/state").StateEffectType<PreviewSqlDiagnostic[]> | null = null;
let setPreviewRunHighlightEffect:
| import("@codemirror/state").StateEffectType<{
@@ -3555,16 +3560,23 @@ function previewCurrentStatementFrameTo(view: import("@codemirror/view").EditorV
return currentStatementFrameRangeTo(view.state.doc, range);
}
function buildPreviewLineNumbersExtension(enabled: boolean) {
return buildQueryEditorLineNumbersExtension(previewLineNumbersFactory, enabled, {
domEventHandlers: {},
});
}
watch(
[previewSettings, editCustomThemes, editActiveCustomThemeId],
async ([ss]) => {
if (!previewView.value || !fontThemeComp || !themeComp || !editorViewModule) return;
if (!previewView.value || !fontThemeComp || !themeComp || !previewLineNumbersComp || !editorViewModule) return;
const themeExt = await loadEditorTheme(ss.theme, ss.appAppearance, ss.customColors, ss.appPalette);
previewView.value.dispatch({
effects: [
themeComp.reconfigure(themeExt),
fontThemeComp.reconfigure(editorFontTheme(editorViewModule.EditorView, ss.fontSize, ss.fontFamily)),
previewLineNumbersComp.reconfigure(buildPreviewLineNumbersExtension(ss.showLineNumbers)),
...(previewRunGutterComp ? [previewRunGutterComp.reconfigure(buildPreviewRunGutterExtension())] : []),
...(currentStatementFrameComp ? [currentStatementFrameComp.reconfigure(buildPreviewCurrentStatementFrameExtension(editorViewModule, ss.showCurrentStatementFrame))] : []),
],
@@ -3588,7 +3600,9 @@ function cleanupPreviewEditor() {
themeComp = null;
diagnosticComp = null;
previewRunGutterComp = null;
previewLineNumbersComp = null;
currentStatementFrameComp = null;
previewLineNumbersFactory = null;
setPreviewDiagnosticsEffect = null;
setPreviewRunHighlightEffect = null;
editorViewModule = null;
@@ -3613,7 +3627,7 @@ watch(previewRef, async (el) => {
previewInitialized = true;
if (previewView.value) return;
const [{ EditorView, Decoration, ViewPlugin, gutter, GutterMarker, layer, RectangleMarker }, { EditorState, Compartment, StateEffect, StateField }, { sql, MySQL }, { basicSetup }] = await Promise.all([
const [{ EditorView, Decoration, ViewPlugin, gutter, GutterMarker, layer, RectangleMarker, lineNumbers, highlightActiveLineGutter }, { EditorState, Compartment, StateEffect, StateField }, { sql, MySQL }, { basicSetup }] = await Promise.all([
import("@codemirror/view"),
import("@codemirror/state"),
import("@codemirror/lang-sql"),
@@ -3627,10 +3641,12 @@ watch(previewRef, async (el) => {
layer,
RectangleMarker,
} as typeof import("@codemirror/view");
previewLineNumbersFactory = lineNumbers;
fontThemeComp = new Compartment();
themeComp = new Compartment();
diagnosticComp = new Compartment();
previewRunGutterComp = new Compartment();
previewLineNumbersComp = new Compartment();
currentStatementFrameComp = new Compartment();
setPreviewDiagnosticsEffect = StateEffect.define<PreviewSqlDiagnostic[]>();
setPreviewRunHighlightEffect = StateEffect.define<{
@@ -3641,6 +3657,7 @@ watch(previewRef, async (el) => {
const ss = previewSettings.value;
const themeExt = await loadEditorTheme(ss.theme, ss.appAppearance, ss.customColors, ss.appPalette);
const previewBasicSetup = (basicSetup as readonly import("@codemirror/state").Extension[]).slice(2);
const diagnosticTheme = EditorView.baseTheme({
".cm-settings-preview-sql-error": {
textDecoration: "underline wavy var(--destructive)",
@@ -3719,7 +3736,9 @@ watch(previewRef, async (el) => {
const state = EditorState.create({
doc: currentPreviewSql(),
extensions: [
basicSetup,
previewLineNumbersComp.of(buildPreviewLineNumbersExtension(ss.showLineNumbers)),
highlightActiveLineGutter(),
previewBasicSetup,
sql({ dialect: MySQL }),
themeComp.of(themeExt),
fontThemeComp.of(editorFontTheme(EditorView, ss.fontSize, ss.fontFamily)),
@@ -28,4 +28,14 @@ describe("EditorSettingsDialog live preview placement", () => {
expect(dialogSource).toContain("watch(previewRef, async (el) => {");
expect(dialogSource).toContain("cleanupPreviewEditor();");
});
it("updates preview line-number visibility from the unsaved editor draft", () => {
expect(dialogSource).toContain("showLineNumbers: editShowLineNumbers.value");
expect(dialogSource).toContain('import { buildQueryEditorLineNumbersExtension } from "@/lib/editor/queryEditorLineNumbers";');
expect(dialogSource).toContain('let previewLineNumbersComp: import("@codemirror/state").Compartment | null = null;');
expect(dialogSource).toContain('const previewBasicSetup = (basicSetup as readonly import("@codemirror/state").Extension[]).slice(2);');
expect(dialogSource).toContain("previewLineNumbersComp.of(buildPreviewLineNumbersExtension(ss.showLineNumbers))");
expect(dialogSource).toContain("previewLineNumbersComp.reconfigure(buildPreviewLineNumbersExtension(ss.showLineNumbers))");
expect(dialogSource).toContain("return buildQueryEditorLineNumbersExtension(previewLineNumbersFactory, enabled");
});
});