feat(editor): add configurable line comment shortcut
This commit is contained in:
1 parent
184e235999
commit
5a9ab5c036
13 files changed
+109
-11
No files matched your search
@@ -34,4 +34,8 @@ describe("shortcut display", () => {
|
||||
expect(formatShortcutDisplay("Mod+Plus", "Win32")).toBe("Ctrl + +");
|
||||
expect(formatShortcutDisplay("Shift+Mod++", "Win32")).toBe("Ctrl + Shift + +");
|
||||
});
|
||||
|
||||
it("displays multi-stroke shortcuts", () => {
|
||||
expect(formatShortcutDisplay("Ctrl+K Ctrl+C", "Win32")).toBe("Ctrl + K, Ctrl + C");
|
||||
});
|
||||
});
|
||||
@@ -2,7 +2,24 @@ import { describe, expect, it } from "vitest";
|
||||
import { DEFAULT_SHORTCUT_SETTINGS, SHORTCUT_DEFINITIONS, findShortcutConflict, formatShortcut, normalizeShortcutSettings, shortcutToCodeMirrorKey, type ShortcutActionId } from "@/lib/editor/shortcutRegistry";
|
||||
|
||||
describe("shortcutRegistry editor actions", () => {
|
||||
const formatterEditorActionIds: ShortcutActionId[] = ["formatSql", "indentMore", "indentLess", "duplicateLine", "deleteLine", "moveLineUp", "moveLineDown", "copyLineUp", "copyLineDown", "undo", "redo", "selectAll", "uppercaseSelection", "lowercaseSelection", "exPasteSqlInCondition"];
|
||||
const formatterEditorActionIds: ShortcutActionId[] = [
|
||||
"formatSql",
|
||||
"toggleLineComment",
|
||||
"indentMore",
|
||||
"indentLess",
|
||||
"duplicateLine",
|
||||
"deleteLine",
|
||||
"moveLineUp",
|
||||
"moveLineDown",
|
||||
"copyLineUp",
|
||||
"copyLineDown",
|
||||
"undo",
|
||||
"redo",
|
||||
"selectAll",
|
||||
"uppercaseSelection",
|
||||
"lowercaseSelection",
|
||||
"exPasteSqlInCondition",
|
||||
];
|
||||
const sidebarShortcutActionIds: ShortcutActionId[] = ["copySidebarSelection", "pasteSidebarSelection", "editSidebarConnection"];
|
||||
|
||||
it("registers formatter editor shortcuts in the generic editor scope", () => {
|
||||
@@ -19,6 +36,7 @@ describe("shortcutRegistry editor actions", () => {
|
||||
|
||||
expect(shortcuts.executeSql).toBe("Mod+Shift+Enter");
|
||||
expect(shortcuts.formatSql).toBe("Shift+Mod+F");
|
||||
expect(shortcuts.toggleLineComment).toBe("Mod+/");
|
||||
expect(shortcuts.indentMore).toBe("");
|
||||
expect(shortcuts.indentLess).toBe("Shift+Tab");
|
||||
expect(shortcuts.duplicateLine).toBe("Mod+D");
|
||||
@@ -71,4 +89,12 @@ describe("shortcutRegistry editor actions", () => {
|
||||
expect(shortcutToCodeMirrorKey("Mod+Plus")).toBe("Mod-+");
|
||||
expect(shortcutToCodeMirrorKey("Shift+Mod++")).toBe("Shift-Mod-+");
|
||||
});
|
||||
|
||||
it("converts slash shortcuts for CodeMirror keymaps", () => {
|
||||
expect(shortcutToCodeMirrorKey("Mod+/")).toBe("Mod-/");
|
||||
});
|
||||
|
||||
it("converts multi-stroke shortcuts for CodeMirror keymaps", () => {
|
||||
expect(shortcutToCodeMirrorKey("Ctrl+K Ctrl+C")).toBe("Ctrl-k Ctrl-c");
|
||||
});
|
||||
});
|
||||
@@ -13,6 +13,11 @@ export function parseShortcutParts(shortcut?: string): string[] {
|
||||
return shortcut.split("+").filter(Boolean);
|
||||
}
|
||||
|
||||
export function parseShortcutStrokes(shortcut?: string): string[][] {
|
||||
if (!shortcut) return [];
|
||||
return shortcut.trim().split(/\s+/).filter(Boolean).map(parseShortcutParts);
|
||||
}
|
||||
|
||||
function shortcutDisplayOrder(parts: string[], platform = globalThis.navigator?.platform || ""): string[] {
|
||||
if (parts.length <= 2 || isMacShortcutPlatform(platform)) return parts;
|
||||
|
||||
@@ -43,6 +48,10 @@ export function shortcutDisplayParts(shortcut?: string, platform = globalThis.na
|
||||
return shortcutDisplayOrder(parseShortcutParts(shortcut), platform);
|
||||
}
|
||||
|
||||
export function shortcutDisplayStrokes(shortcut?: string, platform = globalThis.navigator?.platform || ""): string[][] {
|
||||
return parseShortcutStrokes(shortcut).map((parts) => shortcutDisplayOrder(parts, platform));
|
||||
}
|
||||
|
||||
export function shortcutKeyLabel(part: string, platform = globalThis.navigator?.platform || ""): string {
|
||||
const isMac = isMacShortcutPlatform(platform);
|
||||
if (part === "Mod") return isMac ? "⌘" : "Ctrl";
|
||||
@@ -65,10 +74,15 @@ export function shortcutKeyLabel(part: string, platform = globalThis.navigator?.
|
||||
}
|
||||
|
||||
export function shortcutDisplayKeys(shortcut?: string, platform = globalThis.navigator?.platform || ""): string[] {
|
||||
return shortcutDisplayParts(shortcut, platform).map((part) => shortcutKeyLabel(part, platform));
|
||||
return shortcutDisplayStrokes(shortcut, platform)
|
||||
.flat()
|
||||
.map((part) => shortcutKeyLabel(part, platform));
|
||||
}
|
||||
|
||||
export function formatShortcutDisplay(shortcut: string, platform = globalThis.navigator?.platform || ""): string {
|
||||
if (!shortcut) return "—";
|
||||
return shortcutDisplayKeys(shortcut, platform).join(isMacShortcutPlatform(platform) ? " " : " + ");
|
||||
const keySeparator = isMacShortcutPlatform(platform) ? " " : " + ";
|
||||
return shortcutDisplayStrokes(shortcut, platform)
|
||||
.map((parts) => parts.map((part) => shortcutKeyLabel(part, platform)).join(keySeparator))
|
||||
.join(", ");
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
import { parseShortcutParts, shortcutDisplayParts } from "@/lib/editor/shortcutDisplay";
|
||||
import { parseShortcutStrokes, shortcutDisplayParts } from "@/lib/editor/shortcutDisplay";
|
||||
|
||||
export type ShortcutActionId =
|
||||
| "executeSql"
|
||||
| "formatSql"
|
||||
| "toggleLineComment"
|
||||
| "saveSql"
|
||||
| "acceptCompletion"
|
||||
| "indentMore"
|
||||
@@ -74,6 +75,12 @@ export const SHORTCUT_DEFINITIONS: ShortcutDefinition[] = [
|
||||
scope: "editor",
|
||||
defaultShortcut: "Shift+Mod+F",
|
||||
},
|
||||
{
|
||||
id: "toggleLineComment",
|
||||
labelKey: "settings.shortcutToggleLineComment",
|
||||
scope: "editor",
|
||||
defaultShortcut: "Mod+/",
|
||||
},
|
||||
{
|
||||
id: "saveSql",
|
||||
labelKey: "settings.shortcutSaveSql",
|
||||
@@ -359,10 +366,14 @@ export function normalizeShortcutSettings(settings?: Partial<ShortcutSettings>):
|
||||
}
|
||||
|
||||
export function shortcutToCodeMirrorKey(shortcut: string): string {
|
||||
return parseShortcutParts(shortcut)
|
||||
.map((part) => (part.length === 1 ? part.toLowerCase() : part))
|
||||
.map((part) => (part === "Plus" ? "+" : part))
|
||||
.join("-");
|
||||
return parseShortcutStrokes(shortcut)
|
||||
.map((parts) =>
|
||||
parts
|
||||
.map((part) => (part.length === 1 ? part.toLowerCase() : part))
|
||||
.map((part) => (part === "Plus" ? "+" : part))
|
||||
.join("-"),
|
||||
)
|
||||
.join(" ");
|
||||
}
|
||||
|
||||
export function formatShortcut(shortcut: string, platform = globalThis.navigator?.platform || ""): string {
|
||||
|
||||
Reference in new issue
Block a user