<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Org-Mode on Wai Hon&#39;s Blog</title>
    <link>https://whhone.com/tags/org-mode/</link>
    <description>Recent content in Org-Mode on Wai Hon&#39;s Blog</description>
    <generator>weblorg 0.1.0 (https://emacs.love/weblorg)</generator>
    <language>en</language>
    <lastBuildDate>Sun, 08 Mar 2026 16:30:00 -0700</lastBuildDate>
    <atom:link
        href='https://whhone.com/tags/org-mode/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>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>Use Syncthing with WebDAV to Sync Everywhere</title>
      <link>https://whhone.com/posts/webdav-syncthing/</link>
      <guid>https://whhone.com/posts/webdav-syncthing/</guid>
      <pubDate>Fri, 04 Nov 2022 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="#why-not-just-syncthing">Why not just Syncthing?</a></li>
<li><a href="#overview">Overview</a></li>
<li><a href="#webdav-setup">WebDAV Setup</a>
<ul>
<li><a href="#attempt-1-nextcloud">Attempt #1: Nextcloud</a></li>
<li><a href="#attempt-2-caddy-webdav">Attempt #2: Caddy WebDAV</a></li>
</ul>
</li>
<li><a href="#android-and-ios-setup">Android and iOS Setup</a></li>
<li><a href="#syncthing-setup">Syncthing Setup</a>
<ul>
<li><a href="#tweak-1-reduce-file-watch-delay">Tweak #1: Reduce File Watch Delay</a></li>
<li><a href="#tweak-2-restart-syncthing-on-wakeup">Tweak #2: Restart Syncthing on Wakeup</a>
<ul>
<li><a href="#a-script-to-restart-syncthing">A Script to Restart Syncthing</a></li>
<li><a href="#run-the-script-on-wakeup-macos">Run the Script on Wakeup (MacOS)</a></li>
<li><a href="#run-the-script-on-wakeup-linux">Run the Script on Wakeup (Linux)</a></li>
<li><a href="#run-the-script-on-wakeup-chromeos">Run the Script on Wakeup (ChromeOS)</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
</div>
</nav>
<p>
I have been using Syncthing with <a href="https://caddyserver.com/docs/modules/http.handlers.webdav">Caddy's WebDAV</a> to synchronize my <a href="https://orgmode.org/">Org Mode</a> files across computers and mobiles for few weeks. I am satisfied with it and writing this post about the setup.
</p>
<div id="outline-container-why-not-just-syncthing" class="outline-2">
<h2 id="why-not-just-syncthing">Why not just Syncthing?</h2>
<div class="outline-text-2">
<p>
My previous setup use solely Syncthing to synchronize them across computers and mobiles. While Syncthing works great on computers, it is problematic on mobiles because mobile can switch networks, have a limited battery, and have limited background sync capability (especially on iOS). Out-dated files or conflicts happen more often to me when I use a mobile device.
</p>

<p>
I noticed some Org Mode mobile apps (like "beorg" and "Orgzly") support WebDAV sync. Hence, I tried to add a WebDAV entry point for my org files and see how it goes.
</p>
</div>
</div>
<div id="outline-container-overview" class="outline-2">
<h2 id="overview">Overview</h2>
<div class="outline-text-2">

<figure>
<img src="/attachment/webdav.jpg" alt="webdav.jpg">

</figure>

<p>
I run Syncthing and WebDAV both watching the same org directory on a tiny server, Raspberry Pi 3B. Computers and mobiles are connected with Syncthing and WebDAV respectively.
</p>
</div>
</div>
<div id="outline-container-webdav-setup" class="outline-2">
<h2 id="webdav-setup">WebDAV Setup</h2>
<div class="outline-text-2">
<p>
I first tried Nextcloud but chose Caddy eventually to set up WebDAV.
</p>
</div>
<div id="outline-container-attempt-1-nextcloud" class="outline-3">
<h3 id="attempt-1-nextcloud">Attempt #1: Nextcloud</h3>
<div class="outline-text-3">
<p>
My first attempt was using Nextcloud's WebDAV, after searching "Syncthing WebDAV" and found <a href="https://forum.syncthing.net/t/mixed-syncthing-with-nextcloud/10499">this story</a>.
</p>

<p>
I added the Syncthing's local folder to Nextcloud via <a href="https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/external_storage_configuration_gui.html">external storage</a> so it could be accessed from WebDAV. It worked. It proved that Syncthing with WebDAV is a viable solution.
</p>

<p>
However, Nextcloud is too heavy for my Raspberry Pi 3. The latency is high enough to degrade the mobile experience. This could be a good solution for existing Nextcloud users with a faster hosting machine.
</p>
</div>
</div>
<div id="outline-container-attempt-2-caddy-webdav" class="outline-3">
<h3 id="attempt-2-caddy-webdav">Attempt #2: Caddy WebDAV</h3>
<div class="outline-text-3">
<p>
Since my Raspberry Pi is already using Caddy as the web server, why not give <a href="https://caddyserver.com/docs/modules/http.handlers.webdav">Caddy's WebDAV</a> a shot? Caddy is written in Go and should have better performance.
</p>

<p>
The WebDAV module was not built-in and I need to built a new Caddy binary with <code>xcaddy</code>. Then, I updated the systemd service to run as the same user as syncthing to get the file permission right.
</p>

<p>
It worked and indeed ran so much faster. I am satisfied!
</p>

<p>
Here is the snippet from my Caddyfile WebDAV config.
</p>

<div class="org-src-container">
<pre class="src src-caddyfile"><span class="org-caddyfile-label">my.webdav.host</span> {
<span class="org-caddyfile-directive">
</span>    <span class="org-caddyfile-directive">basicauth</span> * {
        <span class="org-caddyfile-subdirective">&lt;user&gt;</span> &lt;hash&gt;
    }
<span class="org-caddyfile-directive">
</span>    <span class="org-caddyfile-directive">root</span> * /path/to/webdav
<span class="org-caddyfile-directive">
</span>    <span class="org-caddyfile-directive">@get</span> method GET
    <span class="org-caddyfile-directive">route</span> {
        <span class="org-caddyfile-subdirective">file_server</span> @get {
            hide .git .gitignore .stfolder .stversions
            browse
        }
<span class="org-caddyfile-subdirective">
</span>        <span class="org-caddyfile-subdirective">webdav</span>
    }
}
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-android-and-ios-setup" class="outline-2">
<h2 id="android-and-ios-setup">Android and iOS Setup</h2>
<div class="outline-text-2">
<p>
I use beorg on iOS and Orgzly on Android. Both of them support "WebDAV" with "Auto-sync". "Auto-sync" performs a sync when a note is changed or when the app is resumed. This greatly reduces the chance of conflict, when compared with Syncthing.
</p>

<p>
In addition, I found beorg also comes with a LISP runtime (<a href="https://www.biwascheme.org/">BiwaScheme</a>) and allows users to customize the app <a href="https://beorg.app/manual/scripting/">in a way similar to Emacs</a>. The customization is limited at the moment but it has the potential!
</p>
</div>
</div>
<div id="outline-container-syncthing-setup" class="outline-2">
<h2 id="syncthing-setup">Syncthing Setup</h2>
<div class="outline-text-2">
<p>
I use most of the default configuration with two tweaks.
</p>
</div>
<div id="outline-container-tweak-1-reduce-file-watch-delay" class="outline-3">
<h3 id="tweak-1-reduce-file-watch-delay">Tweak #1: Reduce File Watch Delay</h3>
<div class="outline-text-3">
<p>
I reduce the <a href="https://docs.syncthing.net/users/config.html#config-option-folder.fswatcherdelays"><code>fsWatcherDelayS</code></a> from 10s to 1s in all instances. This makes the synchronization happens more instantly and seamlessly between devices. For example, when I make a change on the phone, it updates the Raspberry Pi and synchronizes across other computers in a second.
</p>
</div>
</div>
<div id="outline-container-tweak-2-restart-syncthing-on-wakeup" class="outline-3">
<h3 id="tweak-2-restart-syncthing-on-wakeup">Tweak #2: Restart Syncthing on Wakeup</h3>
<div class="outline-text-3">
<p>
When waking up from sleep, Syncthing can take quite a while to recover the connection.
</p>

<p>
Syncthing used to provide an option called <code>restartOnWakeup</code> to restart Syncthing on wakeup and avoid this long delay. However, this option <a href="https://github.com/syncthing/syncthing/issues/8448">has been removed in 2022</a>. I replicated this behavior myself, by writing a script to restart Syncthing, and running it on wake up.
</p>
</div>
<div id="outline-container-a-script-to-restart-syncthing" class="outline-4">
<h4 id="a-script-to-restart-syncthing">A Script to Restart Syncthing</h4>
<div class="outline-text-4">
<p>
Creates a script to hit the REST endpoint (<code>/rest/system/restart</code>) on the local Syncthing instance.
</p>

<div class="org-src-container">
<pre class="src src-sh"><span class="org-variable-name">LOCAL_ENDPOINT</span>=http://localhost:8384
<span class="org-variable-name">LOCAL_API_KEY</span>=&lt;API_KEY&gt;

<span class="org-builtin">echo</span> <span class="org-string">"Restarting Local Syncthing"</span>

curl --silent -H <span class="org-string">"X-API-Key: ${LOCAL_API_KEY}"</span> <span class="org-sh-escaped-newline">\</span>
     --connect-timeout 1 <span class="org-sh-escaped-newline">\</span>
     -X POST <span class="org-sh-escaped-newline">\</span>
     ${<span class="org-variable-name">LOCAL_ENDPOINT</span>}/rest/system/restart
</pre>
</div>
</div>
</div>
<div id="outline-container-run-the-script-on-wakeup-macos" class="outline-4">
<h4 id="run-the-script-on-wakeup-macos">Run the Script on Wakeup (MacOS)</h4>
<div class="outline-text-4">
<p>
For MacOS, uses <code>sleepwatcher</code> to detect wakeup event and execute the above script.
</p>

<p>
First, install and start <code>sleepwatcher</code> service.
</p>

<div class="org-src-container">
<pre class="src src-sh"><span class="org-comment-delimiter"># </span><span class="org-comment">To install sleepwatcher
</span>brew install sleepwatcher

<span class="org-comment-delimiter"># </span><span class="org-comment">To start sleepwatcher now and restart at login
</span>brew services start sleepwatcher
</pre>
</div>

<p>
Second, creates another script <code>~/.wakeup</code>, which will be executed by <code>sleepwatcher</code> on system wakeup.
</p>

<div class="org-src-container">
<pre class="src src-sh">/path/to/syncthing-restart.sh
</pre>
</div>
</div>
</div>
<div id="outline-container-run-the-script-on-wakeup-linux" class="outline-4">
<h4 id="run-the-script-on-wakeup-linux">Run the Script on Wakeup (Linux)</h4>
<div class="outline-text-4">
<p>
For Linux, creates a script under <code>/usr/lib/systemd/system-sleep/</code>, which will be executed both "pre" and "post" system sleep.
</p>

<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-keyword">case</span> $<span class="org-variable-name">1</span><span class="org-keyword"> in</span>
    post)
        /path/to/syncthing-restart.sh
        ;;
