feat(lib): add :depth support to add-hook!

The semantics of add-hook's APPEND argument changed in 27.1: it was
replaced with DEPTH, which controls its exact order of the hook (and is
respected every time a function is added to a hook, throughout its
lifetime).

Includes a general refactor for add-hook! too.
This commit is contained in:
Henrik Lissner 2021-10-08 23:21:04 +02:00
parent 8e285177d9
commit 91770b66e5

View file

@ -522,7 +522,7 @@ This macro accepts, in order:
thereof, a list of `defun's, or body forms (implicitly wrapped in a thereof, a list of `defun's, or body forms (implicitly wrapped in a
lambda). lambda).
\(fn HOOKS [:append :local] FUNCTIONS)" \(fn HOOKS [:append :local [:depth N]] FUNCTIONS-OR-FORMS...)"
(declare (indent (lambda (indent-point state) (declare (indent (lambda (indent-point state)
(goto-char indent-point) (goto-char indent-point)
(when (looking-at-p "\\s-*(") (when (looking-at-p "\\s-*(")
@ -531,43 +531,31 @@ This macro accepts, in order:
(let* ((hook-forms (doom--resolve-hook-forms hooks)) (let* ((hook-forms (doom--resolve-hook-forms hooks))
(func-forms ()) (func-forms ())
(defn-forms ()) (defn-forms ())
append-p append-p local-p remove-p depth)
local-p
remove-p
depth
forms)
(while (keywordp (car rest)) (while (keywordp (car rest))
(pcase (pop rest) (pcase (pop rest)
(:append (setq append-p t)) (:append (setq append-p t))
(:depth (setq depth (pop rest))) (:depth (setq depth (pop rest)))
(:local (setq local-p t)) (:local (setq local-p t))
(:remove (setq remove-p t)))) (:remove (setq remove-p t))))
(let ((first (car-safe (car rest)))) (while rest
(cond ((null first) (let* ((next (pop rest))
(setq func-forms rest)) (first (car-safe next)))
(push (cond ((memq first '(quote function nil))
((eq first 'defun) next)
(setq func-forms (mapcar #'cadr rest) ((memq first '(defun cl-defun))
defn-forms rest)) (push next defn-forms)
(list 'function (cadr next)))
((memq first '(quote function)) ((prog1 `(lambda (&rest _) ,@(cons next rest))
(setq func-forms (setq rest nil))))
(if (cdr rest) func-forms)))
(mapcar #'doom-unquote rest) `(progn
(doom-enlist (doom-unquote (car rest)))))) ,@defn-forms
(dolist (hook (nreverse ',hook-forms))
((setq func-forms (list `(lambda (&rest _) ,@rest))))) (dolist (func (list ,@func-forms))
(dolist (hook hook-forms) ,(if remove-p
(dolist (func func-forms) `(remove-hook hook func ,local-p)
(push (if remove-p `(add-hook hook func ,(or depth append-p) ,local-p)))))))
`(remove-hook ',hook #',func ,local-p)
`(add-hook ',hook #',func ,(or depth append-p) ,local-p))
forms)))
(macroexp-progn
(append defn-forms
(if append-p
(nreverse forms)
forms))))))
(defmacro remove-hook! (hooks &rest rest) (defmacro remove-hook! (hooks &rest rest)
"A convenience macro for removing N functions from M hooks. "A convenience macro for removing N functions from M hooks.