feat(editor): allow hiding query line numbers
This commit is contained in:
1 parent
eaad88cc80
commit
4a478acf07
18 files changed
+205
-7
No files matched your search
@@ -0,0 +1,74 @@
|
||||
// @vitest-environment happy-dom
|
||||
import { Compartment, EditorState } from "@codemirror/state";
|
||||
import { EditorView, GutterMarker, gutter, lineNumbers } from "@codemirror/view";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { buildQueryEditorLineNumbersExtension } from "@/lib/editor/queryEditorLineNumbers";
|
||||
|
||||
class StatementRunMarker extends GutterMarker {}
|
||||
|
||||
const activeViews: EditorView[] = [];
|
||||
|
||||
function createEditor(showLineNumbers: boolean) {
|
||||
const lineNumbersCompartment = new Compartment();
|
||||
const runGutterCompartment = new Compartment();
|
||||
const runMarker = new StatementRunMarker();
|
||||
const selectLine = vi.fn((_view: EditorView, _line: { from: number; to: number }, _event: Event) => true);
|
||||
const view = new EditorView({
|
||||
state: EditorState.create({
|
||||
doc: "SELECT 1;\nSELECT 2;",
|
||||
extensions: [
|
||||
lineNumbersCompartment.of(
|
||||
buildQueryEditorLineNumbersExtension(lineNumbers, showLineNumbers, {
|
||||
domEventHandlers: { mousedown: selectLine },
|
||||
}),
|
||||
),
|
||||
runGutterCompartment.of(
|
||||
gutter({
|
||||
class: "cm-run-statement-gutter",
|
||||
lineMarker: () => runMarker,
|
||||
}),
|
||||
),
|
||||
],
|
||||
}),
|
||||
parent: document.createElement("div"),
|
||||
});
|
||||
activeViews.push(view);
|
||||
return { lineNumbersCompartment, selectLine, view };
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
for (const view of activeViews.splice(0)) view.destroy();
|
||||
});
|
||||
|
||||
describe("query editor line numbers", () => {
|
||||
it("keeps line selection behavior when enabled", () => {
|
||||
const { selectLine, view } = createEditor(true);
|
||||
const lineNumber = view.dom.querySelector<HTMLElement>(".cm-lineNumbers .cm-gutterElement");
|
||||
|
||||
lineNumber?.dispatchEvent(new MouseEvent("mousedown", { bubbles: true, button: 0 }));
|
||||
|
||||
expect(view.dom.querySelector(".cm-lineNumbers")).not.toBeNull();
|
||||
expect(selectLine).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("reconfigures line numbers without removing the statement run gutter", () => {
|
||||
const { lineNumbersCompartment, view } = createEditor(true);
|
||||
|
||||
expect(view.dom.querySelector(".cm-lineNumbers")).not.toBeNull();
|
||||
expect(view.dom.querySelector(".cm-run-statement-gutter")).not.toBeNull();
|
||||
|
||||
view.dispatch({
|
||||
effects: lineNumbersCompartment.reconfigure(buildQueryEditorLineNumbersExtension(lineNumbers, false, { domEventHandlers: {} })),
|
||||
});
|
||||
|
||||
expect(view.dom.querySelector(".cm-lineNumbers")).toBeNull();
|
||||
expect(view.dom.querySelector(".cm-run-statement-gutter")).not.toBeNull();
|
||||
|
||||
view.dispatch({
|
||||
effects: lineNumbersCompartment.reconfigure(buildQueryEditorLineNumbersExtension(lineNumbers, true, { domEventHandlers: {} })),
|
||||
});
|
||||
|
||||
expect(view.dom.querySelector(".cm-lineNumbers")).not.toBeNull();
|
||||
expect(view.dom.querySelector(".cm-run-statement-gutter")).not.toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
import type { Extension } from "@codemirror/state";
|
||||
import type { lineNumbers } from "@codemirror/view";
|
||||
|
||||
type LineNumbersFactory = typeof lineNumbers;
|
||||
type LineNumbersConfig = NonNullable<Parameters<LineNumbersFactory>[0]>;
|
||||
|
||||
export function buildQueryEditorLineNumbersExtension(factory: LineNumbersFactory | null, enabled: boolean, config: LineNumbersConfig): Extension {
|
||||
return enabled && factory ? factory(config) : [];
|
||||
}
|
||||
@@ -38,6 +38,10 @@ describe("EDITOR_SETTINGS_DRAFT_KEYS", () => {
|
||||
expect(EDITOR_SETTINGS_DRAFT_KEYS).not.toContain("globalQueryTimeoutSecs");
|
||||
});
|
||||
|
||||
it("includes showLineNumbers", () => {
|
||||
expect(EDITOR_SETTINGS_DRAFT_KEYS).toContain("showLineNumbers");
|
||||
});
|
||||
|
||||
it("includes continueOnErrorOnBatch", () => {
|
||||
expect(EDITOR_SETTINGS_DRAFT_KEYS).toContain("continueOnErrorOnBatch");
|
||||
});
|
||||
@@ -103,6 +107,16 @@ describe("EDITOR_SETTINGS_DRAFT_KEYS", () => {
|
||||
});
|
||||
|
||||
describe("editorSettingsDraftFromSettings", () => {
|
||||
it("round-trips a hidden line-number preference through the draft patch", () => {
|
||||
const settings = makeSettings({ showLineNumbers: true });
|
||||
const draft = editorSettingsDraftFromSettings(settings);
|
||||
const base = editorSettingsDraftFromSettings(settings);
|
||||
|
||||
draft.showLineNumbers = false;
|
||||
|
||||
expect(editorSettingsPatchFromDraft(draft, base)).toEqual({ showLineNumbers: false });
|
||||
});
|
||||
|
||||
it("toggles substitution without discarding per-database overrides", () => {
|
||||
const base = editorSettingsDraftFromSettings(
|
||||
makeSettings({
|
||||
|
||||
@@ -37,6 +37,30 @@ describe("settings search", () => {
|
||||
{ id: "desktop", category: "about", titleKey: "hidden", visible: ({ isWeb }) => !isWeb },
|
||||
];
|
||||
|
||||
it("indexes the query editor line-number preference", () => {
|
||||
const definition = SETTINGS_SEARCH_DEFINITIONS.find((entry) => entry.id === "editor-line-numbers");
|
||||
expect(definition).toEqual({
|
||||
id: "editor-line-numbers",
|
||||
category: "editor",
|
||||
titleKey: "settings.showLineNumbers",
|
||||
descriptionKey: "settings.showLineNumbersDescription",
|
||||
targetId: "editor",
|
||||
});
|
||||
|
||||
const entries = resolveSettingsSearchEntries(
|
||||
[definition!],
|
||||
{ isWeb: false, visibleCategories: new Set<SettingsCategory>(["editor"]) },
|
||||
(key) =>
|
||||
({
|
||||
"settings.showLineNumbers": "Show line numbers",
|
||||
"settings.showLineNumbersDescription": "Show line numbers in the SQL editor gutter",
|
||||
})[key] ?? key,
|
||||
categoryLabels,
|
||||
);
|
||||
|
||||
expect(searchSettings(entries, "line number", "en").map((entry) => entry.id)).toEqual(["editor-line-numbers"]);
|
||||
});
|
||||
|
||||
it("does not index connection or query timeout under editor settings", () => {
|
||||
expect(SETTINGS_SEARCH_DEFINITIONS.map((definition) => definition.id)).not.toContain("editor-global-connect-timeout");
|
||||
expect(SETTINGS_SEARCH_DEFINITIONS.map((definition) => definition.id)).not.toContain("editor-global-query-timeout");
|
||||
|
||||
@@ -16,6 +16,7 @@ export const EDITOR_SETTINGS_DRAFT_KEYS = [
|
||||
"executeAllOnBlankLine",
|
||||
"showExecutionTargetPicker",
|
||||
"showStatementRunButtons",
|
||||
"showLineNumbers",
|
||||
"showCurrentStatementFrame",
|
||||
"showInsertValueHints",
|
||||
"autoAliasTables",
|
||||
|
||||
@@ -109,6 +109,7 @@ export const SETTINGS_SEARCH_DEFINITIONS: readonly SettingsSearchDefinition[] =
|
||||
{ id: "editor-execute-all-on-blank-line", category: "editor", titleKey: "settings.executeAllOnBlankLine", descriptionKey: "settings.executeAllOnBlankLineDescription", targetId: "editor" },
|
||||
{ id: "editor-execution-target", category: "editor", titleKey: "settings.showExecutionTargetPicker", descriptionKey: "settings.showExecutionTargetPickerDescription", targetId: "editor" },
|
||||
{ id: "editor-run-buttons", category: "editor", titleKey: "settings.showStatementRunButtons", descriptionKey: "settings.showStatementRunButtonsDescription", targetId: "editor" },
|
||||
{ id: "editor-line-numbers", category: "editor", titleKey: "settings.showLineNumbers", descriptionKey: "settings.showLineNumbersDescription", targetId: "editor" },
|
||||
{ id: "editor-statement-frame", category: "editor", titleKey: "settings.showCurrentStatementFrame", descriptionKey: "settings.showCurrentStatementFrameDescription", targetId: "editor" },
|
||||
{ id: "editor-value-hints", category: "editor", titleKey: "settings.showInsertValueHints", descriptionKey: "settings.showInsertValueHintsDescription", targetId: "editor" },
|
||||
{ id: "editor-word-wrap", category: "editor", titleKey: "settings.wordWrap", descriptionKey: "settings.wordWrapDescription", targetId: "editor" },
|
||||
|
||||
Reference in new issue
Block a user