<span class="org-keyword">esac</span>
</pre>
</div>

<p>
Credit to <a href="https://blog.christophersmart.com/2016/05/11/running-scripts-before-and-after-suspend-with-systemd/">this blog post</a>.
</p>
</div>
</div>
<div id="outline-container-run-the-script-on-wakeup-chromeos" class="outline-4">
<h4 id="run-the-script-on-wakeup-chromeos">Run the Script on Wakeup (ChromeOS)</h4>
<div class="outline-text-4">
<p>
Unfortunately, the Linux systemd method does not work for ChromeOS via Crostini. My solution is to use a script to check the system timestamp every second. If the current timestamp and the last timestamp differ more than 3 seconds, then I consider it as a system wakeup.
</p>

<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">bash</span><span class="org-comment">
</span>
<span class="org-variable-name">last</span>=$(<span class="org-sh-quoted-exec">date +%s</span>)

<span class="org-keyword">while</span> true; <span class="org-keyword">do</span>
  <span class="org-variable-name">current</span>=$(<span class="org-sh-quoted-exec">date +%s</span>)

  <span class="org-keyword">if</span> [[ $(<span class="org-sh-quoted-exec">($current - $last</span>)) -ge 3 ]]; <span class="org-keyword">then</span>
    <span class="org-builtin">echo</span> <span class="org-string">"Detected wake up. Restarting Syncthing."</span>
    /path/to/syncthing-restart.sh
  <span class="org-keyword">fi</span>

  <span class="org-variable-name">last</span>=${<span class="org-variable-name">current</span>}
  sleep 1
