[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/which-key ebb4e92 47/51: Add which-key-add-keymap-based

From: Stefan Monnier
Subject: [elpa] externals/which-key ebb4e92 47/51: Add which-key-add-keymap-based-replacements
Date: Tue, 8 Sep 2020 10:26:22 -0400 (EDT)

branch: externals/which-key
commit ebb4e92b3ccab1d813346e24dccf9692850754db
Author: Justin Burkett <justin@burkett.cc>
Commit: Justin Burkett <justin@burkett.cc>

    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
    Ref #226 #261
 README.org   | 28 +++++++++++++++++++++++++++-
 which-key.el | 60 +++++++++++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 74 insertions(+), 14 deletions(-)

diff --git a/README.org b/README.org
index cb31655..c335e45 100644
--- a/README.org
+++ b/README.org
@@ -4,6 +4,11 @@
 ** Recent Changes
+*** 2020-08-28: Added =which-key-add-keymap-based-replacements=
+    This function provides an alternative interface allowing replacements to be
+    stored directly in keymaps, allowing one to avoid using
+    =which-key-replacement-alist=, which may cause performance issues when it
+    gets very big.
 *** 2019-08-01: Added =which-key-show-early-on-C-h=
     Allows one to trigger =which-key= on demand, rather than automatically. See
     the docstring and [[#manual-activation][Manual Activation]].
@@ -29,6 +34,7 @@
 ** Table of Contents                                                  :TOC_3:
 - [[#which-key][which-key]]
   - [[#recent-changes][Recent Changes]]
+    - [[#2020-08-28-added-which-key-add-keymap-based-replacements][2020-08-28: 
Added =which-key-add-keymap-based-replacements=]]
     - [[#2019-08-01-added-which-key-show-early-on-c-h][2019-08-01: Added 
     - [[#2017-12-13-added-which-key-enable-extended-define-key][2017-12-13: 
Added =which-key-enable-extended-define-key=]]
     - [[#2017-11-13-added-which-key-show-major-mode][2017-11-13: Added 
@@ -255,7 +261,7 @@
     idea of behind each alist is that you specify a selection string in the
     =car= of each cons cell and the replacement string in the =cdr=.
-**** Automatic
+**** Automatic ("keymap-based") replacement
      A newer option is to set =which-key-enable-extended-define-key= which
      advises =define-key= to allow which-key to pre-process its arguments. The
@@ -273,6 +279,26 @@
      (define-key some-map "b" '("bar-prefix"))
+     If you do not want to enable the advise on =define-key=, you may also use
+     =which-key-add-keymap-based-replacements=. The above examples can be
+     alternatively written as
+     #+BEGIN_SRC emacs-lisp
+     (which-key-add-keymap-based-replacements some-map
+       "f" '("foo" . long-name-for-command-foo)
+       ;; or
+       ;; "f" "foo"
+       "b" '("bar-prefix")
+       ;; or
+       ;; "b" "bar-prefix"
+     )
+     #+END_SRC
+     Note that while the alternative methods below use
+     =which-key-replacement-alist=, the "keymap-based" replacements store
+     replacements in the keymaps themselves, so should avoid performance issues
+     when =which-key-replacement-alist= becomes very large.
 **** "Key-Based" replacement
      Using this method, the description of a key is replaced using a string 
      you provide. Here's an example
diff --git a/which-key.el b/which-key.el
index 766c8f1..6eb8e35 100644
--- a/which-key.el
+++ b/which-key.el
@@ -913,6 +913,41 @@ but more functional."
 ;;; Helper functions to modify replacement lists.
+(defun which-key-add-keymap-based-replacements (keymap key replacement &rest 
+  "Replace the description of KEY using REPLACEMENT in KEYMAP.
+KEY should take a format suitable for use in
+`kbd'. REPLACEMENT is the string to use to describe the
+command associated with KEY in the KEYMAP. You may also use a
+cons cell of the form \(STRING . COMMAND\) for each REPLACEMENT,
+where STRING is the replacement string and COMMAND is a symbol
+corresponding to the intended command to be replaced. In the
+latter case, which-key will verify the intended command before
+performing the replacement. COMMAND should be nil if the binding
+corresponds to a key prefix. For example,
+\(which-key-add-keymap-based-replacements global-map
+  \"C-x w\" \"Save as\"\)
+\(which-key-add-keymap-based-replacements global-map
+  \"C-x w\" '\(\"Save as\" . write-file\)\)
+both have the same effect for the \"C-x C-w\" key binding, but
+the latter causes which-key to verify that the key sequence is
+actually bound to write-file before performing the replacement."
+  (while key
+    (let ((string (if (stringp replacement)
+                      replacement
+                    (car-safe replacement)))
+          (command (cdr-safe replacement)))
+      (define-key keymap (which-key--pseudo-key (kbd key))
+        `(which-key ,(cons string command))))
+    (setq key (pop more)
+          replacement (pop more))))
+(put 'which-key-add-keymap-based-replacements 'lisp-indent-function 'defun)
 (defun which-key-add-key-based-replacements
     (key-sequence replacement &rest more)
   "Replace the description of KEY-SEQUENCE with REPLACEMENT.
@@ -1462,19 +1497,18 @@ local bindings coming first. Within these categories 
order using
                                (cdr key-binding)))))))
 (defun which-key--get-pseudo-binding (key-binding &optional prefix)
-  (let* ((pseudo-binding
-          (key-binding (which-key--pseudo-key (kbd (car key-binding)) prefix)))
-         (pseudo-binding (when pseudo-binding (cadr pseudo-binding)))
-         (pseudo-desc (when pseudo-binding (car pseudo-binding)))
-         (pseudo-def (when pseudo-binding (cdr pseudo-binding)))
-         (real-def (key-binding (kbd (car key-binding))))
-         ;; treat keymaps as if they're nil bindings. This creates the
-         ;; possibility that we rename the wrong binding but this seems
-         ;; unlikely.
-         (real-def (unless (keymapp real-def) real-def)))
-    (when (and pseudo-binding
-               (eq pseudo-def real-def))
-      (cons (car key-binding) pseudo-desc))))
+  (let* ((key (kbd (car key-binding)))
+         (pseudo-binding (key-binding (which-key--pseudo-key key prefix))))
+    (when pseudo-binding
+      (let* ((command-replacement (cadr pseudo-binding))
+             (pseudo-desc (car command-replacement))
+             (pseudo-def (cdr command-replacement)))
+        (when (and (stringp pseudo-desc)
+                   (or (null pseudo-def)
+                       ;; don't verify keymaps
+                       (keymapp pseudo-def)
+                       (eq pseudo-def (key-binding key))))
+          (cons (car key-binding) pseudo-desc))))))
 (defsubst which-key--replace-in-binding (key-binding repl)
   (cond ((or (not (consp repl)) (null (cdr repl)))

reply via email to

[Prev in Thread] Current Thread [Next in Thread]