<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Emacs on Wai Hon&#39;s Blog</title>
    <link>https://whhone.com/tags/emacs/</link>
    <description>Recent content in Emacs on Wai Hon&#39;s Blog</description>
    <generator>weblorg 0.1.0 (https://emacs.love/weblorg)</generator>
    <language>en</language>
    <lastBuildDate>Fri, 03 Jan 2025 18:00:00 -0800</lastBuildDate>
    <atom:link
        href='https://whhone.com/tags/emacs/index.xml'
        rel="self"
        type="application/rss+xml" />

    <item>
      <title>Distinguish Repeated Tasks in Org Agenda</title>
      <link>https://whhone.com//posts/org-agenda-repeated-tasks/</link>
      <guid>https://whhone.com//posts/org-agenda-repeated-tasks/</guid>
      <pubDate>Fri, 03 Jan 2025 18:00:00 -0800</pubDate>
      <author>whhone@gmail.com (Wai Hon Law)</author>
      <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="#problem-repeated-or-not">Problem: Repeated or Not?</a></li>
<li><a href="#solution-setting-the-prefix-format">Solution: Setting the Prefix Format</a></li>
<li><a href="#alternatives">Alternatives</a>
<ul>
<li><a href="#using-the-agenda-finalize-hook-hacky">Using the Agenda Finalize Hook (Hacky)</a></li>
<li><a href="#using-column-view-cluttered">Using Column View (Cluttered)</a></li>
</ul>
</li>
</ul>
</div>
</nav>
<div id="outline-container-problem-repeated-or-not" class="outline-2">
<h2 id="problem-repeated-or-not">Problem: Repeated or Not?</h2>
<div class="outline-text-2">
<p>
In the Org agenda view, <a href="https://orgmode.org/manual/Repeated-tasks.html">repeated</a> and non-repeated tasks look identical. This similarity makes me hesitant to mark a task as DONE; if a task that should be recurring is missing its repeater (e.g., <code>++1w</code>), it will disappear permanently from the agenda instead of being rescheduled.
</p>

<p>
It would be helpful if repeated tasks were visually distinct in the Org agenda, for example, by displaying the repeater interval (<code>++1w</code>) as part of the entry.
</p>
</div>
</div>
<div id="outline-container-solution-setting-the-prefix-format" class="outline-2">
<h2 id="solution-setting-the-prefix-format">Solution: Setting the Prefix Format</h2>
<div class="outline-text-2">

<figure>
<img src="/attachment/org-agenda-repeat-prefix-compare.png" alt="org-agenda-repeat-prefix-compare.png">

</figure>

<p>
Thanks to a <a href="https://fosstodon.org/@yantar92/113769144726128359">tip</a> from yantar92 (the current Org maintainer), I was able to add the repeater to the Org agenda using <code>org-agenda-prefix-format</code>. The process involves three steps:
</p>

<ul class="org-ul">
<li>Shorten the scheduled leaders to make space for the repeater.</li>
<li>Add a function to retrieve the formatted repeater.</li>
<li>Include the new function in <code>org-agenda-prefix-format</code>.</li>
</ul>

<p>
This requires only a few lines of Elisp:
</p>

<div class="org-src-container">
<pre class="src src-elisp"><span class="org-comment-delimiter">;; </span><span class="org-comment">Shorten leaders to reserve space for the repeater.
</span>(<span class="org-keyword">setq</span> org-agenda-scheduled-leaders '(<span class="org-string">"Sched."</span> <span class="org-string">"S.%2dx"</span>))
(<span class="org-keyword">setq</span> org-agenda-deadline-leaders '(<span class="org-string">"Deadl."</span> <span class="org-string">"In%2dd"</span> <span class="org-string">"D.%2dx"</span>))

(<span class="org-keyword">defun</span> <span class="org-function-name">my/org-agenda-repeater</span> ()
  <span class="org-doc">"Return the repeater string for the current agenda entry."</span>
  (<span class="org-keyword">if</span> (org-before-first-heading-p)
      <span class="org-string">"-------"</span>  <span class="org-comment-delimiter">; </span><span class="org-comment">Align with the time grid
</span>    (format <span class="org-string">"%5s: "</span> (<span class="org-keyword">or</span> (org-get-repeat) <span class="org-string">""</span>))))

<span class="org-comment-delimiter">;; </span><span class="org-comment">Add `</span><span class="org-comment"><span class="org-constant">my/org-agenda-repeater</span></span><span class="org-comment">' to the agenda prefix format.
</span>(setcdr (assoc 'agenda org-agenda-prefix-format)
        <span class="org-string">" %i %-12:c%?-12t%s%(my/org-agenda-repeater)"</span>)
</pre>
</div>
</div>
</div>
<div id="outline-container-alternatives" class="outline-2">
<h2 id="alternatives">Alternatives</h2>
<div class="outline-text-2" id="text-alternatives">
</div>
<div id="outline-container-using-the-agenda-finalize-hook-hacky" class="outline-3">
<h3 id="using-the-agenda-finalize-hook-hacky">Using the Agenda Finalize Hook (Hacky)</h3>
<div class="outline-text-3">
<p>
Before learning about yantar92's tip, I used a hackier solution (<a href="https://gist.github.com/whhone/214fa34d57ec6eebc09f3c45bc153378">gist</a>):
</p>

<ul class="org-ul">
<li>Fetch the repeater using <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Text-Properties.html">text properties</a> associated with the agenda entry.</li>
<li>Use <code>org-agenda-finalize-hook</code>, which runs after the agenda view is built but before it is displayed, to insert the repeater string.</li>
</ul>
</div>
</div>
<div id="outline-container-using-column-view-cluttered" class="outline-3">
<h3 id="using-column-view-cluttered">Using Column View (Cluttered)</h3>
<div class="outline-text-3">
<p>
Prior to that, I tried another solution using column view (<code>M-x org-agenda-columns</code>). This method involves setting the <code>:COLUMNS:</code> property to display the <code>SCHEDULED</code> date as a separate column.
</p>


<figure>
<img src="/attachment/org-agenda-columns-with-scheduled.png" alt="org-agenda-columns-with-scheduled.png">

</figure>

<div class="org-src-container">
<pre class="src src-elisp">(<span class="org-keyword">setq</span> org-columns-default-format-for-agenda
      <span class="org-string">"%TODO %PRIORITY(Pri) %60ITEM(Task) %SCHEDULED"</span>)
</pre>
</div>

<p>
While this approach works and is built-in, the resulting display is verbose and difficult to parse visually. This led me to seek a better solution with custom Elisp.
</p>
</div>
</div>
</div>
]]></description>
    </item>

    <item>
      <title>Using Emacs in a Terminal</title>
      <link>https://whhone.com//posts/emacs-in-a-terminal/</link>
      <guid>https://whhone.com//posts/emacs-in-a-terminal/</guid>
      <pubDate>Fri, 23 Aug 2024 20:00:00 -0700</pubDate>
      <author>whhone@gmail.com (Wai Hon Law)</author>
      <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="#introduction">Introduction</a></li>
<li><a href="#issues">Issues</a></li>
<li><a href="#solutions">Solutions</a>
<ul>
<li><a href="#pick-a-good-terminal-emulator">Pick a Good Terminal Emulator</a></li>
<li><a href="#use-emacs-in-a-tmux-session">Use Emacs in a Tmux Session</a></li>
<li><a href="#make-emacs-colorful">Make Emacs Colorful</a></li>
<li><a href="#copy-text-to-native-clipboard-osc-52">Copy Text to Native Clipboard (OSC 52)</a></li>
<li><a href="#open-link-in-local-browser">Open Link in Local Browser</a></li>
<li><a href="#tweak-for-xterm-paste">Tweak for xterm-paste</a></li>
<li><a href="#update-key-maps-that-works-in-terminal">Update Key Maps that Works in Terminal</a></li>
<li><a href="#show-diff-highlighting-with-margin">Show Diff Highlighting with Margin</a></li>
<li><a href="#enable-mouse-support">Enable Mouse Support</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
</div>
</nav>

<figure>
<img src="/attachment/24-bit-color.png" alt="24-bit-color.png">

</figure>

<p>
<i>Fun fact: a coworker thought I was using a GUI application when they saw my terminal Emacs.</i>
</p>
<div id="outline-container-introduction" class="outline-2">
<h2 id="introduction">Introduction</h2>
<div class="outline-text-2">
<p>
At my workplace, most coding tasks must be performed on a remote workstation (or a browser-based IDE) due to policies prohibiting local storage of source code and the limited development tools available on company laptops.
</p>

<p>
Coding with Emacs on a remote workstation requires access via SSH or a remote desktop connection. I have experimented with various solutions, including Tramp, Chrome Remote Desktop, <a href="https://docs.gtk.org/gtk3/broadway.html">GTK Broadway</a>, <a href="https://github.com/Xpra-org/xpra">xpra</a>, and <a href="https://github.com/wayland-transpositor/wprs">wprs</a>. However, these proved buggy, resource-intensive, or slow. Consequently, I settled on the reliable terminal-based approach using SSH and Tmux.
</p>
</div>
</div>
<div id="outline-container-issues" class="outline-2">
<h2 id="issues">Issues</h2>
<div class="outline-text-2">
<p>
Initially, I encountered several issues using Emacs in the terminal, as things were not working out-of-the-box:
</p>

<ul class="org-ul">
<li>Emacs was no longer colorful.</li>
<li>Some keybindings did not work.</li>
<li>I could not copy text to the native clipboard.</li>
<li>Version control diff highlighting was not visible.</li>
<li>Opening links in a local browser was not easy.</li>
</ul>

<p>
Over time, I discovered solutions and workarounds for these issues and began to enjoy some extra benefits I had not expected:
</p>

<ul class="org-ul">
<li>Using the same Emacs instance across multiple computers.</li>
<li>Eliminating Crostini on my Chromebook.</li>
<li>Reducing the need to synchronize files and resolve conflicts.</li>
<li>Remote file editing is faster than Tramp.</li>
<li>Providing a more native terminal experience via Tmux multiplexing (compared to <code>vterm</code>, <code>shell</code>, etc.).</li>
<li>No font size scaling issue.</li>
</ul>
</div>
</div>
<div id="outline-container-solutions" class="outline-2">
<h2 id="solutions">Solutions</h2>
<div class="outline-text-2">
<p>
Here's how I configured Emacs for comfortable terminal use.
</p>
</div>
<div id="outline-container-pick-a-good-terminal-emulator" class="outline-3">
<h3 id="pick-a-good-terminal-emulator">Pick a Good Terminal Emulator</h3>
<div class="outline-text-3">
<p>
First, pick a terminal emulator that supports at least:
</p>

<ol class="org-ol">
<li>true color, and</li>
<li>OSC 52 (for system clipboard integration).</li>
</ol>

<p>
Ideally, it should have fewer default keybindings or allow customization to avoid conflicts with Emacs.
</p>

<p>
The default Chrome OS terminal (<a href="https://hterm.org/">hterm</a>) is what I currently use, as it meets all three requirements. I do not use Linux, macOS, or Windows frequently enough nowadays to offer recommendations for those platforms.
</p>

<p>
Some terminals can even display images! E.g., the <a href="https://sw.kovidgoyal.net/kitty/graphics-protocol/">terminal graphics protocol</a> by Kitty, the <a href="https://iterm2.com/documentation-images.html">inline image protocol</a> by iTerm2, and the <a href="https://en.wikipedia.org/wiki/Sixel">Sixel protocol</a>. It would be nice if there were Emacs integration with them!
</p>
</div>
</div>
<div id="outline-container-use-emacs-in-a-tmux-session" class="outline-3">
<h3 id="use-emacs-in-a-tmux-session">Use Emacs in a Tmux Session</h3>
<div class="outline-text-3">
<p>
I use Emacs inside Tmux because it provides a persistent session that can be reattached from any computer or after losing an SSH connection. I also automatically reattach to the Tmux session upon SSH connection with this SSH config:
</p>

<div class="org-src-container">
<pre class="src src-ssh-config"><span class="org-keyword">Host</span> myhost
  <span class="org-keyword">RemoteCommand</span> tmux -u new -A -D -s main
  <span class="org-keyword">RequestTTY</span> yes
</pre>
</div>

<p>
Alternative ssh command:
</p>

<div class="org-src-container">
<pre class="src src-sh">ssh -t myhost tmux -u new -A -D -s main
</pre>
</div>

<p>
Alternative shell script approach:
</p>

<div class="org-src-container">
<pre class="src src-sh"><span class="org-comment-delimiter"># </span><span class="org-comment">.bashrc
</span><span class="org-comment-delimiter"># </span><span class="org-comment">Attach to the main Tmux session if it is
</span><span class="org-comment-delimiter"># </span><span class="org-comment">- in SSH session
</span><span class="org-comment-delimiter"># </span><span class="org-comment">- not inside Tmux
</span><span class="org-comment-delimiter"># </span><span class="org-comment">- not inside Emacs
</span><span class="org-keyword">if</span> [[ -n <span class="org-string">"$SSH_CLIENT"</span> &amp;&amp; -z <span class="org-string">"$TMUX"</span> &amp;&amp; -z <span class="org-string">"$INSIDE_EMACS"</span> ]]; <span class="org-keyword">then</span>
    <span class="org-comment-delimiter"># </span><span class="org-comment">"-A" : reattach if session-name already exists
</span>    <span class="org-comment-delimiter"># </span><span class="org-comment">"-D" : detach other clients (ensure $SSH_TTY is always correct)
</span>    tmux new -A -D -s main
<span class="org-keyword">fi</span>
</pre>
</div>

<p>
Tmux also allows me to have multiple workspaces using Tmux windows (or sessions).
</p>

<p>
If I need extra terminals, I split new panes or new windows. I find the Tmux terminal better than Emacs's <code>term</code>, <code>shell</code>, <code>vterm</code>, or <code>eat</code>, because it is more native, faster, and easily distinguishable from an Emacs buffer.
</p>

<p>
Also, I can add information like the system status (CPU, RAM, Disk, etc.) and the current time to the Tmux status bar.
</p>

<p>
Optionally, change the default Tmux leader to reserve <code>C-b</code> for moving the cursor.
</p>

<div class="org-src-container">
<pre class="src src-tmux"><span class="org-keyword">set-option</span> <span class="org-type">-g</span> <span class="org-builtin">prefix</span> M-<span class="org-escape">\</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-make-emacs-colorful" class="outline-3">
<h3 id="make-emacs-colorful">Make Emacs Colorful</h3>
<div class="outline-text-3">
<p>
The screenshots below show the difference with and without true color (24-bit color) enabled.
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Without true color, low contrast</th>
<th scope="col" class="org-left">With true color, high contrast</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><img src="/attachment/emacs-without-truecolor.png" alt="emacs-without-truecolor.png"></td>
<td class="org-left"><img src="/attachment/emacs-with-truecolor.png" alt="emacs-with-truecolor.png"></td>
</tr>
</tbody>
</table>

<p>
There are a few ways to get true color in a terminal Emacs session:
</p>
<ol class="org-ol">
<li>Use a <code>TERM</code> that supports true color, e.g., <code>xterm-direct</code>. (This won't work inside Tmux, which changes the term to <code>tmux-256color</code>.)</li>
<li>Set the <code>COLORTERM</code> environment variable to <code>truecolor</code>. (<b>preferred</b>)</li>
</ol>

<div class="org-src-container">
<pre class="src src-sh"><span class="org-comment-delimiter"># </span><span class="org-comment">.bashrc
</span><span class="org-builtin">export</span> <span class="org-variable-name">COLORTERM</span>=truecolor
</pre>
</div>

<p>
There are a few ways to get true color support in Tmux:
</p>
<ol class="org-ol">
<li>Use a <code>TERM</code> that supports true color, e.g., <code>xterm-direct</code>, or</li>
<li>Start tmux with the RGB feature, e.g., <code>tmux -T RGB</code>, or</li>
<li>Override the features of your terminal in <code>.tmux.conf</code>, e.g.:</li>
</ol>

<div class="org-src-container">
<pre class="src src-sh"><span class="org-comment-delimiter"># </span><span class="org-comment">.tmux.conf
</span><span class="org-comment-delimiter"># </span><span class="org-comment">See https://github.com/tmux/tmux/wiki/FAQ#how-do-i-use-rgb-colour.
</span><span class="org-builtin">set</span> -as terminal-overrides <span class="org-string">",xterm-256color:RGB"</span>
</pre>
</div>

<p>
Tip: Use <a href="https://gist.github.com/whhone/6852e485e8ccf51fd3631ba29ab7fad2">this script</a> to test for true color support.
</p>
</div>
</div>
<div id="outline-container-copy-text-to-native-clipboard-osc-52" class="outline-3">
<h3 id="copy-text-to-native-clipboard-osc-52">Copy Text to Native Clipboard (OSC 52)</h3>
<div class="outline-text-3">
<p>
OSC 52 works by printing an unreadable sequence, <code>\033]52;c;[base64 data]\a</code>, which instructs the terminal to alter the system clipboard with the base64-encoded data. To verify that OSC 52 is working for your terminal setup, run <code>printf "\033]52;c;$(printf \"Hello, world\" | base64)\a"</code> from the terminal. It should put "Hello, world" into the system clipboard.
</p>

<p>
In the Emacs config, install the <a href="https://github.com/spudlyo/clipetty">Clipetty</a> package, which sends text that you kill in Emacs to the native clipboard.
</p>

<div class="org-src-container">
<pre class="src src-elisp"><span class="org-comment-delimiter">;; </span><span class="org-comment">init.el
</span>(<span class="org-keyword">use-package</span> clipetty
  <span class="org-builtin">:hook</span> (after-init . global-clipetty-mode))
</pre>
</div>

<p>
To enable clipboard support in Tmux, add these lines to <code>.tmux.conf</code>:
</p>

<div class="org-src-container">
<pre class="src src-sh"><span class="org-comment-delimiter"># </span><span class="org-comment">.tmux.conf
</span><span class="org-builtin">set</span> -g set-clipboard on

<span class="org-comment-delimiter"># </span><span class="org-comment">Required to make Clipetty work better on re-attach by appending
</span><span class="org-comment-delimiter"># </span><span class="org-comment">"SSH_TTY" to "update-environment". See
</span><span class="org-comment-delimiter"># </span><span class="org-comment">https://github.com/spudlyo/clipetty?tab=readme-ov-file#dealing-with-a-stale-ssh_tty-environment-variable
</span><span class="org-builtin">set</span> -ag update-environment <span class="org-string">"SSH_TTY"</span>
</pre>
</div>

<p>
If it still does not work, try running the <code>printf</code> verification command above and check <a href="https://github.com/tmux/tmux/wiki/Clipboard">the Tmux clipboard wiki</a>.
</p>
</div>
</div>
<div id="outline-container-open-link-in-local-browser" class="outline-3">
<h3 id="open-link-in-local-browser">Open Link in Local Browser</h3>
<div class="outline-text-3">
<p>
I have two workarounds for opening a web link from a remote Emacs session in a local browser:
</p>

<ol class="org-ol">
<li>Use a mouse click if the terminal emulator can recognize links and open them locally.</li>
<li>Copy the link to the local clipboard and paste it into the browser.</li>
</ol>

<p>
For (2), I added an advice to <code>browse-url</code> to place the URL into the native clipboard via OSC 52. I then paste it into a local browser. I also added key and mouse bindings for the function to make copying more seamless.
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span class="org-keyword">define-advice</span> <span class="org-function-name">browse-url</span>
    (<span class="org-builtin">:around</span> (orig-fun <span class="org-type">&amp;rest</span> args) copy-url-if-terminal)
  (<span class="org-keyword">if</span> (display-graphic-p)
      (apply orig-fun args)
    (<span class="org-keyword">let</span> ((url (nth 0 args)))
      (message <span class="org-string">"Clipetty link: %s"</span> url)
      (clipetty--emit (clipetty--osc url t)))))
</pre>
</div>

<p>
See <a href="https://whhone.com/emacs-config/">my Emacs configuration</a> for the full and updated version.
</p>
</div>
</div>
<div id="outline-container-tweak-for-xterm-paste" class="outline-3">
<h3 id="tweak-for-xterm-paste">Tweak for xterm-paste</h3>
<div class="outline-text-3">
<p>
When pasting from the native clipboard, I would like to delete the region if one is active.
</p>

<p>
This is like <code>(delete-selection-mode)</code> for <code>xterm-paste</code>.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">define-advice</span> <span class="org-function-name">xterm-paste</span>
    (<span class="org-builtin">:before</span> (<span class="org-type">&amp;args</span>) delete-active-region)
  <span class="org-doc">"Delete the selected text first before pasting from xterm."</span>
  (<span class="org-keyword">when</span> (use-region-p) (delete-active-region)))
</pre>
</div>
</div>
</div>
<div id="outline-container-update-key-maps-that-works-in-terminal" class="outline-3">
<h3 id="update-key-maps-that-works-in-terminal">Update Key Maps that Works in Terminal</h3>
<div class="outline-text-3">
<p>
The idea is to have a set of keybindings that the terminal can respond to.
</p>

<p>
This part varies from person to person. For example, I have remapped:
</p>

<ul class="org-ul">
<li><code>C-x C-;</code> to <code>C-x ;</code> for <code>comment-line</code> (<code>C-;</code> is unsupported).</li>
<li><code>C-c C-,</code> to <code>C-c ,</code> for <code>org-insert-structure-template</code> (<code>C-,</code> is unsupported).</li>
</ul>

<p>
We can use <code>key-translation-map</code> for the mapping.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span class="org-comment-delimiter">;; </span><span class="org-comment">e.g., comment-line
</span>(define-key key-translation-map (kbd <span class="org-string">"C-x ;"</span>) (kbd <span class="org-string">"C-x C-;"</span>))

<span class="org-comment-delimiter">;; </span><span class="org-comment">e.g., org-insert-structure-template
</span>(define-key key-translation-map (kbd <span class="org-string">"C-c ,"</span>) (kbd <span class="org-string">"C-c C-,"</span>))
</pre>
</div>
</div>
</div>
<div id="outline-container-show-diff-highlighting-with-margin" class="outline-3">
<h3 id="show-diff-highlighting-with-margin">Show Diff Highlighting with Margin</h3>
<div class="outline-text-3">
<p>
<code>diff-hl</code> does not work in the terminal by default, and this issue had annoyed me for a while until I searched for a solution. It turns out that <code>diff-hl</code> already has <a href="https://github.com/dgutov/diff-hl/issues/155">a solution</a>: using the "margin" to show the diff.
</p>

<p>
I added this Elisp config to turn on <code>diff-hl-margin-mode</code> whenever I am inside a terminal.
</p>

<div class="org-src-container">
<pre class="src src-elisp"><span class="org-comment-delimiter">;; </span><span class="org-comment">init.el
</span>(add-hook 'diff-hl-mode-on-hook
          (<span class="org-keyword">lambda</span> ()
            (<span class="org-keyword">unless</span> (display-graphic-p)
              (diff-hl-margin-local-mode))))
</pre>
</div>


<figure>
<img src="/attachment/diff-hl-margin-mode.png" alt="diff-hl-margin-mode.png">

</figure>
</div>
</div>
<div id="outline-container-enable-mouse-support" class="outline-3">
<h3 id="enable-mouse-support">Enable Mouse Support</h3>
<div class="outline-text-3">
<p>
Don't forget to enable mouse support.
</p>

<p>
Note that there was a conflict where any mouse movement over Emacs would deactivate the Tmux prefix key (this is fixed in Tmux 3.5!). See <a href="https://github.com/tmux/tmux/issues/4111">https://github.com/tmux/tmux/issues/4111</a>.
</p>

<div class="org-src-container">
<pre class="src src-elisp"><span class="org-comment-delimiter">;; </span><span class="org-comment">init.el
</span>(xterm-mouse-mode +1)
</pre>
</div>

<div class="org-src-container">
<pre class="src src-tmux"><span class="org-comment-delimiter"># </span><span class="org-comment">.tmux.conf
</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">Enables mouse support in Tmux (switching windows and panes,
</span><span class="org-comment-delimiter"># </span><span class="org-comment">resizing panes, etc.). Setting mouse </span><span class="org-comment"><span class="org-constant">on</span></span><span class="org-comment"> or </span><span class="org-comment"><span class="org-constant">off</span></span><span class="org-comment"> does not disable
</span><span class="org-comment-delimiter"># </span><span class="org-comment">Emacs's xterm-mouse-mode.
</span><span class="org-keyword">set</span> <span class="org-type">-g</span> <span class="org-builtin">mouse</span> <span class="org-constant">on</span>
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-conclusion" class="outline-2">
<h2 id="conclusion">Conclusion</h2>
<div class="outline-text-2">
<p>
For most Emacsers, GUI Emacs is still a better choice because it:
</p>

<ul class="org-ul">
<li>Has no network latency.</li>
<li>Has better multimedia support (images, PDFs, etc.).</li>
<li>Can handle all keybindings.</li>
<li>Can interact with the clipboard natively.</li>
<li>Can open links in a local browser easily.</li>
<li>Is more customizable (font size per buffer, tooltips, etc.).</li>
</ul>

<p>
However, if you, like me, need to work remotely or want to use the same Emacs instance across multiple computers via SSH and Tmux, I hope the tricks above can improve your setup, even at the expense of the aforementioned GUI features.
</p>

<p>
<b>Update on 2025-09</b>: also check out this YouTube video <a href="https://youtu.be/2_6OxZDoWvw">nobody knows that using Emacs in the terminal is so great</a> by Jake B!</p>
</div>
</div>
]]></description>
    </item>

    <item>
      <title>Text Replacement Tools for Large Codebases</title>
      <link>https://whhone.com//posts/large-scale-replace-string/</link>
      <guid>https://whhone.com//posts/large-scale-replace-string/</guid>
      <pubDate>Wed, 25 Oct 2023 00:00:00 -0700</pubDate>
      <author>whhone@gmail.com (Wai Hon Law)</author>
      <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="#for-simple-replacement-sed">For Simple Replacement - <code>sed</code></a></li>
<li><a href="#for-very-large-code-base-fastmod">For Very Large Code Base - <code>fastmod</code></a></li>
<li><a href="#for-simple-replacement-in-emacs-dired">For Simple Replacement in Emacs - <code>dired</code></a></li>
<li><a href="#for-interactive-replacement-in-emacs-wgrep">For Interactive Replacement in Emacs - <code>wgrep</code></a></li>
<li><a href="#for-interactive-replacement-in-emacs-project-project-query-replace-regex">For Interactive Replacement in Emacs Project - <code>project-query-replace-regex</code></a></li>
<li><a href="#epilogue">Epilogue</a></li>
</ul>
</div>
</nav>
<p>
10 years ago, when I became a software engineer, my mentor showed me how to replace all occurrences of a string (or a regex) under a large codebase effectively with a tool called <a href="https://github.com/facebookarchive/codemod">codemod</a>. It turned out to be one of the most useful text-editing techniques in my next 10 years, saving me many hours of "find and replace" manually.
</p>

<p>
Over time, I discovered additional options for different use cases. Here they are.
</p>
<div id="outline-container-for-simple-replacement-sed" class="outline-2">
<h2 id="for-simple-replacement-sed">For Simple Replacement - <code>sed</code></h2>
<div class="outline-text-2">
<p>
<code>sed</code> is my favorite for simple cases because it comes pre-installed in most operating systems.
</p>

<div class="org-src-container">
<pre class="src src-sh"><span class="org-comment-delimiter"># </span><span class="org-comment">replace all instances of `foo` (regex) with `bar` (regex) in a file
</span>sed -i.bak <span class="org-string">"s/foo/bar/g"</span> path/to/file

<span class="org-comment-delimiter"># </span><span class="org-comment">replace all instances of `foo` (regex) with `bar` (regex) found by `find`
</span>find . -name <span class="org-string">'*.cpp'</span> | xargs sed -i.bak <span class="org-string">"s/foo/bar/g"</span>

<span class="org-comment-delimiter"># </span><span class="org-comment">replace all instances of `foo` (regex) with `bar` (regex) in modified files under git
</span>git diff --name-only | xargs sed -i.bak <span class="org-string">"s/foo/bar/g"</span>

<span class="org-comment-delimiter"># </span><span class="org-comment">replace all instances of `foo` (regex) with `bar` (regex) in modified files under hg
</span>hg status --rev .^ -n | xargs sed -i.bak <span class="org-string">"s/foo/bar/g"</span>
</pre>
</div>

<p>
If I encounter a performance issue, I will switch to <code>fastmod</code>.
</p>
</div>
</div>
<div id="outline-container-for-very-large-code-base-fastmod" class="outline-2">
<h2 id="for-very-large-code-base-fastmod">For Very Large Code Base - <code>fastmod</code></h2>
<div class="outline-text-2">
<p>
<a href="https://github.com/facebookincubator/fastmod">fastmod</a> is a fast partial replacement for <a href="https://github.com/facebookarchive/codemod">codemod</a>. It is written in Rust and is designed for large-scale codebase refactoring.
</p>

<div class="org-src-container">
<pre class="src src-sh"><span class="org-comment-delimiter"># </span><span class="org-comment">replace a regex pattern in specific files or directories:
</span>fastmod <span class="org-string">'foo'</span> <span class="org-string">'bar'</span> -- {{path/to/file path/to/directory ...}}
</pre>
</div>

<p>
To install, run <code>cargo install fastmod</code>, assume you have Rust's Cargo installed.
</p>

<p>
For more use cases, see <a href="https://tldr.inbrowser.app/pages/common/fastmod">tldr:fastmod</a>.
</p>
</div>
</div>
<div id="outline-container-for-simple-replacement-in-emacs-dired" class="outline-2">
<h2 id="for-simple-replacement-in-emacs-dired">For Simple Replacement in Emacs - <code>dired</code></h2>
<div class="outline-text-2">
<p>
As an Emacser, I must also provide a way to achieve this in Emacs.
</p>

<ol class="org-ol">
<li>M-x dired</li>
<li>Mark the required files and directories (<code>m</code> to select, <code>t</code> to toggle all)</li>
<li>Press <code>Q</code> (<code>dired-do-find-regexp-and-replace</code>) to replace string by regex
<ol class="org-ol">
<li>Press <code>y</code> to accept.</li>
<li>Press <code>!</code> to accept all.</li>
</ol></li>
</ol>
</div>
</div>
<div id="outline-container-for-interactive-replacement-in-emacs-wgrep" class="outline-2">
<h2 id="for-interactive-replacement-in-emacs-wgrep">For Interactive Replacement in Emacs - <code>wgrep</code></h2>
<div class="outline-text-2">
<p>
<code>wgrep</code> stands for "Writable Grep Buffer". It is a very flexible interactive replacement in Emacs. It gathers all occurrences in a buffer and then you can use whatever you want edit them.
</p>

<ol class="org-ol">
<li>Search with <code>counsel</code>, e.g., <code>counsel-rg</code></li>
<li>C-c C-o (<code>ivy-occur</code>)</li>
<li>C-x C-q (<code>ivy-wgrep-change-to-wgrep-mode</code>)</li>
<li>Edit (e.g., <code>replace-regex</code>)</li>
<li>C-c C-c (commit the changes)</li>
</ol>

<p>
For more details on this method, see:
</p>

<ul class="org-ul">
<li><a href="https://sam217pa.github.io/2016/09/11/nuclear-power-editing-via-ivy-and-ag/">Nuclear weapon multi-editing via Ivy and Ag · Samuel Barreto</a></li>
<li><a href="https://emacs-china.org/t/emacs/16537">Emacs 核弹级的功能与应用 - Emacs China</a></li>
</ul>
</div>
</div>
<div id="outline-container-for-interactive-replacement-in-emacs-project-project-query-replace-regex" class="outline-2">
<h2 id="for-interactive-replacement-in-emacs-project-project-query-replace-regex">For Interactive Replacement in Emacs Project - <code>project-query-replace-regex</code></h2>
<div class="outline-text-2">
<p>
<code>project.el</code> provides a command called <code>project-query-replace-regex</code> (default keybinding: <code>C-x p r</code>) that allows you to interactively replace a regex pattern within a project.
</p>
</div>
</div>
<div id="outline-container-epilogue" class="outline-2">
<h2 id="epilogue">Epilogue</h2>
<div class="outline-text-2">
<p>
In most cases, I prefer <code>sed</code> and <code>fastmod</code> since they allow me to do it in a single command, which makes it easier to iterate the desired command (execute and revert for the right "foo" and "bar").
</p>
</div>
</div>
]]></description>
    </item>

    <item>
      <title>Implementing the PARA Method in Org-mode</title>
      <link>https://whhone.com//posts/para-org-mode/</link>
      <guid>https://whhone.com//posts/para-org-mode/</guid>
      <pubDate>Sat, 31 Dec 2022 00:00:00 -0800</pubDate>
      <author>whhone@gmail.com (Wai Hon Law)</author>
      <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="#the-para-method">The PARA Method</a>
<ul>
<li><a href="#project-vs-area-vs-resource">Project vs Area vs Resource</a></li>
<li><a href="#para-is-pragmatic">PARA is Pragmatic</a></li>
</ul>
</li>
<li><a href="#org-mode-implementation">Org-mode Implementation</a>
<ul>
<li><a href="#tags-and-categories">Tags and Categories</a></li>
<li><a href="#organizing-my-notes">Organizing my Notes</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
</div>
</nav>
<p>
This post first talks about the PARA method and then my Org-mode implementation for organizing tasks and notes.
</p>
<div id="outline-container-the-para-method" class="outline-2">
<h2 id="the-para-method">The PARA Method</h2>
<div class="outline-text-2">
<p>
<a href="https://fortelabs.com/blog/para/">The PARA Method</a> is a modern system for organizing digital information. It stands for Projects-Areas-Resources-Archives, the four categories of all digital information.
</p>

<blockquote>
<ul class="org-ul">
<li><b>Project</b>: a series of tasks linked to a goal, with a deadline.</li>
<li><b>Area</b>: a sphere of activity with a standard to be maintained over time.</li>
<li><b>Resource</b>: a topic or theme of ongoing interest.</li>
<li><b>Archive</b>: inactive items from the other 3 categories.</li>
</ul>
</blockquote>
</div>
<div id="outline-container-project-vs-area-vs-resource" class="outline-3">
<h3 id="project-vs-area-vs-resource">Project vs Area vs Resource</h3>
<div class="outline-text-3">
<p>
"Projects" and "Areas" are inherited from GTD. "Distinguish Project and Area" is a common challenge for GTD and PARA adopters, including me. I once had many unimportant projects without deadlines that cluttered my agenda. There are many discussions and articles on it<sup><a id="fnr.project-vs-area" class="footref" href="#fn.project-vs-area" role="doc-backlink">1</a></sup> and the model answer is to check (1) the nature of the task and (2) if there is a deadline.
</p>

<blockquote>
<ul class="org-ul">
<li>A project has (1) a specific outcome/goal and (2) a deadline.</li>
<li>An area has (1) a standard to be maintained that (2) is continuous over time.</li>
</ul>
</blockquote>

<p>
In addition to the model answer, I have my interpretation,
</p>
<ul class="org-ul">
<li><b>Projects contain the tasks I should focus on</b> (because of the importance, urgency and desirability). They have higher priority over the other categories. I work on them first, especially when there is a chunk of uninterrupted time or my energy level is high. If a "project" does not come with a deadline, I set one for it.</li>
<li><b>Areas contain the tasks I have to do.</b> I reserve some time for these tasks every day to keep areas maintained. I can also skip them for a while when the current projects are too demanding.</li>
<li><b>Resources contain the tasks I am interested to do.</b> When there is no pressure from projects or areas, I can choose to work on these tasks or simply take a rest.</li>
</ul>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">

<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">&#xa0;</th>
<th scope="col" class="org-left">Project</th>
<th scope="col" class="org-left">Area</th>
<th scope="col" class="org-left">Resource</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">Need my focus</td>
<td class="org-left"><b>Yes</b></td>
<td class="org-left">No</td>
<td class="org-left">No</td>
</tr>

<tr>
<td class="org-left">Have to do</td>
<td class="org-left"><i>Maybe</i></td>
<td class="org-left"><b>Yes</b></td>
<td class="org-left">No</td>
</tr>

<tr>
<td class="org-left">Want to do</td>
<td class="org-left"><i>Maybe</i></td>
<td class="org-left"><i>Maybe</i></td>
<td class="org-left"><b>Yes</b></td>
</tr>

<tr>
<td class="org-left">Priority</td>
<td class="org-left">High</td>
<td class="org-left">Medium</td>
<td class="org-left">Low</td>
</tr>
</tbody>
</table>

<p>
These three questions help decide which PARA categories a task should go to:
</p>

<ol class="org-ol">
<li><b>Does it require my focus within a timeframe?</b> If yes, make it a <b>project</b>.</li>
<li><b>Is it something I have to do?</b> If yes, move it to an <b>area</b></li>
<li><b>Is it something I want to do?</b> If yes, move it to a <b>resource</b>.</li>
</ol>
</div>
</div>
<div id="outline-container-para-is-pragmatic" class="outline-3">
<h3 id="para-is-pragmatic">PARA is Pragmatic</h3>
<div class="outline-text-3">
<p>
On one hand, I organize my tasks. On the other hand, I know it is not necessary to get it perfect.
</p>

<p>
Firstly, it takes a lot of effort. I move forward and do the actual work when the tasks are by-and-large in the right places that help to prioritize. The end goal should be the actual outcomes instead of organizing.
</p>

<p>
Secondly, it is impossible. PARA is a system of single classification. Everything is either a project, an area, or a resource. In practice, a task or note can fall into multiple projects, areas, or interests. For example, "planning a trip for the 10-th anniversary" could arguably belong to either area "spouse" or area "travel".
</p>

<p>
Organizing should be forgiving. It is okay to organize wrongly as long as it works. PARA is not a system for perfectionism but for pragmatism.
</p>

<p>
Let's talk about my implementation!
</p>
</div>
</div>
</div>
<div id="outline-container-org-mode-implementation" class="outline-2">
<h2 id="org-mode-implementation">Org-mode Implementation</h2>
<div class="outline-text-2">
<p>
I organize my tasks with PARA using a single <code>todo.org</code> file.
</p>


<figure>
<img src="/attachment/para-todo-org.png" alt="para-todo-org.png">

</figure>
</div>
<div id="outline-container-tags-and-categories" class="outline-3">
<h3 id="tags-and-categories">Tags and Categories</h3>
<div class="outline-text-3">
<p>
I use <b>tags</b> for the actual areas and resources. I assign each of them a specific tag to the corresponding subheadings. This gives me a set of <a href="https://en.wikipedia.org/wiki/Controlled_vocabulary">controlled vocabularies</a> for tagging projects and notes. For example, I know I should use <code>writing</code> instead of <code>write</code> or <code>blogging</code> for area "writing". I don't create tags for projects (which are short-term and grow over time) to keep my tag set small and useful<sup><a id="fnr.tag" class="footref" href="#fn.tag" role="doc-backlink">2</a></sup>.
</p>

<p>
I use <b>categories</b> for the PARA top categories, Project-Area-Resource. When looking at my org agenda view, I immediately know which tasks are my top focuses (Project), which are things I need to do (Area) or interested to do (Resource). I also know which exact area or resource they belong to with the tags on the right.
</p>


<figure>
<img src="/attachment/para-agenda.png" alt="para-agenda.png">

</figure>

<p>
Tip: I can filter tasks by category and tag by pressing <code>/</code> (<code>M-x org-agenda-filter</code>) and clear filters with <code>|</code> (<code>M-x org-agenda-filter-remove-all</code>).
</p>
</div>
</div>
<div id="outline-container-organizing-my-notes" class="outline-3">
<h3 id="organizing-my-notes">Organizing my Notes</h3>
<div class="outline-text-3">
<p>
For project notes, I add or link them directly under the corresponding org subtree in <code>todo.org</code> as I avoid adding project tags. When a project is completed or canceled, I convert the reusable part into the area or resource notes, and archive the project subtree to <code>todo.org_archive</code>.
</p>

<p>
I place the areas and resources notes under <code>~/note</code>. I tag them with the tags defined in <code>todo.org</code> and reserve the directory hierarchy<sup><a id="fnr.subdirectory" class="footref" href="#fn.subdirectory" role="doc-backlink">3</a></sup> for the note types. This gives me the flexibility to have multiple tags for a note.
</p>

<p>
Here is a simplified version of my org directory:
</p>

<pre class="example">
org
├─ todo.org
└─ note
   ├─ 20221125T211904--org-attach__emacs.org
   ├─ ...
   ├─ meta
   │  ├─ ...
   │  └─ 20200202T222222--using-org-mode__emacs.org
   └─ reference
      ├─ article
      │  ├─ ...
      │  └─ 20221226T150449--creating-family-rules__parenting.org
      └─ book
         ├─ ...
         └─ 20220907T134123--building-a-second-brain-tiago-forte__pkm.org
</pre>

<ul class="org-ul">
<li><b><code>note/20221125T211904--org-attach__emacs.org</code></b> is a regular note.</li>
<li><b><code>note/meta/20200202T222222--using-org-mode__emacs.org</code></b> is a meta note that connects other notes, like the <code>org-attach__eamcs.org</code> above.</li>
<li><b><code>note/reference/article/20221226T150449--creating-family-rules__parenting.org</code></b> is a reference note for the article "<a href="https://www.cdc.gov/parents/essentials/structure/rules.html">Creating Family Rules</a>", tagged with my resource "parenting".</li>
<li><b><code>note/reference/book/20220907T134123--building-a-second-brain-tiago-forte__pkm.org</code></b> is a new book note for the book "Building a Second Brain" by Tiago Forte.</li>
</ul>

<p>
So far, I don't archive notes under <code>~/note</code>. If I need to, I might use the tag <code>ARCHIVED</code> and write some elisp to filter them.
</p>
</div>
</div>
</div>
<div id="outline-container-conclusion" class="outline-2">
<h2 id="conclusion">Conclusion</h2>
<div class="outline-text-2">
<p>
Defining how I am going to organize my digital information reduces the cognitive load when working with tasks and notes. I can add or retrieve the information without thinking too much.
</p>

<p>
I love to learn how other people works and I hope this post could be interesting and helpful to you, too. If you like it, you probably also check out these:
</p>
<ul class="org-ul">
<li><a href="https://tasshin.com/blog/implementing-a-second-brain-in-emacs-and-org-mode/">Tassin's implementation</a> which combines Org-mode and Evernote for tasks and notes respectively.</li>
<li><a href="https://renatgalimov.github.io/org-basb-code/#orgb77d8dc">Emacs CODE implementation</a> which focuses on its note taking workflow with lots of details.</li>
</ul>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.project-vs-area" class="footnum" href="#fnr.project-vs-area" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Search them yourself or read this great article: <a href="https://fortelabs.com/blog/project-people-vs-area-people-are-you-running-a-sprint-or-a-marathon/">Project People vs. Area People - Forte Lab</a>.
</p></div></div>

<div class="footdef"><sup><a id="fn.tag" class="footnum" href="#fnr.tag" role="doc-backlink">2</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
It is <a href="https://karl-voit.at/2022/01/29/How-to-Use-Tags/">suggested</a> to <i>use a self-defined set of tags</i> and <i>keep them as few as possible</i>.
</p></div></div>

<div class="footdef"><sup><a id="fn.subdirectory" class="footnum" href="#fnr.subdirectory" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
That is why <a href="https://whhone.com/posts/denote-with-subdirectories/">using denote with subdirectories</a> is important for me.
</p></div></div>


</div>
</div>]]></description>
    </item>

    <item>
      <title>Using Denote with Subdirectories</title>
      <link>https://whhone.com//posts/denote-with-subdirectories/</link>
      <guid>https://whhone.com//posts/denote-with-subdirectories/</guid>
      <pubDate>Thu, 08 Dec 2022 00:00:00 -0800</pubDate>
      <author>whhone@gmail.com (Wai Hon Law)</author>
      <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="#1-search-by-filename-in-subdirectories">#1 Search by Filename in Subdirectories</a></li>
<li><a href="#2-full-text-search-in-subdirectories">#2 Full-Text Search in Subdirectories</a></li>
<li><a href="#3-create-notes-in-subdirectories">#3 Create Notes in Subdirectories</a></li>
<li><a href="#comparing-with-org-roam-again">Comparing with Org-roam Again</a></li>
</ul>
</div>
</nav>
<p>
My <a href="https://whhone.com/posts/denote-vs-org-roam/">last post</a> mentioned the out-of-the-box experience of <a href="https://protesilaos.com/emacs/denote">Denote</a> is not so great, especially when having notes across many subdirectories. By default, Denote searches and creates notes from the root <code>denote-directory</code>. I need to know the exact file location before searching for a note. I need to move note from the root directory to subdirectories after creating the note.
</p>

<p>
The good news is that, these issues are now fixed and this post talks about how.
</p>
<div id="outline-container-1-search-by-filename-in-subdirectories" class="outline-2">
<h2 id="1-search-by-filename-in-subdirectories">#1 Search by Filename in Subdirectories</h2>
<div class="outline-text-2">
<p>
By default, Denote searches only in the <code>denote-directory</code>. To find a note hidden inside a subdirectory, the user needs to know the path to that file and navigate there. Needing to know the exact directory to be able to search for a file is counter-intuitive.
</p>

<p>
However, thanks to <a href="https://git.sr.ht/~protesilaos/denote/commit/6bb6da088211324cdd1ad35396c2988ccb2eccb7">a recent (2022-11-18) refactoring</a> by nobiot@, it is no longer the case! The commit makes notes inside subdirectories searchable with common Denote commands like <code>denote-open-or-create</code> and <code>denote-link-*</code>. This greatly improves the out-of-the-box experience of Denote. Update Denote to a newer version including this new change!
</p>
</div>
</div>
<div id="outline-container-2-full-text-search-in-subdirectories" class="outline-2">
<h2 id="2-full-text-search-in-subdirectories">#2 Full-Text Search in Subdirectories</h2>
<div class="outline-text-2">
<p>
By default, Denote does not come with any command for full-text search.
</p>

<p>
However, it could be done easily with <code>consult-ripgrep</code>.
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span class="org-keyword">defun</span> <span class="org-function-name">consult-denote-ripgrep</span> ()
  <span class="org-doc">"Search with &#8216;</span><span class="org-doc"><span class="org-constant">rg</span></span><span class="org-doc">&#8217; for files in denote-directory where the content matches a regexp."</span>
  (<span class="org-keyword">interactive</span>)
  (consult-ripgrep denote-directory <span class="org-string">""</span>))
</pre>
</div>
</div>
</div>
<div id="outline-container-3-create-notes-in-subdirectories" class="outline-2">
<h2 id="3-create-notes-in-subdirectories">#3 Create Notes in Subdirectories</h2>
<div class="outline-text-2">
<p>
By default, Denote creates notes in the root <code>denote-directory</code>. Every time after creating a note, I need to move them manually to the right subdirectory. This is cumbersome.
</p>

<p>
However, it turned out to be my fault of not reading the official documentation, which has already <a href="https://protesilaos.com/emacs/denote#h:887bdced-9686-4e80-906f-789e407f2e8f">suggested</a> two ways to select a specific directory when creating a new note:
</p>

<ol class="org-ol">
<li>includes <code>subdirectory</code> to <code>denote-prompts</code>, or</li>
<li>uses <code>M-x denote-subdirectory</code>.</li>
</ol>

<p>
I go with (1) because it works with all Denote commands that could create a note, like <code>denote-open-or-create</code> and <code>denote-link-or-create</code>. It also allows other customizations to <code>denote-prompts</code>. For example, I prefer setting "subdirectory" before "title" (reorder <code>title</code> and <code>subdirectory</code>) and updating keyword later with <code>denote-keyword-*</code> (remove <code>keyword</code> from <code>denote-prompts</code>).
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span class="org-keyword">setq</span> denote-prompts '(subdirectory title))
</pre>
</div>

<p>
If you have too much subdirectories, use <code>denote-excluded-directories-regexp</code> to exclude some of them.
</p>
</div>
</div>
<div id="outline-container-comparing-with-org-roam-again" class="outline-2">
<h2 id="comparing-with-org-roam-again">Comparing with Org-roam Again</h2>
<div class="outline-text-2">
<p>
With these tweaks, I can now use Denote as my primary note-taking package.
</p>

<p>
I mentioned a concern with the link type <code>denote:</code> in my <a href="https://whhone.com/posts/denote-vs-org-roam/">last post</a>. It turns out to be not concerning because it is easy to migrate to or away from this link type with some elisp. I don't use other features like org-roam-daily, org-roam-bibtex, or org-roam-ui at all. The last step before removing Org-roam is probably migrating the existing links.
</p>
</div>
</div>
]]></description>
    </item>

    <item>
      <title>Denote vs Org-roam</title>
      <link>https://whhone.com//posts/denote-vs-org-roam/</link>
      <guid>https://whhone.com//posts/denote-vs-org-roam/</guid>
      <pubDate>Sun, 27 Nov 2022 00:00:00 -0800</pubDate>
      <author>whhone@gmail.com (Wai Hon Law)</author>
      <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="#key-differences">Key Differences</a>
<ul>
<li><a href="#identifier-and-linking">Identifier and Linking</a></li>
<li><a href="#supported-formats">Supported Formats</a></li>
<li><a href="#file-naming-scheme">File-naming Scheme</a></li>
<li><a href="#searching-mechanism">Searching Mechanism</a></li>
</ul>
</li>
<li><a href="#denote-comparison-to-org-roam">Denote Comparison to Org-roam</a>
<ul>
<li><a href="#pros">Pros</a></li>
<li><a href="#cons">Cons</a></li>
</ul>
</li>
<li><a href="#my-choice">My Choice</a></li>
<li><a href="#appendix">Appendix</a></li>
</ul>
</div>
</nav>
<p>
<b>Updates</b>
</p>
<ul class="org-ul">
<li>2022-12-08: Check out the followup post <a href="https://whhone.com/posts/denote-with-subdirectories/">Using Denote with Subdirectories</a> to improve the out-of-the-box experience of Denote.</li>
</ul>

<hr>

<p>
<a href="https://protesilaos.com/emacs/denote">Denote</a> is getting popular in the Emacs community recently. I decided to give it a shot, learn how it works and see if I should migrate from Org-roam to it. I am writing this blog post to compares Denote with Org-roam.
</p>

<p>
In essence, Denote is a note-taking package for Emacs based on its file-naming scheme, which works for all kinds of files. Org-roam is a note-taking package for Org-mode, utilizing a database indexing org files.
</p>
<div id="outline-container-key-differences" class="outline-2">
<h2 id="key-differences">Key Differences</h2>
<div class="outline-text-2" id="text-key-differences">
</div>
<div id="outline-container-identifier-and-linking" class="outline-3">
<h3 id="identifier-and-linking">Identifier and Linking</h3>
<div class="outline-text-3">
<p>
Denote uses the timestamp in its file-naming scheme as the identifier and uses its link type <code>denote:</code> for linking. This approach allows notes to be taken in other formats (<code>.md</code> and <code>.txt</code>).
</p>

<p>
Org-roam uses the <code>ID</code> properties as the identifier and the built-in link type <code>id:</code> for linking. It sticks with the Org-mode ecosystem. It utilizes an external database to indexes note metadata, like titles, tags, and locations and searching notes efficiently without parsing any org files. When working on multiple computers, the user might need to re-index the org files.
</p>

<p>
This is the biggest architectural difference between Denote and Org-roam. If all notes are written in Org-mode, I find Org-roam provides cleaner org files because it does not introduce a new link type.
</p>
</div>
</div>
<div id="outline-container-supported-formats" class="outline-3">
<h3 id="supported-formats">Supported Formats</h3>
<div class="outline-text-3">
<p>
Denote works for all files. Not only can the user take notes in Org-mode, Markdown, or Txt, but also name a PDF file so that it could be identified, linked, searched and tagged.
</p>

<p>
Org-roam works for only Org-mode files. It leverages the mature Org-mode ecosystem. For example, the user can use <code>org-attach</code> to associate a PDF file with a note.
</p>

<p>
Frankly speaking, Denote is designed for Emacs users. Org-roam is designed for Org-mode users.
</p>
</div>
</div>
<div id="outline-container-file-naming-scheme" class="outline-3">
<h3 id="file-naming-scheme">File-naming Scheme</h3>
<div class="outline-text-3">
<p>
In a file-based note system, it is inevitable to have coupling between the filename and the content (e.g., keeping <code>#+TITLE:</code> and file name in Org-mode).
</p>

<p>
Denote answers with its file-naming scheme and need to keep filename consistent and update-to-date so that search results remain valid after changing title or tags. Maintaining the naming scheme could become a burden without any automation. Denote provides <code>denote-rename-*</code> and <code>denote-dired-rename-*</code> for the job.
</p>

<p>
Org-roam does not enforce any file-naming scheme. The default <code>org-roam-capture-templates</code> uses the creation timestamp and title slug as the filename, and that is all.
</p>

<p>
Note that the Denote file-naming scheme has a limitation: cannot define a tag with multiple words. For example, the tag "note-taking" becomes two tags "note" and "taking" unless combining them to "notetaking".
</p>
</div>
</div>
<div id="outline-container-searching-mechanism" class="outline-3">
<h3 id="searching-mechanism">Searching Mechanism</h3>
<div class="outline-text-3">
<p>
Utilizing its file-naming scheme, Denote can efficiently search for a note by filename without parsing the content of the file. Users can search notes with titles and tags by prefix <code>-</code> and <code>_</code> respectively. The out-of-the-box experience does not fit my need. Users need to write some emacs lisp or learn Dired to search efficiently.
</p>

<p>
Org-roam provides better out-of-the-box searching experience. With <a href="https://whhone.com/emacs-config/#taking-note-with-org-roam">a little customization</a>, I can search notes by folder name, title, and tags, recursively across sub-folders, sorted by the last modification time. This suits most of my needs.
</p>


<figure>
<img src="/attachment/org-roam-node-find.png" alt="org-roam-node-find.png">

</figure>

<p>
It is nice to eradicate the dependency on a database with Denote. However, I found it hard to replicate the Org-roam searching experience with Denote, especially sorting notes by last modification time within subdirectories. Note that full-text search could be achieved by <code>counsel-rg</code> for both.
</p>
</div>
</div>
</div>
<div id="outline-container-denote-comparison-to-org-roam" class="outline-2">
<h2 id="denote-comparison-to-org-roam">Denote Comparison to Org-roam</h2>
<div class="outline-text-2" id="text-denote-comparison-to-org-roam">
</div>
<div id="outline-container-pros" class="outline-3">
<h3 id="pros">Pros</h3>
<div class="outline-text-3">
<ul class="org-ul">
<li>No database is needed. Seamless across multiple machines.</li>
<li>A simple but powerful file-naming scheme that works for all files.</li>
<li>Allow notes in other formats (txt, md). (Not for me. All my notes are in org.)</li>
</ul>
</div>
</div>
<div id="outline-container-cons" class="outline-3">
<h3 id="cons">Cons</h3>
<div class="outline-text-3">
<ul class="org-ul">
<li>Uses non-standard link type <code>denote:</code>.</li>
<li>Worse out-of-the-box searching experience. (I believe it is hackable)</li>
<li>Tag with multiple words like "note-taking" becomes "note" and "taking"</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-my-choice" class="outline-2">
<h2 id="my-choice">My Choice</h2>
<div class="outline-text-2">
<p>
It is tempting to eradicate the dependency on a database with a simple file-naming scheme. However, I am hesitant to introduce <code>denote:</code> to my org files and want to develop a searching experience that on is par with Org-roam first.
</p>

<p>
I decided to stick with Org-roam but keep exploring Denote in the next couple of weeks. Stay tune :-)
</p>
</div>
</div>
<div id="outline-container-appendix" class="outline-2">
<h2 id="appendix">Appendix</h2>
<div class="outline-text-2">
<ul class="org-ul">
<li><a href="https://whhone.com/emacs-config/#note-taking-with-denote">My Denote configuration</a></li>
</ul>
</div>
</div>
]]></description>
    </item>

    <item>
      <title>Ignore &#34;save-buffer&#34; Unless Visiting a File</title>
      <link>https://whhone.com//posts/my-save-buffer/</link>
      <guid>https://whhone.com//posts/my-save-buffer/</guid>
      <pubDate>Sat, 09 Apr 2022 00:00:00 -0700</pubDate>
      <author>whhone@gmail.com (Wai Hon Law)</author>
      <description><![CDATA[<p>
I have a habit of hitting the save shortcut (<code>C-x C-s</code>) occasionally. However, if the buffer does not have a visited file (like treemacs, vterm, scratch, help, etc), Emacs asks me where to save the file and I need to cancel with triple <code>ESC</code>.
</p>

<p>
For example, hitting <code>C-x C-s</code> within the <code>*scratch*</code> buffer.
</p>


<figure>
<img src="/attachment/save-buffer.png" alt="save-buffer.png">

</figure>

<p>
This is annoying. To fix it, I remap <code>save-buffer</code> to the function below<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup> which does nothing for non-file-visiting buffer.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">defun</span> <span class="org-function-name">my/save-buffer</span> (<span class="org-type">&amp;optional</span> arg)
  <span class="org-doc">"Like `</span><span class="org-doc"><span class="org-constant">save-buffer</span></span><span class="org-doc">', but does nothing if buffer is not visiting a file."</span>
  (<span class="org-keyword">interactive</span> <span class="org-string">"p"</span>)
  (<span class="org-keyword">unless</span> (<span class="org-keyword">or</span> (buffer-file-name)                       <span class="org-comment-delimiter">; </span><span class="org-comment">regular buffer
</span>              (buffer-file-name (buffer-base-buffer))) <span class="org-comment-delimiter">; </span><span class="org-comment">indirect buffer
</span>    (<span class="org-warning">user-error</span> <span class="org-string">"Use 'M-x save-buffer' explicitly to save this buffer with no visited file"</span>))
  (save-buffer arg))

(global-set-key [remap save-buffer] #'my/save-buffer)
</pre>
</div>

<p>
Now, I get the message below and do not need to cancel the save operation.
</p>


<figure>
<img src="/attachment/my-save-buffer.png" alt="my-save-buffer.png">

</figure>

<hr>

<p>
<i><b>Update</b></i>: My friend AhLeung has an alternative using <code>save-all-buffers</code>:
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">defun</span> <span class="org-function-name">my/save-all-buffers</span> ()
  <span class="org-doc">"Save all motified file-visiting buffers without asking."</span>
  (<span class="org-keyword">interactive</span>)
  (save-some-buffers t))

(global-set-key [remap save-buffer] #'my/save-all-buffers)
</pre>
</div>
<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">
This elisp is updated with <a href="https://www.reddit.com/r/emacs/comments/u09yf9/comment/i4522jb/">the suggestion</a> from Phil-Hudson. Thanks!
</p></div></div>


</div>
</div>]]></description>
    </item>

    <item>
      <title>Write with Emacs 2: Synonyms</title>
      <link>https://whhone.com//posts/write-with-emacs-2/</link>
      <guid>https://whhone.com//posts/write-with-emacs-2/</guid>
      <pubDate>Fri, 05 Nov 2021 00:00:00 -0700</pubDate>
      <author>whhone@gmail.com (Wai Hon Law)</author>
      <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="#looking-up-synonyms-with-power-thesaurus">Looking up Synonyms with Power Thesaurus</a></li>
<li><a href="#configuration">Configuration</a></li>
<li><a href="#caveat">Caveat</a></li>
</ul>
</div>
</nav>
<blockquote>
<p>
The limits of language are the limits of one's world. ~Ludwig Wittgenstein
</p>
</blockquote>

<p>
My limited vocabulary should be a limit of my writing.
</p>
<div id="outline-container-looking-up-synonyms-with-power-thesaurus" class="outline-2">
<h2 id="looking-up-synonyms-with-power-thesaurus">Looking up Synonyms with Power Thesaurus</h2>
<div class="outline-text-2">
<p>
I find looking up synonyms is a way to extend one's <a href="https://en.wiktionary.org/wiki/active_vocabulary">active vocabulary</a>. For instance, I can replace <b>beautiful</b> (active vocabulary) with something more specific and accurate, like <i>attractive</i>, <i>lovely</i>, <i>gorgeous</i>, <i>charming</i>, <i>splendid</i>, <i>appealing</i> (passive vocabulary).
</p>

<p>
In Emacs, <a href="https://github.com/SavchenkoValeriy/emacs-powerthesaurus">emacs-powerthesaures</a> is a package to look up synonyms by fetching data from <a href="https://www.powerthesaurus.org/">Power Thesaurus</a>.
</p>

<p>
Here is a mini demo:
</p>


<figure>
<img src="/attachment/powerthesaurus.gif" alt="powerthesaurus.gif">

</figure>
</div>
</div>
<div id="outline-container-configuration" class="outline-2">
<h2 id="configuration">Configuration</h2>
<div class="outline-text-2">
<p>
The package defines three interactive functions:
</p>
<ol class="org-ol">
<li><code>powerthesaurus-lookup-word</code>: look up synonyms of a provided word</li>
<li><code>powerthesaurus-lookup-word-at-point</code>: look up synonyms of the word at point</li>
<li><code>powerthesaurus-lookup-word-dwim</code>: combine the above two,
<ul class="org-ul">
<li>if the current point (cursor) has a word, then calls (2)</li>
<li>otherwise, calls (1)</li>
</ul></li>
</ol>

<p>
Here is my configuration:
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span class="org-keyword">use-package</span> powerthesaurus
  <span class="org-builtin">:bind</span>
  (<span class="org-string">"M-`"</span> . powerthesaurus-lookup-word-dwim))
