diff options
| author | Justin Burkett | 2020-08-28 10:17:40 -0400 |
|---|---|---|
| committer | Justin Burkett | 2020-08-28 10:17:40 -0400 |
| commit | ebb4e92b3ccab1d813346e24dccf9692850754db (patch) | |
| tree | dabadbfd664482690440523b22452fb4c98e763f | |
| parent | e48e190a75a0c176e1deac218b891e77792d6921 (diff) | |
| download | emacs-ebb4e92b3ccab1d813346e24dccf9692850754db.tar.gz emacs-ebb4e92b3ccab1d813346e24dccf9692850754db.zip | |
Add which-key-add-keymap-based-replacements
This is an alternative to advising define-key using
which-key-enable-extended-define-key, but functions the same beneath the
surface.
Ref #226 #261
| -rw-r--r-- | README.org | 28 | ||||
| -rw-r--r-- | which-key.el | 60 |
2 files changed, 74 insertions, 14 deletions
diff --git a/README.org b/README.org index cb31655237b..c335e457b30 100644 --- a/README.org +++ b/README.org | |||
| @@ -4,6 +4,11 @@ | |||
| 4 | 4 | ||
| 5 | ** Recent Changes | 5 | ** Recent Changes |
| 6 | 6 | ||
| 7 | *** 2020-08-28: Added =which-key-add-keymap-based-replacements= | ||
| 8 | This function provides an alternative interface allowing replacements to be | ||
| 9 | stored directly in keymaps, allowing one to avoid using | ||
| 10 | =which-key-replacement-alist=, which may cause performance issues when it | ||
| 11 | gets very big. | ||
| 7 | *** 2019-08-01: Added =which-key-show-early-on-C-h= | 12 | *** 2019-08-01: Added =which-key-show-early-on-C-h= |
| 8 | Allows one to trigger =which-key= on demand, rather than automatically. See | 13 | Allows one to trigger =which-key= on demand, rather than automatically. See |
| 9 | the docstring and [[#manual-activation][Manual Activation]]. | 14 | the docstring and [[#manual-activation][Manual Activation]]. |
| @@ -29,6 +34,7 @@ | |||
| 29 | ** Table of Contents :TOC_3: | 34 | ** Table of Contents :TOC_3: |
| 30 | - [[#which-key][which-key]] | 35 | - [[#which-key][which-key]] |
| 31 | - [[#recent-changes][Recent Changes]] | 36 | - [[#recent-changes][Recent Changes]] |
| 37 | - [[#2020-08-28-added-which-key-add-keymap-based-replacements][2020-08-28: Added =which-key-add-keymap-based-replacements=]] | ||
| 32 | - [[#2019-08-01-added-which-key-show-early-on-c-h][2019-08-01: Added =which-key-show-early-on-C-h=]] | 38 | - [[#2019-08-01-added-which-key-show-early-on-c-h][2019-08-01: Added =which-key-show-early-on-C-h=]] |
| 33 | - [[#2017-12-13-added-which-key-enable-extended-define-key][2017-12-13: Added =which-key-enable-extended-define-key=]] | 39 | - [[#2017-12-13-added-which-key-enable-extended-define-key][2017-12-13: Added =which-key-enable-extended-define-key=]] |
| 34 | - [[#2017-11-13-added-which-key-show-major-mode][2017-11-13: Added =which-key-show-major-mode=]] | 40 | - [[#2017-11-13-added-which-key-show-major-mode][2017-11-13: Added =which-key-show-major-mode=]] |
| @@ -255,7 +261,7 @@ | |||
| 255 | idea of behind each alist is that you specify a selection string in the | 261 | idea of behind each alist is that you specify a selection string in the |
| 256 | =car= of each cons cell and the replacement string in the =cdr=. | 262 | =car= of each cons cell and the replacement string in the =cdr=. |
| 257 | 263 | ||
| 258 | **** Automatic | 264 | **** Automatic ("keymap-based") replacement |
| 259 | A newer option is to set =which-key-enable-extended-define-key= which | 265 | A newer option is to set =which-key-enable-extended-define-key= which |
| 260 | advises =define-key= to allow which-key to pre-process its arguments. The | 266 | advises =define-key= to allow which-key to pre-process its arguments. The |
| 261 | statement | 267 | statement |
| @@ -273,6 +279,26 @@ | |||
| 273 | (define-key some-map "b" '("bar-prefix")) | 279 | (define-key some-map "b" '("bar-prefix")) |
| 274 | #+END_SRC | 280 | #+END_SRC |
| 275 | 281 | ||
| 282 | If you do not want to enable the advise on =define-key=, you may also use | ||
| 283 | =which-key-add-keymap-based-replacements=. The above examples can be | ||
| 284 | alternatively written as | ||
| 285 | |||
| 286 | #+BEGIN_SRC emacs-lisp | ||
| 287 | (which-key-add-keymap-based-replacements some-map | ||
| 288 | "f" '("foo" . long-name-for-command-foo) | ||
| 289 | ;; or | ||
| 290 | ;; "f" "foo" | ||
| 291 | "b" '("bar-prefix") | ||
| 292 | ;; or | ||
| 293 | ;; "b" "bar-prefix" | ||
| 294 | ) | ||
| 295 | #+END_SRC | ||
| 296 | |||
| 297 | Note that while the alternative methods below use | ||
| 298 | =which-key-replacement-alist=, the "keymap-based" replacements store | ||
| 299 | replacements in the keymaps themselves, so should avoid performance issues | ||
| 300 | when =which-key-replacement-alist= becomes very large. | ||
| 301 | |||
| 276 | **** "Key-Based" replacement | 302 | **** "Key-Based" replacement |
| 277 | Using this method, the description of a key is replaced using a string that | 303 | Using this method, the description of a key is replaced using a string that |
| 278 | you provide. Here's an example | 304 | you provide. Here's an example |
diff --git a/which-key.el b/which-key.el index 766c8f1f86a..6eb8e359959 100644 --- a/which-key.el +++ b/which-key.el | |||
| @@ -913,6 +913,41 @@ but more functional." | |||
| 913 | ;;; Helper functions to modify replacement lists. | 913 | ;;; Helper functions to modify replacement lists. |
| 914 | 914 | ||
| 915 | ;;;###autoload | 915 | ;;;###autoload |
| 916 | (defun which-key-add-keymap-based-replacements (keymap key replacement &rest more) | ||
| 917 | "Replace the description of KEY using REPLACEMENT in KEYMAP. | ||
| 918 | KEY should take a format suitable for use in | ||
| 919 | `kbd'. REPLACEMENT is the string to use to describe the | ||
| 920 | command associated with KEY in the KEYMAP. You may also use a | ||
| 921 | cons cell of the form \(STRING . COMMAND\) for each REPLACEMENT, | ||
| 922 | where STRING is the replacement string and COMMAND is a symbol | ||
| 923 | corresponding to the intended command to be replaced. In the | ||
| 924 | latter case, which-key will verify the intended command before | ||
| 925 | performing the replacement. COMMAND should be nil if the binding | ||
| 926 | corresponds to a key prefix. For example, | ||
| 927 | |||
| 928 | \(which-key-add-keymap-based-replacements global-map | ||
| 929 | \"C-x w\" \"Save as\"\) | ||
| 930 | |||
| 931 | and | ||
| 932 | |||
| 933 | \(which-key-add-keymap-based-replacements global-map | ||
| 934 | \"C-x w\" '\(\"Save as\" . write-file\)\) | ||
| 935 | |||
| 936 | both have the same effect for the \"C-x C-w\" key binding, but | ||
| 937 | the latter causes which-key to verify that the key sequence is | ||
| 938 | actually bound to write-file before performing the replacement." | ||
| 939 | (while key | ||
| 940 | (let ((string (if (stringp replacement) | ||
| 941 | replacement | ||
| 942 | (car-safe replacement))) | ||
| 943 | (command (cdr-safe replacement))) | ||
| 944 | (define-key keymap (which-key--pseudo-key (kbd key)) | ||
| 945 | `(which-key ,(cons string command)))) | ||
| 946 | (setq key (pop more) | ||
| 947 | replacement (pop more)))) | ||
| 948 | (put 'which-key-add-keymap-based-replacements 'lisp-indent-function 'defun) | ||
| 949 | |||
| 950 | ;;;###autoload | ||
| 916 | (defun which-key-add-key-based-replacements | 951 | (defun which-key-add-key-based-replacements |
| 917 | (key-sequence replacement &rest more) | 952 | (key-sequence replacement &rest more) |
| 918 | "Replace the description of KEY-SEQUENCE with REPLACEMENT. | 953 | "Replace the description of KEY-SEQUENCE with REPLACEMENT. |
| @@ -1462,19 +1497,18 @@ local bindings coming first. Within these categories order using | |||
| 1462 | (cdr key-binding))))))) | 1497 | (cdr key-binding))))))) |
| 1463 | 1498 | ||
| 1464 | (defun which-key--get-pseudo-binding (key-binding &optional prefix) | 1499 | (defun which-key--get-pseudo-binding (key-binding &optional prefix) |
| 1465 | (let* ((pseudo-binding | 1500 | (let* ((key (kbd (car key-binding))) |
| 1466 | (key-binding (which-key--pseudo-key (kbd (car key-binding)) prefix))) | 1501 | (pseudo-binding (key-binding (which-key--pseudo-key key prefix)))) |
| 1467 | (pseudo-binding (when pseudo-binding (cadr pseudo-binding))) | 1502 | (when pseudo-binding |
| 1468 | (pseudo-desc (when pseudo-binding (car pseudo-binding))) | 1503 | (let* ((command-replacement (cadr pseudo-binding)) |
| 1469 | (pseudo-def (when pseudo-binding (cdr pseudo-binding))) | 1504 | (pseudo-desc (car command-replacement)) |
| 1470 | (real-def (key-binding (kbd (car key-binding)))) | 1505 | (pseudo-def (cdr command-replacement))) |
| 1471 | ;; treat keymaps as if they're nil bindings. This creates the | 1506 | (when (and (stringp pseudo-desc) |
| 1472 | ;; possibility that we rename the wrong binding but this seems | 1507 | (or (null pseudo-def) |
| 1473 | ;; unlikely. | 1508 | ;; don't verify keymaps |
| 1474 | (real-def (unless (keymapp real-def) real-def))) | 1509 | (keymapp pseudo-def) |
| 1475 | (when (and pseudo-binding | 1510 | (eq pseudo-def (key-binding key)))) |
| 1476 | (eq pseudo-def real-def)) | 1511 | (cons (car key-binding) pseudo-desc)))))) |
| 1477 | (cons (car key-binding) pseudo-desc)))) | ||
| 1478 | 1512 | ||
| 1479 | (defsubst which-key--replace-in-binding (key-binding repl) | 1513 | (defsubst which-key--replace-in-binding (key-binding repl) |
| 1480 | (cond ((or (not (consp repl)) (null (cdr repl))) | 1514 | (cond ((or (not (consp repl)) (null (cdr repl))) |