# Where parallels cross

Interesting bits of life

# An Helm source for Org Roam v2

How I wrote a Helm source for Org Roam.

## The problem

Org Roam is fantastic for my note taking. Still there is an ever returning bug with Helm: all of a sudden the formatting of your completion buffer would change. This makes me aesthetically cringe.

Since I have been playing around with Helm lately, I thought why not writing an Helm source for Org Roam? One with actions. And that fits perfectly with my little escalator mode!

## And there is a solution

It wasn't hard with the amazing community that Emacs pulled together. I started at peeking at helm-org-roam, which is a functioning source for Org Roam v1. Then through browsing I got to a nice post by John Kitchin, which nudged me into understanding how to define Helm actions.

Anyway I started small:

(defun helm-org-roam (&optional input candidates)
(interactive)
(require 'org-roam)
(helm
:input input
:sources (list
(helm-build-sync-source "Roam: "
:must-match nil
:fuzzy-match t
:candidates (or candidates (org-roam--get-titles))
:action
'(("Find File" . (lambda (x)
(--> x
org-roam-node-from-title-or-alias
(org-roam-node-visit it t))))
)))))


The candidate lists is the titles of my notes. The only action is to open a file. The code is copied from Org Roam, naturally.

But then I thought, I may also want to insert a link. And so I added another action using Org Roam's API:

("Insert link" . (lambda (x)
(--> x
org-roam-node-from-title-or-alias
(insert
(format
"[[id:%s][%s]]"
(org-roam-node-id it)
(org-roam-node-title it))))))


That is pretty easy and smooth. Only thing, you need to use TAB to pick the right action (or use the F2 key). I still didn't learn how to assign keybindings for helm actions.

It was at this point that I remembered my useful function to navigate backlinks. Knowing Helm, I believed I could make it extremely more compact as an action:

("Follow backlinks" . (lambda (x)
(let ((candidates
(--> x
org-roam-node-from-title-or-alias
(--map
(org-roam-node-title
it))))
(helm-org-roam nil (or candidates (list x))))))


How cool is that? An huge improvement over my many lines function that needed to implement recursion. Helm is my recursion with (helm-org-roam nil (or candidates (list x))), where I start it with a new list of candidates.

The only bit missing at this point is to create a note, if it does not exist already. So I discovered that Helm allows multiple sources for a searcher and so I wrote my dummy source to create a note:

(helm-build-dummy-source
"Create note"
:action '(("Capture note" . (lambda (candidate)
(org-roam-capture-
:node (org-roam-node-create :title candidate)
:props '(:finalize find-file))))))


The result is beautiful! I finally can compose navigation (of backlinks), insertion and opening notes as I want: Helm is really powerful.

I am now thinking about how to make moldable-emacs molds available to use as actions!

The overall code is in my escalator.el code.

## Conclusion

Writing Helm searchers is simpler than I thought! And the modular actions mixed with recursion provide a powerful engine to search and act. If you are an Org Roam user, you may really like to try this version of helm-org-roam: load it and invoke it.

Happy searching!