</pre>
</div>
</div>
</div>
<div id="outline-container-caveat" class="outline-2">
<h2 id="caveat">Caveat</h2>
<div class="outline-text-2">
<p>
Use words that you know. Otherwise, check the meaning and learn that new word first!
</p>
</div>
</div>
]]></description>
    </item>

    <item>
      <title>Write with Emacs 1: Spell-Checking</title>
      <link>https://whhone.com//posts/write-with-emacs-1/</link>
      <guid>https://whhone.com//posts/write-with-emacs-1/</guid>
      <pubDate>Fri, 29 Oct 2021 00:00:00 -0700</pubDate>
      <author>whhone@gmail.com (Wai Hon Law)</author>
      <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="#check-and-correct-spelling-with-flyspell">Check and Correct Spelling with Flyspell</a></li>
<li><a href="#configuration">Configuration</a></li>
<li><a href="#caveat">Caveat</a></li>
</ul>
</div>
</nav>
<p>
I am bad at writing, especially in English, which is not my native language. I misspell words, have limited vocabulary, and misuse grammar without being aware of it.
</p>

<p>
On the other hand, I write and need to write a lot. Emacs is my main writing tool and I use it to take notes, compose commit messages and blog posts, etc. Over the years, I have learned some tricks to write better with this awesome tool. I am going to share them in the next couple of posts,
</p>

<p>
Let's start with the basic &#x2013; spell-checking.
</p>
<div id="outline-container-check-and-correct-spelling-with-flyspell" class="outline-2">
<h2 id="check-and-correct-spelling-with-flyspell">Check and Correct Spelling with Flyspell</h2>
<div class="outline-text-2">
<p>
I use <a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Spelling.html">Flyspell</a>, an Emacs built-in minor mode, for performing on-the-fly spelling checking and correcting.
</p>

<p>
When enabled, misspelled words will be highlighted. I can use <code>(flyspell-auto-correct-word)</code> to correct the word at the point. Most of the time, the first candidate is the correct one. It is smart enough to me.
</p>

<p>
I also use the context menu a lot (by middle-clicking the misspelled word). I can choose the right word from all candidates or save the word, so that it does not complain anymore.
</p>


<figure>
<img src="/attachment/flyspell-mouse.gif" alt="flyspell-mouse.gif">

</figure>

<p>
If you don't like touching the mouse, <a href="https://github.com/d12frosted/flyspell-correct">flyspell-correct</a> is a package to correct misspelled words with other interfaces, like helm and ivy, all inside the keyboard.
</p>

<p>
Here is a demo for  <code>(flyspell-correct-wrapper)</code>.
</p>


<figure>
<img src="/attachment/flyspell-ivy.gif" alt="flyspell-ivy.gif">

