Fix #1310: use internal macro for leader binds
Creates a separate doom--define-leader-key macro for internal use (in map!). define-leader-key! will continue to exist as a convenience macro for users who want a general.el interface to defining leader keys. Possibly relevant to: #1309
This commit is contained in:
parent
182ab918b6
commit
1fab389d9e
1 changed files with 44 additions and 30 deletions
|
@ -80,10 +80,9 @@ If any hook returns non-nil, all hooks after it are ignored.")
|
||||||
(defalias 'define-key! #'general-def)
|
(defalias 'define-key! #'general-def)
|
||||||
(defalias 'unmap! #'general-unbind)
|
(defalias 'unmap! #'general-unbind)
|
||||||
|
|
||||||
;; A `define-leader-key' defined with `general-create-definer' consumes 20-30%
|
;; `map!' uses this instead of `define-leader-key!' because it consumes 20-30%
|
||||||
;; of Doom's startup time, we reimplement it ourselves.
|
;; more startup time, so we reimplement it ourselves.
|
||||||
(defmacro define-leader-key! (&rest keys)
|
(defmacro doom--define-leader-key (&rest keys)
|
||||||
"Define a leader key on `doom-leader-key'."
|
|
||||||
(let (prefix forms wkforms)
|
(let (prefix forms wkforms)
|
||||||
(while keys
|
(while keys
|
||||||
(let ((key (pop keys))
|
(let ((key (pop keys))
|
||||||
|
@ -91,38 +90,53 @@ If any hook returns non-nil, all hooks after it are ignored.")
|
||||||
(if (keywordp key)
|
(if (keywordp key)
|
||||||
(when (memq key '(:prefix :infix))
|
(when (memq key '(:prefix :infix))
|
||||||
(setq prefix def))
|
(setq prefix def))
|
||||||
(let ((unquoted-def (cdr-safe (doom-unquote def))))
|
(when prefix
|
||||||
(when prefix
|
(setq key `(general--concat t ,prefix ,key)))
|
||||||
(setq key `(general--concat t ,prefix ,key)))
|
(let* ((udef (doom-unquote def))
|
||||||
(when-let* ((desc (plist-get unquoted-def :which-key)))
|
(bdef (if (general--extended-def-p udef)
|
||||||
|
(general--extract-def (general--normalize-extended-def udef))
|
||||||
|
def)))
|
||||||
|
(unless (eq bdef :ignore)
|
||||||
|
(push `(define-key doom-leader-map (general--kbd ,key)
|
||||||
|
,bdef)
|
||||||
|
forms))
|
||||||
|
(when-let* ((desc (plist-get udef :which-key)))
|
||||||
(push `(which-key-add-key-based-replacements
|
(push `(which-key-add-key-based-replacements
|
||||||
(general--concat t doom-leader-key ,key)
|
(general--concat t doom-leader-key ,key)
|
||||||
,desc)
|
,desc)
|
||||||
wkforms))
|
wkforms))))))
|
||||||
(push `(define-key doom-leader-map (general--kbd ,key)
|
|
||||||
,(if (general--extended-def-p unquoted-def)
|
|
||||||
(plist-get unquoted-def :def)
|
|
||||||
def))
|
|
||||||
forms)))))
|
|
||||||
(macroexp-progn
|
(macroexp-progn
|
||||||
(append (nreverse forms)
|
(append (nreverse forms)
|
||||||
(when wkforms
|
(when wkforms
|
||||||
`((eval-after-load 'which-key
|
`((with-eval-after-load 'which-key
|
||||||
(lambda () ,@(nreverse wkforms)))))))))
|
,@(nreverse wkforms))))))))
|
||||||
|
|
||||||
(general-create-definer define-localleader-key!
|
(defmacro define-leader-key! (&rest args)
|
||||||
:major-modes t
|
"Define <leader> keys.
|
||||||
:prefix doom-localleader-alt-key)
|
|
||||||
|
|
||||||
;; :non-normal-prefix doesn't apply to non-evil sessions (only evil's emacs
|
Uses `general-define-key' under the hood, but does not support :states,
|
||||||
;; state), so we must redefine `define-localleader-key!' to behave differently
|
:wk-full-keys or :keymaps."
|
||||||
;; where evil is present.
|
`(general-define-key
|
||||||
(after! evil
|
:states nil
|
||||||
(general-create-definer define-localleader-key!
|
:wk-full-keys nil
|
||||||
:states '(normal visual motion emacs)
|
:keymaps 'doom-leader-map
|
||||||
:major-modes t
|
,@args))
|
||||||
:prefix doom-localleader-key
|
|
||||||
:non-normal-prefix doom-localleader-alt-key))
|
(defmacro define-localleader-key! (&rest args)
|
||||||
|
(if (featurep 'evil)
|
||||||
|
;; :non-normal-prefix doesn't apply to non-evil sessions (only evil's
|
||||||
|
;; emacs state), so we must redefine `define-localleader-key!' to behave
|
||||||
|
;; differently where evil is present.
|
||||||
|
`(general-define-key
|
||||||
|
:states '(normal visual motion emacs)
|
||||||
|
:major-modes t
|
||||||
|
:prefix doom-localleader-key
|
||||||
|
:non-normal-prefix doom-localleader-alt-key
|
||||||
|
,@args)
|
||||||
|
`(general-define-key
|
||||||
|
:major-modes t
|
||||||
|
:prefix doom-localleader-alt-key
|
||||||
|
,@args)))
|
||||||
|
|
||||||
;; We use a prefix commands instead of general's :prefix/:non-normal-prefix
|
;; We use a prefix commands instead of general's :prefix/:non-normal-prefix
|
||||||
;; properties because general is incredibly slow binding keys en mass with them
|
;; properties because general is incredibly slow binding keys en mass with them
|
||||||
|
@ -236,7 +250,7 @@ For example, :nvi will map to (list 'normal 'visual 'insert). See
|
||||||
(pcase key
|
(pcase key
|
||||||
(:leader
|
(:leader
|
||||||
(doom--map-commit)
|
(doom--map-commit)
|
||||||
(setq doom--map-fn 'define-leader-key!))
|
(setq doom--map-fn 'doom--define-leader-key))
|
||||||
(:localleader
|
(:localleader
|
||||||
(doom--map-commit)
|
(doom--map-commit)
|
||||||
(setq doom--map-fn 'define-localleader-key!))
|
(setq doom--map-fn 'define-localleader-key!))
|
||||||
|
@ -310,7 +324,7 @@ For example, :nvi will map to (list 'normal 'visual 'insert). See
|
||||||
(cond ((and (listp def)
|
(cond ((and (listp def)
|
||||||
(keywordp (car-safe (setq unquoted (doom-unquote def)))))
|
(keywordp (car-safe (setq unquoted (doom-unquote def)))))
|
||||||
(setq def (list 'quote (plist-put unquoted :which-key desc))))
|
(setq def (list 'quote (plist-put unquoted :which-key desc))))
|
||||||
((setq def (cons 'list
|
((setq def (list 'quote
|
||||||
(if (and (equal key "")
|
(if (and (equal key "")
|
||||||
(null def))
|
(null def))
|
||||||
`(:ignore t :which-key ,desc)
|
`(:ignore t :which-key ,desc)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue