diff options
| author | Stefan Monnier <monnier@iro.umontreal.ca> | 2023-07-01 16:05:34 -0400 |
|---|---|---|
| committer | Axel Forsman <axel@axelf.se> | 2023-08-12 10:47:11 +0200 |
| commit | 3d7faadf30016a8c20699a5fb1b5731b8a49dcd2 (patch) | |
| tree | fba9d494396f727f0bb8607253aee7a31768870a /evil-common.el | |
| parent | 5e72cf5b6d57b785ea229236bb5c4638db2c9a05 (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.el | 50 |
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 |