</figure>
</div>
</div>
<div id="outline-container-configuration" class="outline-2">
<h2 id="configuration">Configuration</h2>
<div class="outline-text-2">
<p>
Flyspell provides two minor modes:
</p>
<ol class="org-ol">
<li><code>flyspell-mode</code> for writing</li>
<li><code>flyspell-prog-mode</code> for programming (only text inside comments and strings is checked)ema</li>
</ol>

<p>
Here is how I enable them respectively and set up the packages mentioned above.
</p>

<div class="org-src-container">
<pre class="src src-elisp">(add-hook 'text-mode-hook 'flyspell-mode)
(add-hook 'prog-mode-hook 'flyspell-prog-mode)

(<span class="org-keyword">use-package</span> flyspell-correct
  <span class="org-builtin">:after</span> flyspell
  <span class="org-builtin">:bind</span> (<span class="org-builtin">:map</span> flyspell-mode-map (<span class="org-string">"C-;"</span> . flyspell-correct-wrapper)))

<span class="org-comment-delimiter">;; </span><span class="org-comment">Replace with flyspell-correct-helm if you are a helm person.
</span>(<span class="org-keyword">use-package</span> flyspell-correct-ivy
  <span class="org-builtin">:after</span> flyspell-correct)
</pre>
</div>
</div>
</div>
<div id="outline-container-caveat" class="outline-2">
<h2 id="caveat">Caveat</h2>
<div class="outline-text-2">
<p>
This trick does not work if the misspelled word is valid. For example, when misspelling "summit" as "submit". So, you should still check the spelling even with tool like this.
</p>
</div>
</div>
]]></description>
    </item>

    <item>
      <title>Another Emacs i3 Integration</title>
      <link>https://whhone.com//posts/emacs-i3-integration/</link>
      <guid>https://whhone.com//posts/emacs-i3-integration/</guid>
      <pubDate>Fri, 15 Oct 2021 00:00:00 -0700</pubDate>
      <author>whhone@gmail.com (Wai Hon Law)</author>
      <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="#1-add-an-elisp-function-my-wm-integration">1: Add an Elisp function <code>my/wm-integration</code></a></li>
