An External Brain
I have a terrible memory…
And like most folks dealing w/ software architecture, I have to deal w/ a humongous amount of information.
So I take notes. Lots of them.
In fact I’ve extended this practice to every subjects I work on / study, with extensive cross-referencing.
The trick is not to remember stuff but to find it back quickly.
My current setup1 is pretty straightforward: I use Org mode inside Emacs. To quickly search a piece of information I use deft or sometimes deadgrep.
The combination of these tools + my collection of notes act like an external brain.
Digital Gardening & Zettlekasten
My notes are organized in a very specific way.
I organize them hierarchically under subfolders.
I like mid-sized files, only splitting them when they attain a critical mass in term of size or complexity.
This practice of building and maintaining a personal wiki, as old as the world itself, is now getting qualified of digital gardening2. Indeed, you just don’t add content but have to regularly reorganize it, like you would clear a patch of soil.
I also stumbled upon the Zettelkasten Method and liked its idea of bidirectional links3 but quickly rejected one aspect of its philosophy: creating many many small files, one for capturing each incoming thought.
Indeed, bidirectional links allow for a very fluid way to structure information (akin to what you may find in a graph database).
Still, I like to impose some structure, a taxonomy loosely based on how I mentally represent things. Having to deal with a gazillion files would not imped finding information back, but would discourage me from regularly gardening my notes.
So while I adhered to the digital gardening philosophy, I rejected (my understanding of) Zettelkasten.
I discovered Org-Roam through its accompanying visualization tool: Org-Roam-UI.
It’s an extension to Org to provide it a similar feature set to Roam, the most famous Zettlekasten software.
Even if I didn’t buy to the Zettlekasten philosophy, the ability to graph all the notes relationships dynamically was tempting.
I took a quick look around and realized that the implementation isn’t too intrusive:
- relies on the native
- uses a local SQLite DB, but it’s only a cache that is easy to prune and re-create4
Furthermore, in its latest iteration it supports:
- recursive parsing of the notes directory
- having note titles different from file names
So I didn’t see any reason not to try it.
Indexing Existing Notes
Things worked smoothly, but I was struggling to find a command to register existing notes in Org-Roam’s DB.
org-id-get-create would allow generating an org id for current file / outline. But that wasn’t sufficient to make it appear.
Indeed, I also had to register it in the
org-id-locations-file by passing the current file path to
Finally, I needed to call
org-roam-db-update-file for Org-Roam to update its DB entry for the current file.
(defun prf/org-roam/add-index-current () "Add index to file of currently visited buffer, if applicable." (interactive) (unless (and (buffer-file-name) (file-exists-p (buffer-file-name))) (user-error "Current buffer is not visiting a file that exists on disk.")) (unless (prf/org/file-path-indexable-p (buffer-file-name)) (user-error "Current buffer is not visiting an indexable file.")) (unless (org-id-get) (org-id-get-create) (call-interactively #'save-buffer)) (org-id-update-id-locations (list (buffer-file-name))) (org-roam-db-update-file))
Forcing Index of All Files
Sometimes I like to massively rename / move / delete note files and Org-Roam doesn’t seem to be super happy about this.
Using the same logic as above, I came up w/ the following command:
(defun prf/org-roam/rescan () "Force rescan of whole `prf/dir/notes'." (interactive) (prf/org/index-rescan-all) (org-roam-db-sync)) (defun prf/org/index-rescan-all () "Populate `org-id-locations' by rescaning recursively all files in `prf/dir/notes'." (interactive) (let ((buffs-snapshot (buffer-list))) (org-id-update-id-locations (f-files prf/dir/notes #'prf/org/file-path-indexable-p t)) ;; NB: `org-id-update-id-locations' opens all matching files, we close them after processing (mapc #'kill-buffer (-difference (buffer-list) buffs-snapshot))))
I’m pretty happy with this setup.
The Org-Roam-UI helps me visualize the current structure of my notes and has helped me discover patterns and anomalies I had no idea existed.
Not supported natively by Org as of writting. I was circumventing this limitation by creating a link in each of the 2 cross-referenced files. ↩
This DB is just a cache, a derived data systems (i.e. materialized view). The system of record are the org files themselves. Hence there is no risk of unrepairable corruption. ↩
Tagged #emacs, #information-architecture, #productivity.