From b5b0d6e4c53fcedea92df03e86c57af856c9fbb7 Mon Sep 17 00:00:00 2001 From: Hugo Heagren Date: Sun, 4 Aug 2024 12:54:27 +0100 Subject: [PATCH] Add commands to interactively set/unset keyboard translations * lisp/keymap.el (key-translate): Add an interactive form, prompting for keys to translate, and update docstring to reflect this. (key-translate-selection-function): New custom option. (key-select-translation): New function, default value of above option. (key-translate-remove): New command, for removing entries from `keyboard-translate-table'. --- lisp/keymap.el | 57 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/lisp/keymap.el b/lisp/keymap.el index 861d6724c9e..d5bf51fd849 100644 --- a/lisp/keymap.el +++ b/lisp/keymap.el @@ -392,9 +392,13 @@ key-translate and then modifies one entry in it. Both FROM and TO should be specified by strings that satisfy `key-valid-p'. -If TO is nil, remove any existing translation for FROM." +If TO is nil, remove any existing translation for FROM. + +Interactively, prompt for FROM and TO with `read-char'." (declare (compiler-macro (lambda (form) (keymap--compile-check from to) form))) + (interactive `(,(key-description `[,(read-char "From: ")]) + ,(key-description `[,(read-char "To: ")]))) (keymap--check from) (when to (keymap--check to)) @@ -417,6 +421,57 @@ key-translate (aref from-key 0) (and to (aref to-key 0))))) +(defcustom key-translate-selection-function #'key-select-translation + "Function to select one current key translation pair. + +`key-translate-remove' uses this function to prompt for the translation +to remove. It must take no arguments, prompt the user for a translation +pair in `keyboard-translate-table', and return a vector containing only +the FROM key of the selected pair (e.g. if the selected pair translates +\"=\" to \"+\", the function should return the vector [61])" + :type 'function + :group 'keyboard) + +(defun key-select-translation () + "Prompt for a current keyboard translation pair with `'completing-read'. + +Each pair is formatted as \"FROM -> TO\"." + (let* ((minibuffer-allow-text-properties t) + (collection) + ;; Alignment helpers + (pad 0) + (_ (map-char-table + (lambda (k _) + (when (> (length (key-description `[,k])) pad) + (setq pad (length (key-description `[,k]))))) + keyboard-translate-table + )) + (format-func + (lambda (k v) + (setq collection + (cons + (propertize + (format + "%s -> %s" + (string-pad (key-description `[,k]) pad) + (key-description `[,v])) + 'key-translate-from `[,k]) + collection))))) + ;; Populate collection + (map-char-table format-func keyboard-translate-table) + (get-text-property 0 'key-translate-from + (completing-read "Key Translation: " collection)))) + +(defun key-translate-remove (from) + "Remove translation of FROM from `keyboard-translate-table'. + +FROM must satisfy `key-valid-p'. If FROM has no entry in +`keyboard-translate-table', this has no effect." + (interactive (list (key-description + (funcall key-translate-selection-function)))) + (set-char-table-range + keyboard-translate-table (aref (key-parse from) 0) nil)) + (defun keymap-lookup (keymap key &optional accept-default no-remap position) "Return the binding for command KEY in KEYMAP. KEY is a string that satisfies `key-valid-p'. -- 2.20.1