<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title><![CDATA[programming (and other) musings]]></title>
<description><![CDATA[programming (and other) musings]]></description>
<link>https://jao.io/blog/</link>
<atom:link href="https://jao.io/blog/rss.xml" rel="self" type="application/rss+xml" />
<lastBuildDate>Mon, 04 May 2026 20:18:56 +0100</lastBuildDate>
<item>
  <title><![CDATA[geiser moved to codeberg]]></title>
  <description><![CDATA[
<p>
I've moved the repositories of the <a href="https://geiser.nongnu.org">geiser</a> packages I maintain to <a href="https://codeberg.org/geiser">codeberg</a>, so
make sure you update your remotes if you access them directly through git. The
URLs are already updated in the ELPAs, so nothing changed if you installed
them via their packages.
</p>

<p>
Seventeen years and running. Happy hacking!
</p>

<!-- preview-end -->
<div class="taglist"><a href="https://jao.io/blog/tags.html"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://jao.io/blog/tag-emacs.html" class="tag" data-tag="emacs" data-index="0">emacs</a> </span></div>]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://jao.io/blog/geiser-moved-to-codeberg.html</link>
  <guid>https://jao.io/blog/geiser-moved-to-codeberg.html</guid>
  <pubDate>Mon, 04 May 2026 20:09:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[mailbox spring cleaning with notmuch]]></title>
  <description><![CDATA[
<p>
After many years of switching between email systems, service providers, backup
and sychronisation strategies, mail folders layouts, protocols and inadvertent
replications, i ended up with a sizeable amount of local email folders
containing, i was quite sure, lots of duplicates. My current email handling
systems of choice, Gnus with nnml and notmuch, are pretty good at hiding them
from me in normal operation, but i know those dups are there, lurking in the
dark, and periodically look for a way to uncover and kill them.
</p>

<p>
I know about the sophisticated <a href="https://github.com/kdeldycke/mail-deduplicate">mail-deduplicate</a> utility, but I guess it's too
sophisticated for me :) Turns out the solution was in front of my eyes:
notmuch knows about duplicates, and can list them easily:
</p>

<div class="org-src-container">
<pre class="src src-bash">notmuch search --duplicate=2 --output=files <span style="color: #023770;">'*'</span><span style="color: #005555;">`</span>
</pre>
</div>

<p>
That command will list the full path to the second file in duplicate pairs
found by notmuch. So, getting rid of them is as easy as
</p>

<div class="org-src-container">
<pre class="src src-bash"><span style="color: #023770;">for</span> f<span style="color: #023770;"> in</span>  <span style="color: #005555;">`notmuch search --duplicate=2 --output=files '*'``; do
  rm $f;
done
notmuch new</span>
</pre>
</div>

<p>
After doing that (note we rebuild notmuch's database at the end, searching
again for level-2 duplicates might discover new files if you have emails
duplicated more than twice (i had). Rinse and repeat.
</p>

<!-- preview-end -->
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-sundry.html">sundry</a> </div>]]></description>
  <category><![CDATA[sundry]]></category>
  <link>https://jao.io/blog/mailbox-spring-cleaning-with-notmuch.html</link>
  <guid>https://jao.io/blog/mailbox-spring-cleaning-with-notmuch.html</guid>
  <pubDate>Fri, 03 Oct 2025 03:55:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[application badges at your command line]]></title>
  <description><![CDATA[
<p>
I've been playing with macOS lately, and <i>needed</i> a quick way of grabbing the
number of unread articles in <a href="https://en.wikipedia.org/wiki/NetNewsWire">NetNewsWire</a>. So I wondered if I could somehow
access its application badge label.
</p>
<div id="outline-container-orgcad507d" class="outline-2">
<h2 id="orgcad507d">The tip</h2>
<div class="outline-text-2" id="text-orgcad507d">
<p>
Turns out one can:
</p>

<div class="org-src-container">
<pre class="src src-bash">lsappinfo info -app NetNewsWire -only StatusLabel
</pre>
</div>

<p>
which produces something like:
</p>

<pre class="example">
"StatusLabel"={ "label"="6" }
</pre>


<p>
One day I'll learn <code>awk</code> and feel ashamed of what I'm about to write below,
but here's how to use grep to get just that count, if you must:
</p>

<div class="org-src-container">
<pre class="src src-bash">lsappinfo info -app NetNewsWire -only StatusLabel | grep -E <span style="color: #023770;">'[0-9]+'</span> -o
</pre>
</div>

<p>
and we get only the digits in the output:
</p>

<pre class="example">
6
</pre>


<p>
Hat tip to <a href="https://stackoverflow.com/questions/75163201/how-can-i-get-the-dock-badge-text-of-other-applications">Alexander's answer to this question</a>, which put me on the right
track despite his reservations.  Reading the convoluted code in the other
answers, I have none at all.
</p>

<!-- preview-end -->
</div>
</div>
<div id="outline-container-org08b5612" class="outline-2">
<h2 id="org08b5612">The context</h2>
<div class="outline-text-2" id="text-org08b5612">
<p>
You won't be surprised to know that the actual place where I wanted to
read that badge wasn't the CLI but Emacs, to display it in <a href="https://codeberg.org/jao/elibs/src/commit/d03b2109650003ff98d89ebe9db22d62df1374e1/lib/eos/jao-minibuffer.el">my little
notification centre hosted in the minibuffer</a>. I've been putting together
some utilities to run applescript and such, and at first I thought of
using NetNewsWire's dictionary with something like:
</p>

<div class="org-src-container">
<pre class="src src-applescript">tell application "NetNewsWire"
  set result to 0
  repeat with acc in accounts
     set theFeeds to allWebFeeds of acc
     repeat with f in theFeeds
       set theArticles to articles of f
       repeat with a in theArticles
         if (not (read of a)) then set result to (result + 1)
       end repeat
     end repeat
  end repeat
  return result
end tell
</pre>
</div>

<p>
which works&#x2026; if you're willing to wait the couple of minutes it takes to
run! Reminded me of the old adage in systems programming stating that a
result that comes in late is an incorrect result.
</p>
</div>
</div>
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-macos.html">macos</a> </div>]]></description>
  <category><![CDATA[macos]]></category>
  <link>https://jao.io/blog/application-badges-at-your-command-line.html</link>
  <guid>https://jao.io/blog/application-badges-at-your-command-line.html</guid>
  <pubDate>Thu, 02 Oct 2025 18:05:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[eww to org]]></title>
  <description><![CDATA[
<!-- preview-start -->

<p>
Here's a quick'n'dirty command to generate an <code>org-mode</code> rendering of an eww
page, taking into account not only links (as the built-in
<code>org-eww-copy-for-org-mode</code> does), but also headings, italic and bold faces.
</p>

<!-- preview-end -->

<p>
I am pretty sure it's full of corner cases and rough edges, but it's working
for me as a starting point.
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #023770;">defun</span> <span style="color: #005555;">jao-eww-to-org</span> (<span style="color: #023770;">&amp;optional</span> dest)
  <span style="color: #666666; font-style: italic;">"Render the current eww buffer using org markup.
If DEST, a buffer, is provided, insert the markup there."</span>
  (<span style="color: #023770;">interactive</span>)
  (<span style="color: #023770;">unless</span> (org-region-active-p)
    (<span style="color: #023770;">let</span> ((shr-width 80)) (eww-readable)))
  (<span style="color: #023770;">let*</span> ((start (<span style="color: #023770;">if</span> (org-region-active-p) (region-beginning) (point-min)))
         (end (<span style="color: #023770;">if</span> (org-region-active-p) (region-end) (point-max)))
         (buff (<span style="color: #023770;">or</span> dest (generate-new-buffer <span style="color: #023770;">"*eww-to-org*"</span>)))
         (link (eww-current-url))
         (title (<span style="color: #023770;">or</span> (plist-get eww-data <span style="color: #023770;">:title</span>) <span style="color: #023770;">""</span>)))
    (<span style="color: #023770;">with-current-buffer</span> buff
      (insert <span style="color: #023770;">"#+title: "</span> title <span style="color: #023770;">"\n#+link: "</span> link <span style="color: #023770;">"\n\n"</span>)
      (org-mode))
    (<span style="color: #023770;">save-excursion</span>
      (goto-char start)
      (<span style="color: #023770;">while</span> (&lt; (point) end)
        (<span style="color: #023770;">let*</span> ((p (point))
               (props (text-properties-at p))
               (k (seq-find (<span style="color: #023770;">lambda</span> (x) (plist-get props x))
                            '(shr-url image-url outline-level face)))
               (prop (<span style="color: #023770;">and</span> k (list k (plist-get props k))))
               (next (<span style="color: #023770;">if</span> prop
                         (next-single-property-change p (car prop) nil end)
                       (next-property-change p nil end)))
               (txt (buffer-substring (point) next))
               (txt (replace-regexp-in-string <span style="color: #023770;">"\\*"</span> <span style="color: #023770;">"&#183;"</span> txt)))
          (<span style="color: #023770;">with-current-buffer</span> buff
            (insert
             (<span style="color: #023770;">pcase</span> prop
               ((<span style="color: #023770;">and</span> (<span style="color: #023770;">or</span> `(shr-url ,url) `(image-url ,url))
                     (guard (string-match-p <span style="color: #023770;">"^http"</span> url)))
                (<span style="color: #023770;">let</span> ((tt (replace-regexp-in-string <span style="color: #023770;">"\n</span><span style="color: #023770;">\\</span><span style="color: #023770;">(</span><span style="color: #023770;">[</span><span style="color: #023770;">^</span><span style="color: #023770;">$]</span><span style="color: #023770;">\\</span><span style="color: #023770;">)</span><span style="color: #023770;">"</span> <span style="color: #023770;">" \\1"</span> txt)))
                  (org-link-make-string url tt)))
               (`(outline-level ,n)
                (concat (make-string (- (* 2 n) 1) ?*) <span style="color: #023770;">" "</span> txt <span style="color: #023770;">"\n"</span>))
               ('(face italic) (format <span style="color: #023770;">"/%s/ "</span> (string-trim txt)))
               ('(face bold) (format <span style="color: #023770;">"*%s* "</span> (string-trim txt)))
               (_ txt))))
          (goto-char next))))
    (pop-to-buffer buff)
    (goto-char (point-min))))
</pre>
</div>
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-emacs.html">emacs</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://jao.io/blog/eww-to-org.html</link>
  <guid>https://jao.io/blog/eww-to-org.html</guid>
  <pubDate>Tue, 30 Jul 2024 16:26:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[wittgenstein's mistress]]></title>
  <description><![CDATA[
<!-- preview-start -->


<figure id="org0c31a0f">
<img src="../img/wittgenstein-mistress.jpg" alt="wittgenstein-mistress.jpg">

</figure>

<!-- preview-end -->
<p>
It took me twenty or thirty pages to really <i>enter</i> in this book, but once I got
in its mood I had a truly great time. It includes a subliminal tour over
classic literature, painting and philosophy all in a truy original narrative
voice. Foster Wallace's afterword has also some interesting bits, once you
pardon him his pretentiousness (definitely a much better writer than
critic). And remember, the protagonist is <i>not</i> called Helen.
</p>
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-books.html">books</a> </div>]]></description>
  <category><![CDATA[books]]></category>
  <link>https://jao.io/blog/wittgensteins-mistress.html</link>
  <guid>https://jao.io/blog/wittgensteins-mistress.html</guid>
  <pubDate>Sun, 24 Mar 2024 21:05:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[la casa verde]]></title>
  <description><![CDATA[
<!-- preview-start -->


<figure id="org678e3f7">
<img src="../img/la-casa-verde.jpg" alt="la-casa-verde.jpg">

</figure>

<!-- preview-end -->

<p>
Vargas Llosa's political views are so obnoxious that I've been putting off
reading him for decades out of contempt. But one of my teachers insisted I
should forget about politics and read this one, or <i>La fiesta del chivo</i>, and I
finally took the plunge. And I must say I am happy I did: the way Vargas Llosa
plays with language in <i>La casa verde</i> is astounding, and he's able to do things
I would have thought impossible. Reminded me of that scene in the movie
<i>Amadeus</i> where Mozart explains to the king how three or four people talking at
once is just noise, but four voices singing at once is harmony and
beauty. Well, Vargas Llosa does the same in writing. He's also able to play
with time, interlocking two or three temporal lines in a single narrative and
even making the whole thing at times loop into itself. The man knew how to
write (I read his latest works are not as good as they used to be) and was
creating something I've not seen any other writer do. I read afterwards <i>La
fiesta del chivo</i>, which is good but not as good. All that in Spanish: I am
not sure all those fireworks can be translated, but one would surely need a
talented translator for them!
</p>
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-books.html">books</a> </div>]]></description>
  <category><![CDATA[books]]></category>
  <link>https://jao.io/blog/la-casa-verde.html</link>
  <guid>https://jao.io/blog/la-casa-verde.html</guid>
  <pubDate>Sun, 24 Mar 2024 20:33:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[poor things]]></title>
  <description><![CDATA[
<!-- preview-start -->


<figure id="orgd059ba4">
<img src="../img/poor-things.jpg" alt="poor-things.jpg">

</figure>

<!-- preview-end -->

<p>
I've read good things about the forthcoming movie, and liked what I saw in the
promotional video, but I cannot believe it's going to be near as good as this
novel. The book has too many nuances, literary tricks and wordplay and
paragraphs one has to read and reread, to be translated to a film. The latter
might be its own work of art, and that's fine. But if you're curious about the
movie, I'd definitely recommend to read this book. If you're not, I'd
definitely recommend to read this book. The writing is fresh and funny, in
typical Gray fashion, and the real themes of the book are universal and
exposed in a way that is very entertaining on the surface, but with a subtext
that gives you food for thought. I don't remember when was the last time that
I read two hundred pages of a book in a single day, time just flew, as they
say.
</p>
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-books.html">books</a> </div>]]></description>
  <category><![CDATA[books]]></category>
  <link>https://jao.io/blog/poor-things.html</link>
  <guid>https://jao.io/blog/poor-things.html</guid>
  <pubDate>Wed, 11 Oct 2023 02:28:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[in no particular order]]></title>
  <description><![CDATA[
<p>
Interesting bits elsewhere:
</p>

<ul class="org-ul">
<li><a href="https://www.cambridge.org/core/journals/journal-of-functional-programming/article/programming-language-semantics-its-easy-as-123/EC2C046CF94382B3B408036B84475DC7">Programming language semantics: It’s easy as 1,2,3</a></li>
<li><a href="https://fermatslibrary.com/s/no-silver-bullet-essence-and-accident-in-software-engineering">No Silver Bullet - Essence and Accident in Software Engineering</a></li>
</ul>


<p>
<a href="https://jao.io/pages/links.html">Older entries</a>
</p>

<!-- preview-end -->
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-sundry.html">sundry</a> </div>]]></description>
  <category><![CDATA[sundry]]></category>
  <link>https://jao.io/blog/in-no-particular-order.html</link>
  <guid>https://jao.io/blog/in-no-particular-order.html</guid>
  <pubDate>Wed, 11 Oct 2023 02:00:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[the cambridge centenary ulysess]]></title>
  <description><![CDATA[
<!-- preview-start -->


<figure id="org39ceb15">
<img src="../img/ulysses.jpg" alt="ulysses.jpg">

</figure>

<!-- preview-end -->

<p>
Physically, this book is obnoxious: huge, wasted margins frame a reproduction
of the original text that painstakingly tries to look as shabby as it was,
including faded letters and all its typos, and its size and weight border on
the unmanageable.  Ah, but the contents is really good: on the one hand
there's of course Joyce's text itself (after twenty years since the last time,
my English, with the help of the annotations, was closer to be up to the task,
and enjoy it even when it wasn't), and next to it the essays introducing every
chapter, which i found (with an exception or two) very informative and,
sometimes, even illuminating.  I was also delighted to confirm that the
parallels with Homer's work are a strecht to say the least: i quickly read The
Odyssey in preparation and found it, again, boring at best and disheartening
in its depiction of the society of the time (not that Joyce's Dublin was
without its blemishes, but you hopefully get my point).
</p>

<p>
So, just get an electronic version and enjoy!
</p>
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-books.html">books</a> </div>]]></description>
  <category><![CDATA[books]]></category>
  <link>https://jao.io/blog/the-cambridge-centenary-ulysess.html</link>
  <guid>https://jao.io/blog/the-cambridge-centenary-ulysess.html</guid>
  <pubDate>Sun, 30 Oct 2022 01:50:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[visual differential geometry and forms]]></title>
  <description><![CDATA[
<!-- preview-start -->


<figure id="org27190c8">
<img src="../img/visual-differential-geometry.jpg" alt="visual-differential-geometry.jpg">

</figure>

<!-- preview-end -->

<p>
This is a beautiful book.  Crystal-clear and insightful explanations, with the
right amount of historical background and quite original outlook (without
going overboard).  I can only echo what other quoted reviewers have said: i
wish i had had this book when i was studying these matters in earnest, i'm
pretty sure i've understood some fine points for the first time only now!  I'd
also perhaps make an exception on the last part (or <i>act</i>, as Needham calls
them) on differential forms, which feels at times a bit rushed and in need of
some editing, and it'd had been wonderful if the manufacture of the book were
up to its contents: most images and photographs look really, really cheap, and
there are more typos than granted, which is a pity (as to other figures,
they're decent, although it must be said that Needham is not Penrose, but then
who is?).
</p>
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-books.html">books</a> </div>]]></description>
  <category><![CDATA[books]]></category>
  <link>https://jao.io/blog/visual-differential-geometry-and-forms.html</link>
  <guid>https://jao.io/blog/visual-differential-geometry-and-forms.html</guid>
  <pubDate>Sun, 30 Oct 2022 01:30:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[inline snippets and grouping in consult-recoll]]></title>
  <description><![CDATA[
<p>
I've just released a new version of <a href="https://codeberg.org/jao/consult-recoll">consult-recoll</a>, which implements a couple
of features that i am really liking, namely, grouping of search results by
mime type:
</p>


<figure id="orgdd11142">
<img src="../img/consult-recoll-group.png" alt="consult-recoll-group.png">

</figure>

<p>
and inline snippets:
</p>


<figure id="org1c42db9">
<img src="../img/consult-recoll-inline.png" alt="consult-recoll-inline.png">

</figure>

<p>
Happy searches!
</p>

<!-- preview-end -->
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-emacs.html">emacs</a> <a href="https://jao.io/blog/tag-programming.html">programming</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[programming]]></category>
  <link>https://jao.io/blog/inline-snippets-and-grouping-in-consult-recoll.html</link>
  <guid>https://jao.io/blog/inline-snippets-and-grouping-in-consult-recoll.html</guid>
  <pubDate>Thu, 04 Aug 2022 18:29:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[parisian lives]]></title>
  <description><![CDATA[
<!-- preview-start -->


<figure id="orga0dd38a">
<img src="https://jao.io/img/parisian-lives.jpg" alt="parisian-lives.jpg">

</figure>

<!-- preview-end -->

<p>
A very interesting view of how a biographer started her career in the
seventies, with two heavy-weights, Beckett and de Beauvoir.  Bair calls the
book a <i>bio-memoir</i>, and it's indeed quite deserving of a name of its own for
its genre.  One learns of the struggle it was not only to be a biographer of
famous writers still living (and her fascinating relationship with them) but
also to be a successful woman in the seventies.  And there are lots of
interesting details about her writing process, and its all too human side.
Very well written all around, it really whets your appetite: i've already
ordered her Beckett bio!
</p>
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-books.html">books</a> </div>]]></description>
  <category><![CDATA[books]]></category>
  <link>https://jao.io/blog/parisian-lives.html</link>
  <guid>https://jao.io/blog/parisian-lives.html</guid>
  <pubDate>Sun, 31 Jul 2022 04:42:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[consult recoll with live preview]]></title>
  <description><![CDATA[
<p>
Lately, i've gravitated towards <i>recoll</i> as a unified search engine for all my
local data, including org and text notes, documents in PDF or similar formats,
HTML files, and local email. As a result, my little <a href="https://codeberg.org/jao/consult-recoll">consult-recoll</a> package has
gone up a few notches up in my list.  i've just released version 0.5,
featuring live previews.
</p>



<figure id="orgf7e9fef">
<img src="https://jao.io/img/consult-recoll-preview.png" alt="consult-recoll-preview.png">

</figure>

<!-- preview-end -->

<p>
<a href="https://www.lesbonscomptes.com/recoll/">Recoll</a> is a local search engine that knows how to index a wide variety of file
formats.  It also offers a sophisticated query language, and, for some
document kinds, snippets of the text of the document that actually match your
query: that's always been one of my favourite features, and wanted to bring it
to emacs.
</p>

<p>
i found consult's <a href="https://github.com/minad/consult#live-previews">live previews</a> a very nice venue to bring snippets into
emacs, via a new version of <a href="https://codeberg.org/jao/consult-recoll">consult-recoll</a>, and there you go, just a small
matter of programming<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.
</p>

<p>
There are several things of this package that make me happy.  For one, it's
very small (less than 200 lines of code, including comments) and does quite a
bit, thanks to the help of consult on the emacs side and of recoll on the
system's side.  In my opinion, it's a very good example of how the operative
environment provided by emacs brings the Unix philosophy to the next level:
here, it's gluing together functionality provided by emacs packages
(completing read, consult's asynchronous searches and previews, and so on),
and the indexing and search capabilities of a totally unrelated, orthogonal
program, recoll, which in turn delegates to a swarm of other unix programs
(such as antiword, unrtf, poppler, pstotext and a long etc) to extract
information from local files<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.  Very pleasant!
</p>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
If you're not into consult, my unpublished little library <a href="https://codeberg.org/jao/elibs/src/branch/main/lib/doc/jao-recoll.el">jao-recoll</a>
knows how to render recoll query results (including snippets) in an
org-prettified buffer.
</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">
Another way in which recoll is true to the same philosophy is in its
nice separation of indexing, query and presentation programs; for instance,
its CLI interface, <code>recollq</code>, is what made <code>consult-recoll</code> such a breeze.
</p></div></div>


</div>
</div><div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-emacs.html">emacs</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://jao.io/blog/consult-recoll-with-live-preview.html</link>
  <guid>https://jao.io/blog/consult-recoll-with-live-preview.html</guid>
  <pubDate>Fri, 22 Jul 2022 19:08:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[klara and the sun]]></title>
  <description><![CDATA[
<!-- preview-start -->

<figure id="org78cfbc9">
<img src="https://jao.io/img/klara-and-the-sun.jpg" alt="klara-and-the-sun.jpg">

</figure>
<!-- preview-end -->

<p>
A nicely written (as always with Ishiguro) history of Stevens turned into an
artificially intelligent being, in a near future reminiscent of <i>Never let me
go</i>.  In other words, i found this novel heavily inspired in previous works of
the author, which i admittedly find better than this one, but that doesn't
mean the book doesn't throw at you a bunch of provocative musings or lacks a
tranquil beauty that makes it absolutely worth reading.
</p>
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-books.html">books</a> </div>]]></description>
  <category><![CDATA[books]]></category>
  <link>https://jao.io/blog/klara-and-the-sun.html</link>
  <guid>https://jao.io/blog/klara-and-the-sun.html</guid>
  <pubDate>Sun, 19 Jun 2022 18:36:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[simple note taking]]></title>
  <description><![CDATA[
<p>
I was just watching <a href="https://www.youtube.com/watch?v=mLzFJcLpDFI">Prot's explanation</a> of his new package <i>denote</i>, a very
elegant note-taking system with a stress on simplicity and, as the author puts
it, low-tech requirements.  Now, those are excellent qualities in my book, and
i think i'd quickly become a <i>denote</i> user if it weren't for the fact that i
already have a homegrown set of utilities following a similar philosophy.
Inevitably, they differ in some details, as is to be expected from software
that has grown with me, as Prot's with him, during more than a decade, but
they are similar in important ways.
</p>

<p>
I've had in mind writing a brief note on my notes utilities for a while, so i
guess this is a good time for it: i can, after showing you mine, point you to
a polished package following a similar philosophy and sidestep any temptation
of doing anything similar with my little functions :)
</p>


<figure id="orgeec5c72">
<img src="https://jao.io/img/consult-recoll.png" alt="consult-recoll.png">

</figure>

<!-- preview-end -->

<p>
As you'll see in a moment, in some ways, my note taking system is even simpler
than Prot's, while in others i rely on more sophisticated software,
essentially meaning that where <i>denote</i> is happy to use dired and filenames,  i
am using grep over the front-matter of the notes.  So if you loved the
filename-as-metadata idea in <i>denote</i>, you can skip the rest of this post!
</p>

<p>
These are the main ideas around which i built my note-taking workflow:
</p>

<ul class="org-ul">
<li>Personally, i have such a dislike for non-human readable identifiers, that
i cannot even stand those 20221234T142312 prefixes (for some reason, i
find them quite hard to read and distracting). When i evolved my notes
collection, i wanted my files to be named by their title and nothing more.
I am also pretty happy to limit myself to org-mode files.  So i wanted a
directory of (often short) notes with names like <code>the-lisp-machine.org</code>,
<code>david-foster-wallace.org</code> or <code>combinator-parsing-a-short-tutorial.org</code>.<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup></li>

<li>I like tags, so all my notes, besides a title, are going to have attached
a list of them (<i>denote</i> puts them in the filename and inside the file's
headers; i'm content with the latter, because, as you'll see in a moment,
i have an easy way of searching through that contents).</li>

<li>I'm not totally averse to hierarchies: besides tagging, i put my notes in
a subdirectory indicating their broad category.  I can then quickly narrow
my searches to a general <i>theme</i> if needed<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>.</li>

<li>As mentioned, i want to be able to search by the title and tag (besides
more broadly by contents) of my notes.  Since that's all information
available in plain text in the files, <code>grep</code> and family (via their emacs
lovely helpers) are all that is needed; but i can easily go a step further
and use other indexers of plain text like, say, recoll (via my
<a href="https://codeberg.org/jao/consult-recoll">consult-recoll package</a>).</li>

<li>It must be easy to quickly create notes that link to any contents i'm
seeing in my emacs session, be it text, web, pdf, email, or any other.
That comes for free thanks to org and <code>org-capture</code>.</li>

<li>I want the code i have to write to accomplish all the above to be short
and sweet, let's say well below two hundred lines of code.</li>
</ul>

<p>
Turns out that i was able to write a little emacs lisp library doing all the
above, thanks to the magic of org-mode and consult: you can find it over at my
repo by the name of <a href="https://codeberg.org/jao/elibs/src/main/lib/doc/jao-org-notes.el">jao-org-notes.el</a>.  The implementation is quite simple and
is based on having all note files in a parent directory (<code>jao-org-notes-dir</code>)
with a subfolder for each of the main top-level categories, and, inside each
of them, note files in org mode with a preamble that has the structure of this
example:
</p>

<div class="org-src-container">
<pre class="src src-org"><span style="color: #8b8970;">#+title:</span> magit tips
<span style="color: #8b8970;">#+date:</span> &lt;2021-07-22 Thu&gt;
<span style="color: #8b8970;">#+filetags: git tips</span>
</pre>
</div>

<p>
The header above corresponds to the note in the file <code>emacs/magit-tips.org</code>.
Now, it's very easy to write a new command to ask for a top-level category and
a list of tags and insert a header like that in a new file: it's called
<a href="https://codeberg.org/jao/elibs/src/main/lib/doc/jao-org-notes.el#L133">jao-org-notes-open-or-create</a> in my little lib, and with it one can define a
new org template:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #023770;">"N"</span> <span style="color: #023770;">"Note"</span> plain (file jao-org-notes-open-or-create)
 <span style="color: #023770;">"\n- %a\n  %i"</span>
 <span style="color: #023770;">:jump-to-captured</span> t)
</pre>
</div>

<p>
that one can then add to <code>org-capture-templates</code> (above, i'm using "N" as its
shortcut; in the package, this is done by <a href="https://codeberg.org/jao/elibs/src/main/lib/doc/jao-org-notes.el#L174">jao-org-notes-setup</a>, which takes the
desired shortcut as a parameter).  I maintain a simple list of possible tags
in the variable <code>jao-org-notes--tags</code>, whose value is persisted in the file
denoted by the value <code>jao-org-notes-tags-cache-file</code>, so that we can remember
newly-added tags; with that and the magic of emacs's completing read, handling
tags is a breeze.
</p>

<p>
Now for search.  These are text files, so if i want to search for contents, i
just need grepping, for instance with <code>M-x rgrep</code> or, even better, <code>M-x
consult-ripgrep</code>.  That is what the command <a href="https://codeberg.org/jao/elibs/src/main/lib/doc/jao-org-notes.el#L143">jao-org-notes-grep</a> does.
</p>

<p>
But it is also very useful to be able to limit searches to the title and tags
of the notes: that's what the command <a href="https://codeberg.org/jao/elibs/src/main/lib/doc/jao-org-notes.el#L126">jao-org-notes-open</a> does using <code>consult</code>
and <code>ripgrep</code> by the very simple device of searching for regular expressions in
the first few lines of each file that start with either <code>#+title:</code> or
<code>#+filetags:</code> followed by the terms we're looking for.  That's something one
could already do with <code>rgrep</code> alone; what consult adds to the party is the
ability of displaying the matching results nicely formatted:
</p>


<figure id="org229eee2">
<img src="https://jao.io/img/org-notes.png" alt="org-notes.png">

</figure>

<p>
Links between notes are simply org <code>file:</code> links, and having a simple
"backlinks" command is, well, simple if you don't want anything fancy<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>.
A command to insert a new link to another note is so boring to almost not
meriting mention (okay, almost: <a href="https://codeberg.org/jao/elibs/src/main/lib/doc/jao-org-notes.el#L161">jao-org-notes-insert-link</a>).
</p>

<p>
And that's about it.  With those simple commands and in about 160 lines of
code i find myself comfortably managing plain text notes, and easily finding
contents within them.  I add a bit of icing by asking <a href="https://www.lesbonscomptes.com/recoll/">Recoll</a> to index my notes
directory (as well as my email and PDFs): it is clever enough to parse org
files, and give you back pointers to the sections in the files, and then issue
queries with the comfort of a consult asynchronous command thanks to
<a href="https://codeberg.org/jao/consult-recoll">consult-recoll</a> (the screenshot in the introduction is just me using it).  It's
a nice use case of how having little, uncomplicated packages that don't try to
be too sophisticated and center on the functionality one really needs makes it
very easy to combine solutions in beatiful ways<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>.
</p>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
I also hate with a passion those <code>:PROPERTIES:</code> drawers and other
metadata embellishments so often used in org files, and wanted to avoid them
as much as possible, so i settled with the only mildly annoying <code>#+title</code> and
friends at the beginning of the files and nothing more.  The usual caveat that
that makes it more difficult to have unique names has proven a non-problem to
me over the years.
</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">
Currently i use <code>work</code>, <code>books</code>, <code>computers</code>, <code>emacs</code>, <code>letters</code>, <code>maths</code>, and
<code>physics</code>: as you see, i am not making a great effort on finding the perfect
ontology of all knowledge; rather, i just use the first broad breakdown of the
themes that interest me most at the moment.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Just look for the regular expression matching "[[file:" followed by the
name of the current file.  I find myself seldom needing this apparently very
popular functionality, but it should be pretty easy to present the search
results in a separate buffer if needed.
</p></div></div>

<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Another example would be how easy it becomes to incorporate web
contents nicely formatted as text when one uses eww as a browser.  Or how how
seamless it is taking notes on PDFs one's reading in emacs, or even externally
zathura (that's for a future blog post though! :)).
</p></div></div>


</div>
</div><div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-emacs.html">emacs</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://jao.io/blog/simple-note-taking.html</link>
  <guid>https://jao.io/blog/simple-note-taking.html</guid>
  <pubDate>Sun, 19 Jun 2022 04:36:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[slimmer emacs with kitty]]></title>
  <description><![CDATA[
<p>
A problem of using Emacs as my operating system is that any otherwise
minor friction with its interface quickly becomes an irritant, and i
thus find myself needed a truly smooth emacs-human interaction; or, to
be more precise <i>emacs-jao</i> interaction: my must needs are going to be,
sometimes, triffles to you, and the other way round.
</p>

<p>
During the last year, a perceived sluggishness in Emacs's X11 display
performance, together with a very noticeably increased RAM consumption
have become one of those irritants, and i decided that enough is
enough, and moved (for the time being at least) from exwm to,
essentially, using xmonad and kitty as my Emacs's display engine.
</p>


<figure id="org5018855">
<img src="https://jao.io/img/emacs-kitty.png" alt="emacs-kitty.png">

</figure>

<!-- preview-end -->

<p>
For several years now, i've been using exwm as my main desktop, and
been quite happy with it.  One of the reasons is that i almost don't
get bit by blocking external programs because, well, i don't use many
external programs.  It's still a bit annoying when every now and then
emacs gets stuck in a busy loop and i have to wait to regain control
of my computer (since emacs is single threaded), and for that reason,
i also have an <a href="https://codeberg.org/jao/xmonad-config">xmonad configuration</a> tailored to essentially use emacs
for everything, with an occasional detour to a web browser or maybe a
video player.  That way, if emacs gets stuck, i can do something else,
and, also, i don't need to restart my desktop when i recompile Emacs.
</p>

<p>
Before that, i had been using emacs as a daemon and <code>emacsclient -t</code> in
an <code>rxvt</code> terminal as my primary emacs interface for many years.  The
limitations weren't many for my use cases: one cannot display images,
but it's very easy to set up things so that one gets a, say, <code>feh</code> pop
up when needed (which is not often) or open an <code>eww</code> buffer in Firefox
instead; and one cannot display PDFs inside Emacs.  That last one was
harder, because i keep my notes (using a <a href="https://codeberg.org/jao/elibs/src/branch/main/lib/doc/jao-org-notes.el">very simple library of mine</a>)
in org mode with links to PDFs and need to be able to easily go from
one to the other. I found a good (for my needs) solution for the
latter too, but well, running Emacs under X11 (or even under wayland
in sway) also worked and was convenient, so i thoght my terminal days
were just a fond memory.
</p>

<p>
Until a year or so ago, when i started noticing my X11 Emacs instance
consuming considerably more RAM (as in, 5 times what it used to need
for long running sessions&#x2026; still more or less what a "modern"
browser takes, i know, but i don't want my Emacs to resemble a browser
in any way).  I normally run Emacs compiled from master, so hiccups
happen and i didn't panic: there probably was some accidental leak
that would be fixed and i could even help locating it.  Unfortunately,
with the release of Emacs 28, this higher memory needs seem
consolidated (and no, i don't use native compilation, so they don't
come from there), as is the tendency to eat more memory as the session
grows longer (without changes in my usage patterns, the RSS footprint
of the process tends to increase at least 500Mb per day).  And, even
more unfortunately, i seem to be the only person on earth suffering
from this: i haven't found yet any fellow emacser observing the
problem, and, although i've tried, i couldn't find a single package
(or combination thereof) causing this issue.  Except, that is, for the
X11 display mode.
</p>

<p>
Fact is, if i run emacs in a terminal with the same packages as normal
and with the same usage patterns (which are essentially the same as
when i use it in X11), there is no memory leak.  Once i load the
standard set of packages i use (chats, eww, notmuch, cider, that kind
of thing, plush all <a href="https://codeberg.org/jao/elibs/src/branch/main">my customizations</a>), an X11 emacs will take around
500Mb RAM, while a terminal one is happy with 250Mb.  And that's fair
enough.  Problem is, after 3 or 4 days using the X11 version, RAM is
consumption jumping to 3 or 4 Gb, while a terminal-based emacs used in
essentially the same way will typically be around 500Mb.
</p>

<p>
Thanks to the experiment above, i'm reasonably sure that the graphical
interface is at the root of my memory woes.  That by itself would have
already been enough to seriously consider a return to my emacs daemon
days, but there was more: using emacs in an X terminal after all this
time, really made me realize how slow the rendering in X11 Emacs is by
comparison.  I mean, rendering in X11 is not slow in absolute terms,
it's perfectly usable in my experience; but, in a terminal? let me
tell you, it's <i>fast</i>, an a real pleasure to use.
</p>

<p>
So all i needed was to smooth out a few wrinkles and it'd be a done
deal.  First thing was to try with <a href="https://sw.kovidgoyal.net/kitty/">kitty</a> as terminal emulator, just
because it's the one i use these days and i like how it's developed.
It took a bit of wrestling to make sure that my usual keybindings (or
slight modifications of them) would work, and also some documentation
reading to come up with a good configuration, but it wasn't too hard:
you can find my <code>kitty.conf</code> <a href="https://codeberg.org/jao/elibs/src/branch/main/data/kitty.conf">here</a>.  A point worth making is that running
Emacs with kitty as a graphical frontend is, for practical purposes,
very close to running Emacs in "graphical mode"; for instance, kitty
has background transparency, uses the same font rendering engine
(<a href="https://en.wikipedia.org/wiki/HarfBuzz">HarfBuzz</a>) as X11 Emacs, and it's perfectly able to display things
like emojis; it just does all that faster!  One only needs to get rid
of the discontinuous vertical separators in Emacs:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(set-display-table-slot standard-display-table 'vertical-border (make-glyph-code ?&#9474;))
</pre>
</div>

<p>
and also clean up the end of the modeline:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #023770;">setq</span> mode-line-end-spaces nil)
</pre>
</div>

<p>
and then you get the screenshot above of some random buffers in and
emacs running with the config above (and my regular color theme): as
you can see, hard to distinguish from an X session.
</p>

<p>
Also, i definitely needed to interact seamlessly with the X clipboard,
as you'd do in X11 Emacs:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #023770;">use-package</span> xclip
  <span style="color: #023770;">:ensure</span> t)

(<span style="color: #023770;">unless</span> (display-graphic-p) (xclip-mode 1))
</pre>
</div>

<p>
As mentioned, i delegate image display to <code>feh</code> and <code>firefox</code> in the few
cases i need it, and interplay with <code>zathura</code> to handle PDFs and my
associated notes, but that's stuff for a future post<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.  With that
in place, i'm finding myself pretty comfortable living in terminal
Emacs most of my time.
</p>

<p>
Speedy hacking!
</p>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
The gist of it is pretty simple though, and it's basically
distilled in <a href="https://codeberg.org/jao/elibs/src/main/init.el#L1595">this section</a> of my configuration.
</p></div></div>


</div>
</div><div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-emacs.html">emacs</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://jao.io/blog/slimmer-emacs-with-kitty.html</link>
  <guid>https://jao.io/blog/slimmer-emacs-with-kitty.html</guid>
  <pubDate>Wed, 08 Jun 2022 18:53:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[el infinito en un junco]]></title>
  <description><![CDATA[
<!-- preview-start -->

<figure id="orgcc03e0f">
<img src="https://jao.io/img/el-infinito-en-un-junco.jpg" alt="el-infinito-en-un-junco.jpg">

</figure>
<!-- preview-end -->

<p>
If you can read Spanish, i wouldn't miss the opportunity to read this
beautfiul essay in the original: Irene Vallejo's prose is clear,
elegant and very beautiful.  It's a delight (and a relief) to read.
And, if you can't read Spanish but have a translation handy, i
wouldn't miss the opportunity to read it either, for a very
entertaining account of the history of ancient books sprinkled with
lots of interesting (to me, at least!) bits about the Greek and Roman
worlds.  The book is morever wrapped in a subdued and sober optimism
that i've found reinvigorating and sorely needed in these times, when
one often feels like running on empty.  Heartily recommended!
</p>
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-books.html">books</a> </div>]]></description>
  <category><![CDATA[books]]></category>
  <link>https://jao.io/blog/el-infinito-en-un-junco.html</link>
  <guid>https://jao.io/blog/el-infinito-en-un-junco.html</guid>
  <pubDate>Sun, 29 May 2022 00:39:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[let's talk lisp]]></title>
  <description><![CDATA[
<!-- preview-start -->

<p>
I just got a second-hand copy of this classic.  Sometimes, used books
are more charming than new ones:
</p>

<table>


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

<col  class="org-left">
</colgroup>
<tbody>
<tr>
<td class="org-left"><img src="https://jao.io/img/lets-talk-lisp-0.jpg" alt="lets-talk-lisp-0.jpg"></td>
<td class="org-left"><img src="https://jao.io/img/lets-talk-lisp-1.jpg" alt="lets-talk-lisp-1.jpg"></td>
</tr>
</tbody>
</table>

<!-- preview-end -->
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-books.html">books</a> <a href="https://jao.io/blog/tag-programming.html">programming</a> </div>]]></description>
  <category><![CDATA[books]]></category>
  <category><![CDATA[programming]]></category>
  <link>https://jao.io/blog/lets-talk-lisp.html</link>
  <guid>https://jao.io/blog/lets-talk-lisp.html</guid>
  <pubDate>Sat, 16 Apr 2022 20:41:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[relaying mail to multiple smarthosts with opensmtpd]]></title>
  <description><![CDATA[
<p>
I like to use a local smtp daemon for sending email from my laptop,
because that way i can send emails even while disconnected and, even
when the network is up, because i don't have to wait for the network
protocol to be completed with a remote smarthost.  Oh, and i also need
local mail delivery.
</p>

<p>
For many years i've used postfix to those ends; it has an acceptably
simply-ish configuration; but recently i've become fond of VPNs
(<a href="https://en.wikipedia.org/wiki/Mullvad">mullvad</a>, if you want to know), and was annoyed by its getting
confused when <code>/etc/resolv.conf</code> changes (for instance, because you get
the VPN up after postfix's service has started).  I've found a
pleasantly simple alternative: <a href="https://www.opensmtpd.org/">OpenSMTPD</a>.
</p>


<!-- preview-end -->

<p>
Say i want to use the SMTP server fencepost.gnu.org when sending an
email as jao@gnu.org and smtp.jao.io when writing with mail@jao.io or
news@xmobar.org in my <code>From</code> header.  OpenSMTPD let's you do that with a
very simple configuration file in <code>/etc/smtpd.conf</code><sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>:
</p>

<div class="org-src-container">
<pre class="src src-conf">
table aliases file:/etc/aliases
table secrets db:/etc/mail/secrets.db

table sendergnu { jao@gnu.org }
table senderjao { mail@jao.io, news@xmobar.org }

listen on localhost

action <span style="color: #023770;">"local"</span> mbox alias &lt;aliases&gt;
action <span style="color: #023770;">"relaygnu"</span> relay host smtp+tls://gnu@fencepost.gnu.org:587 auth &lt;secrets&gt;
action <span style="color: #023770;">"relayjao"</span> relay host smtps://jao@smtp.jao.io:465 auth &lt;secrets&gt;

match for local action <span style="color: #023770;">"local"</span>
match for any from mail-from &lt;sendergnu&gt; action <span style="color: #023770;">"relaygnu"</span>
match for any from mail-from &lt;senderjao&gt; action <span style="color: #023770;">"relaygan"</span>

</pre>
</div>

<p>
where we have also configured local delivery for a good measure.
That's the full configuration file! The only other thing needed is
generating the <code>secrets.db</code> file with the users and passwords
corresponding to the keys <code>gnu</code> and <code>jao</code> (those are just arbitrary
names).  To that end, we create a plain text file with them, using
entries of the form <code>&lt;key&gt; &lt;user&gt;:&lt;password&gt;</code>:
</p>

<div class="org-src-container">
<pre class="src src-conf">gnu  jao:my fencepost password
jao  mail@jao.io:xxxxxxxxxxxxxxxxx
</pre>
</div>

<p>
where my user for <code>fencepost.gnu.org</code> is <code>jao</code> and for <code>smtp.jao.io</code> is
<code>mail@jao.io</code> (you see there's no need of escaping spaces or ats).  Then
we use the program <code>makemap</code> to create the secrets db:
</p>

<pre class="example" id="org6662086">
makemap secrets &amp;&amp; rm secrets
</pre>
<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">
That's the default configuration file in my debian box; other
popular alternative is <code>/etc/openstmpd.conf</code>.
</p></div></div>


</div>
</div><div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-sundry.html">sundry</a> </div>]]></description>
  <category><![CDATA[sundry]]></category>
  <link>https://jao.io/blog/relaying-mail-to-multiple-smarthosts.html</link>
  <guid>https://jao.io/blog/relaying-mail-to-multiple-smarthosts.html</guid>
  <pubDate>Tue, 09 Nov 2021 05:32:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[a high signal to noise emacs command]]></title>
  <description><![CDATA[
<p>
Over the years, i've written perhaps hundreds of little emacs
commands.  Most of them looked useful at the time (why, i absolutely
<i>needed</i> them!), but just faded away after a few weeks.  There are a
handful though that i use all the time, and i specially like it when
their signal (features, usefulness) to noise (lines of code) ratio is
above average.  Here's one with a surprisingly high one:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #023770;">defun</span> <span style="color: #005555;">jao-buffer-same-mode</span> (<span style="color: #023770;">&amp;rest</span> modes)
  <span style="color: #666666; font-style: italic;">"Pop to a buffer with a mode among MODES, or the current one if not given."</span>
  (<span style="color: #023770;">interactive</span>)
  (<span style="color: #023770;">let*</span> ((modes (<span style="color: #023770;">or</span> modes (list major-mode)))
         (pred (<span style="color: #023770;">lambda</span> (b)
                 (<span style="color: #023770;">let</span> ((b (get-buffer (<span style="color: #023770;">if</span> (consp b) (car b) b))))
                   (member (buffer-local-value 'major-mode b) modes)))))
    (pop-to-buffer (read-buffer <span style="color: #023770;">"Buffer: "</span> nil t pred))))
</pre>
</div>

<!-- preview-end -->
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-emacs.html">emacs</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://jao.io/blog/high-signal-to-noise-emacs-command.html</link>
  <guid>https://jao.io/blog/high-signal-to-noise-emacs-command.html</guid>
  <pubDate>Wed, 08 Sep 2021 01:37:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[apropos library]]></title>
  <description><![CDATA[
<p>
A gem introduced in emacs 23 that i've overlooked all these years:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">M-x apropos-library
</pre>
</div>

<!-- preview-end -->
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-emacs.html">emacs</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://jao.io/blog/apropos-library.html</link>
  <guid>https://jao.io/blog/apropos-library.html</guid>
  <pubDate>Sat, 04 Sep 2021 20:49:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[notmuch threads folding in emacs]]></title>
  <description><![CDATA[
<p>
In the last couple of months, i've been moving from Gnus (after more
than twenty years using it!) to notmuch, as part of a simplification
journey (simpler code means a more hackable (emacs) environment) and
also because tagging finally clicked-in (but don't believe anyone
telling you that notmuch is only about tagging, it allows search and
folder-based workflows just as nicely).  Naturally, i've found several
things i liked in Gnus's interface missing in notmuch's, but the
simplicity of the latter has made possible implementing most of them,
sometimes with remarkably little code.  One of them is thread folding.
</p>

<!-- preview-end -->

<p>
notmuch comes with a tree-view (for searches of kind <i>tree</i> in notmuch's
lingo) where you see your messages in a split window, with the upper
half showing a forest of trees, similar to what you'd see in Gnus
summary buffer (and many other clients, i suppose).  Similar but not
quite the same.  In notmuch, all threads are always expanded, while
Gnus has a nice mode in which all but the current one are folded.  I
<i>really</i> wanted that in notmuch.
</p>

<p>
Well, emacs to the rescue. Folding and unfolding sections of a buffer
is the bread and butter of many emacs packages (i'm sure you've heard
of org mode), and one of the simpler and more robust of them is
outline-mode.  So how about we activate <code>outline-minor-mode</code> in
<code>notmuch-tree-mode</code> buffers, with an appropriate regular expression
definition making the first message of each thread a header of the
buffer?  Is there a common pattern in that first message that we can
use?  Well, not quite: since the format of the message lines is
customizable by the user, it's difficult to come up with a pattern
that is not brittle.  Unless we insert in the buffer, invisibly, our
own section marker:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #023770;">defun</span> <span style="color: #005555;">jao-notmuch-tree--msg-prefix</span> (msg)
  (insert (propertize (<span style="color: #023770;">if</span> (plist-get msg <span style="color: #023770;">:first</span>) <span style="color: #023770;">"&gt; "</span> <span style="color: #023770;">"  "</span>) 'display <span style="color: #023770;">""</span>)))
</pre>
</div>

<p>
and advice the notmuch function inserting messages
(<code>notmuch-tree-insert-msg</code>) to call us:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(advice-add 'notmuch-tree-insert-msg <span style="color: #023770;">:before</span> #'jao-notmuch-tree--msg-prefix)
</pre>
</div>

<p>
With that, we've put an invisible <code>"&gt; "</code> prefix on message lines that
are the first in a thread (notmuch handily marks them with <code>:first</code> in
the message metadata passed to <code>notmuch-tree-insert-msg</code>).
</p>

<p>
Now all we need is to tell outline mode to use a regular expression
that recognises the marker above:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #023770;">defun</span> <span style="color: #005555;">jao-notmuch-tree--mode-setup</span> ()
  (<span style="color: #023770;">setq-local</span> outline-regexp <span style="color: #023770;">"^&gt; </span><span style="color: #023770;">\\</span><span style="color: #023770;">|</span><span style="color: #023770;">^En"</span>)
  (outline-minor-mode t))
(add-hook 'notmuch-tree-mode-hook #'jao-notmuch-tree--mode-setup)
</pre>
</div>

<p>
And that's (almost) it! We have now at our disposal all outline
commands in the tree view, with thread folding that is even more
powerful than Gnus's.  For starters, we can use <code>outline-cycle</code>: i have
it in <code>TAB</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(define-key notmuch-tree-mode-map (kbd <span style="color: #023770;">"TAB"</span>) #'outline-cycle)
(define-key notmuch-tree-mode-map (kbd <span style="color: #023770;">"M-TAB"</span>) #'outline-cycle-buffer)
</pre>
</div>

<p>
and let's define a command that shows only the current thread and
folds the others:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #023770;">defun</span> <span style="color: #005555;">jao-notmuch-tree-hide-others</span> (<span style="color: #023770;">&amp;optional</span> and-show)
  (<span style="color: #023770;">interactive</span>)
  (outline-hide-body)
  (outline-show-entry)
  (<span style="color: #023770;">when</span> and-show (notmuch-tree-show-message nil)))
</pre>
</div>

<p>
We can bind it to a convenient key, or perhaps just define a keymap
with the most common outline commands and let my user bind it to the
prefix they prefer:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #023770;">defvar</span> <span style="color: #000000;">jao-notmuch-tree-prefix-map</span>
  (<span style="color: #023770;">let</span> ((m (make-keymap <span style="color: #023770;">"Thread operations"</span>)))
    (define-key m (kbd <span style="color: #023770;">"TAB"</span>) #'outline-cycle)
    (define-key m (kbd <span style="color: #023770;">"t"</span>) #'outline-toggle-children)
    (define-key m (kbd <span style="color: #023770;">"s"</span>) #'outline-show-entry)
    (define-key m (kbd <span style="color: #023770;">"S"</span>) #'outline-show-all)
    (define-key m (kbd <span style="color: #023770;">"h"</span>) #'outline-hide-entry)
    (define-key m (kbd <span style="color: #023770;">"H"</span>) #'outline-hide-body)
    (define-key m (kbd <span style="color: #023770;">"o"</span>) #'jao-notmuch-tree-hide-others)
    (define-key m (kbd <span style="color: #023770;">"n"</span>) #'outline-hide-other)
    m))
</pre>
</div>

<p>
i like to have it at <code>"T"</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(define-key notmuch-tree-mode-map (kbd <span style="color: #023770;">"T"</span>) jao-notmuch-tree-prefix-map)
</pre>
</div>

<p>
There's still one gnusim i missed: i wanted to have a command that
goes to the next (or previous) message (or thread) folding and
unfolding threads if i went from one to another.  That takes a little
more work, but it's not too bad:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #023770;">defun</span> <span style="color: #005555;">jao-notmuch--looking-at-new-p</span> ()
  (<span style="color: #023770;">when-let</span> (ts (notmuch-show-get-tags))
    (<span style="color: #023770;">or</span> (member <span style="color: #023770;">"unread"</span> ts) (member <span style="color: #023770;">"new"</span> ts))))

(<span style="color: #023770;">defun</span> <span style="color: #005555;">jao-notmuch-tree--next</span> (prev thread no-exit)
  (<span style="color: #023770;">let</span> ((line-move-ignore-invisible nil))
    (<span style="color: #023770;">cond</span> ((jao-notmuch--looking-at-new-p))
          (thread
           (<span style="color: #023770;">when</span> (notmuch-tree-next-thread prev)
             (<span style="color: #023770;">unless</span> (jao-notmuch--looking-at-new-p)
               (notmuch-tree-matching-message prev (not no-exit)))))
          ((notmuch-tree-get-message-id)
           (notmuch-tree-matching-message prev (not no-exit)))))
  (<span style="color: #023770;">when</span> (notmuch-tree-get-message-id)
    (jao-notmuch-tree-hide-others t)))

(<span style="color: #023770;">defun</span> <span style="color: #005555;">jao-notmuch-tree-next</span> (thread <span style="color: #023770;">&amp;optional</span> no-exit)
  <span style="color: #666666; font-style: italic;">"Next message or thread in forest, taking care of thread visibility."</span>
  (<span style="color: #023770;">interactive</span> <span style="color: #023770;">"P"</span>)
  (jao-notmuch-tree--next nil thread no-exit))

(<span style="color: #023770;">defun</span> <span style="color: #005555;">jao-notmuch-tree-previous</span> (thread)
  <span style="color: #666666; font-style: italic;">"Previous message or thread in forest, taking care of thread visibility.."</span>
  (<span style="color: #023770;">interactive</span> <span style="color: #023770;">"P"</span>)
  (jao-notmuch-tree--next t thread t))
</pre>
</div>

<p>
I just bind the two new commands to <code>n</code> and <code>p</code> in <code>notmuch-tree-mode-map</code>.
The final icing on the cake is having the tree view start folded.
Since notmuch doesn't provide a proper hook informing you when it's
been fully populated, we have to recur again to a little advice, this
time for the function that is called when the notmuch process filling
the buffer is done, namely <code>notmuch-tree-process-sentinel</code>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #023770;">defun</span> <span style="color: #005555;">jao-notmuch--tree-sentinel</span> (proc <span style="color: #023770;">&amp;rest</span> _)
  (<span style="color: #023770;">when</span> (eq (process-status proc) 'exit) (jao-notmuch-tree-hide-others)))

(advice-add 'notmuch-tree-process-sentinel <span style="color: #023770;">:after</span> #'jao-notmuch--tree-sentinel))
</pre>
</div>

<p>
And we're done.  As mentioned, i find it very remarkable how little
code is needed to get such a robust feature, thanks to the plethora of
libraries already available in the elisp environment and the
flexibility of the means at your disposal to combine them.
</p>

<p>
You can find the current status of this hack as part of my little
<a href="https://codeberg.org/jao/elibs/src/branch/main/lib/net/jao-notmuch.el#L302">jao-notmuch</a> personal package for notmuch extensions.
</p>

<p>
Happy folding!
</p>
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-emacs.html">emacs</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://jao.io/blog/notmuch-threads-folding-in-emacs.html</link>
  <guid>https://jao.io/blog/notmuch-threads-folding-in-emacs.html</guid>
  <pubDate>Thu, 19 Aug 2021 21:15:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[fun with dependent types]]></title>
  <description><![CDATA[
<!-- preview-start -->


<figure id="org8ae89e2">
<img src="https://jao.io/img/the-little-typer.jpg" alt="the-little-typer.jpg">

</figure>

<!-- preview-end -->

<p>
It had been a while since i last had this much fun with a programming
languages book, and learnt so much in the process.  It sure helped
that i am a complete neophyte on the subject matter of dependent
types: i had recently started playing with <a href="https://www.idris-lang.org/">Idris</a>, but reading this
book really clarified the basics for me.  I still remember how, after
<i>The little schemer</i> kindled my love for parenthesis, <i>The seasoned
schemer</i> made me finally grasp the meaning of continuations.  I've got
the feeling that the <i>typer</i> has done again the trick, this time giving
me the jump start i needed on Curry-Howard, programs as proofs and the
beauty of dependent types.  As with continuations back in the day, i
had read a lot about those things, and thought i had understood them,
only to realise that i had not really.
</p>

<p>
The authors, Daniel P. Friedman and David Thrane Christiansen, have
also created a language, Pie, and implemented it in Racket and <a href="https://github.com/david-christiansen/pie-hs">in
Haskell</a>.  I've used the latter in a couple of ways: first, it's a very
fun learning experience as a weak haskeller (or as a fading racketeer,
for that matter) to go over the code (make sure to check <a href="http://www.davidchristiansen.dk/tutorials/nbe/">Checking
Dependent Types with Normalization by Evaluation: A Tutorial</a>, by David
himself, if you're interested in how these things are implemented).
And, second, the Haskell-based REPL has been my constant companion
while reading the book, thanks to <a href="https://codeberg.org/jao/epie">a little package that i put together</a>
to use it in Emacs, complete with syntax highlighting and a bit of
completion for the predefined forms of Pie (it might have a couple of
rough corners, but the plan is to submit it to MELPA at some point).
</p>

<p>
Or you can also use the DrRacket interface if that's your thing, but,
be it as it may, don't miss this book!
</p>
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-books.html">books</a> <a href="https://jao.io/blog/tag-programming.html">programming</a> <a href="https://jao.io/blog/tag-emacs.html">emacs</a> </div>]]></description>
  <category><![CDATA[books]]></category>
  <category><![CDATA[programming]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://jao.io/blog/the-little-typer.html</link>
  <guid>https://jao.io/blog/the-little-typer.html</guid>
  <pubDate>Mon, 17 May 2021 05:29:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[reading and searching gmane with gnus, fast]]></title>
  <description><![CDATA[
<p>
Reading mailing lists via Gnus by pointing it to the usenet service
news.gmane.io is a well-known trick among emacsers.  It has a couple
of drawbacks, though: network latency and no search.  The two problems
have, as almost always with almost any problem in Emacs land, a cure.
The names of the game are, in this case, leafnode and notmuch.
</p>

<!-- preview-end -->

<p>
I've been using <a href="https://leafnode.sourceforge.io/">leafnode</a> since i was young to avoid network latency
issues when Gnus fetches news from remote usenet servers.  <a href="https://leafnode.sourceforge.io/">Leafnode</a> is
a store &amp; forward NNTP proxy that can be used to give a regular
newsreader off-line functionality. It works by fetching in the
background news articles from a number of configured remote servers
(gmane.io in our case), storing them locally and offering a local NNTP
server to Gnus (or any other newsreader, for that matter).  That way,
one configures Gnus to fetch news from localhost, which is fast and
will never block, even when one is disconnected from the interwebs.
Leafnode's server implements the full protocol, so one can also post
to the remote servers.
</p>

<p>
For our case, leafnode's configuration file is very simple:
</p>

<div class="org-src-container">
<pre class="src src-config">## Unread articles will be deleted after this many days
expire = 365

## This is the NNTP server leafnode fetches its news from.
## You need read and post access to it. Mandatory.
server = news.gmane.io

## Fetch only a few articles when we subscribe a new newsgroup. The
## default is to fetch all articles.
initialfetch = 100
</pre>
</div>

<p>
With leafnode in place, i've rarely needed to subscribe to a mailing
list<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, and all their messages are available with the Gnus
interface that we all know and love.
</p>

<p>
With one caveat: one can search over e-mails, using either IMAP (i
like dovecot's lucene indexes) or (even better) notmuch.  Can we do
the same with those messages we access through leafnode?  Well, it
turns out that, using notmuch, you can!
</p>

<p>
First of all, leafnode stores its articles in a format recognised by
notmuch's indexer.  In my debian installation, the live in the
directory <code>/var/spool/news/gmane</code>.  On the other hand, my notmuch
configuration points to <code>~/var/mail</code> as the parent directory where my
mailboxes are to be found.  I just created a symlink in the latter to
the former and voila, notmuch is indexing all the messages retrieved
by leafnode and i can search over them!<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>
</p>

<p>
With the version of Gnus in current emacs master, it's even better.  I
can tell Gnus that the search engine for the news server is notmuch:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #023770;">setq</span> gnus-select-method
      '(nntp <span style="color: #023770;">"localhost"</span>
             (gnus-search-engine gnus-search-notmuch
                                 (remove-prefix <span style="color: #023770;">"/home/jao/var/mail/"</span>))))
</pre>
</div>

<p>
and perform searches directly in Gnus using the notmuch indexes.  Or,
if you prefer, you can use directly notmuch.el to find and read those
usenet articles: they look just like good old email<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup> :)
</p>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Actually, gmane also includes <i>gwene</i> groups that mirror RSS
feeds as usenet messages, so you could extend the trick to feeds too.
I however use <a href="https://wiki.archlinux.org/title/Rss2email">rss2email</a> to read RSS feeds as email, for a variety of
reasons best left to a separate post.
</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">
With the <code>expire</code> parameter in leafnode's configuration set to
365, i keep locally an indexed archive of the mailing list posts less
than a year old: in this age of cheap storage, one can make that much
longer.  One can also play with <code>initialfetch</code>.
</p></div></div>

<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
I am not a mu4e user, but i am pretty sure one can play the
same trick if that's your email indexer and reader.
</p></div></div>


</div>
</div><div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-emacs.html">emacs</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://jao.io/blog/reading-and-searching-gmane-with-gnus-fast.html</link>
  <guid>https://jao.io/blog/reading-and-searching-gmane-with-gnus-fast.html</guid>
  <pubDate>Mon, 17 May 2021 04:42:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[reading source code is fun]]></title>
  <description><![CDATA[
<p>
From a recent checkout of the Emacs source code:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp"><span style="color: #005555;">;;; desktop.el --- save partial status of Emacs when killed </span><span style="color: #666666; font-style: italic;">-*- lexical-binding: t -*-</span><span style="color: #005555;">
</span>
<span style="color: #666666; font-style: italic;">;; </span><span style="color: #666666; font-style: italic;">Copyright (C) 1993-1995, 1997, 2000-2021 Free Software Foundation,
</span><span style="color: #666666; font-style: italic;">;; </span><span style="color: #666666; font-style: italic;">Inc.
</span>
<span style="color: #666666; font-style: italic;">;; </span><span style="color: #666666; font-style: italic;">Author: Morten Welinder <a href="mailto:terra%40diku.dk">&lt;terra@diku.dk&gt;</a>
</span><span style="color: #666666; font-style: italic;">;; </span><span style="color: #666666; font-style: italic;">Keywords: convenience
</span><span style="color: #666666; font-style: italic;">;; </span><span style="color: #666666; font-style: italic;">Favorite-brand-of-beer: None, I hate beer.
</span>
<span style="color: #666666; font-style: italic;">;; </span><span style="color: #666666; font-style: italic;">This file is part of GNU Emacs.</span>
</pre>
</div>

<p>
Mine is Guinness :)
</p>

<!-- preview-end -->
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-emacs.html">emacs</a> <a href="https://jao.io/blog/tag-programming.html">programming</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[programming]]></category>
  <link>https://jao.io/blog/reading-source-code-is-fun.html</link>
  <guid>https://jao.io/blog/reading-source-code-is-fun.html</guid>
  <pubDate>Mon, 05 Apr 2021 21:45:00 +0100</pubDate>
</item>
<item>
  <title><![CDATA[simplicity pays off]]></title>
  <description><![CDATA[
<p>
i've been using <a href="https://bastibe.de/">Bastian Bechtold</a>'s <a href="https://github.com/bastibe/org-static-blog">org-static-blog</a> for this blog for
more than a year now. Back in the day, i <a href="https://jao.io/blog/2020-02-11-simplicity.html">mentioned</a> how well it
integrated with my emacs workflow and how its simplicity was a big
asset<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.
</p>

<p>
During this year, i've contributed several little features to the
package, and it's always been an easy and natural process.  The last
instance has been prompted by <a href="https://sachachua.com/blog/">Sacha Chua</a> asking me whether an
emacs-specifc RSS feed was available, in order to add this blog to
<a href="https://planet.emacslife.com/">Planet Emacslife</a>.
</p>

<p>
Turns out it <i>wasn't</i> available: <code>org-static-blog</code> did know how to use
tags, but didn't generate per-tag RSS feeds.  Until yesterday.  It was
a question of half an hour and <a href="https://github.com/bastibe/org-static-blog/pull/92">a little PR</a> to add that functionality.
If you check the changeset, you'll see that most of its 62 additions
and 24 deletions are just a bit of refactoring that make adding the
feature almost trivial.
</p>

<p>
It was just another example of something i experience almost everyday
in this Emacs life, namely, how easy and direct it is to mold the
computer environment to fulfil new requirements, sometimes in
idiosyncratic ways no external package is going to implement for you,
and some other times (as in this case) in ways you can share with the
community.  The result is an environment almost exquisitely adapted to
your needs, and it think that it is precisely this rooting in direct,
day-to-day user needs that, at the same time, makes individual hacks
so rich and useful to everyone else.  That, and the fact that adapting
an external package to your liking is so often just a couple lines of
elisp away.
</p>

<p>
I hope i did it right, and you all Emacslife followers can see me
waving hello, and this big <i>thank you, Sacha!</i> :)
</p>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
Inevitably, i've been tweaking my configuration since then: you
can see it, as a literate org file, in my emacs configuration repo
<a href="https://codeberg.org/jao/elibs/src/branch/main/blog.org">here</a>.
</p></div></div>


</div>
</div><div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-emacs.html">emacs</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://jao.io/blog/simplicity-pays-off.html</link>
  <guid>https://jao.io/blog/simplicity-pays-off.html</guid>
  <pubDate>Fri, 26 Feb 2021 02:29:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[consulting hunks]]></title>
  <description><![CDATA[
<p>
I use Dmitry Gutov's <a href="https://github.com/dgutov/diff-hl">diff-hl</a> to highlight (with fringe marks) modified
hunks in my files under git revision control.  The package comes with
a command, <code>diff-hl-next-hunk</code>, that one can use to navigate them.  So,
taking a peek at <code>consult-lines</code>, it was straightforward to put together
a consult function to navigate, with completion and preview (although
i disable the latter) the hunks in the current file:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #023770;">defun</span> <span style="color: #005555;">jao-consult--diff-lines</span> (<span style="color: #023770;">&amp;optional</span> backward)
  (<span style="color: #023770;">let</span> ((candidates)
        (width (length (number-to-string
                        (line-number-at-pos (point-max)
                                            consult-line-numbers-widen)))))
    (<span style="color: #023770;">save-excursion</span>
      (<span style="color: #023770;">while</span> (<span style="color: #023770;">ignore-errors</span> (diff-hl-next-hunk backward))
        (<span style="color: #023770;">let*</span> ((str (buffer-substring (line-beginning-position)
                                      (line-end-position)))
               (no (line-number-at-pos (point)))
               (no (consult--line-number-prefix (point-marker) no width)))
          (<span style="color: #023770;">push</span> (concat no str) candidates))))
    (<span style="color: #023770;">if</span> backward candidates (nreverse candidates))))

(<span style="color: #023770;">defun</span> <span style="color: #005555;">jao-consult-hunks</span> ()
  <span style="color: #666666; font-style: italic;">"Search for modified hunks in the current buffer."</span>
  (<span style="color: #023770;">interactive</span>)
  (<span style="color: #023770;">let</span> ((candidates (append (jao-consult--diff-lines)
                            (jao-consult--diff-lines t))))
    (<span style="color: #023770;">unless</span> candidates (<span style="color: #8b5a00;">error</span> <span style="color: #023770;">"No changes!"</span>))
    (consult--jump (consult--read candidates
                                  <span style="color: #023770;">:prompt</span> <span style="color: #023770;">"Go to hunk: "</span>
                                  <span style="color: #023770;">:category</span> 'consult--encode-location
                                  <span style="color: #023770;">:require-match</span> t
                                  <span style="color: #023770;">:lookup</span> #'consult--line-match
                                  <span style="color: #023770;">:state</span> (consult--jump-state)))))

(global-set-key (kbd <span style="color: #023770;">"C-x v c"</span>) #'jao-consult-hunks)
</pre>
</div>

<p>
i am sure i've taken one or two detours there that can be coded better
using consult's API, but it was so nice to be able to have a working
command in fifteen minutes that i couldn't resist showing off :)
</p>
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-emacs.html">emacs</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://jao.io/blog/consulting-hunks.html</link>
  <guid>https://jao.io/blog/consulting-hunks.html</guid>
  <pubDate>Mon, 01 Feb 2021 03:12:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[an emacs packages hat trick]]></title>
  <description><![CDATA[
<p>
i've found these last days a handful of really useful little emacs
packages:
</p>

<ul class="org-ul">
<li><p>
<a href="http://www.masteringemacs.org/article/smart-scan-jump-symbols-buffer">smartscan</a>, a simple way of navigating programming modes
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #023770;">use-package</span> smartscan
  <span style="color: #023770;">:ensure</span> t
  <span style="color: #023770;">:commands</span> smartscan-mode
  <span style="color: #023770;">:init</span> (add-hook 'prog-mode-hook #'smartscan-mode)
  <span style="color: #023770;">:diminish</span>)
</pre>
</div></li>

<li><p>
<a href="https://github.com/sshaw/git-link">git-link</a>, because i almost never look at files using the browser,
but some people don't have my repos checked out.  Specially nice the
bit about being able to use git config variables.
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #023770;">use-package</span> git-link
  <span style="color: #023770;">:ensure</span> t
  <span style="color: #023770;">:custom</span> ((git-link-default-remote <span style="color: #023770;">"bigml"</span>)))
</pre>
</div></li>

<li><p>
<code>visible-mode</code>, an Emacs built-in, especially useful in org buffers,
where i hide markup and sometimes it's a chore to ascertain whether
point is before or after a it.  With a binding to this minor mode,
it's a breeze to toggle them:
</p>
<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #023770;">use-package</span> visible-mode
  <span style="color: #023770;">:bind</span> ((<span style="color: #023770;">"s-v"</span> . visible-mode)))
</pre>
</div></li>
</ul>

<p>
Tip of the hat to <a href="https://github.com/danielmai/.emacs.d/blob/master/config.org">Daniel Mai</a>, for a couple of the above.  You might
find some other interesting tidbits in his config.
</p>
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-emacs.html">emacs</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://jao.io/blog/emacs-packages-hat-trick.html</link>
  <guid>https://jao.io/blog/emacs-packages-hat-trick.html</guid>
  <pubDate>Thu, 21 Jan 2021 04:07:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[an even better video wharf]]></title>
  <description><![CDATA[
<p>
A couple of days ago, <a href="https://jao.io/blog/2021-01-09-embarking-videos.html">i was writing</a> about <a href="https://github.com/oantolin/embark">embark</a> and my first experiment
defining a new embarking to play remote video streams.  Omar Antolín
Camarena, embark's author, has been kind enough to not only read it,
but comment on a couple of significant improvements that i think well
deserve this follow-up.
</p>

<p>
First, you'll remember that we were defining a function to detect a
video URL:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #023770;">defun</span> <span style="color: #005555;">jao-video-finder</span> ()
  <span style="color: #666666; font-style: italic;">"Check whether we're looking at a video URL.
Return (video-url . &lt;URL&gt;) if so."</span>
  (<span style="color: #023770;">when-let</span> ((url (thing-at-point-url-at-point)))
    (<span style="color: #023770;">when</span> (string-match-p jao-video-url-rx url)
      (cons 'video-url url))))
</pre>
</div>

<p>
Once we've got a non-null <code>url</code> value, even if it's not a video URL,
it's still certainly a URL, and embark has a <code>url</code> category, so we could
save a new parsing by the default URL finder by saying:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #023770;">when-let</span> ((url (thing-at-point-url-at-point)))
  (cons (<span style="color: #023770;">if</span> (string-match-p jao-video-url-rx url) 'video-url 'url) url))
</pre>
</div>

<p>
This has the potential drawback that we're overriding embark's finder,
<code>embark-target-url-at-point</code>, and we might prefer to keep the latter.
</p>

<p>
Turns out that we can do that thanks to embark's <i>target transformers</i>.
One can add to <code>embark-transformers-alist</code> an arbitrary function to be
applied to a target of any given category, and embark will apply its
actions to the transformed value.  Omar calls this process, very
aptly, a refinement of the target; here's how we would do it:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #023770;">defun</span> <span style="color: #005555;">jao-refine-url-type</span> (url)
  <span style="color: #666666; font-style: italic;">"Refine type of URL in case it is a video."</span>
  (cons (<span style="color: #023770;">if</span> (string-match-p jao-video-url-rx url) 'video-url 'url) url))

(add-to-list 'embark-transformer-alist '(url . jao-refine-url-type))
</pre>
</div>

<p>
With this strategy, we don't need <code>jao-video-finder</code> at all, and it also
makes lots of sense, conceptually, to have our <code>video-url</code> defined as a
refinement rather than a new target<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.  Omar's second suggestion
is also in line with this concept: surely we want all actions
available for <code>url</code> also for our <code>video-url</code>, don't we?  Well, that's
exactly the reason why the <code>embark-define-keymap</code> macro we used to
define our actions can inherit all the actions already defined in
another keymap, using the <code>:parent</code> keyword<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup>:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(embark-define-keymap jao-video-url-map
  <span style="color: #023770;">"Actions on URLs pointing to remote video streams."</span>
  <span style="color: #023770;">:parent</span> embark-url-map
  (<span style="color: #023770;">"p"</span> jao-play-video-url))

(add-to-list 'embark-keymap-alist '(video-url . jao-video-url-map))
</pre>
</div>

<p>
It is worth noting that this ability to inherit a keymap is not really
an embark add-on: vanilla Emacs keymaps already have it, via the
standard function <code>set-keymap-parent</code>.  You could actually define
<code>jao-video-url-map</code> without using <code>embark-define-keymap</code> at all, and it'd
work exactly the same.
</p>

<p>
So, our code has become shorter and more featureful: thanks, Omar!
</p>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara">
There's a scenario where keeping jao-video-finder could make
sense, namely, if we want to alter the URL detection function.  For
instance, i use emacs-w3m, and there often a URL is stored as a text
property (the actual text being the link text).  To retrieve the URL
at point there, one needs to call <code>w3m-anchor</code>, and
<code>embark-target-url-at-point</code> will miss it.  For that scenario, i ended
up writing (and using) <code>jao-video-finder</code> defined with:
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #023770;">when-let</span> ((url (<span style="color: #023770;">or</span> (w3m-anchor) (thing-at-point-url-at-point))))
  (cons (<span style="color: #023770;">if</span> (string-match-p jao-video-url-rx url) 'video-url 'url) url))
</pre>
</div>

<p class="footpara">
Another way of accomplishing the same thing (with another tip of the
hat to Omar) would be to add a specific finder for w3m anchors (and
keep using the transformer for video-url):
</p>

<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span style="color: #023770;">defun</span> <span style="color: #005555;">jao-w3m-url-finder</span> ()
  (<span style="color: #023770;">when-let</span> ((url (w3m-anchor)))
    (cons 'url url)))

(add-to-list 'embark-target-finders #'jao-w3m-url-finder)
</pre>
</div>

<p class="footpara">
This way is more modular and, depending on your taste, more elegant.
These functions are small and there's not a big difference between the
two approaches, but if one keeps adding finders, things can easily get
uglier with the former approach.
</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">
In my original example, i was adding also <code>browse-url</code> and
<code>browse-url-firefox</code> to the video map.  The former is no longer
necessary, because it's already present in <code>embark-url-map</code>.  If we
wanted to make <code>browse-url-firefox</code> available to <i>all</i> URLs, we could add
it to <code>embark-url-map</code> (remember, embark's keymaps are just Emacs
keymaps).  That's yet another simple way of extending embark.
</p></div></div>


</div>
</div><div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-emacs.html">emacs</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <link>https://jao.io/blog/an-even-better-video-wharf.html</link>
  <guid>https://jao.io/blog/an-even-better-video-wharf.html</guid>
  <pubDate>Mon, 11 Jan 2021 19:17:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[what's not to like]]></title>
  <description><![CDATA[
<p>
I've just discovered <a href="https://blog.codeberg.org/">Codeberg</a>, a code hosting site that, <i>finally</i>, has
let me create a user with plain emacs-w3m, shows me content reasonably
well there, with a refreshingly uncluttered layout, handles graciously
org files (why, it's even generating a table of contents for me), has
a good privacy policy, it's not under the wings of any corporation and
had my preferred username free for grabs.
</p>

<p>
So i'm definitely testing the waters for it to become my default site
for (newish) published code: here's my <a href="https://codeberg.org/jao/elibs">jao/elibs: Emacs libraries and
little utilities</a> repository for starters (and, if you look closely,
you'll find also my emacs config nearby).  If and when that happens,
they're going to <a href="https://join.codeberg.org/">to get my humble contribution too</a>, i reckon.
</p>
<div class="taglist"><a href="https://jao.io/blog/tags.html">Tags</a>: <a href="https://jao.io/blog/tag-programming.html">programming</a> <a href="https://jao.io/blog/tag-emacs.html">emacs</a> </div>]]></description>
  <category><![CDATA[programming]]></category>
  <category><![CDATA[emacs]]></category>
  <link>https://jao.io/blog/whats-not-to-like.html</link>
  <guid>https://jao.io/blog/whats-not-to-like.html</guid>
  <pubDate>Tue, 29 Dec 2020 20:53:00 +0000</pubDate>
</item>
</channel>
</rss>
