From df83c62dec3a08f87f7dfc624a1715ecab971c2c Mon Sep 17 00:00:00 2001 From: Zef Hemel Date: Fri, 22 Dec 2023 13:22:25 +0100 Subject: [PATCH] Fixes #605 --- web/client.ts | 2 +- web/editor_state.ts | 39 ++++++++++++++++++++++++++++++++++++++- web/hooks/command.ts | 4 ++-- web/types.ts | 7 +++++++ website/CHANGELOG.md | 5 +++++ website/SETTINGS.md | 24 ++++++++++++------------ 6 files changed, 65 insertions(+), 16 deletions(-) diff --git a/web/client.ts b/web/client.ts index 2215be97..48ce45de 100644 --- a/web/client.ts +++ b/web/client.ts @@ -930,7 +930,7 @@ export class Client { } } - async runCommandByName(name: string, args?: string[]) { + async runCommandByName(name: string, args?: any[]) { const cmd = this.ui.viewState.commands.get(name); if (cmd) { if (args) { diff --git a/web/editor_state.ts b/web/editor_state.ts index 772580a5..409a53d6 100644 --- a/web/editor_state.ts +++ b/web/editor_state.ts @@ -1,4 +1,6 @@ -import buildMarkdown from "../common/markdown_parser/parser.ts"; +import buildMarkdown, { + commandLinkRegex, +} from "../common/markdown_parser/parser.ts"; import { readonlyMode } from "./cm_plugins/readonly.ts"; import customMarkdownStyle from "./style.ts"; import { @@ -51,6 +53,40 @@ export function createEditorState( readOnly: boolean, ): EditorState { const commandKeyBindings: KeyBinding[] = []; + + // Keyboard shortcuts from SETTINGS take precedense + if (client.settings?.keyboardShortcuts) { + for (const shortcut of client.settings.keyboardShortcuts) { + console.info("Configuring keyboard shortcut", shortcut); + commandKeyBindings.push({ + key: shortcut.key, + mac: shortcut.mac, + run: (): boolean => { + const commandMatch = commandLinkRegex.exec(shortcut.command); + + let cleanCommandName = shortcut.command; + let args: any[] = []; + if (commandMatch) { + cleanCommandName = commandMatch[1]; + args = commandMatch[5] ? JSON.parse(`[${commandMatch[5]}]`) : []; + } + client.runCommandByName(cleanCommandName, args).catch((e: any) => { + console.error(e); + client.flashNotification( + `Error running command: ${e.message}`, + "error", + ); + }).then(() => { + // Always be focusing the editor after running a command + client.focus(); + }); + return true; + }, + }); + } + } + + // Then add bindings for plug commands for (const def of client.system.commandHook.editorCommands.values()) { if (def.command.key) { commandKeyBindings.push({ @@ -81,6 +117,7 @@ export function createEditorState( }); } } + let touchCount = 0; const markdownLanguage = buildMarkdown(client.system.mdExtensions); diff --git a/web/hooks/command.ts b/web/hooks/command.ts index eb2bdcd4..0014d100 100644 --- a/web/hooks/command.ts +++ b/web/hooks/command.ts @@ -14,7 +14,7 @@ export type CommandDef = { export type AppCommand = { command: CommandDef; - run: (args?: string[]) => Promise; + run: (args?: any[]) => Promise; }; export type CommandHookT = { @@ -44,7 +44,7 @@ export class CommandHook extends EventEmitter this.editorCommands.set(cmd.name, { command: cmd, run: (args?: string[]) => { - return plug.invoke(name, [cmd, ...args??[]]); + return plug.invoke(name, [cmd, ...args ?? []]); }, }); } diff --git a/web/types.ts b/web/types.ts index 95477d04..ec944940 100644 --- a/web/types.ts +++ b/web/types.ts @@ -19,10 +19,17 @@ export type Notification = { export type PanelMode = number; +export type KeyboardShortcut = { + command: string; + key?: string; + mac?: string; +}; + export type BuiltinSettings = { indexPage: string; customStyles?: string | string[]; plugOverrides?: Record>; + keyboardShortcuts?: KeyboardShortcut[]; // Format: compatible with docker ignore spaceIgnore?: string; }; diff --git a/website/CHANGELOG.md b/website/CHANGELOG.md index 295756d8..b0024690 100644 --- a/website/CHANGELOG.md +++ b/website/CHANGELOG.md @@ -3,6 +3,11 @@ release. --- +## Next +* Keyboard shortcuts can now be configured in [[SETTINGS]] + +--- + ## 0.5.10 * **Breaking change**: Local attachment URLs (`[page](url)` syntax and `![alt](url)` image syntax) are now interpreted to relative to the page's folder, unless their URL starts with a `/` then they're relative to the space root (as per [this issue](https://github.com/silverbulletmd/silverbullet/issues/363)) * **Breaking change:** Revamped [[Templates]], specifically changed the format of [[Page Templates]]. The “Template: Instantiate Page” has been renamed to {[Page: From Template]}. diff --git a/website/SETTINGS.md b/website/SETTINGS.md index 320cb297..153adf8b 100644 --- a/website/SETTINGS.md +++ b/website/SETTINGS.md @@ -7,29 +7,29 @@ indexPage: "[[SilverBullet]]" # Load custom CSS styles from the following page, can also be an array customStyles: "[[STYLES]]" +# Template settings quickNotePrefix: "📥 " - dailyNotePrefix: "📅 " dailyNoteTemplate: "[[template/page/Daily Note]]" - weeklyNotePrefix: "🗓️ " weeklyNoteTemplate: "[[template/page/Weekly Note]]" weeklyNoteMonday: false -# Markdown -previewOnRHS: true +# Keyboard shortcut overrides take presedence over built-in shortcuts +keyboardShortcuts: + # Using the command-link syntax + - command: "{[Stats: Show]}" + # Mac-specific keyboard + mac: "Cmd-s" + # Key binding for Windows/Linux (and Mac if not defined) + key: "Ctrl-s" + - command: "Navigate: Center Cursor" + key: "Alt-x" # Defines files to ignore in a format compatible with .gitignore spaceIgnore: | dist largefolder *.mp4 -# Plug overrides allow you to override any property in a plug manifest at runtime -# The primary use case of this is to override or define keyboard shortcuts. You can use the . notation, to quickly "dive deep" into the structure -plugOverrides: - editor: - # Matching this YAML structure: - # https://github.com/silverbulletmd/silverbullet/blob/main/plugs/editor/editor.plug.yaml - # and overriding the "key" for centering the cursor - functions.centerCursor.command.key: Ctrl-Alt-p + ```