[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] master fb09d75 39/39: Merge commit 'ff79dfff66f880885c5893dd6fd05
From: |
Justin Burkett |
Subject: |
[elpa] master fb09d75 39/39: Merge commit 'ff79dfff66f880885c5893dd6fd05dc51173a476' |
Date: |
Thu, 21 Jun 2018 15:48:19 -0400 (EDT) |
branch: master
commit fb09d75ea1fb655ddc4e043590ea1378454f8792
Merge: 81c4a3d ff79dff
Author: Justin Burkett <address@hidden>
Commit: Justin Burkett <address@hidden>
Merge commit 'ff79dfff66f880885c5893dd6fd05dc51173a476'
---
packages/which-key/which-key-tests.el | 23 +
packages/which-key/which-key.el | 810 +++++++++++++++++++++-------------
2 files changed, 520 insertions(+), 313 deletions(-)
diff --git a/packages/which-key/which-key-tests.el
b/packages/which-key/which-key-tests.el
index 5c17ab7..3e75d6f 100644
--- a/packages/which-key/which-key-tests.el
+++ b/packages/which-key/which-key-tests.el
@@ -122,5 +122,28 @@
(should (equal (which-key--extract-key "<left> a .. c") "a .. c"))
(should (equal (which-key--extract-key "M-a a .. c") "a .. c")))
+(ert-deftest which-key-test--get-keymap-bindings ()
+ (let ((map (make-sparse-keymap))
+ which-key-replacement-alist)
+ (define-key map [which-key-a] '(which-key "blah"))
+ (define-key map "b" 'ignore)
+ (define-key map "c" "c")
+ (define-key map "dd" "dd")
+ (define-key map "eee" "eee")
+ (should (equal
+ (sort (which-key--get-keymap-bindings map)
+ (lambda (a b) (string-lessp (car a) (car b))))
+ '(("b" . "ignore")
+ ("c" . "c")
+ ("d" . "Prefix Command")
+ ("e" . "Prefix Command"))))
+ (should (equal
+ (sort (which-key--get-keymap-bindings map t)
+ (lambda (a b) (string-lessp (car a) (car b))))
+ '(("b" . "ignore")
+ ("c" . "c")
+ ("d d" . "dd")
+ ("e e e" . "eee"))))))
+
(provide 'which-key-tests)
;;; which-key-tests.el ends here
diff --git a/packages/which-key/which-key.el b/packages/which-key/which-key.el
index f973c19..09effbc 100644
--- a/packages/which-key/which-key.el
+++ b/packages/which-key/which-key.el
@@ -5,7 +5,7 @@
;; Author: Justin Burkett <address@hidden>
;; Maintainer: Justin Burkett <address@hidden>
;; URL: https://github.com/justbur/emacs-which-key
-;; Version: 3.1.0
+;; Version: 3.3.0
;; Keywords:
;; Package-Requires: ((emacs "24.4"))
@@ -69,7 +69,7 @@ to shorten the delay for subsequent popups in the same key
sequence. The default is for this value to be nil, which disables
this behavior."
:group 'which-key
- :type 'float)
+ :type '(choice float (const :tag "Disabled" nil)))
(defcustom which-key-echo-keystrokes (if (and echo-keystrokes
(> (+ echo-keystrokes 0.01)
@@ -88,7 +88,7 @@ which-key popup."
"Truncate the description of keys to this length.
Also adds \"..\". If nil, disable any truncation."
:group 'which-key
- :type 'integer)
+ :type '(choice integer (const :tag "Disable truncation" nil)))
(defcustom which-key-add-column-padding 0
"Additional padding (number of spaces) to add to the left of
@@ -115,7 +115,7 @@ of the which-key popup."
(defcustom which-key-dont-use-unicode nil
"If non-nil, don't use any unicode characters in default setup."
:group 'which-key
- :type 'integer)
+ :type 'boolean)
(defcustom which-key-separator
(if which-key-dont-use-unicode " : " " → ")
@@ -189,10 +189,10 @@ Finally, you can multiple replacements to occur for a
given key
binding by setting `which-key-allow-multiple-replacements' to a
non-nil value."
:group 'which-key
- :type '(alist :key-type (cons (choice regexp nil)
- (choice regexp nil))
- :value-type (cons (choice string nil)
- (choice string nil))))
+ :type '(alist :key-type (cons (choice regexp (const nil))
+ (choice regexp (const nil)))
+ :value-type (cons (choice string (const nil))
+ (choice string (const nil)))))
(when (bound-and-true-p which-key-key-replacement-alist)
(mapc
@@ -215,6 +215,19 @@ only the first match is used to perform replacements from
:group 'which-key
:type 'boolean)
+(defcustom which-key-show-docstrings nil
+ "If non-nil, show each command's docstring next to the command
+in the which-key buffer. This will only display the docstring up
+to the first line break. If you set this variable to the symbol
+docstring-only, then the command's name with be omitted. You
+probably also want to adjust `which-key-max-description-length'
+at the same time if you use this feature."
+ :group 'which-key
+ :type '(radio
+ (const :tag "Do not show docstrings" nil)
+ (const :tag "Add docstring to command names" t)
+ (const :tag "Replace command name with docstring" docstring-only)))
+
(defcustom which-key-highlighted-command-list '()
"A list of strings and/or cons cells used to highlight certain
commands. If the element is a string, assume it is a regexp
@@ -269,7 +282,7 @@ and nil. Nil turns the feature off."
"The maximum number of columns to display in the which-key
buffer. nil means don't impose a maximum."
:group 'which-key
- :type 'integer)
+ :type '(choice integer (const :tag "Unbounded" nil)))
(defcustom which-key-side-window-location 'bottom
"Location of which-key popup when `which-key-popup-type' is side-window.
@@ -405,6 +418,8 @@ prefixes in `which-key-paging-prefixes'"
(let ((map (make-sparse-keymap)))
(dolist (bind '(("\C-a" . which-key-abort)
("a" . which-key-abort)
+ ("\C-d" . which-key-toggle-docstrings)
+ ("d" . which-key-toggle-docstrings)
("\C-h" . which-key-show-standard-help)
("h" . which-key-show-standard-help)
("\C-n" . which-key-show-next-page-cycle)
@@ -412,7 +427,16 @@ prefixes in `which-key-paging-prefixes'"
("\C-p" . which-key-show-previous-page-cycle)
("p" . which-key-show-previous-page-cycle)
("\C-u" . which-key-undo-key)
- ("u" . which-key-undo-key)))
+ ("u" . which-key-undo-key)
+ ("1" . which-key-digit-argument)
+ ("2" . which-key-digit-argument)
+ ("3" . which-key-digit-argument)
+ ("4" . which-key-digit-argument)
+ ("5" . which-key-digit-argument)
+ ("6" . which-key-digit-argument)
+ ("7" . which-key-digit-argument)
+ ("8" . which-key-digit-argument)
+ ("9" . which-key-digit-argument)))
(define-key map (car bind) (cdr bind)))
map)
"Keymap for C-h commands.")
@@ -548,6 +572,11 @@ and it matches a string in
`which-key-highlighted-command-list'."
"Face for special keys (SPC, TAB, RET)"
:group 'which-key-faces)
+(defface which-key-docstring-face
+ '((t . (:inherit which-key-note-face)))
+ "Face for docstrings"
+ :group 'which-key-faces)
+
;;;; Custom popup
(defcustom which-key-custom-popup-max-dimensions-function nil
@@ -556,13 +585,13 @@ Will be passed the width of the active window and is
expected to
return the maximum height in lines and width in characters of the
which-key popup in the form a cons cell (height . width)."
:group 'which-key
- :type 'function)
+ :type '(choice function (const nil)))
(defcustom which-key-custom-hide-popup-function nil
"Variable to hold a custom hide-popup function.
It takes no arguments and the return value is ignored."
:group 'which-key
- :type 'function)
+ :type '(choice function (const nil)))
(defcustom which-key-custom-show-popup-function nil
"Variable to hold a custom show-popup function.
@@ -570,7 +599,7 @@ Will be passed the required dimensions in the form (height .
width) in lines and characters respectively. The return value is
ignored."
:group 'which-key
- :type 'function)
+ :type '(choice function (const nil)))
(defcustom which-key-lighter " WK"
"Minor mode lighter to use in the mode-line."
@@ -605,32 +634,73 @@ Used when `which-key-popup-type' is frame.")
"Internal: Backup the initial value of `echo-keystrokes'.")
(defvar which-key--prefix-help-cmd-backup nil
"Internal: Backup the value of `prefix-help-command'.")
-(defvar which-key--pages-plist nil
- "Internal: Holds page objects")
-(defvar which-key--current-prefix nil
- "Internal: Holds current prefix")
-(defvar which-key--current-page-n nil
- "Internal: Current pages of showing buffer. Nil means no buffer
-showing.")
-(defvar which-key--on-last-page nil
- "Internal: Non-nil if showing last page.")
(defvar which-key--last-try-2-loc nil
"Internal: Last location of side-window when two locations
used.")
+(defvar which-key--automatic-display nil
+ "Internal: Non-nil if popup was triggered with automatic
+update.")
(defvar which-key--multiple-locations nil)
-(defvar which-key--using-top-level nil)
-(defvar which-key--using-show-keymap nil)
-(defvar which-key--using-show-operator-keymap nil)
(defvar which-key--inhibit-next-operator-popup nil)
-(defvar which-key--current-show-keymap-name nil)
(defvar which-key--prior-show-keymap-args nil)
(defvar which-key--previous-frame-size nil)
(defvar which-key--prefix-title-alist nil)
(defvar which-key--debug nil)
+(defvar which-key--evil-keys-regexp (eval-when-compile
+ (regexp-opt '("-state"))))
+(defvar which-key--ignore-non-evil-keys-regexp
+ (eval-when-compile
+ (regexp-opt '("mouse-" "wheel-" "remap" "drag-" "scroll-bar"
+ "select-window" "switch-frame" "which-key-"))))
+(defvar which-key--ignore-keys-regexp
+ (eval-when-compile
+ (regexp-opt '("mouse-" "wheel-" "remap" "drag-" "scroll-bar"
+ "select-window" "switch-frame" "-state"
+ "which-key-"))))
(make-obsolete-variable 'which-key-prefix-name-alist nil "2016-10-05")
(make-obsolete-variable 'which-key-prefix-title-alist nil "2016-10-05")
+(defvar which-key--pages-obj nil)
+(cl-defstruct which-key--pages
+ pages
+ height
+ widths
+ keys/page
+ page-nums
+ num-pages
+ total-keys
+ prefix
+ prefix-title)
+
+(defun which-key--rotate (list n)
+ (let* ((len (length list))
+ (n (if (< n 0) (+ len n) n))
+ (n (mod n len)))
+ (append (last list (- len n)) (butlast list (- len n)))))
+
+(defun which-key--pages-set-current-page (pages-obj n)
+ (setf (which-key--pages-pages pages-obj)
+ (which-key--rotate (which-key--pages-pages pages-obj) n))
+ (setf (which-key--pages-widths pages-obj)
+ (which-key--rotate (which-key--pages-widths pages-obj) n))
+ (setf (which-key--pages-keys/page pages-obj)
+ (which-key--rotate (which-key--pages-keys/page pages-obj) n))
+ (setf (which-key--pages-page-nums pages-obj)
+ (which-key--rotate (which-key--pages-page-nums pages-obj) n))
+ pages-obj)
+
+(defsubst which-key--on-first-page ()
+ (= (which-key--pages-page-nums which-key--pages-obj) 1))
+
+(defsubst which-key--on-last-page ()
+ (= (which-key--pages-page-nums which-key--pages-obj)
+ (which-key--pages-num-pages which-key--pages-obj)))
+
+(defsubst which-key--current-prefix ()
+ (when which-key--pages-obj
+ (which-key--pages-prefix which-key--pages-obj)))
+
;;; Third-party library support
;;;; Evil
@@ -712,7 +782,7 @@ problems at github. If DISABLE is non-nil disable support."
(add-hook 'pre-command-hook #'which-key--hide-popup)
(add-hook 'focus-out-hook #'which-key--stop-timer)
(add-hook 'focus-in-hook #'which-key--start-timer)
- (add-hook 'window-configuration-change-hook
+ (add-hook 'window-size-change-functions
'which-key--hide-popup-on-frame-size-change)
(which-key--start-timer))
(setq echo-keystrokes which-key--echo-keystrokes-backup)
@@ -723,7 +793,7 @@ problems at github. If DISABLE is non-nil disable support."
(remove-hook 'pre-command-hook #'which-key--hide-popup)
(remove-hook 'focus-out-hook #'which-key--stop-timer)
(remove-hook 'focus-in-hook #'which-key--start-timer)
- (remove-hook 'window-configuration-change-hook
+ (remove-hook 'window-size-change-functions
'which-key--hide-popup-on-frame-size-change)
(which-key--stop-timer)))
@@ -999,14 +1069,10 @@ total height."
(defun which-key--hide-popup ()
"This function is called to hide the which-key buffer."
(unless (member real-this-command which-key--paging-functions)
- (setq which-key--current-page-n nil
- which-key--current-prefix nil
- which-key--using-top-level nil
- which-key--using-show-keymap nil
- which-key--using-show-operator-keymap nil
- which-key--current-show-keymap-name nil
- which-key--prior-show-keymap-args nil
- which-key--on-last-page nil)
+ (setq which-key--last-try-2-loc nil)
+ (setq which-key--pages-obj nil)
+ (setq which-key--automatic-display nil)
+ (setq which-key--prior-show-keymap-args nil)
(when (and which-key-idle-secondary-delay
which-key--secondary-timer-active)
(which-key--start-timer))
@@ -1026,7 +1092,7 @@ total height."
(frame (which-key--hide-buffer-frame))
(custom (funcall which-key-custom-hide-popup-function))))
-(defun which-key--hide-popup-on-frame-size-change ()
+(defun which-key--hide-popup-on-frame-size-change (&optional _)
"Hide which-key popup if the frame is resized (to trigger a new
popup)."
(when (which-key--frame-size-changed-p)
@@ -1358,9 +1424,9 @@ local bindings coming first. Within these categories
order using
(throw 'res res)))))))
(nreverse res)))
-(defun which-key--get-pseudo-binding (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)) t)))
+ (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)))
@@ -1373,11 +1439,11 @@ local bindings coming first. Within these categories
order using
(eq pseudo-def real-def))
(cons (car key-binding) pseudo-desc))))
-(defun which-key--maybe-replace (key-binding)
+(defun which-key--maybe-replace (key-binding &optional prefix)
"Use `which-key--replacement-alist' to maybe replace KEY-BINDING.
KEY-BINDING is a cons cell of the form \(KEY . BINDING\) each of
which are strings. KEY is of the form produced by `key-binding'."
- (let* ((pseudo-binding (which-key--get-pseudo-binding key-binding)))
+ (let* ((pseudo-binding (which-key--get-pseudo-binding key-binding prefix)))
(if pseudo-binding
pseudo-binding
(let* ((mode-res (which-key--get-replacements key-binding t))
@@ -1403,7 +1469,7 @@ which are strings. KEY is of the form produced by
`key-binding'."
(t (cdr key-binding))))))))))))
(defsubst which-key--current-key-list (&optional key-str)
- (append (listify-key-sequence which-key--current-prefix)
+ (append (listify-key-sequence (which-key--current-prefix))
(when key-str
(listify-key-sequence (kbd key-str)))))
@@ -1416,24 +1482,29 @@ which are strings. KEY is of the form produced by
`key-binding'."
(intern (cdr keydesc))))
(defun which-key--map-binding-p (map keydesc)
+ "Does MAP contain KEYDESC = (key . binding)?"
(or
(when (bound-and-true-p evil-state)
- (eq (which-key--safe-lookup-key
- map
- (kbd (which-key--current-key-string
- (format "<%s-state> %s" evil-state (car keydesc)))))
- (intern (cdr keydesc))))
- (eq (which-key--safe-lookup-key
- map (kbd (which-key--current-key-string (car keydesc))))
- (intern (cdr keydesc)))))
-
-(defun which-key--pseudo-key (key &optional use-current-prefix)
+ (let ((lookup
+ (which-key--safe-lookup-key
+ map
+ (kbd (which-key--current-key-string
+ (format "<%s-state> %s" evil-state (car keydesc)))))))
+ (or (eq lookup (intern (cdr keydesc)))
+ (and (keymapp lookup) (string= (cdr keydesc) "Prefix Command")))))
+ (let ((lookup
+ (which-key--safe-lookup-key
+ map (kbd (which-key--current-key-string (car keydesc))))))
+ (or (eq lookup (intern (cdr keydesc)))
+ (and (keymapp lookup) (string= (cdr keydesc) "Prefix Command"))))))
+
+(defun which-key--pseudo-key (key &optional prefix)
"Replace the last key in the sequence KEY by a special symbol
in order for which-key to allow looking up a description for the key."
(let* ((seq (listify-key-sequence key))
(final (intern (format "which-key-%s" (key-description (last seq))))))
- (if use-current-prefix
- (vconcat (which-key--current-key-list) (list final))
+ (if prefix
+ (vconcat prefix (list final))
(vconcat (butlast seq) (list final)))))
(defun which-key--maybe-get-prefix-title (keys)
@@ -1460,17 +1531,19 @@ no title exists."
(if alternate alternate
(concat "Following " keys)))
(t ""))))
- (which-key--using-top-level which-key--using-top-level)
- (which-key--current-show-keymap-name
- which-key--current-show-keymap-name)
- (t "")))
+ (t "")))
+
+(defun which-key--propertize (string &rest properties)
+ "Version of `propertize' that checks type of STRING."
+ (when (stringp string)
+ (apply #'propertize string properties)))
(defun which-key--propertize-key (key)
"Add a face to KEY.
If KEY contains any \"special keys\" defined in
`which-key-special-keys' then truncate and add the corresponding
`which-key-special-key-face'."
- (let ((key-w-face (propertize key 'face 'which-key-key-face))
+ (let ((key-w-face (which-key--propertize key 'face 'which-key-key-face))
(regexp (concat "\\("
(mapconcat 'identity which-key-special-keys
"\\|") "\\)"))
@@ -1480,7 +1553,7 @@ If KEY contains any \"special keys\" defined in
(string-match regexp key))
(let ((beg (match-beginning 0)) (end (match-end 0)))
(concat (substring key-w-face 0 beg)
- (propertize (substring key-w-face beg (1+ beg))
+ (which-key--propertize (substring key-w-face beg (1+ beg))
'face 'which-key-special-key-face)
(substring key-w-face end
(which-key--string-width key-w-face))))
@@ -1488,10 +1561,12 @@ If KEY contains any \"special keys\" defined in
(defsubst which-key--truncate-description (desc)
"Truncate DESC description to `which-key-max-description-length'."
- (if (and which-key-max-description-length
- (> (length desc) which-key-max-description-length))
- (concat (substring desc 0 which-key-max-description-length) "..")
- desc))
+ (let* ((last-face (get-text-property (1- (length desc)) 'face desc))
+ (dots (which-key--propertize ".." 'face last-face)))
+ (if (and which-key-max-description-length
+ (> (length desc) which-key-max-description-length))
+ (concat (substring desc 0 which-key-max-description-length) dots)
+ desc)))
(defun which-key--highlight-face (description)
"Return the highlight face for DESCRIPTION if it has one."
@@ -1519,34 +1594,35 @@ removing a \"group:\" prefix.
ORIGINAL-DESCRIPTION is the description given by
`describe-buffer-bindings'."
- (let* ((desc description)
- (desc (if (string-match-p "^group:" desc)
- (substring desc 6) desc))
- (desc (if group (concat which-key-prefix-prefix desc) desc))
- (desc (which-key--truncate-description desc)))
- (make-text-button desc nil
- 'face (cond (hl-face hl-face)
- (group 'which-key-group-description-face)
- (local 'which-key-local-map-description-face)
- (t 'which-key-command-description-face))
- 'help-echo (cond
- ((and original-description
- (fboundp (intern original-description))
- (documentation (intern original-description))
- ;; tooltip-mode doesn't exist in emacs-nox
- (boundp 'tooltip-mode) tooltip-mode)
- (documentation (intern original-description)))
- ((and original-description
- (fboundp (intern original-description))
- (documentation (intern original-description))
- (let* ((doc (documentation
- (intern original-description)))
- (str (replace-regexp-in-string "\n" " " doc))
- (max (floor (* (frame-width) 0.8))))
- (if (> (length str) max)
- (concat (substring str 0 max) "...")
- str))))))
- desc))
+ (when description
+ (let* ((desc description)
+ (desc (if (string-match-p "^group:" desc)
+ (substring desc 6) desc))
+ (desc (if group (concat which-key-prefix-prefix desc) desc)))
+ (make-text-button
+ desc nil
+ 'face (cond (hl-face hl-face)
+ (group 'which-key-group-description-face)
+ (local 'which-key-local-map-description-face)
+ (t 'which-key-command-description-face))
+ 'help-echo (cond
+ ((and original-description
+ (fboundp (intern original-description))
+ (documentation (intern original-description))
+ ;; tooltip-mode doesn't exist in emacs-nox
+ (boundp 'tooltip-mode) tooltip-mode)
+ (documentation (intern original-description)))
+ ((and original-description
+ (fboundp (intern original-description))
+ (documentation (intern original-description))
+ (let* ((doc (documentation
+ (intern original-description)))
+ (str (replace-regexp-in-string "\n" " " doc))
+ (max (floor (* (frame-width) 0.8))))
+ (if (> (length str) max)
+ (concat (substring str 0 max) "...")
+ str))))))
+ desc)))
(defun which-key--extract-key (key-str)
"Pull the last key (or key range) out of KEY-STR."
@@ -1556,12 +1632,32 @@ ORIGINAL-DESCRIPTION is the description given by
(match-string 1 key-str)
(car (last (split-string key-str " ")))))))
-(defun which-key--format-and-replace (unformatted)
+(defun which-key--maybe-add-docstring (current original)
+ "Maybe concat a docstring to CURRENT and return result.
+Specifically, do this if ORIGINAL is a command with a docstring
+and `which-key-show-docstrings' is non-nil. If
+`which-key-show-docstrings' is the symbol docstring-only, just
+return the docstring."
+ (let* ((orig-sym (intern original))
+ (doc (when (commandp orig-sym)
+ (documentation orig-sym)))
+ (docstring (when doc
+ (which-key--propertize (car (split-string doc "\n"))
+ 'face
'which-key-docstring-face))))
+ (cond ((not (and which-key-show-docstrings docstring))
+ current)
+ ((eq which-key-show-docstrings 'docstring-only)
+ docstring)
+ (t
+ (format "%s %s" current docstring)))))
+
+(defun which-key--format-and-replace (unformatted &optional prefix
preserve-full-key)
"Take a list of (key . desc) cons cells in UNFORMATTED, add
faces and perform replacements according to the three replacement
alists. Returns a list (key separator description)."
(let ((sep-w-face
- (propertize which-key-separator 'face 'which-key-separator-face))
+ (which-key--propertize which-key-separator
+ 'face 'which-key-separator-face))
(local-map (current-local-map))
new-list)
(dolist (key-binding unformatted)
@@ -1569,35 +1665,76 @@ alists. Returns a list (key separator description)."
(orig-desc (cdr key-binding))
(group (which-key--group-p orig-desc))
;; At top-level prefix is nil
- (keys (if which-key--current-prefix
- (concat (which-key--current-key-string) " " key)
+ (keys (if prefix
+ (concat (key-description prefix) " " key)
key))
(local (eq (which-key--safe-lookup-key local-map (kbd keys))
(intern orig-desc)))
(hl-face (which-key--highlight-face orig-desc))
- (key-binding (which-key--maybe-replace (cons keys orig-desc))))
+ (key-binding (which-key--maybe-replace (cons keys orig-desc)
prefix))
+ (final-desc (which-key--propertize-description
+ (cdr key-binding) group local hl-face orig-desc)))
+ (when final-desc
+ (setq final-desc
+ (which-key--truncate-description
+ (which-key--maybe-add-docstring final-desc orig-desc))))
(when (consp key-binding)
(push
(list (which-key--propertize-key
- (which-key--extract-key (car key-binding)))
+ (if preserve-full-key
+ (car key-binding)
+ (which-key--extract-key (car key-binding))))
sep-w-face
- (which-key--propertize-description
- (cdr key-binding) group local hl-face orig-desc))
+ final-desc)
new-list))))
(nreverse new-list)))
-(defun which-key--get-keymap-bindings (keymap)
- "Retrieve top-level bindings from KEYMAP."
+(defun which-key--get-keymap-bindings (keymap &optional all prefix)
+ "Retrieve top-level bindings from KEYMAP.
+If ALL is non-nil, get all bindings, not just the top-level
+ones. PREFIX is for internal use and should not be used."
(let (bindings)
(map-keymap
(lambda (ev def)
- (cl-pushnew
- (cons (key-description (list ev))
- (cond ((keymapp def) "Prefix Command")
- ((symbolp def) (copy-sequence (symbol-name def)))
- ((eq 'lambda (car-safe def)) "lambda")
- (t (format "%s" def))))
- bindings :test (lambda (a b) (string= (car a) (car b)))))
+ (let* ((key (append prefix (list ev)))
+ (key-desc (key-description key)))
+ (cond ((or (string-match-p
+ which-key--ignore-non-evil-keys-regexp key-desc)
+ (eq ev 'menu-bar)))
+ ;; extract evil keys corresponding to current state
+ ((and (keymapp def)
+ (boundp 'evil-state)
+ (bound-and-true-p evil-local-mode)
+ (string-match-p (format "<%s-state>$" evil-state)
key-desc))
+ (setq bindings
+ ;; this function keeps the latter of the two duplicates
+ ;; which will be the evil binding
+ (cl-remove-duplicates
+ (append bindings
+ (which-key--get-keymap-bindings def all prefix))
+ :test (lambda (a b) (string= (car a) (car b))))))
+ ((and (keymapp def)
+ (string-match-p which-key--evil-keys-regexp key-desc)))
+ ((and (keymapp def)
+ (or all
+ ;; event 27 is escape, so this will pick up meta
+ ;; bindings and hopefully not too much more
+ (and (numberp ev) (= ev 27))))
+ (setq bindings
+ (append bindings
+ (which-key--get-keymap-bindings def t key))))
+ (t
+ (when def
+ (cl-pushnew
+ (cons key-desc
+ (cond
+ ((keymapp def) "Prefix Command")
+ ((symbolp def) (copy-sequence (symbol-name def)))
+ ((eq 'lambda (car-safe def)) "lambda")
+ ((eq 'menu-item (car-safe def)) "menu-item")
+ ((stringp def) def)
+ (t "unknown")))
+ bindings :test (lambda (a b) (string= (car a) (car
b)))))))))
keymap)
bindings))
@@ -1611,17 +1748,12 @@ Requires `which-key-compute-remaps' to be non-nil"
(copy-sequence (symbol-name remap))
binding)))
-(defun which-key--get-current-bindings ()
+(defun which-key--get-current-bindings (&optional prefix)
"Generate a list of current active bindings."
- (let ((key-str-qt (regexp-quote (key-description which-key--current-prefix)))
+ (let ((key-str-qt (regexp-quote (key-description prefix)))
(buffer (current-buffer))
(ignore-bindings '("self-insert-command" "ignore"
"ignore-event" "company-ignore"))
- (ignore-keys-regexp
- (eval-when-compile
- (regexp-opt '("mouse-" "wheel-" "remap" "drag-" "scroll-bar"
- "select-window" "switch-frame" "-state"
- "which-key-"))))
(ignore-sections-regexp
(eval-when-compile
(regexp-opt '("Key translations" "Function key map translations"
@@ -1629,7 +1761,7 @@ Requires `which-key-compute-remaps' to be non-nil"
(with-temp-buffer
(setq-local indent-tabs-mode t)
(setq-local tab-width 8)
- (describe-buffer-bindings buffer which-key--current-prefix)
+ (describe-buffer-bindings buffer prefix)
(goto-char (point-min))
(let ((header-p (not (= (char-after) ?\f)))
bindings header)
@@ -1644,8 +1776,7 @@ Requires `which-key-compute-remaps' to be non-nil"
((= (char-after) ?\f)
(setq header-p t))
((looking-at "^[ \t]*$"))
- ((or (not (string-match-p ignore-sections-regexp header))
- which-key--current-prefix)
+ ((or (not (string-match-p ignore-sections-regexp header)) prefix)
(let ((binding-start (save-excursion
(and (re-search-forward "\t+" nil t)
(match-end 0))))
@@ -1659,15 +1790,15 @@ Requires `which-key-compute-remaps' to be non-nil"
(save-match-data
(cond
((member binding ignore-bindings))
- ((string-match-p ignore-keys-regexp key))
- ((and which-key--current-prefix
+ ((string-match-p which-key--ignore-keys-regexp key))
+ ((and prefix
(string-match (format "^%s[ \t]\\([^ \t]+\\)[ \t]+$"
key-str-qt) key))
(unless (assoc-string (match-string 1 key) bindings)
(push (cons (match-string 1 key)
(which-key--compute-binding binding))
bindings)))
- ((and which-key--current-prefix
+ ((and prefix
(string-match
(format
"^%s[ \t]\\([^ \t]+\\) \\.\\. %s[ \t]\\([^ \t]+\\)[
\t]+$"
@@ -1688,16 +1819,25 @@ Requires `which-key-compute-remaps' to be non-nil"
(forward-line))
(nreverse bindings)))))
-(defun which-key--get-formatted-key-bindings (&optional bindings filter)
- "Uses `describe-buffer-bindings' to collect the key bindings in
-BUFFER that follow the key sequence KEY-SEQ."
- (let* ((unformatted (if bindings bindings
(which-key--get-current-bindings))))
+(defun which-key--get-bindings (&optional prefix keymap filter recursive)
+ "Collect key bindings.
+If KEYMAP is nil, collect from current buffer using the current
+key sequence as a prefix. Otherwise, collect from KEYMAP. FILTER
+is a function to use to filter the bindings. If RECURSIVE is
+non-nil, then bindings are collected recursively for all prefixes."
+ (let* ((unformatted
+ (cond ((keymapp keymap)
+ (which-key--get-keymap-bindings keymap recursive))
+ (keymap
+ (error "%s is not a keymap" keymap))
+ (t
+ (which-key--get-current-bindings prefix)))))
(when filter
(setq unformatted (cl-remove-if-not filter unformatted)))
(when which-key-sort-order
(setq unformatted
(sort unformatted which-key-sort-order)))
- (which-key--format-and-replace unformatted)))
+ (which-key--format-and-replace unformatted prefix recursive)))
;;; Functions for laying out which-key buffer pages
@@ -1751,16 +1891,15 @@ that width."
(defun which-key--list-to-pages (keys avl-lines avl-width)
"Convert list of KEYS to columns based on dimensions AVL-LINES and AVL-WIDTH.
-Returns a plist that holds the page strings, as well as
-metadata."
+Returns a `which-key--pages' object that holds the page strings,
+as well as metadata."
(let ((cols-w-widths (mapcar #'which-key--pad-column
(which-key--partition-list avl-lines keys)))
(page-width 0) (n-pages 0) (n-keys 0) (n-columns 0)
page-cols pages page-widths keys/page col)
(if (> (apply #'max (mapcar #'car cols-w-widths)) avl-width)
;; give up if no columns fit
- (list :pages nil :page-height 0 :page-widths '(0)
- :keys/page '(0) :n-pages 0 :tot-keys 0)
+ nil
(while cols-w-widths
;; start new page
(cl-incf n-pages)
@@ -1782,10 +1921,14 @@ metadata."
(push (which-key--join-columns page-cols) pages)
(push n-keys keys/page)
(push page-width page-widths))
- (list :pages (nreverse pages) :page-height avl-lines
- :page-widths (nreverse page-widths)
- :keys/page (reverse keys/page) :n-pages n-pages
- :tot-keys (apply #'+ keys/page)))))
+ (make-which-key--pages
+ :pages (nreverse pages)
+ :height avl-lines
+ :widths (nreverse page-widths)
+ :keys/page (reverse keys/page)
+ :page-nums (number-sequence 1 n-pages)
+ :num-pages n-pages
+ :total-keys (apply #'+ keys/page)))))
(defun which-key--create-pages-1
(keys available-lines available-width &optional min-lines vertical)
@@ -1798,8 +1941,9 @@ should be minimized."
keys available-lines available-width))
(min-lines (or min-lines 0))
found prev-result)
- (if (or vertical
- (> (plist-get result :n-pages) 1)
+ (if (or (null result)
+ vertical
+ (> (which-key--pages-num-pages result) 1)
(= 1 available-lines))
result
;; simple search for a fitting page
@@ -1809,10 +1953,10 @@ should be minimized."
prev-result result
result (which-key--list-to-pages
keys available-lines available-width)
- found (> (plist-get result :n-pages) 1)))
+ found (> (which-key--pages-num-pages result) 1)))
(if found prev-result result))))
-(defun which-key--create-pages (keys)
+(defun which-key--create-pages (keys &optional prefix-keys prefix-title)
"Create page strings using `which-key--list-to-pages'.
Will try to find the best number of rows and columns using the
given dimensions and the length and wdiths of KEYS. SEL-WIN-WIDTH
@@ -1820,8 +1964,8 @@ is the width of the live window."
(let* ((max-dims (which-key--popup-max-dimensions))
(max-lines (car max-dims))
(max-width (cdr max-dims))
- (prefix-keys-desc (key-description which-key--current-prefix))
- (full-prefix (which-key--full-prefix prefix-keys-desc))
+ (prefix-desc (key-description prefix-keys))
+ (full-prefix (which-key--full-prefix prefix-desc))
(prefix (when (eq which-key-show-prefix 'left)
(+ 2 (which-key--string-width full-prefix))))
(prefix-top-bottom (member which-key-show-prefix '(bottom top)))
@@ -1829,14 +1973,25 @@ is the width of the live window."
(min-lines (min avl-lines which-key-min-display-lines))
(avl-width (if prefix (- max-width prefix) max-width))
(vertical (and (eq which-key-popup-type 'side-window)
- (member which-key-side-window-location '(left
right)))))
- (which-key--create-pages-1 keys avl-lines avl-width min-lines vertical)))
-
-(defun which-key--lighter-status (page-n)
+ (member which-key-side-window-location '(left right))))
+ result)
+ (setq result
+ (which-key--create-pages-1
+ keys avl-lines avl-width min-lines vertical))
+ (when (and result
+ (> (which-key--pages-num-pages result) 0))
+ (setf (which-key--pages-prefix result) prefix-keys)
+ (setf (which-key--pages-prefix-title result)
+ (or prefix-title
+ (which-key--maybe-get-prefix-title
+ (key-description prefix-keys))))
+ result)))
+
+(defun which-key--lighter-status ()
"Possibly show number of keys and total in the mode line."
(when which-key-show-remaining-keys
- (let ((n-shown (nth page-n (plist-get which-key--pages-plist :keys/page)))
- (n-tot (plist-get which-key--pages-plist :tot-keys)))
+ (let ((n-shown (car (which-key--pages-keys/page which-key--pages-obj)))
+ (n-tot (which-key--pages-total-keys which-key--pages-obj)))
(setcar (cdr (assq 'which-key-mode minor-mode-alist))
(format " WK: %s/%s keys" n-shown n-tot)))))
@@ -1857,12 +2012,9 @@ is the width of the live window."
(paging-key-bound (eq 'which-key-C-h-dispatch
(key-binding (kbd paging-key))))
(key (if paging-key-bound which-key-paging-key "C-h")))
- (when (and which-key-use-C-h-commands
- (or which-key--using-show-operator-keymap
- (not (and which-key-allow-evil-operators
- (bound-and-true-p evil-this-operator)))))
- (propertize (format "[%s paging/help]" key)
- 'face 'which-key-note-face))))
+ (when which-key-use-C-h-commands
+ (which-key--propertize (format "[%s paging/help]" key)
+ 'face 'which-key-note-face))))
(eval-and-compile
(if (fboundp 'universal-argument--description)
@@ -1892,16 +2044,16 @@ including prefix arguments."
(which-key--universal-argument--description)
(when prefix-arg " ")
prefix-keys))
- (dash (if (and which-key--current-prefix
+ (dash (if (and (not (string= prefix-keys ""))
(null left)) "-" "")))
(if (or (eq which-key-show-prefix 'echo) dont-prop-keys)
(concat str dash)
(concat (which-key--propertize-key str)
- (propertize dash 'face 'which-key-key-face)))))
+ (which-key--propertize dash 'face 'which-key-key-face)))))
(defun which-key--get-popup-map ()
"Generate transient-map for use in the top level binding display."
- (unless which-key--current-prefix
+ (unless which-key--automatic-display
(let ((map (make-sparse-keymap)))
(define-key map (kbd which-key-paging-key) #'which-key-C-h-dispatch)
(when which-key-use-C-h-commands
@@ -1909,29 +2061,28 @@ including prefix arguments."
(define-key map (kbd "C-h") #'which-key-C-h-dispatch))
map)))
-(defun which-key--process-page (page-n pages-plist)
+(defun which-key--process-page (pages-obj)
"Add information to the basic list of key bindings, including
if applicable the current prefix, the name of the current prefix,
and a page count."
- (let* ((page (nth page-n (plist-get pages-plist :pages)))
- (height (plist-get pages-plist :page-height))
- (n-pages (plist-get pages-plist :n-pages))
- (prefix-keys (key-description which-key--current-prefix))
- (full-prefix (which-key--full-prefix prefix-keys))
- (nxt-pg-hint (which-key--next-page-hint prefix-keys))
+ (let* ((page (car (which-key--pages-pages pages-obj)))
+ (height (which-key--pages-height pages-obj))
+ (n-pages (which-key--pages-num-pages pages-obj))
+ (page-n (car (which-key--pages-page-nums pages-obj)))
+ (prefix-desc (key-description (which-key--pages-prefix pages-obj)))
+ (prefix-title (which-key--pages-prefix-title pages-obj))
+ (full-prefix (which-key--full-prefix prefix-desc))
+ (nxt-pg-hint (which-key--next-page-hint prefix-desc))
;; not used in left case
(status-line
- (concat (propertize (which-key--maybe-get-prefix-title
- (which-key--current-key-string))
- 'face 'which-key-note-face)
+ (concat (which-key--propertize prefix-title 'face
'which-key-note-face)
(when (< 1 n-pages)
- (propertize (format " (%s of %s)"
- (1+ page-n) n-pages)
- 'face 'which-key-note-face)))))
+ (which-key--propertize (format " (%s of %s)" page-n
n-pages)
+ 'face 'which-key-note-face)))))
(pcase which-key-show-prefix
(`left
- (let* ((page-cnt (propertize (format "%s/%s" (1+ page-n) n-pages)
- 'face 'which-key-separator-face))
+ (let* ((page-cnt (which-key--propertize (format "%s/%s" page-n n-pages)
+ 'face
'which-key-separator-face))
(first-col-width (+ 2 (max (which-key--string-width full-prefix)
(which-key--string-width page-cnt))))
(prefix (format (concat "%-" (int-to-string first-col-width) "s")
@@ -1969,7 +2120,7 @@ and a page count."
(cons page
(lambda ()
(which-key--echo
- (concat full-prefix (when prefix-keys " ")
+ (concat full-prefix (when prefix-desc " ")
status-line (when status-line " ")
nxt-pg-hint)))))
(`mode-line
@@ -1982,23 +2133,22 @@ and a page count."
" " nxt-pg-hint))))))
(_ (cons page nil)))))
-(defun which-key--show-page (n)
- "Show page N, starting from 0."
+(defun which-key--show-page (&optional n)
+ "Show current page. N changes the current page to the Nth page
+relative to the current one."
(which-key--init-buffer) ;; in case it was killed
- (let ((n-pages (plist-get which-key--pages-plist :n-pages))
- (prefix-keys (key-description which-key--current-prefix))
- page-n golden-ratio-mode)
- (if (= 0 n-pages)
+ (let ((prefix-keys (which-key--current-key-string))
+ golden-ratio-mode)
+ (if (null which-key--pages-obj)
(message "%s- which-key can't show keys: There is not \
enough space based on your settings and frame size." prefix-keys)
- (setq page-n (mod n n-pages))
- (setq which-key--current-page-n page-n)
- (when (= n-pages (1+ n)) (setq which-key--on-last-page t))
- (let ((page-echo (which-key--process-page page-n which-key--pages-plist))
- (height (plist-get which-key--pages-plist :page-height))
- (width
- (nth page-n (plist-get which-key--pages-plist :page-widths))))
- (which-key--lighter-status page-n)
+ (when n
+ (setq which-key--pages-obj
+ (which-key--pages-set-current-page which-key--pages-obj n)))
+ (let ((page-echo (which-key--process-page which-key--pages-obj))
+ (height (which-key--pages-height which-key--pages-obj))
+ (width (car (which-key--pages-widths which-key--pages-obj))))
+ (which-key--lighter-status)
(if (eq which-key-popup-type 'minibuffer)
(which-key--echo (car page-echo))
(with-current-buffer which-key--buffer
@@ -2016,29 +2166,29 @@ enough space based on your settings and frame size."
prefix-keys)
;;; Paging functions
;;;###autoload
-(defun which-key-reload-key-sequence (key-seq)
+(defun which-key-reload-key-sequence (&optional key-seq)
"Simulate entering the key sequence KEY-SEQ.
KEY-SEQ should be a list of events as produced by
-`listify-key-sequence'. Any prefix arguments that were used are
-reapplied to the new key sequence."
- (let ((next-event (mapcar (lambda (ev) (cons t ev)) key-seq)))
+`listify-key-sequence'. If nil, KEY-SEQ defaults to
+`which-key--current-key-list'. Any prefix arguments that were
+used are reapplied to the new key sequence."
+ (let* ((key-seq (or key-seq (which-key--current-key-list)))
+ (next-event (mapcar (lambda (ev) (cons t ev)) key-seq)))
(setq prefix-arg current-prefix-arg
unread-command-events next-event)))
(defun which-key-turn-page (delta)
"Show the next page of keys."
- (let ((next-page (if which-key--current-page-n
- (+ which-key--current-page-n delta) 0)))
- (which-key-reload-key-sequence (which-key--current-key-list))
- (if which-key--last-try-2-loc
- (let ((which-key-side-window-location which-key--last-try-2-loc)
- (which-key--multiple-locations t))
- (which-key--show-page next-page))
- (which-key--show-page next-page))
- (which-key--start-paging-timer)))
+ (which-key-reload-key-sequence)
+ (if which-key--last-try-2-loc
+ (let ((which-key-side-window-location which-key--last-try-2-loc)
+ (which-key--multiple-locations t))
+ (which-key--show-page delta))
+ (which-key--show-page delta))
+ (which-key--start-paging-timer))
;;;###autoload
-(defun which-key-show-standard-help ()
+(defun which-key-show-standard-help (&optional _)
"Call the command in `which-key--prefix-help-cmd-backup'.
Usually this is `describe-prefix-bindings'."
(interactive)
@@ -2058,8 +2208,7 @@ Usually this is `describe-prefix-bindings'."
call `which-key-show-standard-help'."
(interactive)
(let ((which-key-inhibit t))
- (if (and which-key--current-page-n
- which-key--on-last-page)
+ (if (which-key--on-last-page)
(which-key-show-standard-help)
(which-key-turn-page 1))))
@@ -2069,13 +2218,11 @@ call `which-key-show-standard-help'."
case do nothing."
(interactive)
(let ((which-key-inhibit t))
- (if (and which-key--current-page-n
- (eq which-key--current-page-n 0))
- (which-key-turn-page 0)
+ (unless (which-key--on-first-page)
(which-key-turn-page -1))))
;;;###autoload
-(defun which-key-show-next-page-cycle ()
+(defun which-key-show-next-page-cycle (&optional _)
"Show the next page of keys, cycling from end to beginning
after last page."
(interactive)
@@ -2083,7 +2230,7 @@ after last page."
(which-key-turn-page 1)))
;;;###autoload
-(defun which-key-show-previous-page-cycle ()
+(defun which-key-show-previous-page-cycle (&optional _)
"Show the previous page of keys, cycling from beginning to end
after first page."
(interactive)
@@ -2091,11 +2238,10 @@ after first page."
(which-key-turn-page -1)))
;;;###autoload
-(defun which-key-show-top-level ()
+(defun which-key-show-top-level (&optional _)
"Show top-level bindings."
(interactive)
- (setq which-key--using-top-level "Top-level bindings")
- (which-key--create-buffer-and-show nil))
+ (which-key--create-buffer-and-show nil nil nil "Top-level bindings"))
;;;###autoload
(defun which-key-show-major-mode ()
@@ -2105,20 +2251,21 @@ This function will also detect evil bindings made using
`evil-define-key' in this map. These bindings will depend on the
current evil state. "
(interactive)
- (setq which-key--using-top-level "Major-mode bindings")
(let ((map-sym (intern (format "%s-map" major-mode))))
(if (and (boundp map-sym) (keymapp (symbol-value map-sym)))
(which-key--create-buffer-and-show
- nil nil (apply-partially #'which-key--map-binding-p (symbol-value
map-sym)))
+ nil nil
+ (apply-partially #'which-key--map-binding-p (symbol-value map-sym))
+ "Major-mode bindings")
(message "which-key: No map named %s" map-sym))))
;;;###autoload
-(defun which-key-undo-key ()
+(defun which-key-undo-key (&optional _)
"Undo last keypress and force which-key update."
(interactive)
(let* ((key-lst (butlast (which-key--current-key-list)))
(which-key-inhibit t))
- (cond ((stringp which-key--current-show-keymap-name)
+ (cond (which-key--prior-show-keymap-args
(if (keymapp (cdr (car-safe which-key--prior-show-keymap-args)))
(let ((args (pop which-key--prior-show-keymap-args)))
(which-key--show-keymap (car args) (cdr args)))
@@ -2126,16 +2273,33 @@ current evil state. "
(key-lst
(which-key-reload-key-sequence key-lst)
(which-key--create-buffer-and-show (apply #'vector key-lst)))
- (t (which-key-show-top-level)))))
+ (t (setq which-key--automatic-display nil)
+ (which-key-show-top-level)))))
(defalias 'which-key-undo 'which-key-undo-key)
-(defun which-key-abort ()
+(defun which-key-abort (&optional _)
"Abort key sequence."
(interactive)
(let ((which-key-inhibit t))
(which-key--hide-popup-ignore-command)
(keyboard-quit)))
+(defun which-key-digit-argument (key)
+ "Version of `digit-argument' for use in `which-key-C-h-map'."
+ (interactive)
+ (let ((last-command-event (string-to-char key)))
+ (digit-argument key))
+ (let ((current-prefix-arg prefix-arg))
+ (which-key-reload-key-sequence)))
+
+(defun which-key-toggle-docstrings (&optional _)
+ "Toggle the display of docstrings."
+ (interactive)
+ (unless (eq which-key-show-docstrings 'docstring-only)
+ (setq which-key-show-docstrings (null which-key-show-docstrings)))
+ (which-key-reload-key-sequence)
+ (which-key--create-buffer-and-show (which-key--current-prefix)))
+
;;;###autoload
(defun which-key-C-h-dispatch ()
"Dispatch C-h commands by looking up key in
@@ -2144,16 +2308,16 @@ prefix) if `which-key-use-C-h-commands' is non nil."
(interactive)
(if (not (which-key--popup-showing-p))
(which-key-show-standard-help)
- (let* ((prefix-keys (key-description which-key--current-prefix))
+ (let* ((prefix-keys (which-key--current-key-string))
(full-prefix (which-key--full-prefix prefix-keys current-prefix-arg
t))
(prompt (concat (when (string-equal prefix-keys "")
- (propertize
+ (which-key--propertize
(concat " "
- (or which-key--current-show-keymap-name
- "Top-level bindings"))
+ (which-key--pages-prefix-title
+ which-key--pages-obj))
'face 'which-key-note-face))
full-prefix
- (propertize
+ (which-key--propertize
(substitute-command-keys
(concat
" \\<which-key-C-h-map>"
@@ -2163,15 +2327,19 @@ prefix) if `which-key-use-C-h-commands' is non nil."
which-key-separator "previous-page,"
" \\[which-key-undo-key]"
which-key-separator "undo-key,"
+ " \\[which-key-toggle-docstrings]"
+ which-key-separator "toggle-docstrings,"
" \\[which-key-show-standard-help]"
which-key-separator "help,"
" \\[which-key-abort]"
- which-key-separator "abort"))
+ which-key-separator "abort"
+ " 1..9"
+ which-key-separator "digit-arg"))
'face 'which-key-note-face)))
(key (string (read-key prompt)))
(cmd (lookup-key which-key-C-h-map key))
(which-key-inhibit t))
- (if cmd (funcall cmd) (which-key-turn-page 0)))))
+ (if cmd (funcall cmd key) (which-key-turn-page 0)))))
;;; Update
@@ -2182,44 +2350,64 @@ prefix) if `which-key-use-C-h-commands' is non nil."
(when (string-match-p regexp string)
(throw 'match t)))))
-(defun which-key--try-2-side-windows (keys page-n loc1 loc2 &rest _ignore)
- "Try to show KEYS (PAGE-N) in LOC1 first.
+(defun which-key--try-2-side-windows
+ (bindings prefix-keys prefix-title loc1 loc2 &rest _ignore)
+ "Try to show BINDINGS (PAGE-N) in LOC1 first.
-Only if no keys fit fallback to LOC2."
+Only if no bindings fit fallback to LOC2."
(let (pages1)
(let ((which-key-side-window-location loc1)
(which-key--multiple-locations t))
- (setq pages1 (which-key--create-pages keys)))
- (if (< 0 (plist-get pages1 :n-pages))
+ (setq pages1 (which-key--create-pages
+ bindings prefix-keys prefix-title)))
+ (if pages1
(progn
- (setq which-key--pages-plist pages1)
+ (setq which-key--pages-obj pages1)
(let ((which-key-side-window-location loc1)
(which-key--multiple-locations t))
- (which-key--show-page page-n))
+ (which-key--show-page))
loc1)
(let ((which-key-side-window-location loc2)
(which-key--multiple-locations t))
- (setq which-key--pages-plist
- (which-key--create-pages keys))
- (which-key--show-page page-n)
+ (setq which-key--pages-obj
+ (which-key--create-pages bindings prefix-keys prefix-title))
+ (which-key--show-page)
loc2))))
-(defun which-key-show-keymap ()
+(defun which-key--read-keymap ()
+ "Read keymap symbol from minibuffer."
+ (intern
+ (completing-read "Keymap: " obarray
+ (lambda (m)
+ (and (boundp m)
+ (keymapp (symbol-value m))
+ (not (equal (symbol-value m)
+ (make-sparse-keymap)))))
+ t
+ (let ((sym (symbol-at-point)))
+ (and (boundp sym)
+ (keymapp (symbol-value sym))
+ (symbol-name sym)))
+ 'which-key-keymap-history)))
+
+;;;###autoload
+(defun which-key-show-keymap (keymap)
"Show the top-level bindings in KEYMAP using which-key. KEYMAP
is selected interactively from all available keymaps."
- (interactive)
- (let ((keymap-sym (intern
- (completing-read
- "Keymap: " obarray
- (lambda (m)
- (and (boundp m)
- (keymapp (symbol-value m))
- (not (equal (symbol-value m)
- (make-sparse-keymap)))))
- t nil 'which-key-keymap-history))))
- (which-key--show-keymap (symbol-name keymap-sym)
- (symbol-value keymap-sym))))
+ (interactive (list (which-key--read-keymap)))
+ (which-key--show-keymap (symbol-name keymap)
+ (symbol-value keymap)))
+
+;;;###autoload
+(defun which-key-show-full-keymap (keymap)
+ "Show all bindings in KEYMAP using which-key. KEYMAP is
+selected interactively from all available keymaps."
+ (interactive (list (which-key--read-keymap)))
+ (which-key--show-keymap (symbol-name keymap)
+ (symbol-value keymap)
+ nil t))
+;;;###autoload
(defun which-key-show-minor-mode-keymap ()
"Show the top-level bindings in KEYMAP using which-key. KEYMAP
is selected interactively by mode in `minor-mode-map-alist'."
@@ -2238,32 +2426,28 @@ is selected interactively by mode in
`minor-mode-map-alist'."
(which-key--show-keymap (symbol-name mode-sym)
(cdr (assq mode-sym minor-mode-map-alist)))))
-(defun which-key--show-keymap (keymap-name keymap &optional prior-args)
- (setq which-key--current-prefix nil
- which-key--current-show-keymap-name keymap-name
- which-key--using-show-keymap t)
+(defun which-key--show-keymap (keymap-name keymap &optional prior-args all)
(when prior-args (push prior-args which-key--prior-show-keymap-args))
- (when (keymapp keymap)
- (let ((formatted-keys (which-key--get-formatted-key-bindings
- (which-key--get-keymap-bindings keymap))))
- (cond ((= (length formatted-keys) 0)
- (message "which-key: Keymap empty"))
- ((listp which-key-side-window-location)
+ (let ((bindings (which-key--get-bindings nil keymap nil all)))
+ (if (= (length bindings) 0)
+ (message "which-key: No bindings found in %s" keymap-name)
+ (cond ((listp which-key-side-window-location)
(setq which-key--last-try-2-loc
(apply #'which-key--try-2-side-windows
- formatted-keys 0 which-key-side-window-location)))
- (t (setq which-key--pages-plist
- (which-key--create-pages formatted-keys))
- (which-key--show-page 0)))))
- (let* ((key (key-description (list (read-key))))
- (next-def (lookup-key keymap (kbd key))))
- (cond ((and which-key-use-C-h-commands (string= "C-h" key))
- (which-key-C-h-dispatch))
- ((keymapp next-def)
- (which-key--hide-popup-ignore-command)
- (which-key--show-keymap (concat keymap-name " " key) next-def
- (cons keymap-name keymap)))
- (t (which-key--hide-popup)))))
+ bindings nil keymap-name
+ which-key-side-window-location)))
+ (t (setq which-key--pages-obj
+ (which-key--create-pages bindings nil keymap-name))
+ (which-key--show-page)))
+ (let* ((key (key-description (list (read-key))))
+ (next-def (lookup-key keymap (kbd key))))
+ (cond ((and which-key-use-C-h-commands (string= "C-h" key))
+ (which-key-C-h-dispatch))
+ ((keymapp next-def)
+ (which-key--hide-popup-ignore-command)
+ (which-key--show-keymap (concat keymap-name " " key) next-def
+ (cons keymap-name keymap)))
+ (t (which-key--hide-popup)))))))
(defun which-key--evil-operator-filter (binding)
(let ((def (intern (cdr binding))))
@@ -2277,25 +2461,25 @@ is selected interactively by mode in
`minor-mode-map-alist'."
(make-composed-keymap (list evil-operator-shortcut-map
evil-operator-state-map
evil-motion-state-map))))
- (setq which-key--current-prefix nil
- which-key--current-show-keymap-name "evil operator/motion keys"
- which-key--using-show-operator-keymap t)
(when (keymapp keymap)
- (let ((formatted-keys (which-key--get-formatted-key-bindings
- (which-key--get-keymap-bindings keymap)
- #'which-key--evil-operator-filter)))
+ (let ((formatted-keys
+ (which-key--get-bindings
+ nil keymap #'which-key--evil-operator-filter)))
(cond ((= (length formatted-keys) 0)
(message "which-key: Keymap empty"))
((listp which-key-side-window-location)
(setq which-key--last-try-2-loc
(apply #'which-key--try-2-side-windows
- formatted-keys 0
which-key-side-window-location)))
- (t (setq which-key--pages-plist
- (which-key--create-pages formatted-keys))
- (which-key--show-page 0)))))
+ formatted-keys nil "evil operator/motion keys"
+ which-key-side-window-location)))
+ (t (setq which-key--pages-obj
+ (which-key--create-pages
+ formatted-keys
+ nil "evil operator/motion keys"))
+ (which-key--show-page)))))
(let* ((key (key-description (list (read-key)))))
- (when (string= key "`")
- ;; evil-goto-mark reads the next char manually
+ (when (member key '("f" "F" "t" "T" "`"))
+ ;; these keys trigger commands that read the next char manually
(setq which-key--inhibit-next-operator-popup t))
(cond ((and which-key-use-C-h-commands (string= "C-h" key))
(which-key-C-h-dispatch))
@@ -2306,38 +2490,35 @@ is selected interactively by mode in
`minor-mode-map-alist'."
(which-key--hide-popup)
(setq unread-command-events (listify-key-sequence key))))))))
-(defun which-key--create-buffer-and-show (&optional prefix-keys from-keymap
filter)
+(defun which-key--create-buffer-and-show
+ (&optional prefix-keys from-keymap filter prefix-title)
"Fill `which-key--buffer' with key descriptions and reformat.
Finally, show the buffer."
- (setq which-key--current-prefix prefix-keys
- which-key--last-try-2-loc nil)
(let ((start-time (when which-key--debug (current-time)))
- (formatted-keys (which-key--get-formatted-key-bindings
- (when from-keymap
- (which-key--get-keymap-bindings from-keymap))
- filter))
- (prefix-keys (key-description which-key--current-prefix)))
+ (formatted-keys (which-key--get-bindings
+ prefix-keys from-keymap filter))
+ (prefix-desc (key-description prefix-keys)))
(cond ((= (length formatted-keys) 0)
- (message "%s- which-key: There are no keys to show" prefix-keys))
+ (message "%s- which-key: There are no keys to show" prefix-desc))
((listp which-key-side-window-location)
(setq which-key--last-try-2-loc
(apply #'which-key--try-2-side-windows
- formatted-keys 0 which-key-side-window-location)))
- (t (setq which-key--pages-plist
- (which-key--create-pages formatted-keys))
- (which-key--show-page 0)))
+ formatted-keys prefix-keys prefix-title
+ which-key-side-window-location)))
+ (t (setq which-key--pages-obj
+ (which-key--create-pages
+ formatted-keys prefix-keys prefix-title))
+ (which-key--show-page)))
(when which-key--debug
- (message "On prefix \"%s\" which-key took %.0f ms." prefix-keys
+ (message "On prefix \"%s\" which-key took %.0f ms." prefix-desc
(* 1000 (float-time (time-since start-time)))))))
-(defun which-key--update ()
- "Function run by timer to possibly trigger
-`which-key--create-buffer-and-show'."
- (let ((prefix-keys (this-single-command-keys))
- delay-time)
- (when (and (equal prefix-keys [key-chord])
+(defun which-key--this-command-keys ()
+ "Version of `this-single-command-keys' corrected for key-chords and
god-mode."
+ (let ((this-command-keys (this-single-command-keys)))
+ (when (and (equal this-command-keys [key-chord])
(bound-and-true-p key-chord-mode))
- (setq prefix-keys
+ (setq this-command-keys
(condition-case nil
(let ((rkeys (recent-keys)))
(vector 'key-chord
@@ -2354,8 +2535,15 @@ Finally, show the buffer."
(when (and which-key--god-mode-support-enabled
(bound-and-true-p god-local-mode)
(eq this-command 'god-mode-self-insert))
- (setq prefix-keys (when which-key--god-mode-key-string
+ (setq this-command-keys (when which-key--god-mode-key-string
(kbd which-key--god-mode-key-string))))
+ this-command-keys))
+
+(defun which-key--update ()
+ "Function run by timer to possibly trigger
+`which-key--create-buffer-and-show'."
+ (let ((prefix-keys (which-key--this-command-keys))
+ delay-time)
(cond ((and (> (length prefix-keys) 0)
(or (keymapp (key-binding prefix-keys))
;; Some keymaps are stored here like iso-transl-ctl-x-8-map
@@ -2380,7 +2568,7 @@ Finally, show the buffer."
(bound-and-true-p god-local-mode)
(eq this-command 'god-mode-self-insert))
(null this-command)))
- (when (and (not (equal prefix-keys which-key--current-prefix))
+ (when (and (not (equal prefix-keys (which-key--current-prefix)))
(or (null which-key-delay-functions)
(null (setq delay-time
(run-hook-with-args-until-success
@@ -2388,6 +2576,7 @@ Finally, show the buffer."
(key-description prefix-keys)
(length prefix-keys))))
(sit-for delay-time)))
+ (setq which-key--automatic-display t)
(which-key--create-buffer-and-show prefix-keys)
(when (and which-key-idle-secondary-delay
(not which-key--secondary-timer-active))
@@ -2402,12 +2591,9 @@ Finally, show the buffer."
((and which-key-show-operator-state-maps
(bound-and-true-p evil-state)
(eq evil-state 'operator)
- (not which-key--using-show-operator-keymap))
+ (not (which-key--popup-showing-p)))
(which-key--show-evil-operator-keymap))
- ((and which-key--current-page-n
- (not which-key--using-top-level)
- (not which-key--using-show-operator-keymap)
- (not which-key--using-show-keymap))
+ (which-key--automatic-display
(which-key--hide-popup)))))
;;; Timers
@@ -2436,10 +2622,8 @@ Finally, show the buffer."
(when (or (not (member real-last-command
which-key--paging-functions))
(and (< 0 (length (this-single-command-keys)))
- (not (equal which-key--current-prefix
- (this-single-command-keys)))))
- (setq which-key--current-page-n nil
- which-key--on-last-page nil)
+ (not (equal (which-key--current-prefix)
+ (which-key--this-command-keys)))))
(cancel-timer which-key--paging-timer)
(which-key--start-timer))))))
- [elpa] master ab60391 21/39: Use cl-struct to hold which-key pages, (continued)
- [elpa] master ab60391 21/39: Use cl-struct to hold which-key pages, Justin Burkett, 2018/06/21
- [elpa] master 0b2739a 27/39: Fix display of meta bindings in which-key-show-keymap, Justin Burkett, 2018/06/21
- [elpa] master f77d421 19/39: Consolidate key binding collection into which-key--get-bindings, Justin Burkett, 2018/06/21
- [elpa] master 4370658 29/39: Factor out which-key--this-command-keys function, Justin Burkett, 2018/06/21
- [elpa] master a4095e8 37/39: Fix handling of duplicate (evil) bindings in show keymap, Justin Burkett, 2018/06/21
- [elpa] master f251541 18/39: Refactor show keymap functions, Justin Burkett, 2018/06/21
- [elpa] master 8a878de 32/39: Version 3.2.0, Justin Burkett, 2018/06/21
- [elpa] master 2c91540 35/39: Add support for evil's auxiliary maps in show-keymap functions, Justin Burkett, 2018/06/21
- [elpa] master bc97659 31/39: Fix and improve defcustoms, Justin Burkett, 2018/06/21
- [elpa] master ed7aa66 23/39: Remove a bunch of global variables, Justin Burkett, 2018/06/21
- [elpa] master fb09d75 39/39: Merge commit 'ff79dfff66f880885c5893dd6fd05dc51173a476',
Justin Burkett <=