<li><a href="#2-create-a-script-i3-msg-proxy">2: Create a Script <code>i3-msg-proxy</code></a></li>
<li><a href="#3-update-the-i3-config">3: Update the i3 config</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
</div>
</nav>
<p>
Pavel Korytov wrote an inspiring <a href="https://sqrtminusone.xyz/posts/2021-10-04-emacs-i3/">blog post</a> to get a consistent set of keybindings between i3 and Emacs. It caught my attention because I use exactly these two tools heavily. Before the integration, I have to define a different keybinding for switching window inside Emacs and i3. After the integration, I can use the same keybinding everywhere. Check out the video in the original <a href="https://sqrtminusone.xyz/posts/2021-10-04-emacs-i3/">blog post</a> to see how cool it is!
</p>

<p>
I followed the blog post and implemented it immediately. It worked and I loved that! However, the proposed (i3 -&gt; Emacs -&gt; i3) solution introduced a coupling between i3 and Emacs. i3 has to know Emacs, and Emacs has to know i3. It does not fit into the <a href="https://en.wikipedia.org/wiki/Law_of_Demeter">Law of Demeter</a>. It makes the solution harder to scale to other tiling window managers or applications.
</p>

<p>
Hence, I implemented another (i3 -&gt; Emacs) solution with less coupling (only the <code>focus</code> command for now).
</p>
<div id="outline-container-1-add-an-elisp-function-my-wm-integration" class="outline-2">
<h2 id="1-add-an-elisp-function-my-wm-integration">1: Add an Elisp function <code>my/wm-integration</code></h2>
<div class="outline-text-2">
<div class="org-src-container">
<pre class="src src-elisp">(<span class="org-keyword">require</span> '<span class="org-constant">windmove</span>)
(<span class="org-keyword">defun</span> <span class="org-function-name">my/wm-integration</span> (command)
  (<span class="org-keyword">pcase</span> command
    ((<span class="org-keyword">rx</span> bos <span class="org-string">"focus"</span>)
     (windmove-do-window-select
      (intern (elt (split-string command) 1))))
    (- (<span class="org-warning">error</span> command))))
</pre>
</div>

<p>
<code>my/wm-integration</code> handles the command from the window manager.
</p>

<p>
Emacs does not need to know what the window manager is, and do not need to call <code>i3-msg</code>. It return a non-zero code if the command is not handled, or a zero code if handled.
</p>

<p>
<i>nit. Emacs still use the protocol defined by i3, like the <code>focus</code> command. Well&#x2026; we have to use a protocol anyway. Let's pick the i3 protocol in this post.</i>
</p>
</div>
</div>
<div id="outline-container-2-create-a-script-i3-msg-proxy" class="outline-2">
<h2 id="2-create-a-script-i3-msg-proxy">2: Create a Script <code>i3-msg-proxy</code></h2>
<div class="outline-text-2">
<div class="org-src-container">
<pre class="src src-sh"><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/</span><span class="org-keyword">sh</span><span class="org-comment">
</span><span class="org-comment-delimiter">#</span><span class="org-comment">
</span><span class="org-comment-delimiter"># </span><span class="org-comment">Proxy the `i3-msg` command to the focused window.
</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">Proxy to Emacs if it is the active window
</span><span class="org-keyword">if</span> [[ <span class="org-string">"$(</span><span class="org-sh-quoted-exec">xdotool getactivewindow getwindowclassname</span><span class="org-string">)"</span> == <span class="org-string">"Emacs"</span> ]]; <span class="org-keyword">then</span>
    <span class="org-variable-name">command</span>=<span class="org-string">"(my/wm-integration \"$@\")"</span>
    <span class="org-keyword">if</span> emacsclient -e <span class="org-string">"$command"</span>; <span class="org-keyword">then</span>
        <span class="org-keyword">exit</span>
    <span class="org-keyword">fi</span>
<span class="org-keyword">fi</span>

<span class="org-comment-delimiter"># </span><span class="org-comment">fallback to i3
</span>i3-msg $<span class="org-variable-name">@</span>
</pre>
</div>

<p>
This script proxies the <code>i3-msg</code> command to the focused window. If the focused window has handled it (return zero), then exit. Otherwise (return non-zero), fallback to i3.
</p>

<p>
This mechanism (using the return code) can work with other applications, like Tmux.
</p>
</div>
</div>
<div id="outline-container-3-update-the-i3-config" class="outline-2">
<h2 id="3-update-the-i3-config">3: Update the i3 config</h2>
<div class="outline-text-2">
<div class="org-src-container">
<pre class="src src-nil">bindsym $mod+Left  exec i3-msg-proxy focus left
bindsym $mod+Down  exec i3-msg-proxy focus down
bindsym $mod+Up    exec i3-msg-proxy focus up
bindsym $mod+Right exec i3-msg-proxy focus right
</pre>
</div>

<p>
Finally, update the i3 config to proxy the command to the focused window. Now, I can move my focus between i3 and Emacs!
</p>
</div>
</div>
<div id="outline-container-conclusion" class="outline-2">
<h2 id="conclusion">Conclusion</h2>
<div class="outline-text-2">
<p>
The key difference between this and the original solution is how Emacs calls i3 back when it failed to handle the command. The original solution calls <code>i3-msg</code> inside Emacs. This solution returns non-zero from Emacs.
</p>
</div>
</div>
]]></description>
    </item>

    <item>
      <title>An Org-mode Workflow for Task Management</title>
      <link>https://whhone.com//posts/org-mode-task-management/</link>
      <guid>https://whhone.com//posts/org-mode-task-management/</guid>
      <pubDate>Sat, 31 Oct 2020 00:00:00 -0700</pubDate>
      <author>whhone@gmail.com (Wai Hon Law)</author>
      <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="#1-the-principles">1 The Principles</a>
