fix(editor): respect custom Ctrl+D shortcuts
This commit is contained in:
1 parent
c63c517b4f
commit
edb136d960
4 files changed
+69
-2
No files matched your search
@@ -103,6 +103,7 @@ import type { SqlHighlighter } from "@/lib/sql/sqlHighlighter";
|
||||
import { EDITOR_FONT_FAMILY_CSS_VAR, EDITOR_FONT_SIZE_CSS_VAR, loadEditorTheme, editorFontTheme, sqlCompletionTheme, sqlSemanticHighlightTheme } from "@/lib/editor/editorThemes";
|
||||
import { createStatementGutterMarkerDom, shouldShowStatementGutter } from "@/lib/editor/codemirrorStatementGutter";
|
||||
import { createQueryEditorSearchKeymap } from "@/lib/editor/queryEditorSearchKeymap";
|
||||
import { searchKeymapWithoutModD } from "@/lib/editor/codemirrorSearchKeymap";
|
||||
import { appendSqlCompletionSpace } from "@/lib/editor/sqlCompletionInsertion";
|
||||
import { compareSqlCompletions, completionLabelPresentation } from "@/lib/editor/sqlCompletionPresentation";
|
||||
import { clampEditorFontSize, createEditorZoomCommitScheduler, fontSizeFromGestureScale, fontSizeFromWheelDelta } from "@/lib/editor/editorZoom";
|
||||
@@ -4855,7 +4856,7 @@ onMounted(async () => {
|
||||
activeLineHighlighter,
|
||||
// Vim must be mounted before DBX/default keymaps so normal-mode keys are handled first.
|
||||
vimModeComp.of(vimModeExtension(initialSettings.vimModeEnabled)),
|
||||
keymap.of([...defaultKeymap, ...searchKeymap, ...historyKeymap, ...foldKeymap, ...completionKeymap]),
|
||||
keymap.of([...defaultKeymap, ...searchKeymapWithoutModD(searchKeymap), ...historyKeymap, ...foldKeymap, ...completionKeymap]),
|
||||
sqlLanguageComp.of(buildSqlLanguageExtension()),
|
||||
sqlSemanticHighlightComp.of(buildSqlSemanticHighlightExtension()),
|
||||
tooltips({ parent: tooltipParent }),
|
||||
|
||||
@@ -10,6 +10,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { useToast } from "@/composables/useToast";
|
||||
import { copyToClipboard } from "@/lib/common/clipboard";
|
||||
import { saveTextFile } from "@/lib/export/saveTextFile";
|
||||
import { searchKeymapWithoutModD } from "@/lib/editor/codemirrorSearchKeymap";
|
||||
import {
|
||||
DEFAULT_SQL_FORMATTER_SETTINGS,
|
||||
SQL_FORMATTER_CONFIG_FORMATTER,
|
||||
@@ -361,7 +362,7 @@ function jsonEditorKeymapExtension(modules: CodeMirrorModules) {
|
||||
const { keymap } = modules.view;
|
||||
const commands = modules.commands;
|
||||
const search = modules.search;
|
||||
return keymap.of([...search.searchKeymap, ...commands.historyKeymap, ...commands.defaultKeymap]);
|
||||
return keymap.of([...searchKeymapWithoutModD(search.searchKeymap), ...commands.historyKeymap, ...commands.defaultKeymap]);
|
||||
}
|
||||
|
||||
async function initJsonEditor() {
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
// @vitest-environment happy-dom
|
||||
|
||||
import { EditorState } from "@codemirror/state";
|
||||
import { EditorView, keymap, runScopeHandlers } from "@codemirror/view";
|
||||
import { searchKeymap } from "@codemirror/search";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { searchKeymapWithoutModD } from "@/lib/editor/codemirrorSearchKeymap";
|
||||
|
||||
describe("searchKeymapWithoutModD", () => {
|
||||
it("drops the built-in Mod-d binding from the search keymap", () => {
|
||||
const filtered = searchKeymapWithoutModD(searchKeymap);
|
||||
expect(filtered.find((binding) => binding.key === "Mod-d")).toBeUndefined();
|
||||
});
|
||||
|
||||
it("keeps the other search bindings intact", () => {
|
||||
const filtered = searchKeymapWithoutModD(searchKeymap);
|
||||
const keys = filtered.map((binding) => binding.key);
|
||||
expect(keys).toContain("Mod-f");
|
||||
expect(keys).toContain("Mod-g");
|
||||
expect(keys).toContain("Mod-Alt-g");
|
||||
expect(keys).toContain("Mod-Shift-l");
|
||||
expect(keys).toContain("F3");
|
||||
});
|
||||
|
||||
it("baseline: the stock searchKeymap consumes Ctrl+D (the bug being fixed)", () => {
|
||||
const view = new EditorView({
|
||||
parent: document.createElement("div"),
|
||||
state: EditorState.create({
|
||||
extensions: [keymap.of([...searchKeymap])],
|
||||
}),
|
||||
});
|
||||
|
||||
expect(runScopeHandlers(view, new KeyboardEvent("keydown", { key: "d", ctrlKey: true }), "editor")).toBe(true);
|
||||
view.destroy();
|
||||
});
|
||||
|
||||
it("no longer consumes Ctrl+D, letting the event bubble to the global shortcut handler", () => {
|
||||
const view = new EditorView({
|
||||
parent: document.createElement("div"),
|
||||
state: EditorState.create({
|
||||
extensions: [keymap.of([...searchKeymapWithoutModD(searchKeymap)])],
|
||||
}),
|
||||
});
|
||||
|
||||
expect(runScopeHandlers(view, new KeyboardEvent("keydown", { key: "d", ctrlKey: true }), "editor")).toBe(false);
|
||||
view.destroy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
import type { KeyBinding } from "@codemirror/view";
|
||||
|
||||
/**
|
||||
* `@codemirror/search` 的 `searchKeymap` 内置硬编码了 `Mod-d` = `selectNextOccurrence`
|
||||
* (多光标选择下一个匹配词),与 DBX 的可配置快捷键体系冲突:
|
||||
*
|
||||
* - DBX 中 `Mod+D` 默认绑定「复制行 / 复制当前行」等用户可配置动作(见 shortcutRegistry.ts);
|
||||
* 一旦用户把 `Mod+D` 配置给其他动作(例如把「新建查询」改为 Ctrl+D),searchKeymap 的
|
||||
* `Mod-d` 会在编辑器中抢先匹配并 `preventDefault`,事件冒泡到 window 时
|
||||
* `defaultPrevented=true`,App.vue 的全局 handleKeydown 直接返回,用户配置的快捷键永不触发。
|
||||
*
|
||||
* 这里移除 `Mod-d` 绑定,保证用户可配置的快捷键优先于 CodeMirror 内置硬编码键位
|
||||
* (与 #4544 修复 Mod+F / Mod+H 冲突的思路一致)。
|
||||
*/
|
||||
export function searchKeymapWithoutModD(searchKeymap: readonly KeyBinding[]): KeyBinding[] {
|
||||
return searchKeymap.filter((binding) => binding.key !== "Mod-d");
|
||||
}
|
||||
Reference in new issue
Block a user