From 8191b7547aeb8705bed1c5f274d3a04ee8b71cbd Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Sun, 4 Apr 2021 12:59:09 -0600 Subject: [PATCH] [vscode] keyboard shortcuts --- projects/kiss-vscode/config/KissConfig.kiss | 64 +++++++++++++++++++-- projects/kiss-vscode/package.json | 9 +-- projects/kiss-vscode/src/Main.kiss | 1 + 3 files changed, 62 insertions(+), 12 deletions(-) diff --git a/projects/kiss-vscode/config/KissConfig.kiss b/projects/kiss-vscode/config/KissConfig.kiss index f6f9107d..00f694fa 100644 --- a/projects/kiss-vscode/config/KissConfig.kiss +++ b/projects/kiss-vscode/config/KissConfig.kiss @@ -98,9 +98,64 @@ (runCommand lastCommand) (errorMessage "No Kiss command was run previously."))) +(defvar &mut :vscode.WebviewPanel shortcutPanel null) +(defun :Void showShortcutPanel [&opt :Map prefixMap] + // When called without a prefixMap, if a shortcut panel is still open, close it and start over: + (unless prefixMap + (when shortcutPanel + // TODO for some reason, method calling an object in (when [object] ...) context, resets the object's type to Any unless (the [Type]) is used + (.dispose (the WebviewPanel shortcutPanel)) + (set shortcutPanel null)) + (set prefixMap commandShortcuts)) + (unless shortcutPanel + (set shortcutPanel (Vscode.window.createWebviewPanel + "kissShortcut" + "Kiss Shortcuts" + vscode.ViewColumn.Two + (object + enableScripts true)))) + (let [&mut keyListener null] + (set keyListener (shortcutPanel.webview.onDidReceiveMessage + ->key (if (prefixMap.exists key) + {(keyListener.dispose) + (case (dictGet prefixMap key) + ((Prefix innerMap) + (showShortcutPanel innerMap)) + ((Final command) + (shortcutPanel.dispose) + // TODO restore focus to previous frame first + (runCommand command)))} + {(warningMessage "$key is not mapped to a shortcut in this context")(return)})))) + (set shortcutPanel.webview.html (shortcutPanelHtml prefixMap))) + +(defun shortcutPanelHtml [:Map prefixMap] + (let [shortcutParagraphs + (for =>key shortcutKey prefixMap + "

${key} - $(case shortcutKey + ((Prefix innerMap) + "$(Lambda.count innerMap) shortcuts") + ((Final command) + command))

")] + " + + + + + Kiss Shortcuts + + + $(shortcutParagraphs.join "") + + + ")) + (defun :Void runKeyboardShortcut [&opt _] - // TODO - (errorMessage "Keyboard shortcut commands are not yet implemented")) + (showShortcutPanel)) // Extract [k]eyboard [s]hortcuts from a string: (defun extractKeyboardShortcuts [str &opt :Stream stream :String shortcuts] @@ -142,15 +197,14 @@ (defun registerCommand [description command] (dictSet commands description command) (whenLet [keyboardShortcut (extractKeyboardShortcuts description)] - (registerShortcut (keyboardShortcut.split "") description)) - //(print commandShortcuts) - ) + (registerShortcut (keyboardShortcut.split "") description))) (defun :Void registerBuiltins [] (set Prelude.print ->[v] { (infoMessage (Std.string v)) v}) + (registerCommand "Run a [k]iss command" runCommand) (registerCommand "Rerun last command" runLastCommand) (registerCommand "Run a keyboard shortcut command" runKeyboardShortcut) (registerCommand "Evaluate and print a Kiss expression" evalAndPrint)) diff --git a/projects/kiss-vscode/package.json b/projects/kiss-vscode/package.json index 6bed956d..fc619233 100644 --- a/projects/kiss-vscode/package.json +++ b/projects/kiss-vscode/package.json @@ -37,11 +37,6 @@ } ], "keybindings": [ - { - "command": "kiss.runCommand", - "key": "ctrl+;", - "mac": "cmd+;" - }, { "command": "kiss.runLastCommand", "key": "ctrl+.", @@ -49,8 +44,8 @@ }, { "command": "kiss.runKeyboardShortcut", - "key": "ctrl+k", - "mac": "cmd+k" + "key": "ctrl+;", + "mac": "cmd+;" } ], "languages": [{ diff --git a/projects/kiss-vscode/src/Main.kiss b/projects/kiss-vscode/src/Main.kiss index 81389577..32347752 100644 --- a/projects/kiss-vscode/src/Main.kiss +++ b/projects/kiss-vscode/src/Main.kiss @@ -10,6 +10,7 @@ (defvar &mut :KissConfig config null) (defun :Void tryLoadConfig [&opt :String text] + // TODO if a config object is active and a shortcut panel is open, dispose the panel before we lose the handle in the current config object (let [activeConfigPath (Path.join [activeConfigDir "config.js"]) backupConfigPath (Path.join [activeConfigDir (+ "config" (timeStamp) ".js")])] // Backup existing config.js