137 lines
10 KiB
Plaintext
137 lines
10 KiB
Plaintext
<p><img alt="org-roam-ui" src="https://www.eigenbahn.com/assets/img/org-roam-ui.png" /></p>
|
||
|
||
<h2 id="an-external-brain">An External Brain</h2>
|
||
|
||
<p>I have a terrible memory…</p>
|
||
|
||
<p>And like most folks dealing w/ software architecture, I have to deal w/ a humongous amount of information.</p>
|
||
|
||
<p>So I take notes. Lots of them.</p>
|
||
|
||
<p>In fact I’ve extended this practice to every subjects I work on / study, with extensive cross-referencing.</p>
|
||
|
||
<p>The trick is not to remember stuff but to find it back quickly.</p>
|
||
|
||
<p>My current setup<sup id="fnref:1"><a class="footnote" href="https://www.eigenbahn.com/atom.emacs.xml#fn:1" rel="footnote">1</a></sup> is pretty straightforward: I use <a href="https://orgmode.org/">Org mode</a> inside <a href="https://www.eigenbahn.com/tag/emacs/">Emacs</a>. To quickly search a piece of information I use <a href="https://github.com/jrblevin/deft">deft</a> or sometimes <a href="https://github.com/Wilfred/deadgrep">deadgrep</a>.</p>
|
||
|
||
<p>The combination of these tools + my collection of notes act like an <strong>external brain</strong>.</p>
|
||
|
||
<h2 id="digital-gardening--zettlekasten">Digital Gardening & Zettlekasten</h2>
|
||
|
||
<p>My notes are organized in a very specific way.</p>
|
||
|
||
<p>I organize them hierarchically under subfolders.</p>
|
||
|
||
<p>I like mid-sized files, only splitting them when they attain a critical mass in term of size or complexity.</p>
|
||
|
||
<p>This practice of building and maintaining a <strong>personal wiki</strong>, as old as the world itself, is now getting qualified of <a href="https://maggieappleton.com/garden-history"><em>digital gardening</em></a><sup id="fnref:2"><a class="footnote" href="https://www.eigenbahn.com/atom.emacs.xml#fn:2" rel="footnote">2</a></sup>. Indeed, you just don’t add content but have to regularly reorganize it, like you would clear a patch of soil.</p>
|
||
|
||
<p>I also stumbled upon the <a href="https://zettelkasten.de/introduction/"><em>Zettelkasten Method</em></a> and liked its idea of bidirectional links<sup id="fnref:3"><a class="footnote" href="https://www.eigenbahn.com/atom.emacs.xml#fn:3" rel="footnote">3</a></sup> but quickly rejected one aspect of its philosophy: creating many many small files, one for capturing each incoming thought.</p>
|
||
|
||
<p>Indeed, bidirectional links allow for a very fluid way to structure information (akin to what you may find in a graph database).</p>
|
||
|
||
<p>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 <em>gardening</em> my notes.</p>
|
||
|
||
<p>So while I adhered to the <em>digital gardening</em> philosophy, I rejected (my understanding of) <em>Zettelkasten</em>.</p>
|
||
|
||
<h2 id="org-roam">Org-Roam</h2>
|
||
|
||
<p>I discovered <a href="https://github.com/org-roam/org-roam">Org-Roam</a> through its accompanying visualization tool: <a href="https://github.com/org-roam/org-roam-ui">Org-Roam-UI</a>.</p>
|
||
|
||
<p>It’s an extension to Org to provide it a similar feature set to <a href="https://roamresearch.com/">Roam</a>, the most famous <em>Zettlekasten</em> software.</p>
|
||
|
||
<p>Even if I didn’t buy to the <em>Zettlekasten</em> philosophy, the ability to graph all the notes relationships dynamically was tempting.</p>
|
||
|
||
<p>I took a quick look around and realized that the implementation isn’t too intrusive:</p>
|
||
<ul>
|
||
<li>relies on the native <code class="language-plaintext highlighter-rouge">org-id</code> feature</li>
|
||
<li>uses a local SQLite DB, but it’s only a cache that is easy to prune and re-create<sup id="fnref:4"><a class="footnote" href="https://www.eigenbahn.com/atom.emacs.xml#fn:4" rel="footnote">4</a></sup></li>
|
||
</ul>
|
||
|
||
<p>Furthermore, in its latest iteration it supports:</p>
|
||
<ul>
|
||
<li>recursive parsing of the notes directory</li>
|
||
<li>having note titles different from file names</li>
|
||
</ul>
|
||
|
||
<p>So I didn’t see any reason not to try it.</p>
|
||
|
||
<h2 id="indexing-an-existing-notes">Indexing an Existing Notes</h2>
|
||
|
||
<p>Things worked smoothly, but I was struggling to find a command to register existing notes in Org-Roam’s DB.</p>
|
||
|
||
<p>Calling <code class="language-plaintext highlighter-rouge">org-id-get-create</code> would allow generating an org id for current file / outline. But that wasn’t sufficient to make it appear.</p>
|
||
|
||
<p>Indeed, I also had to register it in the <code class="language-plaintext highlighter-rouge">org-id-locations-file</code> by passing the current file path to <code class="language-plaintext highlighter-rouge">org-id-update-id-locations</code>.</p>
|
||
|
||
<p>Finally, I needed to call <code class="language-plaintext highlighter-rouge">org-roam-db-update-file</code> for Org-Roam to update its DB entry for the current file.</p>
|
||
|
||
<p>This gives:</p>
|
||
|
||
<div class="language-elisp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">defun</span> <span class="nv">prf/org-roam/add-index-current</span> <span class="p">()</span>
|
||
<span class="s">"Add index to file of currently visited buffer, if applicable."</span>
|
||
<span class="p">(</span><span class="nv">interactive</span><span class="p">)</span>
|
||
|
||
<span class="p">(</span><span class="nb">unless</span> <span class="p">(</span><span class="nb">and</span> <span class="p">(</span><span class="nv">buffer-file-name</span><span class="p">)</span>
|
||
<span class="p">(</span><span class="nv">file-exists-p</span> <span class="p">(</span><span class="nv">buffer-file-name</span><span class="p">)))</span>
|
||
<span class="p">(</span><span class="nv">user-error</span> <span class="s">"Current buffer is not visiting a file that exists on disk."</span><span class="p">))</span>
|
||
|
||
<span class="p">(</span><span class="nb">unless</span> <span class="p">(</span><span class="nv">prf/org/file-path-indexable-p</span> <span class="p">(</span><span class="nv">buffer-file-name</span><span class="p">))</span>
|
||
<span class="p">(</span><span class="nv">user-error</span> <span class="s">"Current buffer is not visiting an indexable file."</span><span class="p">))</span>
|
||
|
||
<span class="p">(</span><span class="nb">unless</span> <span class="p">(</span><span class="nv">org-id-get</span><span class="p">)</span>
|
||
<span class="p">(</span><span class="nv">org-id-get-create</span><span class="p">)</span>
|
||
<span class="p">(</span><span class="nv">call-interactively</span> <span class="nf">#'</span><span class="nv">save-buffer</span><span class="p">))</span>
|
||
|
||
<span class="p">(</span><span class="nv">org-id-update-id-locations</span> <span class="p">(</span><span class="nb">list</span> <span class="p">(</span><span class="nv">buffer-file-name</span><span class="p">)))</span>
|
||
|
||
<span class="p">(</span><span class="nv">org-roam-db-update-file</span><span class="p">))</span>
|
||
</code></pre></div></div>
|
||
|
||
<h2 id="forcing-index-of-all-files">Forcing Index of All Files</h2>
|
||
|
||
<p>Sometimes I like to massively rename / move / delete note files and Org-Roam doesn’t seem to be super happy about this.</p>
|
||
|
||
<p>Using the same logic as above, I came up w/ the following command:</p>
|
||
|
||
<div class="language-elisp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">defun</span> <span class="nv">prf/org-roam/rescan</span> <span class="p">()</span>
|
||
<span class="s">"Force rescan of whole `prf/dir/notes'."</span>
|
||
<span class="p">(</span><span class="nv">interactive</span><span class="p">)</span>
|
||
<span class="p">(</span><span class="nv">prf/org/index-rescan-all</span><span class="p">)</span>
|
||
<span class="p">(</span><span class="nv">org-roam-db-sync</span><span class="p">))</span>
|
||
|
||
<span class="p">(</span><span class="nb">defun</span> <span class="nv">prf/org/index-rescan-all</span> <span class="p">()</span>
|
||
<span class="s">"Populate `org-id-locations' by rescaning recursively all files in `prf/dir/notes'."</span>
|
||
<span class="p">(</span><span class="nv">interactive</span><span class="p">)</span>
|
||
<span class="p">(</span><span class="k">let</span> <span class="p">((</span><span class="nv">buffs-snapshot</span> <span class="p">(</span><span class="nv">buffer-list</span><span class="p">)))</span>
|
||
<span class="p">(</span><span class="nv">org-id-update-id-locations</span>
|
||
<span class="p">(</span><span class="nv">f-files</span> <span class="nv">prf/dir/notes</span> <span class="nf">#'</span><span class="nv">prf/org/file-path-indexable-p</span> <span class="no">t</span><span class="p">))</span>
|
||
<span class="c1">;; NB: `org-id-update-id-locations' opens all matching files, we close them after processing</span>
|
||
<span class="p">(</span><span class="nb">mapc</span> <span class="nf">#'</span><span class="nv">kill-buffer</span>
|
||
<span class="p">(</span><span class="nv">-difference</span> <span class="p">(</span><span class="nv">buffer-list</span><span class="p">)</span> <span class="nv">buffs-snapshot</span><span class="p">))))</span>
|
||
</code></pre></div></div>
|
||
|
||
<h2 id="conclusion">Conclusion</h2>
|
||
|
||
<p>I’m pretty happy with this setup.</p>
|
||
|
||
<p>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.</p>
|
||
|
||
<h2 id="notes">Notes</h2>
|
||
|
||
<div class="footnotes">
|
||
<ol>
|
||
<li id="fn:1">
|
||
<p>I originally started w/ <a href="https://en.wikipedia.org/wiki/Tomboy_(software)">Tomboy</a>, then moved to <a href="https://www.mediawiki.org/wiki/MediaWiki">MediaWiki</a>, Markdown and finally to Org as soon as I started using Emacs. <a class="reversefootnote" href="https://www.eigenbahn.com/atom.emacs.xml#fnref:1">↩</a></p>
|
||
</li>
|
||
<li id="fn:2">
|
||
<p>It’s more than an empty buzzword. Lots of effort has been put on studying and qualifying this phenomenon. Don’t hesitate to browse the rest of <a href="https://maggieappleton.com/garden">Maggie Appleton’s site</a> to learn more. <a class="reversefootnote" href="https://www.eigenbahn.com/atom.emacs.xml#fnref:2">↩</a></p>
|
||
</li>
|
||
<li id="fn:3">
|
||
<p>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. <a class="reversefootnote" href="https://www.eigenbahn.com/atom.emacs.xml#fnref:3">↩</a></p>
|
||
</li>
|
||
<li id="fn:4">
|
||
<p>This DB is just a cache, a <em>derived data systems</em> (i.e. <em>materialized view</em>). The <em>system of record</em> are the org files themselves. Hence there is no risk of unrepairable corruption. <a class="reversefootnote" href="https://www.eigenbahn.com/atom.emacs.xml#fnref:4">↩</a></p>
|
||
</li>
|
||
</ol>
|
||
</div> |