Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 45 additions & 64 deletions general.el
Original file line number Diff line number Diff line change
Expand Up @@ -647,90 +647,71 @@ 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." ;
(intern (replace-regexp-in-string "-map$" "" (symbol-name keymap))))

;; 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)))
(plist-get edef :def))
(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)))))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(real-keymap (if (boundp keymap) (symbol-value keymap) (symbol-value (intern (format "%s-map" keymap)))))
(real-keymap (general--get-keymap nil keymap nil t)))

Have a look at general--get-keymap. I found it while browsing general--define-key-dispatch

)
(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))
)
)
)

(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

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 (general-which-key--pseudo-key (kbd key)))
(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)

Expand Down