<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title><![CDATA[Garjola Dindi]]></title>
<description><![CDATA[Garjola Dindi]]></description>
<link>https://dindi.garjola.net/</link>
<lastBuildDate>Sat, 06 May 2023 18:03:50 +0200</lastBuildDate>
<item>
  <title><![CDATA[AI assistants in Emacs. Don't use ChatGPT. Help Open Science.]]></title>
  <description><![CDATA[
<p>
Everybody seems to be very excited about generative AI models these days. The availability of the Large Language Models (LLMs) through conversational interfaces like ChatGPT and of image generation tools like Dall-E or Stable Diffusion have brought generative AI to the masses. Although Github Copilot, also based on the GPT family of models, has been available for a while now, this was a niche tool, for programmers only. 
</p>

<p>
Of course, Emacs being the best text-based interface to a computer, it is also the best interface to the generative AI models which are driven through textual prompts. Everything being a text buffer in Emacs, sending and receiving text via an API is straightforward (if you know Emacs Lisp).
</p>

<p>
It is therefore not a surprise that there are many Emacs packages allowing to use ChatGPT and Copilot. Just to list a few<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>:
</p>

<ul class="org-ul">
<li><a href="https://github.com/antonhibl/gptai">gptai</a></li>
<li><a href="https://github.com/karthink/gptel">gptel</a></li>
<li><a href="https://github.com/rksm/org-ai">org-ai</a></li>
<li><a href="https://github.com/xenodium/chatgpt-shell">chatgpt-shell</a></li>
<li><a href="https://github.com/zerolfx/copilot.el">copilot.el</a></li>
</ul>

<p>
Recently, David Wilson at System Crafters did <a href="https://www.youtube.com/watch?v=JImYEdqVQR8">a live stream</a> showing some of the capabilities of these packages. To be honest, I was not impressed by the results of the code generated by the LLMs, but I can understand that many people may find them useful.
</p>

<p>
At the end of the stream, David wanted to address the question of the problems and issues with using these models. Of course, being a programmer, David likes recursion, and he asked ChatGPT about that. The LLM answered, as usual, with a balanced view with pros and cons. It is also usual for these models, in my opinion, to give awfully banal answers. There can be legal issues, copyright ones (in both senses, that is, that the models are trained with copyrighted material, and that the copyright of their outputs is not well defined), ethical problems, etc.
</p>

<p>
As always, the Silicon Valley tech firms have not waited for these issues to be settled before deploying the technology to the public. They impose their vision regardless of the consequences. Unfortunately, most programmers like the tech so much that they don't stop thinking before adopting and participating in spreading it.
</p>

<p>
Emacs being one of the most important contributions of the Free Software community, it may be surprising that some of its users are so keen to ride the <a href="https://www.jordiinglada.net/sblog/llm.html">latest Trojan horse of technofeudalism</a>. Fermin pointed out a <a href="https://sasanidas.gitlab.io/f-site/lsp-troyan/">similar kind of issue with the Language Server Protocol</a>, but that was not a real problem, since LSP servers run locally and we have free software implementations of them. This is not the case for ChatGPT or Copilot. We only have an API that can be taken down at any moment. But worse than that, as <a href="https://www.jordiinglada.net/sblog/llm.html">pointed out</a>, using these LLMs means that we are working in training them. Every time that David, in his demo, wrote <i>"… the code is wrong because of …, can you fix it?"</i>, he was giving feedback for the reinforcement learning of ChatGPT.
</p>

<p>
So what can we do? Stop using these tools and loose our programming or writing jobs because we will be less productive than those that use them?
</p>

<p>
Maybe we can do what GNU hackers and other Free Software activists have always done: implement libre tools that are digital common goods that free and empower users. Building and training big AI models is very costly and may be much more difficult than building an OS kernel like Linux, GCC or Emacs, but fortunately, there are already <a href="https://medium.com/geekculture/list-of-open-sourced-fine-tuned-large-language-models-llm-8d95a2e0dc76">alternatives to ChatGPT</a>.
</p>

<p>
The best starting point could be helping the <a href="https://bigscience.huggingface.co/">BigScience Project</a> by using their <a href="https://huggingface.co/bigscience/bloom">Bloom</a> model from Emacs to train it and improve it. Hints on how to install Bloom locally and use it with Python can be found <a href="https://towardsdatascience.com/run-bloom-the-largest-open-access-ai-model-on-your-desktop-computer-f48e1e2a9a32">in this blog post</a>. There are also initiatives to use <a href="https://en.wikipedia.org/wiki/Federated_learning">federated learning</a><sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> to <a href="https://www.reddit.com/r/MachineLearning/comments/zl03b0/project_run_and_finetune_bloom176b_at_home_using/">improve Bloom</a>. The <a href="https://www.bigcode-project.org/">BigCode</a> project targets code generation, and is to BigScience what Copilot is to ChatGPT. You can play with it <a href="https://huggingface.co/chat">here</a>. There is a <a href="https://marketplace.visualstudio.com/items?itemName=Lisoveliy.starcoderex">VSCode plugin</a> for their StarCoder model, but no Emacs package yet. Isn't that a shame?
</p>

<p>
BigScience is Open Science, while OpenAI's <b>is not open</b>, but proprietary technology built from common digital goods harvested on the internet. It shouldn’t be difficult for us, Emacs users, to choose who we want to help.
</p>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
In alphabetical order using <code>M-x sort-lines</code> 😉
</p></div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Yes, federated like in <a href="https://en.wikipedia.org/wiki/Fediverse">Fediverse</a>!
</p></div></div>


</div>
</div><div class="taglist"><a href="https://dindi.garjola.net/tags.html">Tags</a>: <a href="https://dindi.garjola.net/tag-emacs.html">emacs</a> <a href="https://dindi.garjola.net/tag-ai.html">ai</a> <a href="https://dindi.garjola.net/tag-chatgpt.html">chatgpt</a> <a href="https://dindi.garjola.net/tag-open-science.html">open-science</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[ai]]></category>
  <category><![CDATA[chatgpt]]></category>
  <category><![CDATA[open-science]]></category>
  <link>https://dindi.garjola.net/ai-assistants.html</link>
  <guid>https://dindi.garjola.net/ai-assistants.html</guid>
  <pubDate>Sat, 06 May 2023 17:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[A workaround for an annoying EXWM behavior]]></title>
  <description><![CDATA[
<p>
I have been using the Emacs X Window Manager, <a href="https://github.com/ch11ng/exwm">EXWM</a>, for a couple of years now and I have come to depend on it for an efficient and friendly workflow for most of what I do at the computer. Before that, I had been using <a href="https://stumpwm.github.io/">StumpWM</a> for 4 or 5 years and I was already sold on tiling window managers. For someone like me who does everything in Emacs except for browsing sites that need Javascript or watching videos, EXWM seems to be the perfect setup.
</p>

<p>
The pain point with EXWM is that its development and maintenance suddenly stopped after the creator and maintainer went AWOL. There have been discussions here and there to continue the development, but, to the best of my knowledge, no initiative has really taken off.
</p>

<p>
Some well known EXWM users in the community started migrating to other WMs, like StumpWM, <a href="https://herbstluftwm.org/">Herbstluftwm</a> or or <a href="http://www.qtile.org/">QTile</a>. I also tried to get back to StumpWM, since I had used it for a long time, but I found the experience inferior to EXWM: having <code>M-x</code> everywhere and not having to use different key bindings when talking to the WM or to Emacs is a real comfort.
</p>

<p>
However, some time ago, floating windows started behaving annoyingly. For instance, when saving a file in Firefox, the file chooser application would be too high and the <code>Save</code> button would be below the bottom of the screen. I then would have to move the window up so that I could click. Not knowing anything about X, I wasn't able to diagnose the issue.
</p>

<p>
I ended writing a little function to resize a floating window:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">defun</span> <span class="org-function-name">my/resize-floating-frame</span> (width height)
  <span class="org-doc">"Resize a floating exwm frame to WIDTHxHEIGHT"</span>
  (<span class="org-keyword">interactive</span> <span class="org-string">"nWidth: \nnHeight: "</span>)
    (<span class="org-keyword">let</span> ((floating-container (frame-parameter exwm--floating-frame
                                               'exwm-container)))
      (exwm--set-geometry floating-container nil nil width height)
      (exwm--set-geometry exwm--id nil nil width height)
      (xcb:flush exwm--connection)))
</pre>
</div>

<p>
and bound it to a key to call it with a size that would fit:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(exwm-input-set-key (kbd <span class="org-string">"s-x r"</span>) (<span class="org-keyword">lambda</span> () (<span class="org-keyword">interactive</span>) (my/resize-floating-frame 600 800)))
</pre>
</div>

<p>
So now, instead of grabbing the mouse and manually moving the window, I could just use <code>s-x r</code> and hit enter, since the <code>Save</code> button is selected by default. This is a big win, but after a couple of days, I became tired of this and thought that this could be automated. Also, the arbitrary fixed size may not be appropriate depending on the monitor I am using.
</p>

<p>
So with a little more elisp, I wrote a function that computes the size of the window and works with a hook which is called by EXWM and the end of the setup of the floating window:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">defun</span> <span class="org-function-name">my/adjust-floating-frame-size</span> ()
  <span class="org-doc">"Ensure that the current floating exwm frame does not exceed the size of the screen"</span>
  (<span class="org-keyword">let*</span> ((frame (selected-frame))
         (width (frame-pixel-width frame))
         (height (frame-pixel-height frame))
         (w1 (elt (elt exwm-workspace--workareas 0) 2))
         (h1 (elt (elt exwm-workspace--workareas 0) 3))
         (w2 (elt (elt exwm-workspace--workareas 1) 2))
         (h2 (elt (elt exwm-workspace--workareas 1) 3))
         (max-width (round (* 0.75 (min w1 w2))))
         (max-height (round (* 0.75 (min h1 h2))))
         (final-height (min height max-height))
         (final-width (min width max-width)))
    (set-frame-size frame final-width final-height t)))
(add-hook 'exwm-floating-setup-hook #'my/adjust-floating-frame-size 100)
</pre>
</div>

<p>
All this may seem complex and one could think that too much elisp-foo is needed to do all this. This is absolutely not the case. With a little effort and time, it is not difficult to navigate the source code and test things interactively to see how they behave. In this particular case, searching for hooks in the EXWM package (<code>M-x describe-variable</code>) and trying little code snippets on the <code>*scratch*</code> buffer got me there rather quickly.
</p>

<p>
This is yet another demonstration of the power of Emacs: you can modify its behavior interactively and all source code and documentation is immediately accessible. You don't need to be a skilled programmer to do that. 
</p>

<p>
That's user freedom, the real meaning of software freedom.
</p>
<div class="taglist"><a href="https://dindi.garjola.net/tags.html">Tags</a>: <a href="https://dindi.garjola.net/tag-emacs.html">emacs</a> <a href="https://dindi.garjola.net/tag-exwm.html">exwm</a> <a href="https://dindi.garjola.net/tag-bugs.html">bugs</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[exwm]]></category>
  <category><![CDATA[bugs]]></category>
  <link>https://dindi.garjola.net/exwm-floating.html</link>
  <guid>https://dindi.garjola.net/exwm-floating.html</guid>
  <pubDate>Sun, 02 Oct 2022 18:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Read e-books from your Calibre library inside Emacs]]></title>
  <description><![CDATA[
<p>
I read many books in electronic format. I manage my e-book library with the great <a href="https://calibre-ebook.com/">Calibre</a> software. For non fiction books (science, philosophy, productivity, computer science, etc.) I like to read on my laptop, so I can easily take notes, or actually <a href="https://dindi.garjola.net/zettelkustom.html">generate Zettels</a>. Since I create new zettels with org-capture, reading inside Emacs is very handy. For EPUB format, I use the excellent <a href="https://depp.brause.cc/nov.el/">nov.el</a> and for PDF files I use <a href="https://github.com/vedang/pdf-tools">pdf-tools</a>. Both of these packages provide org links, so I don't have to do anything special to capture notes and have a back-link to the point in the e-book where the note was taken from. This is standard org-capture.
</p>

<p>
I also use org links as bookmarks between reading sessions. Yes, that is bookmarks as marks in the book, like real, paper books.
</p>

<p>
The part in my reading workflow where Emacs wasn't used was managing the e-book library. Usually, when I got a new book, I would open Calibre, add the book, fetch missing meta-data and cover if needed and then close Calibre. After that, I would use <a href="https://github.com/whacked/calibre-query.el">calibre-mode.el</a> to call <code>calibre-find</code> to search for the book and insert an org link into my reading list.
</p>

<p>
I have been aware of <a href="https://github.com/chenyanming/calibredb.el">calibredb.el</a> for a couple of years (or maybe a little less), but I had not used it very much. After a recent update of my packages, I had a look at it again and I discovered that it provides all the features I use in the Calibre GUI, so I have started to use it to add books and curate meta-data and covers.
</p>

<p>
<code>calibredb</code> has a function to open a book from the list: <code>calibredb-open-file-with-default-tool</code> which in my case runs <code>ebook-viewer</code> for EPUB and <code>evince</code> for PDF. I did not find an option or a variable to change that, so I looked at the code of the function:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">defun</span> <span class="org-function-name">calibredb-open-file-with-default-tool</span> (arg <span class="org-type">&amp;optional</span> candidate)
  <span class="org-doc">"Open file with the system default tool.</span>
<span class="org-doc">If the universal prefix ARG is used, ignore `</span><span class="org-doc"><span class="org-constant">calibredb-preferred-format</span></span><span class="org-doc">'.</span>
<span class="org-doc">Optional argument CANDIDATE is the selected item."</span>
  (<span class="org-keyword">interactive</span> <span class="org-string">"P"</span>)
  (<span class="org-keyword">unless</span> candidate
    (<span class="org-keyword">setq</span> candidate (car (calibredb-find-candidate-at-point))))
  (<span class="org-keyword">if</span> arg
      (<span class="org-keyword">let</span> ((calibredb-preferred-format nil))
        (calibredb-open-with-default-tool (calibredb-get-file-path candidate t)))
    (calibredb-open-with-default-tool (calibredb-get-file-path candidate t))))
</pre>
</div>

<p>
This function calls <code>calibredb-open-with-default-tool</code>, which looks like this:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">defun</span> <span class="org-function-name">calibredb-open-with-default-tool</span> (filepath)
  <span class="org-doc">"TODO: consolidate default-opener with dispatcher.</span>
<span class="org-doc">Argument FILEPATH is the file path."</span>
  (<span class="org-keyword">cond</span> ((eq system-type 'gnu/linux)
         (call-process <span class="org-string">"xdg-open"</span> nil 0 nil (expand-file-name filepath)))
        ((eq system-type 'windows-nt)
         (start-process <span class="org-string">"shell-process"</span> <span class="org-string">"*Messages*"</span>
                        <span class="org-string">"cmd.exe"</span> <span class="org-string">"/c"</span> (expand-file-name filepath)))
        ((eq system-type 'darwin)
         (start-process <span class="org-string">"shell-process"</span> <span class="org-string">"*Messages*"</span>
                        <span class="org-string">"open"</span> (expand-file-name filepath)))
        (t (message <span class="org-string">"unknown system!?"</span>))))
</pre>
</div>

<p>
So in GNU/Linux, it calls <code>xdg-open</code>, which delegates to the appropriate applications. But of course, I want to use Emacs.
</p>

<p>
I could use <code>xdg-settings</code> to change the behavior, but that would mean using <code>emacsclient</code> which seems weird given that I am already inside Emacs (actually, I use EXWM, so it is still weirder). Furthermore, since my Emacs is configured to open EPUB files with <code>nov.el</code> and PDF with <code>pdf-view</code>, I only need to call <code>find-file</code> on the selected file.
</p>

<p>
So I just adapted <code>calibredb-open-file-with-default-tool</code> and bound it to the same key as the original function:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">  (<span class="org-keyword">defun</span> <span class="org-function-name">my/calibredb-open-file-with-emacs</span> (<span class="org-type">&amp;optional</span> candidate)
    <span class="org-doc">"Open file with Emacs.</span>
<span class="org-doc">Optional argument CANDIDATE is the selected item."</span>
    (<span class="org-keyword">interactive</span> <span class="org-string">"P"</span>)
    (<span class="org-keyword">unless</span> candidate
      (<span class="org-keyword">setq</span> candidate (car (calibredb-find-candidate-at-point))))
    (find-file (calibredb-get-file-path candidate t)))
  (define-key calibredb-search-mode-map <span class="org-string">"V"</span> #'my/calibredb-open-file-with-emacs)
</pre>
</div>

<p>
This is yet another demonstration of the power of Emacs: packages that were not designed to work together can be combined exactly as you want. You don't need to be a skilled programmer to do that. 
</p>

<p>
That's user freedom, the real meaning of software freedom.
</p>
<div class="taglist"><a href="https://dindi.garjola.net/tags.html">Tags</a>: <a href="https://dindi.garjola.net/tag-emacs.html">emacs</a> <a href="https://dindi.garjola.net/tag-calibre.html">calibre</a> <a href="https://dindi.garjola.net/tag-epub.html">epub</a> <a href="https://dindi.garjola.net/tag-nov.html">nov</a> <a href="https://dindi.garjola.net/tag-books.html">books</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[calibre]]></category>
  <category><![CDATA[epub]]></category>
  <category><![CDATA[nov]]></category>
  <category><![CDATA[books]]></category>
  <link>https://dindi.garjola.net/calibredb-view.html</link>
  <guid>https://dindi.garjola.net/calibredb-view.html</guid>
  <pubDate>Fri, 08 Apr 2022 18:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Install Emacs with Conda]]></title>
  <description><![CDATA[
<p>
At work, I frequently use a high performance computing cluster (300 nodes, 1000 CPU, 44 TB of RAM). It is an amazing environment. Many users access the system via <a href="https://jupyter.org/hub">Jupyter Hub</a> and <a href="https://en.wikipedia.org/wiki/Virtual_research_environment">Virtual Research Environments</a> where many tools for development are available. However the recommended editor is VSCode and I need Emacs.
</p>

<p>
I access the system via ssh on a terminal and run Emacs without the GUI. This is enough for me, since I have all I need:
</p>

<ol class="org-ol">
<li><a href="https://opensource.com/article/20/5/split-terminal">Window multiplexing</a> using <a href="https://www.youtube.com/watch?v=dppr_js-U0s">Emacs windows</a></li>
<li>Virtual desktops thanks to <a href="https://ruzkuku.com/texts/emacs-global.html">tab-bar-mode</a></li>
<li>Persistence across sessions using <code>desktop-save-mode</code></li>
<li>IDE features with <a href="https://github.com/joaotavora/eglot">eglot</a></li>
<li>A data science environment with <a href="https://www.youtube.com/watch?v=AP4LX8L7MFM">org-mode's babel</a></li>
</ol>

<p>
This is great, since I can use the same tools I use on my laptop, with the same configuration and be really efficient.
</p>

<p>
Unfortunately, a couple of months ago, the web proxy that we have to go through to access the internet from the cluster was upgraded and the old Emacs version available on the system was not able to fetch packages.
</p>

<p>
Doing some research, I found that Emacs 27 could be configured to work. Since I did not want to bother the sysadmins without being sure that it would work, I decided to compile Emacs from source as I do on my laptop.
</p>

<p>
Unfortunately, I couldn't manage to get all dependencies working. So I needed to find another way to have a recent Emacs on the system.
</p>

<p>
On the cluster, we use <a href="https://docs.conda.io/projects/conda/en/latest/index.html">Conda</a> to build virtual environments for scientific computing. With Conda, we can install whatever package we want at the user level without any particular privilege.
</p>

<p>
So I just did:
</p>

<div class="org-src-container">
<pre class="src src-shell">conda install emacs
</pre>
</div>

<p>
and I got the last stable Emacs release, which is 27.2 at the time of this writing.
</p>

<p>
So if you need to use Emacs in a system where you can't install system wide packages and you don't want or can't build it yourself, Conda can be a good solution. Installing Conda does not need particular privileges.
</p>
<div class="taglist"><a href="https://dindi.garjola.net/tags.html">Tags</a>: <a href="https://dindi.garjola.net/tag-emacs.html">emacs</a> <a href="https://dindi.garjola.net/tag-conda.html">conda</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[conda]]></category>
  <link>https://dindi.garjola.net/emacs-conda.html</link>
  <guid>https://dindi.garjola.net/emacs-conda.html</guid>
  <pubDate>Sat, 02 Apr 2022 18:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Some Org Mode agenda views for my GTD weekly review]]></title>
  <description><![CDATA[
<nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#orgb5f028f">GTD Weekly review</a>
<ul>
<li><a href="#org7b8f17d">What's GTD</a></li>
<li><a href="#orgca8f425">Implementing GTD with org-mode</a></li>
<li><a href="#org0d9e7e2">The GTD weekly review</a></li>
</ul>
</li>
<li><a href="#org704f700">Reschedule / redeadline today's tasks</a></li>
<li><a href="#orgd32fb36">Get current</a>
<ul>
<li><a href="#org269d696">Review next actions list</a></li>
<li><a href="#orgafa4870">Check that we have effort for all</a></li>
</ul>
</li>
<li><a href="#orgac2002f">Go back to previous calendar data and Review upcoming calendar</a></li>
<li><a href="#orgebe243d">Review waiting for list</a></li>
<li><a href="#orgb90eecf">Stuck projects</a></li>
<li><a href="#org2a7ab00">Look at project list</a></li>
<li><a href="#org9aa431e">Review someday/maybe</a></li>
<li><a href="#orgc7fa3d9">Conclusion</a></li>
</ul>
</div>
</nav>

<div id="outline-container-orgb5f028f" class="outline-2">
<h2 id="orgb5f028f">GTD Weekly review</h2>
<div class="outline-text-2" id="text-orgb5f028f">
</div>
<div id="outline-container-org7b8f17d" class="outline-3">
<h3 id="org7b8f17d">What's GTD</h3>
<div class="outline-text-3" id="text-org7b8f17d">
<p>
I am an extremely lazy and messy person. As such, in order to survive, I need a system to find my way out of bed in the morning, have something to eat in the fridge, don't forget to pick my children at school, feed the cat and things like that.
</p>

<p>
More than 15 years ago, when I already was an Emacs user, I heard about <i>Getting Things Done</i> (GTD for short), a book and a personal productivity system that promised to save my life. I bought the book and started implementing the system right away. If you don't know anything about GTD, reading the <a href="https://en.wikipedia.org/wiki/Getting_Things_Done">Wikipedia entry</a> will give you a good overview. In short, the action management part of the system relies on the following steps:
</p>
<ol class="org-ol">
<li>Capture everything you have to remember or solve.</li>
<li>Periodically empty your inboxes (what you have captured, and any other input you get as e-mail, physical stuff, etc.).</li>
<li>Transform every input into either actionable things, reference material or trash. Actionable things can be projects (need more than one action), next actions (everything is ready to do what you need to do) or things to delegate.</li>
<li>Maintain lists for actions and projects.</li>
<li>Periodically review your lists.</li>
<li>Don't forget to do some of your actions from time to time!</li>
</ol>

<p>
This is a crude description of the system, but it will be enough for the rest of this article.
</p>

<p>
The funny thing is that one could imagine that, as an avid Emacs user, I looked for ways to implement GTD with it. But the real story is that I discovered GTD because, when I was looking for ways to manage actions with Emacs I found what I think is the <a href="http://doc.norang.ca/org-mode.html">absolute reference on the use of Org Mode to get organized</a>, and GTD is cited there.
</p>
</div>
</div>

<div id="outline-container-orgca8f425" class="outline-3">
<h3 id="orgca8f425">Implementing GTD with org-mode</h3>
<div class="outline-text-3" id="text-orgca8f425">
<p>
My implementation is much inspired by Bernt Hansen's suggestions in the above-mentioned site. For actions, I use the following states:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">setq</span> org-todo-keywords 
      (<span class="org-keyword">quote</span> ((sequence <span class="org-string">"TODO(t!/!)"</span> <span class="org-string">"NEXT(n!/!)"</span> 
                        <span class="org-string">"STARTED(s!)"</span> <span class="org-string">"|"</span> <span class="org-string">"DONE(d!/!)"</span>)
              (type <span class="org-string">"PROJECT(p!/!)"</span> <span class="org-string">"|"</span> <span class="org-string">"DONE_PROJECT(D!/!)"</span>)
              (sequence <span class="org-string">"WAITING(w@/!)"</span> <span class="org-string">"SOMEDAY(S!)"</span>  <span class="org-string">"|"</span>
                        <span class="org-string">"CANCELLED(c@/!)"</span>))))
</pre>
</div>

<p>
The meaning of these states is:
</p>
<dl class="org-dl">
<dt>NEXT</dt><dd>an action that I need to do, for which I have estimated the effort, and for which I have everything to start acting.</dd>
<dt>TODO</dt><dd>an action that I need to do but that I don't want to see in my next actions list.</dd>
<dt>STARTED</dt><dd>a next action for which some progress has been made.</dd>
<dt>DONE</dt><dd>a finished action.</dd>
<dt>WAITING</dt><dd>an action to be done, but for which I am waiting for some input or some action from somebody else.</dd>
<dt>SOMEDAY</dt><dd>an action that could be interesting to do, but on which I don't want to commit yet.</dd>
<dt>CANCELLED</dt><dd>an action that I decided that I finally don't need to do.</dd>
</dl>

<p>
The projects are just containers for related actions.
</p>

<p>
Next actions are very important. They are what allows to achieve progress even in periods of crisis or low energy. All my actions have tags for contexts. These can be general (work, admin, errands) or specific (the name of a particular project or person, a type of activity (reading, programming, writing). This allows to easily generate lists of actions which match a set of tags. The final thing that makes a next action special is the effort estimation. Using Org Mode properties, I assign an effort estimation to each next action, so that I can also filter by estimated duration when I have limited time available.
</p>

<p>
Since I spend most of my time in Emacs, using the Org Agenda makes being organised an easy and pleasant experience. The Org Agenda is my main dashboard that I trigger with <code>C-c a</code>. I think this is the default key binding, but I have this in my Emacs config:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(define-key global-map <span class="org-string">"\C-ca"</span> 'org-agenda)
</pre>
</div>

<p>
My Org Agenda is built from more than 60 Org Mode files.
</p>
</div>
</div>

<div id="outline-container-org0d9e7e2" class="outline-3">
<h3 id="org0d9e7e2">The GTD weekly review</h3>
<div class="outline-text-3" id="text-org0d9e7e2">
<p>
One key part of maintaining a clean GTD system is the weekly review. Once a week, I sit down for 90 minutes to 2 hours and I go through this checklist:
</p>

<ul class="org-ul">
<li class="off"><code>[&#xa0;]</code> Re-schedule / re-deadline today's tasks</li>
<li class="off"><code>[&#xa0;]</code> Collect loose papers and materials</li>
<li class="off"><code>[&#xa0;]</code> Mental collection</li>
<li class="off"><code>[&#xa0;]</code> Get <i>ins</i> to zero
<ul class="org-ul">
<li>Questions :
<ul class="org-ul">
<li>What is it?
<ul class="org-ul">
<li>Actionable?
<ul class="org-ul">
<li>Yes
<ul class="org-ul">
<li>Next action?
<ul class="org-ul">
<li>2minutes? (do it)</li>
<li>delegate? (waiting for)</li>
<li>defer it to a specific date?</li>
<li>or next action to do it ASAP (tag next)</li>
</ul></li>
<li>Is it multiple actions?
<ul class="org-ul">
<li>Project</li>
</ul></li>
</ul></li>
<li>No
<ul class="org-ul">
<li>Reference material (tag reference)</li>
<li>Incubate (remind me later) (tag incubate)</li>
<li>Trash it</li>
</ul></li>
<li>No</li>
</ul></li>
</ul></li>
</ul></li>
</ul></li>
<li class="off"><code>[&#xa0;]</code> Get current
<ul class="org-ul">
<li class="off"><code>[&#xa0;]</code> Review next actions list
<ul class="org-ul">
<li class="off"><code>[&#xa0;]</code> what might have been important may not be it anymore</li>
<li class="off"><code>[&#xa0;]</code> check that we have effort for all</li>
</ul></li>
<li class="off"><code>[&#xa0;]</code> Go back to previous calendar data
<ul class="org-ul">
<li class="off"><code>[&#xa0;]</code> things which got rescheduled or should</li>
<li class="off"><code>[&#xa0;]</code> actions which were not done</li>
</ul></li>
<li class="off"><code>[&#xa0;]</code> Review upcoming calendar</li>
<li class="off"><code>[&#xa0;]</code> Review waiting for list</li>
<li class="off"><code>[&#xa0;]</code> Stuck projects</li>
<li class="off"><code>[&#xa0;]</code> Look at project list</li>
<li class="off"><code>[&#xa0;]</code> Review relevant checklists</li>
</ul></li>
<li class="off"><code>[&#xa0;]</code> Get creative
<ul class="org-ul">
<li class="off"><code>[&#xa0;]</code> review someday/maybe</li>
<li class="off"><code>[&#xa0;]</code> generate new ideas</li>
</ul></li>
</ul>

<p>
For some of these steps, I have Org Agenda custom commands or specific agenda views which are very useful. I am sharing them below.
</p>
</div>
</div>
</div>

<div id="outline-container-org704f700" class="outline-2">
<h2 id="org704f700">Reschedule / redeadline today's tasks</h2>
<div class="outline-text-2" id="text-org704f700">
<p>
After a week without reviewing my system, undone actions begin to pile-up and my dashboard is very crowded. The first step is therefore reschedule or cancel some actions. For that, I generate a <i>Daily Action List</i> with the following Org Agenda custom command:
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">setq</span> org-agenda-custom-commands
      (<span class="org-keyword">quote</span>
       ((<span class="org-string">"D"</span> <span class="org-string">"Daily Action List"</span>
         ((agenda <span class="org-string">""</span>
                  ((org-agenda-span 1)
                   (org-agenda-sorting-strategy
                    (<span class="org-keyword">quote</span>
                     ((agenda time-up category-up tag-up))))
                   (org-deadline-warning-days 7))))
         nil)
        <span class="org-comment-delimiter">;; </span><span class="org-comment">[....] </span>
        )))
</pre>
</div>

<p>
With <code>C-c a D</code>, I get all the actions for the current day and all undone things which were scheduled earlier or for which the deadline has passed, will also appear. The actions with a deadline in the coming 7 days will also show up.
</p>
</div>
</div>

<div id="outline-container-orgd32fb36" class="outline-2">
<h2 id="orgd32fb36">Get current</h2>
<div class="outline-text-2" id="text-orgd32fb36">
<p>
The first step in getting current, is looking at the list of all next actions. For this, I have a group of custom commands. There is one for all actions, and 2 others which select only <i>work</i> or only <i>home</i> actions respectively:
</p>
</div>
<div id="outline-container-org269d696" class="outline-3">
<h3 id="org269d696">Review next actions list</h3>
<div class="outline-text-3" id="text-org269d696">
<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">setq</span> org-agenda-custom-commands
      (<span class="org-keyword">quote</span>
       (
        <span class="org-comment-delimiter">;; </span><span class="org-comment">[....]</span>
        (<span class="org-string">"n"</span> . <span class="org-string">"Next Actions List"</span>)
        (<span class="org-string">"nn"</span> tags <span class="org-string">"+TODO=\"NEXT\"|+TODO=\"STARTED\""</span>)
        (<span class="org-string">"na"</span> tags <span class="org-string">"+home+admin+TODO=\"NEXT\"|+home+admin+TODO=\"STARTED\""</span>)
        (<span class="org-string">"nh"</span> tags <span class="org-string">"+home+TODO=\"NEXT\"|+home+TODO=\"STARTED\""</span>)
        <span class="org-comment-delimiter">;; </span><span class="org-comment">[....]</span>
        )))
</pre>
</div>

<p>
I can see all my next actions (with <b>TODO</b> state being <b>NEXT</b> or <b>STARTED</b>) by typing <code>C-c a n n</code>.
</p>
</div>
</div>

<div id="outline-container-orgafa4870" class="outline-3">
<h3 id="orgafa4870">Check that we have effort for all</h3>
<div class="outline-text-3" id="text-orgafa4870">
<p>
As I said above, I want to have an effort estimate for all my next actions. I use <a href="https://github.com/alphapapa/org-ql">org-ql</a> to generate an agenda view with all  next actions that don't have <code>Effort</code> property. I display that with the following interactive command:
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">defun</span> <span class="org-function-name">my/show-next-without-effort</span> ()
  (<span class="org-keyword">interactive</span>)
  (org-ql-search (org-agenda-files)
    '(and (todo <span class="org-string">"NEXT"</span>)
          (not (property <span class="org-string">"Effort"</span>)))))
</pre>
</div>
</div>
</div>
</div>

<div id="outline-container-orgac2002f" class="outline-2">
<h2 id="orgac2002f">Go back to previous calendar data and Review upcoming calendar</h2>
<div class="outline-text-2" id="text-orgac2002f">
<p>
One crucial exercise in the weekly review is to have a look at the past week and the coming ones so that we see what we have done, what we should have done but didn't, and what's coming ahead.
</p>

<p>
For this, I also generate an agenda view with 24 days, starting 10 days ago. This way I see the last week and a half and the next 2 weeks. I have built the following interactive command to do that:
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">defun</span> <span class="org-function-name">my/generate-agenda-weekly-review</span> ()
  <span class="org-doc">"Generate the agenda for the weekly review"</span>
  (<span class="org-keyword">interactive</span>)
  (<span class="org-keyword">let</span> ((span-days 24)
        (offset-past-days 10))
    (message <span class="org-string">"Generating agenda for %s days starting %s days ago"</span>
             span-days offset-past-days)
    (org-agenda-list nil (- (time-to-days (date-to-time
                                           (current-time-string)))
                            offset-past-days) 
                     span-days)
    (org-agenda-log-mode)
    (goto-char (point-min))))
</pre>
</div>

<p>
Putting the agenda in log mode, allows to see the tasks marked as <b>DONE</b> at the corresponding time of closing. If, like me, you clock all your working time, the task will appear also every time it was worked on. This is great to get a sens of what was accomplished.
</p>
</div>
</div>

<div id="outline-container-orgebe243d" class="outline-2">
<h2 id="orgebe243d">Review waiting for list</h2>
<div class="outline-text-2" id="text-orgebe243d">
<p>
Reviewing all the actions that are blocked because they are delegated or need an input from someone else is important. Org Mode allows to generate an agenda view for that with the standard agenda dispatcher. Typing <code>C-c a T</code> generates an agenda view with all tasks matching a particular <b>TODO</b> keyword. I enter <b>WAITING</b> at the prompt and that's all!
</p>
</div>
</div>

<div id="outline-container-orgb90eecf" class="outline-2">
<h2 id="orgb90eecf">Stuck projects</h2>
<div class="outline-text-2" id="text-orgb90eecf">
<p>
Sometimes, a project (that is, something that needs several actions to be done) gets stuck. Org Mode has a concept of <i>stuck project</i> (see the description of the variable <code>org-stuck-projects</code>), but I found it difficult to configure to my liking. I use org-ql again to generate a custom command like this:
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">setq</span> org-agenda-custom-commands
      (<span class="org-keyword">quote</span>
       (
        <span class="org-comment-delimiter">;; </span><span class="org-comment">[....]</span>
        (<span class="org-string">"P"</span> <span class="org-string">"Stuck Projects"</span>
         ((org-ql-block '(and (todo <span class="org-string">"PROJECT"</span>)
                              (<span class="org-keyword">or</span> (not (descendants))
                                  (<span class="org-keyword">and</span> (not (descendants 
                                             (<span class="org-keyword">or</span> (todo <span class="org-string">"STARTED"</span>) (todo <span class="org-string">"NEXT"</span>))))
                                       (descendants 
                                        (<span class="org-keyword">and</span> (<span class="org-keyword">or</span> (todo <span class="org-string">"TODO"</span>) (todo <span class="org-string">"WAITING"</span>)) 
                                                         (not (deadline)) 
                                                         (not (scheduled)))))
                                  (not (descendants (<span class="org-keyword">or</span> (todo <span class="org-string">"NEXT"</span>) (todo <span class="org-string">"TODO"</span>) 
                                                        (todo <span class="org-string">"WAITING"</span>) 
                                                        (todo <span class="org-string">"STARTED"</span>)))))))))
        <span class="org-comment-delimiter">;; </span><span class="org-comment">[...]</span>
        )))
</pre>
</div>
<p>
For me, a stuck project is a headline with a <b>PROJECT</b> keyword that does not have a next action, or for which the non next actions don't have a deadline or a scheduled time slot.
</p>
</div>
</div>

<div id="outline-container-org2a7ab00" class="outline-2">
<h2 id="org2a7ab00">Look at project list</h2>
<div class="outline-text-2" id="text-org2a7ab00">
<p>
To generate the list of projects, I use the same approach as for the list of next actions.
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">setq</span> org-agenda-custom-commands
      (<span class="org-keyword">quote</span>
       (
        <span class="org-comment-delimiter">;; </span><span class="org-comment">[....]</span>
        (<span class="org-string">"p"</span> . <span class="org-string">"Projects List"</span>)
        (<span class="org-string">"pp"</span> tags <span class="org-string">"+TODO=\"PROJECT\""</span>)
        (<span class="org-string">"pw"</span> tags <span class="org-string">"+TODO=\"PROJECT\"+work"</span>)
        (<span class="org-string">"ph"</span> tags <span class="org-string">"+TODO=\"PROJECT\"+home"</span>)
        )))
</pre>
</div>

<p>
Typing <code>C-c a p p</code> gives me the list of all my projects.
</p>
</div>
</div>

<div id="outline-container-org9aa431e" class="outline-2">
<h2 id="org9aa431e">Review someday/maybe</h2>
<div class="outline-text-2" id="text-org9aa431e">
<p>
Having a list of things you may want to do someday is exciting. You can add whatever you want knowing that you don't have to commit to it unless or until you feel like it. However, sometimes you forget for too long about all those things and reviewing them can give new ideas or put you in the mood to commit.
</p>

<p>
The main problem with a someday/maybe list is that it keeps growing, so you can't review it weekly. Mine contains more than 2650 items! What I do is that I randomly jump to one point in the list and review items for 5 minutes. I use the following interactive command:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">defun</span> <span class="org-function-name">my/search-random-someday</span> ()
  <span class="org-doc">"Search all agenda files for SOMEDAY and jump to a random item"</span>
  (<span class="org-keyword">interactive</span>)
  (<span class="org-keyword">let*</span> ((todos '(<span class="org-string">"SOMEDAY"</span>))
         (searches (mapcar (<span class="org-keyword">lambda</span> (x) (format <span class="org-string">"+TODO=\"%s\""</span> x)) todos))
         (joint-search (string-join searches <span class="org-string">"|"</span>) )
         (org-agenda-custom-commands '((<span class="org-string">"g"</span> tags joint-search))))
      (org-agenda nil <span class="org-string">"g"</span>)
      (<span class="org-keyword">let</span> ((nlines (count-lines (point-min) (point-max))))
        (goto-line (random nlines)))))
</pre>
</div>

<p>
It seems a little convoluted, since I could have done the same thing as for the waiting for list, but with this command I can use other <b>TODO</b> states by adding them to the list in the first line of the <code>let</code>. Also, the jump to a random point is cool.
</p>
</div>
</div>

<div id="outline-container-orgc7fa3d9" class="outline-2">
<h2 id="orgc7fa3d9">Conclusion</h2>
<div class="outline-text-2" id="text-orgc7fa3d9">
<p>
As you can see, I have a custom set of commands and functions to make my weekly review easy. This is important. Until I automated this things, I would tend do skip the review too often. Now that I have a streamlined workflow I am much more disciplined with my weekly reviews and this results in an increased peace of mind.
</p>

<p>
My elisp code may need cleaning and improvements. Do no hesitate to send me some feedback by e-mail if you have any suggestion or tricks to share.
</p>
</div>
</div>
<div class="taglist"><a href="https://dindi.garjola.net/tags.html">Tags</a>: <a href="https://dindi.garjola.net/tag-emacs.html">emacs</a> <a href="https://dindi.garjola.net/tag-gtd.html">gtd</a> <a href="https://dindi.garjola.net/tag-org-mode.html">org-mode</a> <a href="https://dindi.garjola.net/tag-agenda.html">agenda</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[gtd]]></category>
  <category><![CDATA[org-mode]]></category>
  <category><![CDATA[agenda]]></category>
  <link>https://dindi.garjola.net/org-agenda-weekly.html</link>
  <guid>https://dindi.garjola.net/org-agenda-weekly.html</guid>
  <pubDate>Sat, 12 Mar 2022 18:00:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[My Zettelkustom (with Emacs, of course)]]></title>
  <description><![CDATA[
<div id="outline-container-orgaab1b7b" class="outline-2">
<h2 id="orgaab1b7b">Zettelwhat?</h2>
<div class="outline-text-2" id="text-orgaab1b7b">
<p>
A couple of years ago, I was trying to improve my note taking abilities and did some research. I discovered the Zettelkasten method and read the book <i>How to take smart notes</i> by Sönke Ahrens which describes this approach invented by Niklas Luhmann, a German sociologist.
</p>

<p>
For a quick introduction to the method, I find this <a href="https://zettelkasten.de/posts/overview/">web site</a> very well done. If you get interested in Zettelkasten, before jumping to the last shiny app or Emacs package, I think it's better to read Ahrens' book.
</p>

<p>
Anyway, in a few words, in Zettelkasten, you create notes with small bits of knowledge that are meant to be self contained. These notes may contain links to other notes with related content. The idea is that the knowledge is not organized hierarchically, but in a graph where notes point to other notes.
</p>

<p>
The Zettelkasten is a living thing where notes are regularly added and most importantly, the notes are frequently read and improved, either by reformulating the content, adding links to other notes, etc.
</p>

<p>
The Zettelkasten is meant to be personal, edited by a single person. It's like a second brain.
</p>

<p>
Niklas Luhmann did everything by hand and his Zettelkasten was made of paper cards. He had to invent a clever indexing method and used special <i>structure notes</i> to create tables of contents for different subjects. It is a pleasure to browse <a href="https://niklas-luhmann-archiv.de/bestand/zettelkasten/suche">the original Zettels</a>.
</p>

<p>
In order to implement a digital Zettelkasten, we only need a note taking application with the ability to create links between notes. A nice bonus is adding tags to the notes to simplify search and generation of sets of related notes.
</p>

<p>
There are lots of applications on the proprietary software market that support the creation and management of a Zettelkasten. There are also free software counterparts.
</p>

<p>
Emacs offers several alternatives in terms of packages:
</p>
<ul class="org-ul">
<li><a href="https://github.com/felko/neuron-mode">Neuron mode</a>, which uses markdown;</li>
<li><a href="https://github.com/ymherklotz/emacs-zettelkasten">org-zettelkasten</a>, which is a set of functions on top of org-mode;</li>
<li><a href="https://efls.github.io/zetteldeft/">Zetteldeft</a>, which uses <a href="https://jblevins.org/projects/deft/">deft</a>;</li>
<li><a href="https://github.com/org-roam/org-roam">org-roam</a>, based on org-mode and inspired by a commercial application.</li>
</ul>

<p>
There are probably others that I am not aware of. Org-roam seems to be the most popular one.
</p>

<p>
After reading Ahrens' book, I decided that I wanted to try the approach. I did not think want to choose one of the available Emacs packages for several reasons. The first one is that I did not understand why I needed anything else than plain org-mode. The second one was that I did not want to commit to any particular implementation before understanding how and if the approach would be useful for me.
</p>
</div>
</div>

<div id="outline-container-orged5bd47" class="outline-2">
<h2 id="orged5bd47">How I do Zettelkasten</h2>
<div class="outline-text-2" id="text-orged5bd47">
<p>
I have a big org-mode file called <code>zettels.org</code> with to top-level headings, one for <i>structure notes</i> and another one for standard zettels. Each note is a second level heading with a title, possibly some org-mode tags, a property drawer and the note content.
</p>

<p>
The property drawer contains at least the <code>DATE_CREATED</code> property with an inactive org-mode timestamp for the day and time when the note was created.
</p>

<p>
The <i>structure notes</i> are created by hand. That means that I create a heading, write the note and add the <code>DATE_CREATED</code> property. I do not create many structure notes, so a manual workflow is OK.
</p>

<p>
For the standard zettels, I use org-capture. The capture template automatically inserts the <code>DATE_CREATED</code> property, but also a <code>FROM</code> property with an org-mode link to the place I was in Emacs when I run org-capture. This link can therefore point to another Zettel (for which an org-id will be created), any org-mode heading if I am in an org-mode file, but this can also be an e-mail in Gnus, a pdf document, an EPUB file, a web page, etc. This is possible because I do <b>everything</b> in Emacs. Storing where I was when I created the note gives interesting context.
</p>

<p>
I have 2 org-capture templates for Zettelkasten, one which does what I described above, and another one which is used for quotes. The latter will copy the marked region in the current buffer into a quote org-mode block.
</p>

<p>
So a typical captured zettel may look like this:
</p>

<pre class="example" id="org3b59cf3">
** The title of the note :tag1:tag2:
:PROPERTIES:
:DATE_CREATED: [2021-08-06 Fri 22:43]
:FROM: [[nov:/home/garjola/Calibre Library/abook.epub::26:7069][EPUB file at /home/garjola/Calibre Library/abook.epub]]
:END:

My ideas on the subject. Etc.

#+begin_quote
Some text that was marked in the EPUB I was reading.
#+end_quote

- See also [[id:e2b5839d-d7ef-4151-8676-17dacd261e86][Another note linked with org-id.]]
</pre>

<p>
This way, while I am reading interesting things, I can capture an idea with all its context. I will of course come later to this note to improve it.
</p>

<p>
This is done in my regular <i>gardening sessions</i>. During these sessions, I browse the Zettelkasten, read notes, add tags and links to other notes, rewrite things, etc.
</p>

<p>
For this tasks, I use a couple of functions. The first one jumps to a random Zettel, so I am sure that I regularly explore forgotten parts of the Zettelkasten. The second one finds <i>back-links</i>, that is notes having links that point to the current note. This is useful for a bi-directional browsing of the content.
</p>
</div>
</div>

<div id="outline-container-org54266cd" class="outline-2">
<h2 id="org54266cd">My custom Zettelkasten setup</h2>
<div class="outline-text-2" id="text-org54266cd">
</div>
<div id="outline-container-org27a4ce3" class="outline-3">
<h3 id="org27a4ce3">Capture templates for Zettelkasten</h3>
<div class="outline-text-3" id="text-org27a4ce3">
<p>
The first component of the setup is the capture templates. They look like this:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">setq</span> org-capture-templates 
      (append org-capture-templates
              (<span class="org-keyword">quote</span> ((<span class="org-string">"z"</span> <span class="org-string">"Zettelkasten"</span>)
                      (<span class="org-string">"zz"</span> <span class="org-string">"Zettel"</span> entry
                       (file+headline <span class="org-string">"~/org/zettels.org"</span> <span class="org-string">"Zettels"</span>)
                       (<span class="org-keyword">function</span> my/zettel-template)
                       <span class="org-builtin">:empty-lines</span> 1)
                      (<span class="org-string">"zq"</span> <span class="org-string">"Quote"</span> entry
                       (file+headline <span class="org-string">"~/org/zettels.org"</span> <span class="org-string">"Zettels"</span>)
                       (<span class="org-keyword">function</span> my/zettel-quote-template)
                       <span class="org-builtin">:empty-lines</span> 1)))))
</pre>
</div>

<p>
There are 2 templates, one for notes without quotes (called with <code>zz</code>) and another for notes where I want to insert the marked region in the current buffer as a quote (called with <code>zq</code>). Both templates insert the note in the <code>zettels.org</code> file under the <code>Zettels</code> heading. Instead of writing the template in this code, I prefer using a function to generate it. I find this more readable.
</p>

<p>
The 2 functions are here:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">defun</span> <span class="org-function-name">my/zettel-template</span> ()
  <span class="org-doc">"* %?\n:PROPERTIES:\n:DATE_CREATED: %U\n:FROM: %a\n:END:\n%i\n"</span>)
(<span class="org-keyword">defun</span> <span class="org-function-name">my/zettel-quote-template</span> ()
  <span class="org-doc">"* %?\n:PROPERTIES:\n:DATE_CREATED: %U\n:FROM: %a\n:END:\n#+begin_quote\n%i\n#+end_quote"</span>)
</pre>
</div>

<p>
They are straightforward. The cursor is placed in the heading (with the <code>%?</code> org-expansion) so I can write the title. The property drawer will contain the time stamp and a link to the place Emacs was when org-capture was called. In the case of the quote, the marked region is copied inside the org-mode quote block.
</p>

<p>
And that's it!
</p>
</div>
</div>


<div id="outline-container-org78ed5ad" class="outline-3">
<h3 id="org78ed5ad">Back-links to zettels</h3>
<div class="outline-text-3" id="text-org78ed5ad">
<p>
Back-links can be tricky. The package <a href="https://github.com/alphapapa/org-sidebar">org-sidebar</a> provides a function for that. But for some reason that I don't remember, I didn't like the way it worked (or more probably, my incompetence did not allow me to make it work). So I searched a bit and found <a href="https://www.reddit.com/r/orgmode/comments/fyr2ai/orgsuperlinks_new_package_for_auto_adding/">a bit of elisp</a> that does what I need.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">require</span> '<span class="org-constant">org-ql</span>)
(<span class="org-keyword">require</span> '<span class="org-constant">org-ql-view</span>)

(<span class="org-keyword">defun</span> <span class="org-function-name">my/zettel-backlinks</span> ()
  (<span class="org-keyword">interactive</span>)
  (<span class="org-keyword">let*</span> ((id (org-entry-get (point) <span class="org-string">"ID"</span>))
         (custom-id (org-entry-get (point) <span class="org-string">"CUSTOM_ID"</span>))
         (query (<span class="org-keyword">cond</span> ((<span class="org-keyword">and</span> id custom-id)
                       <span class="org-comment-delimiter">;; </span><span class="org-comment">This will be slow because it isn't optimized to a single regexp.  :(</span>
                       (<span class="org-warning">warn</span> <span class="org-string">"Entry has both ID and CUSTOM_ID set; query will be slow"</span>)
                       `(<span class="org-keyword">or</span> (link <span class="org-builtin">:target</span> ,(concat <span class="org-string">"id:"</span> id))
                            (link <span class="org-builtin">:target</span> ,(concat <span class="org-string">"id:"</span> custom-id))))
                      ((<span class="org-keyword">or</span> id custom-id)
                       `(link <span class="org-builtin">:target</span> ,(concat <span class="org-string">"id:"</span> (<span class="org-keyword">or</span> id custom-id))))
                      (t (<span class="org-warning">error</span> <span class="org-string">"Entry has no ID nor CUSTOM_ID property"</span>))))
         (title (concat <span class="org-string">"Links to: "</span> (org-get-heading t t)))
         (org-agenda-tag-filter nil))
    (org-ql-search (<span class="org-keyword">quote</span> (<span class="org-string">"~/org/zettels.org"</span>)) query <span class="org-builtin">:title</span> title)))
</pre>
</div>

<p>
It uses the wonderful <a href="https://github.com/alphapapa/org-ql">org-ql</a> package to search all org headings with a link matching the org-id of the current note. The search is limited to my <code>zettels.org</code> file. 
</p>
</div>
</div>

<div id="outline-container-org35984f6" class="outline-3">
<h3 id="org35984f6">Jump to a random zettel</h3>
<div class="outline-text-3" id="text-org35984f6">
<p>
The last bit I needed for serendipity is jumping to a random note. For this, I use the <a href="http://github.com/mwfogleman/org-randomnote">org-randomnote</a> package. This package uses the <code>org-randomnote-candidates</code> variable to store the list of files that will be searched for random headings. It is initialized to the value of <code>org-agenda-files</code>. I just wrote a couple of functions to temporary change the list of candidate files so that I can limit the random jump to my zettels file:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">defun</span> <span class="org-function-name">my/random-note</span> (candidates)
  <span class="org-doc">"Jump to a random org heading in one of the `CANDIDATES` files"</span>
  (<span class="org-keyword">let</span> ((old-randomnote-candidates org-randomnote-candidates))
    (<span class="org-keyword">setq</span> org-randomnote-candidates candidates)
    (org-randomnote <span class="org-string">"zettels"</span>)
    (<span class="org-keyword">setq</span> org-randomnote-candidates old-randomnote-candidates)))

(<span class="org-keyword">defun</span> <span class="org-function-name">my/random-zettel</span> ()
  <span class="org-doc">"Jump to a random zettel"</span>
  (<span class="org-keyword">interactive</span>)
  (my/random-note '(<span class="org-string">"~/org/zettels.org"</span>)))
</pre>
</div>
</div>
</div>
</div>

<div id="outline-container-orgfde8560" class="outline-2">
<h2 id="orgfde8560">Moving to org-roam (or maybe not)</h2>
<div class="outline-text-2" id="text-orgfde8560">
<p>
My first Zettel dates back to December 30 2019. I've been using this system since then and I am very happy with it. A year ago, I started seeing a big buzz about org-roam and I looked into it. It seemed very nice, with functionalities that I don't have in my system and I started wondering whether I should use it. Since at that time I understood that there were some breaking changes planned for version 2, I decided to wait for org-roam v2 to be released and re-evaluate the situation.
</p>

<p>
In the meantime, my Zettelkasten has continued growing. Today, it contains 1345 zettels. After org-roam v2 was released, David Wilson at System Crafters did a <a href="https://www.youtube.com/playlist?list=PLEoMzSkcN8oN3x3XaZQ-AXFKv52LZzjqD">series of videos</a> showing the power of org-roam. As always, David's videos are of great help to get started and he has the rare ability of guiding the interested <i>crafter</i> so that he or she is able to customize thing as wanted.
</p>

<p>
I therefore installed org-roam and even wrote the code to migrate my <i>Zettelkustom</i> to org-roam. I was an interesting exercise that allowed me increase my knowledge of Emacs Lisp and get familiar with the <code>org-element</code> API.
</p>

<p>
However, I am not sure that I want to do the migration. Although org-roam is very rich and has a large community of users, I have the feeling that it does to many things that I don't need. I guess that, if I was starting with org-mode, org-roam would be the good choice, but I have been using org-mode for personal organization (with GTD), note taking, writing scientific papers and reports, doing literate programming, and may more things.
</p>

<p>
And I have my personal preferences and habits that I will likely not change. For instance, for me, mixing project management and Zettelkasten does not make sense. I also don't need a special integration between Zettelkasten and my bibliographic database (<a href="https://github.com/jkitchin/org-ref">org-ref</a> and <a href="https://github.com/tmalsburg/helm-bibtex/blob/master/README.ivy-bibtex.org">ivy-bibtex</a> are all I need).
</p>

<p>
Therefore, by now, I'll stick to my 2 capture templates and 2 simple functions that I understand well.
</p>

<p>
I any case, all this shows the power of org-mode and its ecosystem.
</p>
</div>
</div>
<div class="taglist"><a href="https://dindi.garjola.net/tags.html">Tags</a>: <a href="https://dindi.garjola.net/tag-emacs.html">emacs</a> <a href="https://dindi.garjola.net/tag-zettelkasten.html">zettelkasten</a> <a href="https://dindi.garjola.net/tag-org-mode.html">org-mode</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[zettelkasten]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://dindi.garjola.net/zettelkustom.html</link>
  <guid>https://dindi.garjola.net/zettelkustom.html</guid>
  <pubDate>Sun, 03 Oct 2021 21:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Listen to a random album and generate a log entry (all with Emacs, of course)]]></title>
  <description><![CDATA[
<p>
When I was young, and vinyl records were not a cool thing but just the usual thing, I used to sit down and listen to music. Actually, I used to listen to <i>albums</i>, which is a forgotten concept that has been replaced by <i>playlists</i>. Anyway.
</p>

<p>
The fact of just listening to music and not doing anything else has been a luxury for years, but two years ago, I decided that I would sit down and listen again to music with full attention. Unfortunately, I don't have my vinyl collection anymore. All my music has been digitized and lives in the hard disk drive of my laptop. This has the great advantage of being available everywhere I go.
</p>

<p>
I of course use Emacs as my media player. And I use EMMS because it was the only solution available when I started and I like it. EMMS allows to browse the available music by album, artist, song, etc. So, when I want to listen to an album, I can just do <code>M-x emms-browse-by-album</code> and choose one album. This is what the buffer with the albums looks like:
</p>


<figure id="orgf0c90a9">
<img src="./static/media/screenshot-emms.png" alt="screenshot-emms.png">

</figure>

<p>
So for a couple of years I have had a weekly ritual, on Sunday afternoons, where I choose an album, put my comfortable headphones and listen to a full album, track by track, in the order they were defined by the artists. Then, I log the album to an org-mode file, so that I can keep track of what I listen.
</p>

<p>
The issue I have had is of course choosing what to listen to. One year in this new habit, I decided that I would choose the album randomly. So I started using <code>M-:</code> to type <code>(random 1077)</code><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, then <code>M-x goto-line</code> with the result of the random choice.
</p>

<p>
Of course, after several weeks, this became tedious and I had to automate it. I also decided that I did not want to write the log entry by hand. This is what I came up with:
</p>


<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">defun</span> <span class="org-function-name">my/emms-play-random-album</span> ()
  <span class="org-doc">"Play a random album from the EMMS music database.</span>
<span class="org-doc">Generate an org entry with album artist and listened date for my records."</span>
  (<span class="org-keyword">interactive</span>)
  (emms-browse-by-album)
  (<span class="org-keyword">let</span> ((nlines (count-lines (point-min) (point-max))))
    (goto-line (random nlines))
    (emms-browser-add-tracks-and-play))
  (<span class="org-keyword">let*</span> ((album (alist-get 'info-album  (emms-playlist-current-selected-track)))
        (artist (alist-get 'info-artist (emms-playlist-current-selected-track)))
        (org-entry
         (format <span class="org-string">"* %s\n:PROPERTIES:\n:ARTIST: %s\n:LISTEN_DATE: %s\n:END:\n"</span>
                 album artist (format-time-string <span class="org-string">"[%Y-%m-%d %a]"</span>))))
    (kill-new org-entry)
    (message org-entry)))
</pre>
</div>

<p>
The function is easy to understand. I start by opening the album browser. Then, I count the number of lines in the buffer, and jump to a random line. The call to <code>(emms-browser-add-tracks-and-play)</code> just does what it says. This is just automating what I was doing by hand, but calls the same commands I was using.
</p>

<p>
I am more proud of what follows, which allows me to generate the bit of org-mode text that I need for my logs. Here, I get the name of the album and the artist of the track that just started playing using the appropriate EMMS internal function. Then I format the string with an org headline containing the album title and a property drawer with the artist and the date. It looks like this:
</p>

<pre class="example" id="org888a05c">
* Undercover
:PROPERTIES:
:ARTIST: Rolling Stones, The
:LISTEN_DATE: [2021-09-26 Sun]
:END:
</pre>


<p>
I don't automatically put the entry in the log file, because sometimes I play a random album without wanting to log it. What I do here is put the entry in the kill ring so I can yank it in the appropriate place. And I also display it in the echo area.
</p>

<p>
This is yet another example of how powerful living in Emacs is. You can bridge packages that were not designed to work together (here EMMS and org-mode) to automate things. In other <b>operating systems</b>, if the <i>apps</i> are not from the same vendor and that they have not foreseen to use them together, you can't do that.
</p>

<p>
Another nice thing here is that the EMMS buffer (the album list here, but it is the same with the playlists, or any other buffer) is just text, so you can move around as in any other buffer (with <code>goto-line</code> in this example).
</p>

<p>
Finally, being able to use any internal function or variable of a package (<code>emms-playlist-current-selected-track</code> in my case) is very handy. As always, in Emacs, everything (the code, the documentation, etc.) is always available for the users to do whatever they need.
</p>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">yes I have that many albums</p></div></div>


</div>
</div><div class="taglist"><a href="https://dindi.garjola.net/tags.html">Tags</a>: <a href="https://dindi.garjola.net/tag-emacs.html">emacs</a> <a href="https://dindi.garjola.net/tag-emms.html">emms</a> <a href="https://dindi.garjola.net/tag-music.html">music</a> <a href="https://dindi.garjola.net/tag-org-mode.html">org-mode</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[emms]]></category>
  <category><![CDATA[music]]></category>
  <category><![CDATA[org-mode]]></category>
  <link>https://dindi.garjola.net/emms-random-album.html</link>
  <guid>https://dindi.garjola.net/emms-random-album.html</guid>
  <pubDate>Sun, 26 Sep 2021 21:00:00 +0200</pubDate>
</item>
<item>
  <title><![CDATA[Fetch e-mail with mbsync in Emacs with a hydra to choose the channel]]></title>
  <description><![CDATA[
<p>
E-mail is my preferred way of communication, even if some say that <a href="http://jordiinglada.net/sblog/endofemail.html">e-mail is doomed</a>.
</p>

<p>
I read my e-mail with Gnus in Emacs. The IMAP back-end in Gnus can sometimes be slow over the network and therefore lock Emacs while fetching. Another drawback of IMAP is the need to be on-line to access the e-mails on the server. Finally, having a local copy of all my messages is important for e-mail provider independence.
</p>

<p>
This is why I use <a href="https://isync.sourceforge.io/">mbsync/isync</a> to get my e-mail for several accounts. This can happen outside of Emacs by calling the <code>mbsync</code> command which will use the appropriate configuration in <code>.mbsyncrc</code> to do its thing. I could put this on a cron job, but I prefer to run the e-mail fetching at my pace. Since my interface to the computer is Emacs, I want to be able to use <code>mbsync</code> from Emacs.
</p>

<p>
It shouldn't be difficult to write an Elisp function to call an external process running <code>mbsync</code>, but Dimitri Fontaine put together <a href="https://github.com/dimitri/mbsync-el">mbsync.el</a> which does this cleanly logging output to a dedicated buffer and warning if things go wrong when trying to connect to servers.
</p>

<p>
Unfortunately, <code>mbsync.el</code> runs <code>mbsync</code> with the <code>-a</code> flag, which means that all channels (that is the e-mail accounts configured in <code>.mbsyncrc</code>) will be fetched. While this is a sane default, I sometimes want to fetch just one e-mail channel. The author of <code>mbsync.el</code> had the nice idea of providing a customizable variable to store the flags:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">defcustom</span> <span class="org-variable-name">mbsync-args</span> '(<span class="org-string">"-a"</span>)
  <span class="org-doc">"List of options to pass to the `</span><span class="org-doc"><span class="org-constant">mbsync</span></span><span class="org-doc">' command."</span>
  <span class="org-builtin">:group</span> 'mbsync
  <span class="org-builtin">:type</span> '(repeat string))
</pre>
</div>

<p>
We can therefore exploit this to change the flags. I wrote the following function to call <code>mbsync</code> for a particular channel:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">defun</span> <span class="org-function-name">gd/mbsync-single-channel</span> (channel-name)
  <span class="org-doc">"Fetch e-mail with mbsync for a single channel"</span>
  (<span class="org-keyword">interactive</span> <span class="org-string">"smbsync channel: "</span>)
  (message <span class="org-string">"Fetching mail for channel %s"</span> channel-name)
  (<span class="org-keyword">let</span> ((mbsync-args (list channel-name))
        (mbsync-buffer-name (format <span class="org-string">"*mbsync %s*"</span> channel-name)))
    (mbsync)))
</pre>
</div>

<p>
The function takes a string containing the channel name and will use it as the flag to call <code>mbsync</code>. I also change the name of the the buffer where <code>mbsync.el</code> will write the logs (<code>mbsync-buffer-name</code> is a variable defined in <code>mbsync.el</code>). Binding the variables with <code>let</code> leaves them as they were before calling the function.
</p>

<p>
This function can be called as an interactive command (with <code>M-x</code>), but can also be used to define one function for each e-mail channel:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">defun</span> <span class="org-function-name">gd/mbsync-proton</span> ()
  (<span class="org-keyword">interactive</span>)
  (gd/mbsync-single-channel <span class="org-string">"proton"</span>))
(<span class="org-keyword">defun</span> <span class="org-function-name">gd/mbsync-fastmail</span> ()
  (<span class="org-keyword">interactive</span>)
  (gd/mbsync-single-channel <span class="org-string">"fastmail"</span>))
(<span class="org-keyword">defun</span> <span class="org-function-name">gd/mbsync-gmx</span> ()
  (<span class="org-keyword">interactive</span>)
  (gd/mbsync-single-channel <span class="org-string">"gmx"</span>))
(<span class="org-keyword">defun</span> <span class="org-function-name">gd/mbsync-garjola</span> ()
  (<span class="org-keyword">interactive</span>)
  (gd/mbsync-single-channel <span class="org-string">"garjola"</span>))
</pre>
</div>


<p>
I am not very happy with this approach, since there is lots of redundancy. Maybe I could use some macros to simplify this, but I am not proficient enough in Elisp yet.
</p>

<p>
With these functions, I can define a <a href="https://duckduckgo.com/l/?uddg=https%3A%2F%2Fgithub.com%2Fabo%2Dabo%2Fhydra">hydra</a> which will provide a menu to select the e-mail channel to fetch.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">defhydra</span> gd/hydra-mbsync (<span class="org-builtin">:timeout</span> 4)
  <span class="org-doc">"Fetch e-mail with mbsync"</span>
  (<span class="org-string">"p"</span> gd/mbsync-proton  <span class="org-string">"proton"</span>)
  (<span class="org-string">"f"</span> gd/mbsync-fastmail  <span class="org-string">"fastmail"</span>)
  (<span class="org-string">"x"</span> gd/mbsync-gmx  <span class="org-string">"gmx"</span>)
  (<span class="org-string">"g"</span> gd/mbsync-garjola <span class="org-string">"garjola"</span>))

(global-set-key (kbd <span class="org-string">"&lt;f9&gt; O"</span>) 'gd/hydra-mbsync/body)
</pre>
</div>

<p>
Now, when I type <code>&lt;f9&gt; O</code>, the following menu appears in the mini-buffer.
</p>



<figure id="org6203c3a">
<img src="./static/media/screenshot-hydra.png" alt="screenshot-hydra.png">

</figure>

<p>
And I can select which channels to fetch. Yes, channels in plural, because this is a persistent menu which stays there for 4 seconds (the <i>timeout</i> parameter of the hydra) and I can select several of the channels.
</p>
<div class="taglist"><a href="https://dindi.garjola.net/tags.html">Tags</a>: <a href="https://dindi.garjola.net/tag-emacs.html">emacs</a> <a href="https://dindi.garjola.net/tag-hydra.html">hydra</a> <a href="https://dindi.garjola.net/tag-mbsync.html">mbsync</a> <a href="https://dindi.garjola.net/tag-email.html">email</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[hydra]]></category>
  <category><![CDATA[mbsync]]></category>
  <category><![CDATA[email]]></category>
  <link>https://dindi.garjola.net/mbsync-hydra.html</link>
  <guid>https://dindi.garjola.net/mbsync-hydra.html</guid>
  <pubDate>Sun, 11 Apr 2021 21:00:00 +0200</pubDate>
</item>
</channel>
</rss>
