aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustin Burkett2020-08-28 10:17:40 -0400
committerJustin Burkett2020-08-28 10:17:40 -0400
commitebb4e92b3ccab1d813346e24dccf9692850754db (patch)
treedabadbfd664482690440523b22452fb4c98e763f
parente48e190a75a0c176e1deac218b891e77792d6921 (diff)
downloademacs-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.org28
-rw-r--r--which-key.el60
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.
918KEY should take a format suitable for use in
919`kbd'. REPLACEMENT is the string to use to describe the
920command associated with KEY in the KEYMAP. You may also use a
921cons cell of the form \(STRING . COMMAND\) for each REPLACEMENT,
922where STRING is the replacement string and COMMAND is a symbol
923corresponding to the intended command to be replaced. In the
924latter case, which-key will verify the intended command before
925performing the replacement. COMMAND should be nil if the binding
926corresponds to a key prefix. For example,
927
928\(which-key-add-keymap-based-replacements global-map
929 \"C-x w\" \"Save as\"\)
930
931and
932
933\(which-key-add-keymap-based-replacements global-map
934 \"C-x w\" '\(\"Save as\" . write-file\)\)
935
936both have the same effect for the \"C-x C-w\" key binding, but
937the latter causes which-key to verify that the key sequence is
938actually 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)))