<ul>
<li><a href="#1-1-do-not-add-tasks-indiscriminately">1.1 Do Not Add Tasks Indiscriminately</a></li>
<li><a href="#1-2-not-all-tasks-have-to-be-done">1.2 Not All Tasks Have To Be Done</a></li>
<li><a href="#1-3-reduce-the-number-of-open-loops">1.3 Reduce The Number Of Open Loops</a></li>
<li><a href="#1-4-reduce-decision-making-of-what-to-do-next">1.4 Reduce Decision Making Of What To Do Next</a></li>
</ul>
</li>
<li><a href="#2-the-definitions">2 The Definitions</a>
<ul>
<li><a href="#2-1-todo-keywords">2.1 TODO Keywords</a></li>
<li><a href="#2-2-scheduled-and-deadline">2.2 Scheduled and Deadline</a></li>
</ul>
</li>
<li><a href="#3-the-workflow">3 The Workflow</a>
<ul>
<li><a href="#3-1-update-tasks-scheduled-today">3.1 Update Tasks Scheduled Today</a></li>
<li><a href="#3-2-find-the-next-task-to-work-on">3.2 Find the Next Task to Work On</a></li>
<li><a href="#3-3-review-the-system">3.3 Review the System</a></li>
</ul>
</li>
<li><a href="#4-the-configuration">4 The Configuration</a></li>
</ul>
</div>
</nav>
<p>
As mentioned in the <a href="https://whhone.com/posts/from-evernote-to-org-mode/">last post</a>, I switched to Org-mode. I kept adjusting my workflow with this new tool and it has been stabilized for a month. I think it is time to talk about the new workflow for task/time management with Org-mode. This blog post consists of four parts: the principles, the definitions, the workflows, and finally the implementations.
</p>
<div id="outline-container-1-the-principles" class="outline-2">
<h2 id="1-the-principles">1 The Principles</h2>
<div class="outline-text-2">
<p>
Principles remain valid no matter what the tool is.
</p>
</div>
<div id="outline-container-1-1-do-not-add-tasks-indiscriminately" class="outline-3">
<h3 id="1-1-do-not-add-tasks-indiscriminately">1.1 Do Not Add Tasks Indiscriminately</h3>
<div class="outline-text-3">
<p>
Not every task should go into the system. Avoid filling the system with bullshits and diluting the things that matter. I only add tasks that I really want or need to do.
</p>

