]> git.eshelyaron.com Git - emacs.git/commitdiff
Add commands to interactively set/unset keyboard translations
authorHugo Heagren <hugo@heagren.com>
Sun, 4 Aug 2024 11:54:27 +0000 (12:54 +0100)
committerEshel Yaron <me@eshelyaron.com>
Fri, 4 Oct 2024 10:11:16 +0000 (12:11 +0200)
* 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'.

(cherry picked from commit 3139ce7ad42ab883eee5189d6cb19612f525f491)

etc/NEWS
lisp/keymap.el

index 151469dc094e1f50c8cd17051a412a504a9f9d73..6ad0bd7c2f5d7c24acbc534e32485b8d537c666d 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -96,6 +96,11 @@ It is equivalent to running ‘project-any-command’ with ‘find-file’.
 
 \f
 * Editing Changes in Emacs 31.1
+** Commands for keyboard translation
+`key-translate' is now interactive.  It prompts for a key to translate
+from, and another to translate to, and sets `keyboard-translate-table'.
+The new command `key-translate-remove' prompts for a key/translation
+pair with completing-read, and removes it from the translation table.
 
 ** Internationalization
 
index 39442146f01d0f02e1db9abab3656fec5d5b7f54..d53ed70252781c3b057ab00505acffe8b7b8507c 100644 (file)
@@ -384,9 +384,16 @@ This function creates a `keyboard-translate-table' if necessary
 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)))
+  ;; Using `key-description' is a necessary evil here, so that the
+  ;; values can be passed to keymap-* functions, even though those
+  ;; functions immediately undo it with `key-parse'.
+  (interactive `(,(key-description `[,(read-char "From: ")])
+                 ,(key-description `[,(read-char "To: ")])))
   (keymap--check from)
   (when to
     (keymap--check to))
@@ -409,6 +416,55 @@ If TO is nil, remove any existing translation for FROM."
           (aref from-key 0)
           (and to (aref to-key 0)))))
 
+(defun key-select-translation ()
+  "Prompt for a current keyboard translation pair with `completing-read'.
+
+Each pair is formatted as \"FROM -> TO\".
+
+Return the \"FROM\" as a key string."
+  (let* ((formatted-trans-alist nil)
+         ;; Alignment helpers
+         (pad 0)
+         (key-code-func
+          (lambda (kc trans)
+            (let* ((desc (key-description `[,kc]))
+                   (len (length desc)))
+              (when (> len pad)
+                (setq pad len))
+              (push
+               `(,desc . ,(key-description `[,trans]))
+               formatted-trans-alist))))
+         (format-func
+          (lambda (pair) ;; (key . value)
+            (format
+             "%s -> %s"
+             (string-pad (key-description `[,(car pair)]) pad)
+             (key-description `[,(cdr pair)])))))
+    ;; Set `pad' and `formatted-trans-alist'
+    (map-char-table
+     (lambda (chr trans)
+       (if (characterp chr)
+           (funcall key-code-func chr trans)
+         (require 'range)
+         (range-map
+          (lambda (kc) (funcall key-code-func kc trans))
+          chr)))
+     keyboard-translate-table)
+    (car
+     (split-string
+      (completing-read
+       "Key Translation: "
+       (mapcar format-func formatted-trans-alist)
+       nil t)))))
+
+(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-select-translation)))
+  (key-translate from 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'.