aboutsummaryrefslogtreecommitdiff
path: root/evil-common.el
diff options
context:
space:
mode:
authorStefan Monnier <monnier@iro.umontreal.ca>2023-07-01 16:05:34 -0400
committerAxel Forsman <axel@axelf.se>2023-08-12 10:47:11 +0200
commit3d7faadf30016a8c20699a5fb1b5731b8a49dcd2 (patch)
treefba9d494396f727f0bb8607253aee7a31768870a /evil-common.el
parent5e72cf5b6d57b785ea229236bb5c4638db2c9a05 (diff)
(evil-with-delay): New macro, extracted from `evil-delay`
Save some kittens by using a macro instead of using `eval`. This also exposes more code to the compiler, so should result in more efficient code and potentially better compiler warnings. * evil-common.el (evil-unquote): Delete unused function. (evil--with-delay): New function, extracted from `evil-delay`. (evil-with-delay): New macro, extracted from `evil-delay`. (evil-delay): Redefine using `evil-with-delay` and declare obsolete. * evil-states.el (evil-visual-activate-hook): * evil-core.el (evil-define-key): * evil-commands.el (evil-execute-in-normal-state): Use `evil-with-delay`.
Diffstat (limited to 'evil-common.el')
-rw-r--r--evil-common.el50
1 files changed, 30 insertions, 20 deletions
diff --git a/evil-common.el b/evil-common.el
index 59938eb..16ab56f 100644
--- a/evil-common.el
+++ b/evil-common.el
@@ -48,30 +48,40 @@
(if (fboundp 'gui-set-selection) 'gui-set-selection 'x-set-selection))
;; macro helper
-(eval-and-compile
- (defun evil-unquote (exp)
- "Return EXP unquoted."
- (while (eq (car-safe exp) 'quote)
- (setq exp (cadr exp)))
- exp))
+(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)
+where:
+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)))
(defun evil-delay (condition form hook &optional append local name)
"Execute FORM when CONDITION becomes true, checking with HOOK.
-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,
+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."
- (if (and (not (booleanp condition)) (eval condition))
- (eval form)
- (let* ((name (or name (format "evil-delay-form-in-%s" hook)))
- (fun (make-symbol name))
- (condition (or condition t)))
- (fset fun `(lambda (&rest args)
- (when ,condition
- (remove-hook ',hook #',fun ',local)
- ,form)))
- (put fun 'permanent-local-hook t)
- (add-hook hook fun append local))))
-(put 'evil-delay 'lisp-indent-function 2)
+ (declare (obsolete evil-with-delay "1.15.0") (indent 2))
+ (eval `(evil-with-delay ,condition (,hook ,append ,local ,name) ,form) t))
;;; List functions