Let’s say I’m trying to write a function that will let me choose from all the backlinks to a particular node (and I don’t want to use the org-roam buffer, but rather the standard minibuffer completing-read function). I can’t just use org-roam-node-read with a filter function, because the list of nodes that org-roam-node-read is pulling from (which is given by org-roam-node-list) doesn’t have the relevant information. So I need to figure out the list of nodes that link to the node at point, and then somehow input them into org-roam-node-read, which lacks this functionality. Here is a fairly simple way I’ve figured out how to do this (the important work is done by the cl-letf in the first function, based on ideas I read about here and here):
(defun azr/org-roam-node-read (nodes)
"Like org-roam-node-read but takes a list of NODES."
(cl-letf (((symbol-function 'org-roam-node-list) (lambda () nodes)))
(org-roam-node-read)))
(defun azr/org-roam-node-read-backlinks ()
(interactive)
"Like org-roam-node-read but only for backlinks of node at point."
(let ((nodes (seq-uniq (mapcar #'org-roam-backlink-source-node
(org-roam-backlinks-get (org-roam-node-at-point))))))
(azr/org-roam-node-read nodes)))
This works but it feels hacky. Is there a better way?
Thanks. I just learned about cl-letf and am a big fan, especially for deeply nested function calls.
Ideally though the org-roam API would provide a better way to do this, so that I could, for example, also change the prompt text in the minibuffer completion.
until such an API gets done, you can always write your own function using org-roam-node-read as a reference. It’s not a big function and what it is doing is rather clear (it looks a bit complicated because of the API of built-in completion functions, I guess, but it’s almost fixed syntax).
Yeah, I haven’t figured out how the completion API works. But if, as you say, the details of that don’t matter and I can just copy and paste that bit of code, org-roam-node-read is quite simple. I just don’t like copy-pasting code I don’t understand :-).
You don’t need to take my word for it. In addition to the built-in documentation on completing-read, I use this part if Embark’s readme as a reference too. You will see it has the same form as org-roam-node-read when it uses completing-read (I vaguely remember this might be the way described in the built-in documentation, too) ;). It will soon go into C code if you try to read the source, which is for me a sign to turn around… (I don’t usually have C source as I don’t build Emacs on Windows).