From 9d612e0666d185dc1bc81b14ec82d94bf882ab95 Mon Sep 17 00:00:00 2001 From: John Grey Date: Wed, 28 Apr 2021 10:08:49 +0100 Subject: [PATCH 1/3] implement which-key keymap based replacements --- general.el | 100 ++++++++++++++++++++--------------------------------- 1 file changed, 37 insertions(+), 63 deletions(-) diff --git a/general.el b/general.el index b617e65..1702fbe 100644 --- a/general.el +++ b/general.el @@ -647,34 +647,6 @@ globally (they have special interaction with other global keywords). :keymap, on the other hand, doesn't make sense at all globally.") ;; ** Normal Extended Definition Functions -;; *** Which Key Integration -(defvar which-key-replacement-alist) -(defun general--add-which-key-replacement (mode replacement) - (let* ((mode-match (assq mode which-key-replacement-alist)) - (mode-alist (cdr mode-match))) - (cond (mode - (push replacement mode-alist) - (if mode-match - (setcdr mode-match mode-alist) - (push (cons mode mode-alist) - which-key-replacement-alist))) - (t - (push replacement which-key-replacement-alist))))) - -(defvar which-key--prefix-title-alist) -(defun general--add-which-key-title-prefix (mode keys title-prefix) - (let* ((mode-match (assq mode which-key--prefix-title-alist)) - (title-mode-alist (cdr mode-match)) - (title-cons (cons keys title-prefix))) - (cond (mode - (push title-cons title-mode-alist) - (if mode-match - (setcdr mode-match - title-mode-alist) - (push (cons mode title-mode-alist) - which-key--prefix-title-alist))) - (t - (push title-cons which-key--prefix-title-alist))))) (defun general--remove-map (keymap) "Remove \"-map\" from the symbol KEYMAP." ; @@ -682,29 +654,17 @@ the other hand, doesn't make sense at all globally.") ;; TODO better documentation (defun general-extended-def-:which-key (_state keymap key edef kargs) - "Add a which-key description for KEY. + " An alternative which-key implementation for General, using which-key's +which-key-add-keymap-based-replacements. + +Add a which-key description for KEY. If :major-modes is specified in EDEF, add the description for the corresponding major mode. KEY should not be in the kbd format (kbd should have already been run on it)." (general-with-eval-after-load 'which-key (let* ((wk (general--getf2 edef :which-key :wk)) - (major-modes (general--getf edef kargs :major-modes)) (keymaps (plist-get kargs :keymaps)) - ;; index of keymap in :keymaps - (keymap-index (cl-dotimes (ind (length keymaps)) - (when (eq (nth ind keymaps) keymap) - (cl-return ind)))) - (mode (let ((mode (if (and major-modes (listp major-modes)) - (nth keymap-index major-modes) - major-modes))) - (if (eq mode t) - (general--remove-map keymap) - mode))) (key (key-description key)) - (key-regexp (concat (when (general--getf edef kargs :wk-full-keys) - "\\`") - (regexp-quote key) - "\\'")) (prefix (plist-get kargs :prefix)) (binding (or (when (and (plist-get edef :def) (not (plist-get edef :keymp))) @@ -712,25 +672,39 @@ run on it)." (when (and prefix (string= key prefix)) (plist-get kargs :prefix-command)))) - (replacement (cond ((stringp wk) - (cons nil wk)) - (t - wk))) - (match/replacement - (cons - (cons (when (general--getf edef kargs :wk-match-keys) - key-regexp) - (when (and (general--getf edef kargs :wk-match-binding) - binding - (symbolp binding)) - (regexp-quote (symbol-name binding)))) - replacement))) - (general--add-which-key-replacement mode match/replacement) - (when (and (consp replacement) - ;; lambda - (not (functionp replacement))) - (general--add-which-key-title-prefix - mode key (cdr replacement)))))) + (replacement (cond ((consp wk) (cdr wk)) + (t wk))) + ;; check the map exists, if not, try adding -map to it. (ie: global -> global-map) + (real-keymap (if (boundp keymap) (symbol-value keymap) (symbol-value (intern (format "%s-map" keymap))))) + ) + (condition-case-unless-debug err + (general--add-which-key-keymap-replacement _state real-keymap key `(,replacement . ,binding)) + (error (message "Binding Update Error for: (%s : %s : %s : %s) : %s" keymap key binding replacement err)) + ) + ) + ) + ) + +(defun general--add-which-key-keymap-replacement (state keymap key replacement) + " Alt implementation of which-key-add-keymap-based-replacements +that uses evil-define-key*, allowing state bindings +" + (let* ((string (if (stringp replacement) + replacement + (car-safe replacement))) + (command (cdr-safe replacement)) + (pseudo-key (which-key--pseudo-key (kbd key))) + (bind `(which-key ,(cons string command))) + ) + ;;(message "adding replacement: %s : %s" pseudo-key bind) + ;; NOTE: not evil-define-key, the star is needed to correctly bind to the aux map + (if state + (evil-define-key* state keymap pseudo-key bind) + (define-key keymap pseudo-key bind) + ) + ) + ) + (defalias 'general-extended-def-:wk #'general-extended-def-:which-key) From 45586bb0e62715a6bb74974d4801ed500da1421e Mon Sep 17 00:00:00 2001 From: John Grey Date: Thu, 29 Apr 2021 06:44:28 +0100 Subject: [PATCH 2/3] fixup! implement which-key keymap based replacements --- general.el | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/general.el b/general.el index 1702fbe..69dfbdf 100644 --- a/general.el +++ b/general.el @@ -678,33 +678,34 @@ run on it)." (real-keymap (if (boundp keymap) (symbol-value keymap) (symbol-value (intern (format "%s-map" keymap))))) ) (condition-case-unless-debug err - (general--add-which-key-keymap-replacement _state real-keymap key `(,replacement . ,binding)) + (general-which-key-add-keymap-based-evil-replacement _state real-keymap key `(,replacement . ,binding)) (error (message "Binding Update Error for: (%s : %s : %s : %s) : %s" keymap key binding replacement err)) ) ) ) ) -(defun general--add-which-key-keymap-replacement (state keymap key replacement) +(defun general-which-key-add-keymap-based-evil-replacement (state keymap key replacement &rest more) " Alt implementation of which-key-add-keymap-based-replacements -that uses evil-define-key*, allowing state bindings +that uses evil-define-key, allowing state bindings + +Mainly this is useful for a keymap-based-replacement implementation +of general-extended-def-:which-key " + (while key (let* ((string (if (stringp replacement) replacement (car-safe replacement))) (command (cdr-safe replacement)) (pseudo-key (which-key--pseudo-key (kbd key))) - (bind `(which-key ,(cons string command))) - ) - ;;(message "adding replacement: %s : %s" pseudo-key bind) - ;; NOTE: not evil-define-key, the star is needed to correctly bind to the aux map + (bind `(which-key ,string ,command)) + ) (if state (evil-define-key* state keymap pseudo-key bind) (define-key keymap pseudo-key bind) - ) - ) - ) - + )) + (setq key (pop more) + replacement (pop more)))) (defalias 'general-extended-def-:wk #'general-extended-def-:which-key) From 6d3ae072b63e847dd9e70520d2bd3b0bd75a2fb4 Mon Sep 17 00:00:00 2001 From: John Grey Date: Fri, 30 Apr 2021 16:50:31 +0100 Subject: [PATCH 3/3] remove need for eval-after-load 'which-key dramatically speeds up boot time --- general.el | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/general.el b/general.el index 69dfbdf..b8ea19b 100644 --- a/general.el +++ b/general.el @@ -661,7 +661,6 @@ Add a which-key description for KEY. If :major-modes is specified in EDEF, add the description for the corresponding major mode. KEY should not be in the kbd format (kbd should have already been run on it)." - (general-with-eval-after-load 'which-key (let* ((wk (general--getf2 edef :which-key :wk)) (keymaps (plist-get kargs :keymaps)) (key (key-description key)) @@ -679,12 +678,19 @@ run on it)." ) (condition-case-unless-debug err (general-which-key-add-keymap-based-evil-replacement _state real-keymap key `(,replacement . ,binding)) - (error (message "Binding Update Error for: (%s : %s : %s : %s) : %s" keymap key binding replacement err)) - ) - ) + (error (message "Binding Update Error for: (%s : %s : %s : %s) : %s" keymap key binding replacement err)) + ) ) ) +(defun general-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))) + (vconcat (or prefix (butlast seq)) [which-key] (last seq)))) + + + (defun general-which-key-add-keymap-based-evil-replacement (state keymap key replacement &rest more) " Alt implementation of which-key-add-keymap-based-replacements that uses evil-define-key, allowing state bindings @@ -697,7 +703,7 @@ of general-extended-def-:which-key replacement (car-safe replacement))) (command (cdr-safe replacement)) - (pseudo-key (which-key--pseudo-key (kbd key))) + (pseudo-key (general-which-key--pseudo-key (kbd key))) (bind `(which-key ,string ,command)) ) (if state