The "proper" way to set command hook handlers

Sorry if this is a dumb question, but what is the “proper” way to set a handler for a command hook? I am having difficulty figuring it out. I cannot seem to find much documentation on it and looking through the nhooks source code hasn’t helped me much. Also, I have never used Emacs, so please bear with me if the answer would be obvious to an Emacs user.

Currently, I use the following approach for each handler:

(hooks:add-hook HOOK (make-instance 'hooks:handler :fn #'FUNCTION))

HOOK is the hook to add a handler to and FUNCTION is the function to use as a handler.

For example:

(hooks:add-hook copy-url-after-hook (make-instance 'hooks:handler :fn #'wikiwand-copy-url-handler))

wikiwand-copy-url-handler is a function I wrote that takes nothing and returns nothing and grabs the url from the clipboard with (clipboard-text *browser*), checks if it is a Wikiwand link, converts it to a Wikipedia link, and uses copy-to-clipboard to put it in the clipboard. I am including this information because I am not sure if my approach with the handler function is the “proper” way either, particularly how I get the URL from or copy the result to the clipboard.

Currently, this works fine, but I just feel like I’m doing something wrong. Especially with how different creating a URL handler is.

I have tried using hooks:define-hook, but I couldn’t figure out how to use it or if I was even using it for its intended purpose.

Any help or advice would be much appreciated.

There’s no Nyxt-idiomatic way to add hook handler. The prettiness of URL handlers is a mere consequence of them being used most and thus infinitely polished.

With command hooks, you can use a dozen of notations. Take this silly example of setting a hook echoing Lisp REPL started! when you run lisp-repl: there are five (or even more, I suppose) different ways to bind it. I’t merely a matter of your aesthetic preference which notation you use, as all of those are mostly equivalent (I say that those are mostly equivalent, but I leave out one important detail: the handlers attached as symbols allow redefinition – that was the whole point behind nhooks – so you can redefine the function bound to symbol at runtime, if you wish to do so).

(defun echo-lisp-repl-fn ()
  "Echoing handler as a named function."
  (echo "Lisp REPL started!"))

(defvar echo-lisp-repl-var
  (lambda () (echo "Lisp REPL started!"))
  "Echoing handler as a lambda stored inside a variable.")

; Attaching a function object.
(hooks:add-hook nyxt/repl-mode:lisp-repl-after-hook #'echo-lisp-repl-fn)
;; Attaching a symbol.
(hooks:add-hook nyxt/repl-mode:lisp-repl-after-hook 'echo-lisp-repl-fn)
;; Attaching a lambda stored inside a variable.
(hooks:add-hook nyxt/repl-mode:lisp-repl-after-hook echo-lisp-repl-var) 
;; Attaching a handler wrapping around function object.
(hooks:add-hook nyxt/repl-mode:lisp-repl-after-hook (make-instance 'hooks:handler :fn #'echo-lisp-repl-fn))
;; Attaching a handler with symbol.
(hooks:add-hook nyxt/repl-mode:lisp-repl-after-hook (make-instance 'hooks:handler :fn 'echo-lisp-repl-fn))
;; Attaching a lambda (notice the `:name' here: it's necessary with lambdas, as all the hooks should be named). 
(hooks:add-hook nyxt/repl-mode:lisp-repl-after-hook
                (make-instance 'hooks:handler :fn echo-lisp-repl-var :name 'echo-lisp-repl))
2 Likes

Thanks a lot! This is exactly what I was looking for.