<p>
To clarify<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, the task management system described below is not the "inbox" in GTD. I still capture things into my inbox but not all of them will be converted to a task in the task management system (org agenda files) eventually.
</p>
</div>
</div>
<div id="outline-container-1-2-not-all-tasks-have-to-be-done" class="outline-3">
<h3 id="1-2-not-all-tasks-have-to-be-done">1.2 Not All Tasks Have To Be Done</h3>
<div class="outline-text-3">
<p>
There are two reasons for this. First, tasks could be deprioritized or even unnecessary. Second, we have limited time and cannot do everything. We should have an opinion on the priority.
</p>
</div>
</div>
<div id="outline-container-1-3-reduce-the-number-of-open-loops" class="outline-3">
<h3 id="1-3-reduce-the-number-of-open-loops">1.3 Reduce The Number Of Open Loops</h3>
<div class="outline-text-3">
<p>
Open loops are tasks that have been started but not finished. They stay in our minds and occupy some of our limited working memory so that we cannot focus on another task we are working on.
</p>

<p>
Also, open loops reduce agility, according to <a href="https://en.wikipedia.org/wiki/Little%27s_law">Little's Law</a>. The more the open loops, the longer time to finish each of them on average.
</p>
</div>
</div>
<div id="outline-container-1-4-reduce-decision-making-of-what-to-do-next" class="outline-3">
<h3 id="1-4-reduce-decision-making-of-what-to-do-next">1.4 Reduce Decision Making Of What To Do Next</h3>
<div class="outline-text-3">
<p>
The system should suggest to the user what to do next so that the user can reserve the will power to the real task. This also avoids skipping hard tasks with easy tasks unconsciously.
</p>
</div>
</div>
</div>
<div id="outline-container-2-the-definitions" class="outline-2">
<h2 id="2-the-definitions">2 The Definitions</h2>
<div class="outline-text-2">
<p>
Each task in Org-mode has a <a href="https://orgmode.org/manual/Workflow-states.html">TODO keyword</a>, optionally <a href="https://orgmode.org/manual/Deadlines-and-Scheduling.html">a scheduled date, and a deadline</a>. For example,
</p>

<div class="org-src-container">
<pre class="src src-org"><span class="org-org-level-1">* </span><span class="org-org-level-1"><span class="org-org-todo">PROG</span></span><span class="org-org-level-1"> Write a blog post on task management with Org-mode</span>
<span class="org-org-special-keyword">DEADLINE:</span> <span class="org-org-date">&lt;2020-11-07 Sat&gt;</span> <span class="org-org-special-keyword">SCHEDULED:</span> <span class="org-org-date">&lt;2020-10-31 Sat&gt;</span>
</pre>
</div>

<p>
Each Org-mode user could define their own set of TODO keywords and use scheduled dates and deadlines differently. For example, some people use only two TODO keywords, "TODO" and "DONE", while some use more. Some people set "scheduled dates" to all the tasks while some people set it to some of the tasks. These nuances could result in a hugely different workflow, although they are using the same Org-mode. Let’s take a look at how I use them.
</p>
</div>
<div id="outline-container-2-1-todo-keywords" class="outline-3">
<h3 id="2-1-todo-keywords">2.1 TODO Keywords</h3>
<div class="outline-text-3">
<p>
I use as few TODO keywords as possible but not too few. For example, it is common to use only two states ("TODO" and "DONE") but this does not align with the principles I mentioned above. I need a state for "open loops" so that I can keep the number of them small. I also need to distinguish a smaller set of "next actions" from all tasks.
</p>

<p>
So far, I defined these five keywords:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">TODO Keyword</th>
<th scope="col" class="org-left">Definition</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>TODO</code></td>
<td class="org-left"><b>Tasks that are not started and not planned.</b> They could be the backlogs or the GTD’s someday/maybe. These tasks could be converted to <code>NEXT</code> during a review.</td>
</tr>

<tr>
<td class="org-left"><code>NEXT</code></td>
<td class="org-left"><b>Tasks that are not started but planned to do as soon as I can.</b> When there is no actionable <code>PROG</code> (e.g., blocked), I start one of those and convert it to <code>PROG</code>.</td>
</tr>

<tr>
<td class="org-left"><code>PROG</code></td>
<td class="org-left"><b>Tasks that are working in progress (open loops).</b> I work on these tasks before starting another <code>NEXT</code> task to avoid too many open loops at any moment.</td>
</tr>

<tr>
<td class="org-left"><code>INTR</code></td>
<td class="org-left"><b>Tasks that are interruptions.</b> They are urgent things that I should drop everything else and work on it. For example, production issues.</td>
</tr>

<tr>
<td class="org-left"><code>DONE</code></td>
<td class="org-left"><b>The tasks that are completed.</b></td>
</tr>
</tbody>
</table>

<p>
This diagram illustrates the transition of those states.
</p>

<div class="org-src-container">
<pre class="src src-nil">                                 +------+
                                 | INTR |
                                 +------+
                                    |
                                    v
+------+   +------+   +------+   +------+
| TODO |--&gt;| NEXT |--&gt;| PROG |--&gt;| DONE |
+------+   +------+   +------+   +------+
</pre>
</div>
</div>
</div>
<div id="outline-container-2-2-scheduled-and-deadline" class="outline-3">
<h3 id="2-2-scheduled-and-deadline">2.2 Scheduled and Deadline</h3>
<div class="outline-text-3">
<p>
In the past, I tended to set a date for all tasks. If I want to do A, B, and C on Monday, then I schedule them for Monday. This sounds intuitive but, in reality, I ended up rescheduling many incompleted tasks at the end of every day. It was not only wasting time but also depressing.
</p>

<p>
Later, I changed to rely more on the TODO keywords. For example, if a task is still in progress, I keep the state unchanged as <code>PROG</code> instead of rescheduling it every day until it is done. I am now using the "scheduled date" to hide a task until the date I should look at it again. Similar to the snooze feature in Gmail.
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Date</th>
<th scope="col" class="org-left">Definition</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>SCHEDULED</code></td>
<td class="org-left">Hide the task until the scheduled date.</td>
</tr>

<tr>
<td class="org-left"><code>DEADLINE</code></td>
<td class="org-left">The deadline of the task.</td>
</tr>
</tbody>
</table>

<p>
For example, when a <code>PROG</code> task is being blocked, I set the <code>SCHEDULED</code> date to hide it until the date I want to revisit. On the scheduled date, if the task is unblocked, I will remove the <code>SCHEDULED</code> date. If the task is still blocked, I reschedule it again. It acts as the <a href="https://hamberg.no/gtd#the-waiting-for-list">waiting for list</a> in GTD.
</p>
</div>
</div>
</div>
<div id="outline-container-3-the-workflow" class="outline-2">
<h2 id="3-the-workflow">3 The Workflow</h2>
<div class="outline-text-2">
<p>
I customize my org agenda view to drive my daily workflow. The customized agenda view has four sections. From the top to bottom, they are the tasks scheduled today, the <code>INTR</code> tasks, the <code>PROG</code> tasks, and finally the <code>NEXT</code> tasks.
</p>


<figure>
<img src="/attachment/org-agenda.png" alt="org-agenda.png">

</figure>

<p>
My daily workflow goes from the top to the bottom.
</p>
</div>
<div id="outline-container-3-1-update-tasks-scheduled-today" class="outline-3">
<h3 id="3-1-update-tasks-scheduled-today">3.1 Update Tasks Scheduled Today</h3>
<div class="outline-text-3">
<p>
At the beginning of the day, I review the tasks that are scheduled for today. The goal here is not to finish them, but to update or remove the scheduled date so that there is nothing left.
</p>

<ol class="org-ol">
<li>If the task is still blocked, reschedule it</li>
<li>If the task could be done in a few minutes, then do it and mark it as <code>DONE</code>.</li>
<li>Otherwise, remove the scheduled date and optionally update the <code>TODO</code> keywords.</li>
</ol>

<p>
Removing the scheduled date is the best outcome. It indicates the previous estimation was correct, at least not too early. Rescheduling indicates the previous estimation is inaccurate. I would avoid rescheduling the task to tomorrow indiscriminately and try to make a good estimation to reduce the number of rescheduling.
</p>
</div>
</div>
<div id="outline-container-3-2-find-the-next-task-to-work-on" class="outline-3">
<h3 id="3-2-find-the-next-task-to-work-on">3.2 Find the Next Task to Work On</h3>
<div class="outline-text-3">
<p>
After reviewing all tasks scheduled for today, it is time to pick a task and do some real works. This step is straight-forward with the customized agenda view above.
</p>

<ol class="org-ol">
<li>Pick an <code>INTR</code> task if there is any.</li>
<li>If there is no <code>INTR</code> task, then pick a <code>PROG</code> task and work on it. If that task is blocked, set a <code>SCHEDULED</code> date to hide it.</li>
<li>If there is no <code>INTR</code> and <code>PROG</code> task, then start a <code>NEXT</code> task.</li>
<li>If there is no task in the agenda view, then review the <code>TODO</code> tasks and convert some to <code>NEXT</code>.</li>
</ol>
</div>
</div>
<div id="outline-container-3-3-review-the-system" class="outline-3">
<h3 id="3-3-review-the-system">3.3 Review the System</h3>
<div class="outline-text-3">
<p>
The secret of having a system that works in the long-term is regular maintenance. I do it at least once a week. For examples,
</p>