<span class="org-keyword">done</span>
</pre>
</div>

<p>
Then, I create a systemd service (<code>~/.config/systemd/user/sleep-watcher.service</code>) to run this script in the background.
</p>

<div class="org-src-container">
<pre class="src src-systemd"><span class="org-type">[Unit]</span>
<span class="org-keyword">Description</span>=Sleep Watcher Service

<span class="org-type">[Service]</span>
<span class="org-keyword">Type</span>=<span class="org-builtin">simple</span>
<span class="org-keyword">StandardOutput</span>=journal
<span class="org-keyword">ExecStart</span>=/path/to/the/above/sleep-watcher.sh

<span class="org-type">[Install]</span>
<span class="org-keyword">WantedBy</span>=default.target
</pre>
</div>

<p>
Once it is ready, reload systemd, start and enable the service.
</p>

<div class="org-src-container">
<pre class="src src-sh">systemctl --user daemon-reload
systemctl --user enable --now sleep-watcher
</pre>
</div>
</div>
</div>
</div>
</div>
<div id="outline-container-conclusion" class="outline-2">
<h2 id="conclusion">Conclusion</h2>
<div class="outline-text-2">
<p>
Syncthing works brilliant on computers and laptops with the tweaks mentioned above. WebDAV is simple and cheap to host. It is secure to use over the Internet when pairing with BasicAuth and HTTPS (both supported by Caddy). It is not a perfect synchronization tool but good enough to fill the mobile gap.
</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>
