A hook facility for Common Lisp.
This package holds an enhanced implementation of hooks (extension points). It works similarly to Emacs hooks with crucial improvements:
- If the compiler allows it (such as SBCL), type-checking is performed at compile-time and at run-time when adding handlers to a hook.
- On failure, multiple restarts are offered, such as disabling the offending handler or simply continuing to the next function.
- The hook handler execution order and combination can be customized.
- Anonymous functions (lambdas) can be added to hooks as
handler
objects.When inspecting hooks, readable names are thus exposed instead of lambda blackboxes.
Handlers are compared through their names (through the mandatory
name
slot). A hook can not contain multiple handlers with the same name. - A special provision is taken for “setters”, handlers that are meant to set a
given place to a given values.
Such
handler
objects can be compared and identified uniquely.
(let ((hook (make-instance 'nhooks:hook-number->number
:handlers (list #'add-1 #'multiply-by-2)
:combination #'nhooks:combine-composed-hook)))
(nhooks:run-hook hook 17))
;; => 35
See the package documentation for a usage guide and more examples.
- [ ] Handlers should subclass generic functions and thus be funcallable.
- [ ] Setters could subclass handlers.
This library was originally contributed by the maintainers of the Nyxt web browser to Serapeum. Then it got overhauled and backward compatibility broke, so a dedicated library was published instead. The Serapeum contrib is considered deprecated.
- Remove
NASDF
as a dependency.
- Major refactoring (turn all the
defmethod
-defined functions into generics). define-hook-type
: New optionaldocumentation
argument.
- Hooks and handlers are now “funcallable”, for instance with
(funcall HOOK ARGS)
. find-handler
: New optionalinclude-disabled
argument.- Fix bug when appending handler.
- Add
wait-on
helper.
- Add package documentation.
- Fix bug on CLISP.
- Add
on
andonce-on
helpers.