<ul class="org-ul">
<li>Promote some tasks from <code>TODO</code> to <code>NEXT</code>. Demote or even delete deprioritized tasks.</li>
<li>Review the <a href="https://whhone.com/posts/daily-journal/">journal</a> and add <code>TODO</code> if something needs follow-up.</li>
<li><a href="https://orgmode.org/manual/Archiving.html">Archive</a> completed tasks and extract to permanent notes<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-4-the-configuration" class="outline-2">
<h2 id="4-the-configuration">4 The Configuration</h2>
<div class="outline-text-2">
<p>
Finally, here is the configuration for the above workflow.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span class="org-comment-delimiter">;; </span><span class="org-comment">TODO keywords.
</span>(<span class="org-keyword">setq</span> org-todo-keywords
  '((sequence <span class="org-string">"TODO(t)"</span> <span class="org-string">"NEXT(n)"</span> <span class="org-string">"PROG(p)"</span> <span class="org-string">"INTR(i)"</span> <span class="org-string">"DONE(d)"</span>)))

<span class="org-comment-delimiter">;; </span><span class="org-comment">Show the daily agenda by default.
</span>(<span class="org-keyword">setq</span> org-agenda-span 'day)

<span class="org-comment-delimiter">;; </span><span class="org-comment">Hide tasks that are scheduled in the future.
</span>(<span class="org-keyword">setq</span> org-agenda-todo-ignore-scheduled 'future)

<span class="org-comment-delimiter">;; </span><span class="org-comment">Use "second" instead of "day" for time comparison.
</span><span class="org-comment-delimiter">;; </span><span class="org-comment">It hides tasks with a scheduled time like "&lt;2020-11-15 Sun 11:30&gt;"
</span>(<span class="org-keyword">setq</span> org-agenda-todo-ignore-time-comparison-use-seconds t)

<span class="org-comment-delimiter">;; </span><span class="org-comment">Hide the deadline prewarning prior to scheduled date.
</span>(<span class="org-keyword">setq</span> org-agenda-skip-deadline-prewarning-if-scheduled 'pre-scheduled)

<span class="org-comment-delimiter">;; </span><span class="org-comment">Customized view for the daily workflow. (Command: "C-c a n")
</span>(<span class="org-keyword">setq</span> org-agenda-custom-commands
  '((<span class="org-string">"n"</span> <span class="org-string">"Agenda / INTR / PROG / NEXT"</span>
     ((agenda <span class="org-string">""</span> nil)
      (todo <span class="org-string">"INTR"</span> nil)
      (todo <span class="org-string">"PROG"</span> nil)
      (todo <span class="org-string">"NEXT"</span> nil))
     nil)))
</pre>
</div>
</div>
</div>
<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">
Thanks for <a href="https://www.reddit.com/r/orgmode/comments/jmf8dw/an_orgmode_workflow_for_task_management/gavkv1r/?context=3">this comment</a> in Reddit.
</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">
There will be another post for Org-mode note-taking workflow.
</p></div></div>


</div>
</div>]]></description>
    </item>

    <item>
      <title>From Evernote to Org-mode</title>
      <link>https://whhone.com//posts/from-evernote-to-org-mode/</link>
      <guid>https://whhone.com//posts/from-evernote-to-org-mode/</guid>
      <pubDate>Thu, 03 Sep 2020 00:00:00 -0700</pubDate>
      <author>whhone@gmail.com (Wai Hon Law)</author>
      <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="#1-the-privacy-concern-of-evernote">1. The Privacy Concern of Evernote</a></li>
<li><a href="#2-researching-the-alternatives">2. Researching the Alternatives</a>
<ul>
<li><a href="#review-evernote-24">Review: Evernote (24)</a></li>
<li><a href="#review-org-mode-26">Review: Org-mode (26)</a></li>
<li><a href="#review-joplin-22-and-standard-note-24">Review: Joplin (22) and Standard Note (24)</a></li>
<li><a href="#review-taskwarrior-21-and-todo-txt-20">Review: Taskwarrior (21) and TODO.txt (20)</a></li>
<li><a href="#review-tiddlywiki">Review: TiddlyWiki (?)</a></li>
</ul>
</li>
<li><a href="#3-switching-to-org-mode">3. Switching to Org-mode</a></li>
</ul>
</div>
</nav>
<p>
Since 2017, Evernote has been my <a href="https://whhone.com/posts/productivity-system/">productivity system</a> for note-taking and task management. I thought it was my ultimate system to stick with. It has served me so well and I have even became a paid user. However, mentioned in the <a href="https://whhone.com/posts/arch-linux-full-disk-encryption/">last post</a>, I am pursuing more privacy in my digital life. <b>I want to take my notes with a peace of mind, without worrying they are being watched or leaked.</b>
</p>

<p>
This post talks about the privacy concern, my research on the alternatives, and the switch to Org-mode.
</p>
<div id="outline-container-1-the-privacy-concern-of-evernote" class="outline-2">
<h2 id="1-the-privacy-concern-of-evernote">1. The Privacy Concern of Evernote</h2>
<div class="outline-text-2">
<p>
The user data in Evernote is <a href="https://evernote.com/security">encrypted "during transport" and "at-rest"</a>. This sounds secure to readers but actually not enough because Evernote can still see the content. Technically, it is still server-side encryption instead the client-side encryption (a.k.a. end-to-end encryption). The encryption key of the note content is held by the server instead of the client. If the server is hacked, or there is an evil employee, or Evernote needs to comply with legal obligations (i.e., the government asks for user data, and <a href="https://evernote.com/privacy/transparency-report">it does</a>), those notes could be leaked.
</p>
</div>
</div>
<div id="outline-container-2-researching-the-alternatives" class="outline-2">
<h2 id="2-researching-the-alternatives">2. Researching the Alternatives</h2>
<div class="outline-text-2">
<p>
I started researching the alternatives which do not compromise privacy. That means end-to-end encryption is required if the data is hosted on a third-party. This requirement actually simplifies my curation because many solutions are ruled out, including the popular Notion and Roam (o:
</p>

<p>
My final shortlist included <a href="https://orgmode.org/"><b>Org-mode</b></a>, <a href="https://joplinapp.org/"><b>Joplin</b></a>, <a href="https://standardnotes.org/"><b>Standard Note</b></a>, <a href="https://taskwarrior.org/"><b>Taskwarrior</b></a>, <a href="http://todotxt.org/"><b>TODO.txt</b></a>, and <a href="https://tiddlywiki.com/"><b>TiddlyWiki</b></a>. I gave each of them a try, reviewed and scored them with my requirements below:
</p>

<ol class="org-ol">
<li><b>Privacy</b> Can I seclude my data?</li>
<li><b>Basic Task Management</b>: Can I set a date for a task and then view all tasks for today?</li>
<li><b>Task Context</b>: Can I add references (instruction, link) to the task?</li>
<li><b>Linux Usability</b>: How usable is it on Linux?</li>
<li><b>Android Usability</b>: How usable is it on Android?</li>
<li><b>Synchronization</b>: How hard is it to synchronize data between Linux and Android?</li>
</ol>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">

<col  class="org-right">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">&#xa0;</th>
<th scope="col" class="org-right"><b>Evernote</b></th>
<th scope="col" class="org-right"><b>Org-mode</b></th>
<th scope="col" class="org-right"><b>Joplin</b></th>
<th scope="col" class="org-right"><b>Standard Note</b></th>
<th scope="col" class="org-right"><b>Taskwarrior</b></th>
<th scope="col" class="org-right"><b>TODO.txt</b></th>
<th scope="col" class="org-left"><b>TiddlyWiki</b></th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><b>Privacy</b></td>
<td class="org-right">1</td>
<td class="org-right">5</td>
<td class="org-right">5</td>
<td class="org-right">5</td>
<td class="org-right">5</td>
<td class="org-right">5</td>
<td class="org-left">5</td>
</tr>

<tr>
<td class="org-left"><b>Task Management</b></td>
<td class="org-right">4</td>
<td class="org-right">5</td>
<td class="org-right">1</td>
<td class="org-right">1</td>
<td class="org-right">5</td>
<td class="org-right">5</td>
<td class="org-left">?</td>
</tr>

<tr>
<td class="org-left"><b>Task Context</b></td>
<td class="org-right">5</td>
<td class="org-right">4</td>
<td class="org-right">4</td>
<td class="org-right">5</td>
<td class="org-right">2</td>
<td class="org-right">1</td>
<td class="org-left">?</td>
</tr>

<tr>
<td class="org-left"><b>Linux Usability</b></td>
<td class="org-right">4</td>
<td class="org-right">5</td>
<td class="org-right">4</td>
<td class="org-right">4</td>
<td class="org-right">3</td>
<td class="org-right">3</td>
<td class="org-left">?</td>
</tr>

<tr>
<td class="org-left"><b>Android Usability</b></td>
<td class="org-right">5</td>
<td class="org-right">3</td>
<td class="org-right">3</td>
<td class="org-right">4</td>
<td class="org-right">2</td>
<td class="org-right">2</td>
<td class="org-left">?</td>
</tr>

<tr>
<td class="org-left"><b>Synchronization</b></td>
<td class="org-right">5</td>
<td class="org-right">4</td>
<td class="org-right">5</td>
<td class="org-right">5</td>
<td class="org-right">4</td>
<td class="org-right">4</td>
<td class="org-left">?</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left"><b>Total</b></td>
<td class="org-right">24</td>
<td class="org-right">26</td>
<td class="org-right">22</td>
<td class="org-right">24</td>
<td class="org-right">21</td>
<td class="org-right">20</td>
<td class="org-left">?</td>
</tr>
</tbody>
</table>
</div>
<div id="outline-container-review-evernote-24" class="outline-3">
<h3 id="review-evernote-24">Review: Evernote (24)</h3>
<div class="outline-text-3">
<p>
Evernote has a reminder feature for simple task management, which is already enough for me. Since it is a note-taking app, I can add rich context like images or even audio seamlessly. Tusk makes it usabe on Linux and the official Android app is simply awesome. Synchronization works out-of-the-box.
</p>

<p>
However, it fails on the privacy bit.
</p>
</div>
</div>
<div id="outline-container-review-org-mode-26" class="outline-3">
<h3 id="review-org-mode-26">Review: Org-mode (26)</h3>
<div class="outline-text-3">
<p>
Org-mode is for keeping notes, maintaining TODO lists, planning projects, and authoring documents with a fast and effective plain-text system. It is absolutely capable.
</p>

<p>
However, the learning curve of Org-mode is steep and even steeper for non-Emacs users. Users are expected to read documentation and practice. Once familiarized with Emacs, its usability on Linux will jump from 0 to 5 (or even infinity). The Android client Orgzly is usable but could be better. Synchronization works with SyncThing.
</p>
</div>
</div>
<div id="outline-container-review-joplin-22-and-standard-note-24" class="outline-3">
<h3 id="review-joplin-22-and-standard-note-24">Review: Joplin (22) and Standard Note (24)</h3>
<div class="outline-text-3">
<p>
Joplin and Standard Note are both strong note-taking alternatives to Evernote. However, they suck in task management because they simply cannot show all tasks scheduled for today. They both have a decent desktop app written in Electron. Synchronization works natively and users can turn on end-to-end encryption for privacy/security.
</p>

<p>
If task management is not a requirement, both Joplin and Standard Note are very good alternatives.
</p>
</div>
</div>
<div id="outline-container-review-taskwarrior-21-and-todo-txt-20" class="outline-3">
<h3 id="review-taskwarrior-21-and-todo-txt-20">Review: Taskwarrior (21) and TODO.txt (20)</h3>
<div class="outline-text-3">
<p>
Taskwarrior and TODO.txt are both FOSS for task management. However, they both allow only one line per task, which makes adding extra context to the task very hard. Their clients are barely usable to me (or I have not learned enough). Secure synchronization works with a self-hosted server or with SyncThing for Taskwarrior and TODO.txt respectively.
</p>
</div>
</div>
<div id="outline-container-review-tiddlywiki" class="outline-3">
<h3 id="review-tiddlywiki">Review: TiddlyWiki (?)</h3>
<div class="outline-text-3">
<p>
TiddlyWiki is a "non-linear personal web notebook". It looks fancy but I haven't tried it intensively because Org-mode seems working for me already at this point. I will leave it as a question mark.
</p>
</div>
</div>
</div>
<div id="outline-container-3-switching-to-org-mode" class="outline-2">
<h2 id="3-switching-to-org-mode">3. Switching to Org-mode</h2>
<div class="outline-text-2">
<p>
After all these explorations, Org-mode looks promising to me and I started the Org-mode/Emacs 30-day challenge &#x2013; keep using Org-mode/Emacs for a month. Note that I was still using Evernote during the transition but gradually reducing the dependency on it.
</p>

<p>
I have now finished the challenge and can claim myself an Org-mode user. I am happy with Org-mode and the new workflow. Since the org files are in plain text, I manage my notes with Git, review, and polish all the changes before committing it. It helps to improve the quality of my notes!
</p>

<p>
Beyond Org-mode, I also started seeing the beauty of Emacs and why people use it instead of Vim or other modern editors. Emacs is ostensibly an editor but actually a powerful Lisp platform/runtime, which makes it super extensible and capable. Users can customize Emacs and make it their own systems for their own purposes.
</p>

<p>
I am now using Emacs even more. For example, I replace Visual Studio Code, my previous editor/git porcelain, with  <a href="https://magit.vc/">Magit</a>. This blog post is written in Emacs with <a href="https://ox-hugo.scripter.co/">ox-hugo</a>. I probably will blog on these topics sometime in the future.
</p>

<p>
All in all, I am very happy with the privacy gain and the learning from this switch!
</p>
</div>
</div>
]]></description>
    </item>

  </channel>
</rss>
