diff options
| author | Axel Forsman <axel@axelf.se> | 2023-08-07 18:35:24 +0200 |
|---|---|---|
| committer | Axel Forsman <axel@axelf.se> | 2023-08-12 10:47:11 +0200 |
| commit | 1b56ffcc102b4c5f8b015e760b5f9cf5932622af (patch) | |
| tree | cc35e9997c92e6335c8949128a3444a37a904a0f | |
| parent | 3d7faadf30016a8c20699a5fb1b5731b8a49dcd2 (diff) | |
Merge evil-with-delay condition and body lambdas
This commit makes evil-with-delay generated code work using a single
lambda that returns the result of condition, running body if non-nil.
This way the byte compiler sees that body is guarded by condition,
which fixes the FIXME.
| -rw-r--r-- | evil-common.el | 33 | ||||
| -rw-r--r-- | evil-core.el | 17 |
2 files changed, 19 insertions, 31 deletions
diff --git a/evil-common.el b/evil-common.el index 16ab56f..9af0863 100644 --- a/evil-common.el +++ b/evil-common.el @@ -47,19 +47,6 @@ (defalias 'evil-set-selection (if (fboundp 'gui-set-selection) 'gui-set-selection 'x-set-selection)) -;; macro helper -(defun evil--with-delay (cond-fun body-fun hook &optional append local name) - (if (and cond-fun (funcall cond-fun)) - (funcall body-fun) - (let* ((name (or name (format "evil-delay-in-%s" hook))) - (fun (make-symbol name))) - (fset fun (lambda (&rest _) - (when (or (null cond-fun) (funcall cond-fun)) - (remove-hook hook fun local) - (funcall body-fun)))) - (put fun 'permanent-local-hook t) - (add-hook hook fun append local)))) - (defmacro evil-with-delay (condition hook &rest body) "Execute BODY when CONDITION becomes true, checking with HOOK. HOOK can be a simple symbol or of the form (HOOK APPEND LOCAL NAME) @@ -68,12 +55,20 @@ NAME specifies the name of the entry added to HOOK. If APPEND is non-nil, the entry is appended to the hook. If LOCAL is non-nil, the buffer-local value of HOOK is modified." (declare (debug (form sexp body)) (indent 2)) - (unless (consp hook) (setq hook (list hook))) - ;; FIXME: Now the compiler doesn't know that `body' is only run if `condition' - ;; is true, so we get spurious warnings! :-( - `(evil--with-delay ,(when condition `(lambda () ,condition)) - (lambda () ,@body) - ,@(mapcar #'macroexp-quote hook))) + (cl-destructuring-bind (hook-sym &optional append local name) + (mapcar #'macroexp-quote (if (consp hook) hook (list hook))) + (macroexp-let2* nil + ((fun-name `',(make-symbol + (or name (format "evil-delay-in-%s" hook-sym)))) + (fun `(lambda (&rest _) + (when ,(or condition t) + (remove-hook ,hook-sym ,fun-name ,local) + ,@body + t)))) + `(unless ,(and condition `(funcall ,fun)) + (progn (fset ,fun-name ,fun) + ,@(when local `((put ,fun-name 'permanent-local-hook t))) + (add-hook ,hook-sym ,fun-name ,append ,local)))))) (defun evil-delay (condition form hook &optional append local name) "Execute FORM when CONDITION becomes true, checking with HOOK. diff --git a/evil-core.el b/evil-core.el index 1b0dcc7..2f9a575 100644 --- a/evil-core.el +++ b/evil-core.el @@ -980,18 +980,11 @@ mode, in which case `evil-define-minor-mode-key' is used." ;; BEWARE: Can't work for lexically scoped vars `(and (boundp ',keymap) (keymapp ,keymap)) `(keymapp ,keymap)) - (after-load-functions t nil - ,(format "evil-define-key-in-%s" - (if (symbolp keymap) keymap - 'keymap))) - ;; Sadly, the compiler doesn't understand `evil-with-delay's - ;; code well enough to figure out that the keymap var is - ;; necessarily bound since we just tested `boundp'. - ,(when (symbolp keymap) `(defvar ,keymap)) - (condition-case-unless-debug err - (evil-define-key* ,state ,keymap ,key ,def ,@bindings) - (error (message "error in evil-define-key: %s" - (error-message-string err)))))))) + (after-load-functions + t nil ,(format "evil-define-key-in-%s" + (if (symbolp keymap) keymap 'keymap))) + (with-demoted-errors "Error in evil-define-key: %S" + (evil-define-key* ,state ,keymap ,key ,def ,@bindings)))))) (defalias 'evil-declare-key #'evil-define-key) (defun evil-define-key* (state keymap key def &rest bindings) |
