<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Emacs on Noetic Nought</title>
    <link>https://punchagan.muse-amuse.in/tags/emacs/</link>
    <description>Recent content in Emacs on Noetic Nought</description>
    <generator>Hugo</generator>
    <language>en-US</language>
    <copyright>© 2006-2026 CC-BY-SA-4.0</copyright>
    <lastBuildDate>Fri, 30 Jan 2026 16:58:00 +0530</lastBuildDate>
    <atom:link href="https://punchagan.muse-amuse.in/tags/emacs/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Why my Elfeed index was 0 bytes</title>
      <link>https://punchagan.muse-amuse.in/blog/elfeed-index-0-bytes/</link>
      <pubDate>Fri, 30 Jan 2026 16:58:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/elfeed-index-0-bytes/</guid>
      <description>&lt;p&gt;My Linux machine crashed, while I was in the middle of a video call. I&#xA;restarted quickly, and continued the discussion. Later, when I was trying to&#xA;sync &lt;a href=&#34;https://github.com/skeeto/elfeed&#34;&gt;Elfeed&lt;/a&gt; updates onto the &lt;a href=&#34;https://github.com/punchagan/elfeed-offline/&#34;&gt;Elfeed Offline&lt;/a&gt; app on my phone, I found it acting&#xA;weird. All the &lt;a href=&#34;https://punchagan.muse-amuse.in/blog/offline-friendly-elfeed-web-ui/&#34;&gt;bazillion things&lt;/a&gt; needed to get it working were in place, but it&#xA;was still complaining about the Emacs Elfeed server not being accessible. I&#xA;tried opening Elfeed inside Emacs and failed! The index file in &lt;a href=&#34;https://punchagan.muse-amuse.in/blog/elfeed-db-back-up-hooks/&#34;&gt;Elfeed&amp;rsquo;s DB was&#xA;empty&lt;/a&gt;! Gone! Poof!&lt;/p&gt;&#xA;&lt;p&gt;Frustrating, but I didn&amp;rsquo;t have time to look into what happened. I would&amp;rsquo;ve been&#xA;furious if I had been using Elfeed for longer and had a lot more metadata&#xA;saved. But, it was only a few weeks of lost metadata - posts I read, starred,&#xA;etc. I quickly setup a &lt;a href=&#34;https://punchagan.muse-amuse.in/blog/elfeed-db-back-up-hooks/&#34;&gt;Git based backup&lt;/a&gt; to prevent future losses and moved on.&lt;/p&gt;&#xA;&lt;p&gt;Later, I found time to dig into what might have happened&amp;hellip;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-breadcrumbs&#34;&gt;The breadcrumbs&lt;/h2&gt;&#xA;&lt;p&gt;Elfeed stores all the metadata for all the posts in an &lt;code&gt;index&lt;/code&gt; file with a&#xA;&lt;a href=&#34;https://en.wikipedia.org/wiki/Content-addressable_storage&#34;&gt;content addressed store&lt;/a&gt; of the contents of each of the posts. The index file is&#xA;simply a dump of the hash-table containing the metadata for the subscribed&#xA;feeds, their entries and metadata like tags, read/unread status, etc.&lt;/p&gt;&#xA;&lt;p&gt;The DB save happens in &lt;a href=&#34;https://github.com/skeeto/elfeed/blob/a39fb78e34ee25dc8baea83376f929d7c128344f/elfeed-db.el#L271&#34;&gt;&lt;code&gt;elfeed-db-save&lt;/code&gt;&lt;/a&gt;, which simply dumps the hash-table to&#xA;disk inside a call to the &lt;code&gt;with-temp-file&lt;/code&gt; macro.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;elfeed-db-save&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;; &amp;lt;snip&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;with-temp-file&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expand-file-name&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;index&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;elfeed-db-directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;; ...&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;princ&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;format&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;;;; Elfeed Database Index (version %s)\n\n&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                       &lt;span class=&#34;nv&#34;&gt;elfeed-db-version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;; ...&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;prin1&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;elfeed-db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;;...&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;with-temp-file&lt;/code&gt;, as its documentation says, lets you create a new buffer,&#xA;evaluate the &lt;code&gt;body&lt;/code&gt; there, and write the buffer to &lt;code&gt;file&lt;/code&gt;. For a moment, I&#xA;thought there was some temporary file involved, but nope! I guess the name&#xA;comes as an extension from &lt;code&gt;with-temp-buffer&lt;/code&gt; which does create a temporary&#xA;buffer where the &lt;code&gt;body&lt;/code&gt; of the macro gets evaluated. Stripped to its core, &lt;a href=&#34;https://github.com/emacs-mirror/emacs/blob/3b547e4f5dc99dc157b52a059cf234f7a5d15112/lisp/subr.el#L5300-L5318&#34;&gt;this&#xA;function&lt;/a&gt; is:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;temp-file&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;temp-buffer&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;generate-new-buffer&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34; *temp file*&amp;#34;&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;prog1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;with-current-buffer&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;temp-buffer&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;         &lt;span class=&#34;o&#34;&gt;,@&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;with-current-buffer&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;temp-buffer&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;write-region&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;temp-file&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;write-region-and-o-trunc&#34;&gt;&lt;code&gt;write-region&lt;/code&gt; and &lt;code&gt;O_TRUNC&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;p&gt;So, &lt;a href=&#34;https://github.com/emacs-mirror/emacs/blob/3b547e4f5dc99dc157b52a059cf234f7a5d15112/src/fileio.c#L5512&#34;&gt;&lt;code&gt;write-region&lt;/code&gt; is the workhorse&lt;/a&gt; which writes the contents of the temporary&#xA;buffer to disk. It&amp;rsquo;s a roughly 300 line long C function that essentially opens&#xA;the file with the flags &lt;code&gt;O_WRONLY | O_CREAT | O_TRUNC&lt;/code&gt; (in this case) and then&#xA;does something to write the contents to the file, etc. Honestly, I didn&amp;rsquo;t look&#xA;at anything else too carefully after I spotted the &lt;code&gt;O_TRUNC&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;The man page of &lt;code&gt;open&lt;/code&gt; explains &lt;code&gt;O_TRUNC&lt;/code&gt; as follows:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;O_TRUNC :: If the file already exists and is a regular file and the access mode&#xA;allows writing (i.e., is O_RDWR or O_WRONLY) it will be truncated to&#xA;length 0.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Voilà!&lt;/p&gt;&#xA;&lt;p&gt;The write is not atomic. The file first gets truncated to length 0, and then we&#xA;hope that the new contents get correctly written before something goes wrong.&lt;/p&gt;&#xA;&lt;p&gt;It now makes sense why the file got truncated to 0 bytes. The crash happened&#xA;after the &lt;code&gt;open&lt;/code&gt;, but before the write. Somehow the crash happened in this&#xA;short window, and poof!&lt;/p&gt;&#xA;&lt;h2 id=&#34;emacs-has-backup-files-doesn-t-it&#34;&gt;Emacs has backup files, doesn&amp;rsquo;t it?&lt;/h2&gt;&#xA;&lt;p&gt;Temporary files with &lt;code&gt;~&lt;/code&gt; in their file extensions have definitely annoyed me in&#xA;the past when Emacs created them where I didn&amp;rsquo;t want them. So, I do know that&#xA;Emacs has back-up mechanisms out of the box. But, it turns out that the backups&#xA;occur in code paths that are more interactive, like &lt;code&gt;save-buffer&lt;/code&gt;,&#xA;&lt;code&gt;write-file&lt;/code&gt;, etc. And not via the programmatic APIs like &lt;code&gt;write-region&lt;/code&gt; or the&#xA;higher level &lt;code&gt;with-temp-file&lt;/code&gt;. &lt;code&gt;save-buffer&lt;/code&gt; calls &lt;code&gt;backup-buffer&lt;/code&gt; before&#xA;writing, but &lt;code&gt;write-region&lt;/code&gt; is much more low-level and doesn&amp;rsquo;t deal with&#xA;backups.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-fix&#34;&gt;The fix&lt;/h2&gt;&#xA;&lt;p&gt;My &amp;ldquo;fix&amp;rdquo; for this is to backup the Elfeed data in a git repository to be able&#xA;to recover from any such corruptions of data, which I already wrote about &lt;a href=&#34;https://punchagan.muse-amuse.in/blog/elfeed-db-back-up-hooks/&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;I know that any code that uses &lt;code&gt;with-temp-file&lt;/code&gt; (or &lt;code&gt;write-region&lt;/code&gt;) could be&#xA;affected by this, and the right fix for this may be to write to a temporary&#xA;file and rename it. Maybe next time I lose data I&amp;rsquo;ll actually fix it properly.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Elfeed DB backup hooks</title>
      <link>https://punchagan.muse-amuse.in/blog/elfeed-db-back-up-hooks/</link>
      <pubDate>Tue, 20 Jan 2026 23:13:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/elfeed-db-back-up-hooks/</guid>
      <description>&lt;p&gt;I had a bunch of things running on my laptop &amp;ndash; video call with screenshare, my&#xA;Windows VM, Firefox with a lot of tabs, etc. And my laptop crashed! I didn&amp;rsquo;t&#xA;have the time to dig into what, why and how.&lt;/p&gt;&#xA;&lt;p&gt;Later in the day, I discovered my Elfeed&amp;rsquo;s DB was gone &amp;ndash; blown away. :( I&amp;rsquo;m&#xA;guessing the crash happened in the middle of &lt;code&gt;elfeed-db-save&lt;/code&gt;, and the data was&#xA;lost.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve now added some back-up for the DB, since I intend to use Elfeed regularly.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defvar&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/elfeed-db-save-timer&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;Timer for debounced elfeed database saves.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/elfeed-db-save-and-backup&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;Save the elfeed database and commit to git.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;when&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;boundp&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;elfeed-db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;elfeed-db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;elfeed-db-save&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;default-directory&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;elfeed-db-directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;when&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;file-exists-p&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;.git&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;call-process&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;git&amp;#34;&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;*elfeed-db-backup*&amp;#34;&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;add&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;-A&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;call-process&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;git&amp;#34;&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;*elfeed-db-backup*&amp;#34;&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;commit&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;-m&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;auto-backup&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;call-process&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;git&amp;#34;&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;*elfeed-db-backup*&amp;#34;&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;push&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;origin&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/elfeed-db-save-soon&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;Schedule a database save after 10 seconds of idle.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interactive&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;when&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/elfeed-db-save-timer&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;cancel-timer&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/elfeed-db-save-timer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/elfeed-db-save-timer&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;run-with-idle-timer&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pc/elfeed-db-save-and-backup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;;; Save and backup when tags change (elfeed-web usage)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;add-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;elfeed-tag-hooks&lt;/span&gt;   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kp&#34;&gt;&amp;amp;rest&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pc/elfeed-db-save-soon&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;add-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;elfeed-untag-hooks&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kp&#34;&gt;&amp;amp;rest&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pc/elfeed-db-save-soon&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;;; Save and backup when new entries are added&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;add-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;elfeed-db-update-hook&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pc/elfeed-db-save-soon&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>Safari and invalid HTTP/2 headers</title>
      <link>https://punchagan.muse-amuse.in/blog/safari-and-invalid-http-2-headers/</link>
      <pubDate>Fri, 16 Jan 2026 21:37:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/safari-and-invalid-http-2-headers/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://github.com/punchagan/elfeed-offline/&#34;&gt;Elfeed-offline&lt;/a&gt; currently has a &lt;a href=&#34;https://camlworks.github.io/dream/&#34;&gt;Dream web server&lt;/a&gt; which acts as a proxy server in&#xA;front of Elfeed&amp;rsquo;s Emacs &lt;a href=&#34;https://github.com/skeeto/emacs-web-server/tree/master&#34;&gt;simple-httpd&lt;/a&gt; server.&lt;/p&gt;&#xA;&lt;p&gt;simple-httpd supports HTTP/1.1 protocol, while Dream provides transparent&#xA;upgrading of connections to HTTP/2 — if the client can handle HTTP/2 and the&#xA;connection is using HTTPS, it is transparently upgraded to HTTP/2.&lt;/p&gt;&#xA;&lt;p&gt;My proxying code was too simplistic in forwarding the headers too along with&#xA;the content received from the simple-httpd server. Some of the HTTP/1 headers&#xA;are no longer valid in HTTP/2. And, Safari (and curl) strictly adhere to the&#xA;protocol and fail if there are invalid headers. Curl, for instance, fails with&#xA;the following error:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt; HTTP/2 200&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt; server: simple-httpd (Emacs 30.1)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt; date: Fri, 16 Jan 2026 10:57:25 GMT&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;* Invalid HTTP header field was received: frame type: 1, stream: 1, name: [connection], value: [keep-alive]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;* [HTTP2] [1] received invalid frame: FRAME[HEADERS, len=77, hend=1, eos=0], error -531: Invalid HTTP header field was received&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;* HTTP/2 stream 1 was not closed cleanly: unknown (err 4294966765)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;* Connection #0 to host 192.168.1.5 left intact&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl: (92) Invalid HTTP header field was received: frame type: 1, stream: 1, name: [connection], value: [keep-alive]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This was causing issues for &lt;a href=&#34;https://github.com/Feyorsh&#34;&gt;@Feyorsh&lt;/a&gt; who was trying out elfeed-offline with&#xA;Safari. Thanks for taking the time to debug the problem and for suggesting a&#xA;fix!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>An offline-friendly Elfeed web UI</title>
      <link>https://punchagan.muse-amuse.in/blog/offline-friendly-elfeed-web-ui/</link>
      <pubDate>Wed, 07 Jan 2026 02:31:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/offline-friendly-elfeed-web-ui/</guid>
      <description>&lt;p&gt;I want to read articles from my RSS subscriptions on my phone without signing&#xA;up to a hosted service or running a public server.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/skeeto/elfeed&#34;&gt;Elfeed&lt;/a&gt;, the Emacs feed reader, already lets me manage my subscriptions and read&#xA;from within Emacs. It comes with an experimental web UI, but needs the server&#xA;(running on my laptop) to be accessible whenever I want to read. My phone&#xA;becomes useless the moment my laptop sleeps.&lt;/p&gt;&#xA;&lt;p&gt;So, I built an alternate web UI with a service worker that caches content on&#xA;the client side for a smooth offline reading experience. It&amp;rsquo;s written in &lt;a href=&#34;https://ocaml.org/&#34;&gt;OCaml&lt;/a&gt;&#xA;and compiled to JavaScript using &lt;a href=&#34;https://ocsigen.org/js_of_ocaml/latest/manual/overview&#34;&gt;&lt;code&gt;js_of_ocaml&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-bother-with-rss-feeds&#34;&gt;Why bother with RSS feeds?&lt;/h2&gt;&#xA;&lt;p&gt;It is annoyingly easy to fall into the trap of short form videos or other&#xA;algorithmically &amp;ldquo;curated&amp;rdquo; feeds and get sucked into scrolling mindlessly. I&#xA;fear this is going to get even worse with all the generative AI stuff.&lt;/p&gt;&#xA;&lt;p&gt;I want to be more deliberate about what I consume. RSS feels calmer and gives&#xA;me a greater sense of control. Or it may just be nostalgia from good old Google&#xA;Reader days.&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-emacs-and-elfeed&#34;&gt;Why Emacs and Elfeed?&lt;/h2&gt;&#xA;&lt;p&gt;Since Google Reader was killed, I&amp;rsquo;ve bounced between many readers but none of&#xA;them has really stuck with me. I&amp;rsquo;ve had &lt;a href=&#34;https://punchagan.muse-amuse.in/blog/elfeed-hook-to-fetch-full-content/&#34;&gt;different phases&lt;/a&gt; of using Elfeed, over&#xA;the years, though.&lt;/p&gt;&#xA;&lt;p&gt;I like the fact that everything is local with Elfeed &amp;ndash; no hosted services, no&#xA;public servers. And since it lives inside Emacs, everything from tagging to how&#xA;entries are displayed can be tweaked.&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-elfeed-offline&#34;&gt;Why Elfeed offline?&lt;/h2&gt;&#xA;&lt;p&gt;Elfeed also ships a basic web UI that lets me read my feeds from a different&#xA;device, but only when my laptop is online and reachable. I&amp;rsquo;d like to be able to&#xA;read these posts even when I&amp;rsquo;m &amp;ldquo;on the road&amp;rdquo;, say, while waiting for a train or&#xA;while taking a cab ride.&lt;/p&gt;&#xA;&lt;p&gt;I knew it should be possible to do this with some client side caching. And, I&#xA;considered improving the web UI of Elfeed itself but it doesn&amp;rsquo;t seem to be&#xA;&lt;a href=&#34;https://github.com/skeeto/elfeed/pulls&#34;&gt;actively maintained&lt;/a&gt; in the last couple of years. Creating a separate project&#xA;would also give me more freedom to experiment.&lt;/p&gt;&#xA;&lt;h2 id=&#34;how-does-it-work&#34;&gt;How does it work?&lt;/h2&gt;&#xA;&lt;p&gt;Elfeed offline comes with a tiny &lt;a href=&#34;https://camlworks.github.io/dream/&#34;&gt;Dream&lt;/a&gt; based webserver that acts as a proxy in&#xA;front of the Emacs Elfeed webserver for the API requests. The Dream web server&#xA;also serves the static assets like the HTML, JavaScript, stylesheets and the&#xA;Service Worker for the web app. The diagram below shows how data flows between the different components.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-artist&#34; data-lang=&#34;artist&#34;&gt;+---------------+     +-----------------+&#xA;|  Emacs Elfeed |&amp;lt;---&amp;gt;|     Dream       |&#xA;|     Server    |     |   Web-server    |&#xA;+---------------+     +-----------------+&#xA;                               ^&#xA;                               |&#xA;                               v&#xA; +------------+        +----------------+       +---------+&#xA; |    Web     |        |    Service     |       | Browser |&#xA; |  Client    |&amp;lt;------&amp;gt;|     Worker     |&amp;lt;-----&amp;gt;|  Cache  |&#xA; +------------+        +----------------+       +---------+&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The Service Worker intercepts all the &lt;code&gt;GET&lt;/code&gt; requests from the client and&#xA;responds using a &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Guides/Caching#cache_first_with_cache_refresh&#34;&gt;cache-first-with-cache-refresh&lt;/a&gt; strategy. This makes the&#xA;reading experience feel very responsive. The web client also implements a &amp;ldquo;good&#xA;enough&amp;rdquo; clone of the original search functionality of Elfeed to allow searching&#xA;and filtering content while offline.&lt;/p&gt;&#xA;&lt;p&gt;The web app also lets me mark entries as read or star them when I&amp;rsquo;m offline.&#xA;The Service Worker caches these operations and updates the server when the&#xA;server becomes reachable. There&amp;rsquo;s no smart conflict resolution here, and the&#xA;API requests just overwrite and update the state on the server.&lt;/p&gt;&#xA;&lt;p&gt;I have been using this for a couple of weeks now, and am quite happy with how&#xA;responsive the UI feels and the number of posts I managed to read so far.&lt;/p&gt;&#xA;&lt;p&gt;But, there are definitely some rough edges to smoothen out.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;It&amp;rsquo;s a pain to make sure that both the servers are running when I&amp;rsquo;m online&#xA;and want to sync new updates to my phone. I&amp;rsquo;m considering adding a tiny Emacs&#xA;helper to manage this.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;I need to remember to open the app on my phone to trigger a cache update&#xA;before stepping away from my laptop. I want to explore using the &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/API/Background_Synchronization_API&#34;&gt;Background&#xA;Sync API&lt;/a&gt; (not available on Firefox) to possibly make this easier.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;The UI could use some improvements to indicate pending syncs when offline and&#xA;also indicate the last sync with the server to help ensure everything is&#xA;synced before stepping away from my laptop.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Service workers need the server to be accessible via https. I have a wrapper&#xA;script around mkcert to make this easy, but some apps on my phone &lt;a href=&#34;https://www.reddit.com/r/UPI/comments/1p4le9x/what_happened_to_my_bhim_app/&#34;&gt;refuse to&#xA;work&lt;/a&gt; correctly when there are user installed certificates.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;why-ocaml&#34;&gt;Why OCaml?&lt;/h2&gt;&#xA;&lt;p&gt;At work, I write OCaml every day and enjoy it. This project seemed like a good&#xA;one to try out &lt;code&gt;js_of_ocaml&lt;/code&gt; since everything is local and I don&amp;rsquo;t need to&#xA;worry about bundle sizes, etc.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;js_of_ocaml&lt;/code&gt; makes it quite convenient to share code between the server and&#xA;the client side. And given there&amp;rsquo;s also a &amp;ldquo;third&amp;rdquo; Service Worker component in&#xA;the mix, I thought it would make life easier. For instance, the message types&#xA;and the serialization code for the messages between the client and the service&#xA;worker are shared.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;m also using this project to experiment with Dune&amp;rsquo;s &amp;ldquo;soon to be released&amp;rdquo;™&#xA;&lt;a href=&#34;https://dune.readthedocs.io/en/stable/tutorials/dune-package-management/index.html&#34;&gt;package management&lt;/a&gt; that our team at Tarides is working on building.&lt;/p&gt;&#xA;&lt;h2 id=&#34;how-can-you-use-it&#34;&gt;How can you use it?&lt;/h2&gt;&#xA;&lt;p&gt;You can try out Elfeed offline&amp;rsquo;s UI &lt;a href=&#34;https://elfeed-offline.muse-amuse.in/&#34;&gt;here&lt;/a&gt; as a static site (with some posts from&#xA;Planet Emacslife and The OCaml Planet). You should be able to read posts,&#xA;search and filter for posts, mark them as read or star them. Any changes you&#xA;make should be preserved between reloads.&lt;/p&gt;&#xA;&lt;p&gt;If you are an Emacs user but don&amp;rsquo;t use Elfeed, you can checkout the &lt;a href=&#34;https://github.com/skeeto/elfeed&#34;&gt;Elfeed&amp;rsquo;s&#xA;README&lt;/a&gt; for instructions to set it up. It also has links to a bunch of blog&#xA;posts and videos that show off the features of Elfeed.&lt;/p&gt;&#xA;&lt;p&gt;If you are already using Elfeed, you should be able to set it up quite easily&#xA;if you&amp;rsquo;re happy installing some OCaml tooling. The installations instructions&#xA;are available in the &lt;a href=&#34;https://github.com/punchagan/elfeed-offline/blob/main/README.org&#34;&gt;README&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;outro&#34;&gt;Outro&lt;/h2&gt;&#xA;&lt;p&gt;I have been enjoying using Elfeed offline for the past couple of weeks. And I&amp;rsquo;m&#xA;hoping I&amp;rsquo;ll end up spending much more time reading in it, than fixing and&#xA;building it. It currently definitely feels like something I built for myself,&#xA;but I&amp;rsquo;d love to hear from others who try it out.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Responsive Auto Export for Org Hugo</title>
      <link>https://punchagan.muse-amuse.in/blog/responsive-auto-export-for-org-hugo/</link>
      <pubDate>Wed, 13 Nov 2024 00:17:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/responsive-auto-export-for-org-hugo/</guid>
      <description>&lt;p&gt;I use &lt;a href=&#34;https://github.com/kaushalmodi/ox-hugo/&#34;&gt;ox-hugo&lt;/a&gt; to &lt;a href=&#34;https://punchagan.muse-amuse.in/blog/deploying-hugo-drafts-simplified/&#34;&gt;write blog posts&lt;/a&gt; in org-mode and publish them using &lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt;. I&#xA;&lt;a href=&#34;https://punchagan.muse-amuse.in/blog/why-i-like-org-as-a-markup/&#34;&gt;enjoy using org-mode&lt;/a&gt; for any writing that I do, including blog posts (when I am&#xA;able to get myself to write them). After a long hiatus, I&amp;rsquo;ve been trying to get&#xA;back to blogging, as this post might have given away. But, ox-hugo&amp;rsquo;s &lt;a href=&#34;https://ox-hugo.scripter.co/doc/auto-export-on-saving/&#34;&gt;auto&#xA;export&lt;/a&gt; seemed much slower than I remember it being.&lt;/p&gt;&#xA;&lt;p&gt;Each time I hit save on my &lt;code&gt;blog-posts.org&lt;/code&gt; file, Emacs gets busy for about&#xA;10ish seconds exporting the post to Hugo markdown. And this is annoying because&#xA;I tend to hit &lt;code&gt;save-buffer&lt;/code&gt; multiple times while writing in &lt;code&gt;Emacs&lt;/code&gt; &amp;ndash; thanks,&#xA;muscle memory!&lt;/p&gt;&#xA;&lt;h2 id=&#34;enter-emacs-profiler&#34;&gt;Enter Emacs profiler&lt;/h2&gt;&#xA;&lt;p&gt;I was on a flight and had some time to dig into this. If I was online, I&#xA;probably would have looked through the README and/or the issue tracker, but I&#xA;&lt;a href=&#34;https://punchagan.muse-amuse.in/blog/how-i-learnt-to-use-emacs-profiler/&#34;&gt;jumped in&lt;/a&gt; with the handy &lt;a href=&#34;https://www.gnu.org/software/emacs/manual/html_node/elisp/Profiling.html&#34;&gt;Emacs profiler&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;The profiler-report showed that a big chunk of time was being spent in&#xA;&lt;code&gt;org-id-update-id-locations&lt;/code&gt; even before the actual export started. And then,&#xA;during the export, a bulk of the time was spent in&#xA;&lt;code&gt;org-hugo--get-pre-processed-buffer&lt;/code&gt;. Once I knew the problem areas, I started&#xA;poking around in the &lt;code&gt;ox-hugo&lt;/code&gt; code to &amp;ldquo;fix&amp;rdquo; these issues.&lt;/p&gt;&#xA;&lt;h2 id=&#34;turn-off-org-id-location-update&#34;&gt;Turn off Org ID location update&lt;/h2&gt;&#xA;&lt;p&gt;&lt;code&gt;org-id-update-id-locations&lt;/code&gt; scans a bunch of org-mode files and stores a&#xA;mapping of all the IDs of subtrees to their filenames. If you have a lot of org&#xA;subtrees this can take a while, even if none of them actually have IDs. It&#xA;turns out that I didn&amp;rsquo;t have any ID properties set, and this caused the &lt;a href=&#34;https://github.com/kaushalmodi/ox-hugo/blob/98421a1298adc6d80ce21b3cb5c951af818b27bf/ox-hugo.el#L4881-L4882&#34;&gt;update&#xA;function to run before every export&lt;/a&gt;!&lt;/p&gt;&#xA;&lt;p&gt;I simply added a new ID property on one of the subtrees in my blog-posts file&#xA;to prevent the ID updation from running on every export! I&amp;rsquo;m not sure how a&#xA;stale &lt;code&gt;org-id-locations&lt;/code&gt; value affects cross links, but at this stage of&#xA;writing I don&amp;rsquo;t care about the cross links. (spoiler: The next hack actually&#xA;nullifies any impact a stale value might have had!)&lt;/p&gt;&#xA;&lt;p&gt;Cutting down auto export time by 4-5 seconds is great! But, I&amp;rsquo;m still not happy&#xA;to wait for 5-6 seconds in the middle of writing my posts. Let&amp;rsquo;s look at the&#xA;other hotspot &amp;ndash; the buffer preprocessing!&lt;/p&gt;&#xA;&lt;h2 id=&#34;turn-off-buffer-preprocessing-maybe&#34;&gt;Turn off buffer preprocessing, maybe?&lt;/h2&gt;&#xA;&lt;p&gt;Currently, I don&amp;rsquo;t have any cross links between posts in my org-mode source.&#xA;So, I can turn off this feature completely by setting&#xA;&lt;code&gt;org-hugo--preprocess-buffer&lt;/code&gt; to &lt;code&gt;nil&lt;/code&gt;. Viola! Hitting &lt;code&gt;save-buffer&lt;/code&gt; doesn&amp;rsquo;t&#xA;freeze my Emacs any more. I can compose &amp;ldquo;100s of blog posts&amp;rdquo;™ in a flurry! ;)&lt;/p&gt;&#xA;&lt;p&gt;But, if I&amp;rsquo;m going to have these &amp;ldquo;100s of blog posts&amp;rdquo;, wouldn&amp;rsquo;t it be better to&#xA;have cross links? But, with preprocessing turned off when there are&#xA;cross-links, the &amp;ldquo;auto-export and build&amp;rdquo; workflow breaks. The variable&#xA;&lt;code&gt;org-hugo--preprocess-buffer&lt;/code&gt; MUST be non-nil to produce posts with &lt;strong&gt;valid&lt;/strong&gt;&#xA;cross-links. If not, the exported markdown file processed by &lt;code&gt;hugo&lt;/code&gt; ends up&#xA;having broken cross-links, which crashes &lt;code&gt;hugo serve&lt;/code&gt; and/or &lt;code&gt;hugo build&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Unsetting and setting the &lt;code&gt;org-hugo--preprocess-buffer&lt;/code&gt; variable for the&#xA;writing vs publishing phase, respectively, isn&amp;rsquo;t an ergonomic workflow. It&amp;rsquo;s&#xA;not an improvement over disabling and enabling the auto-export mode as needed.&#xA;I want to enjoy auto export with Hugo&amp;rsquo;s &lt;a href=&#34;https://gohugo.io/getting-started/usage/#livereload&#34;&gt;live reload&lt;/a&gt; feature.&lt;/p&gt;&#xA;&lt;h2 id=&#34;moar-workaround&#34;&gt;Moar workaround!&lt;/h2&gt;&#xA;&lt;p&gt;Looking through the code some more, I learnt &lt;a href=&#34;https://github.com/kaushalmodi/ox-hugo/blob/98421a1298adc6d80ce21b3cb5c951af818b27bf/ox-hugo.el#L2723&#34;&gt;&lt;code&gt;org-hugo-link&lt;/code&gt;&lt;/a&gt; first uses a&#xA;custom export handler, if one exists for a link&amp;rsquo;s protocol. I decided to piggy&#xA;back on this functionality and made up &lt;code&gt;hugo:&lt;/code&gt; protocol for cross-links.&lt;/p&gt;&#xA;&lt;p&gt;The &lt;code&gt;hugo&lt;/code&gt; link simply contains the &lt;code&gt;EXPORT_FILE_NAME&lt;/code&gt; of the linked blog post&#xA;i.e., name of the exported markdown file (without the .md extension) as the&#xA;&amp;lsquo;path&amp;rsquo; of the link. The custom protocol export handler can then generates a&#xA;&lt;code&gt;relref&lt;/code&gt; shortcode for Hugo to process in the exported markdown file.&lt;/p&gt;&#xA;&lt;p&gt;This nicely works around the need to preprocess my entire &lt;code&gt;blog-posts.org&lt;/code&gt;&#xA;buffer to generate &lt;strong&gt;valid&lt;/strong&gt; cross-links!&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-link-set-parameters&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;hugo&amp;#34;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:export&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pc/org-hugo-link-export-to-md&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Export Hugo blog link to markdown file&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/org-hugo-link-export-to-md&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;path&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;backend&lt;/span&gt; &lt;span class=&#34;kp&#34;&gt;&amp;amp;optional&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;Export a link to a Hugo blog link in markdown format.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;format&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;path: %s, desc: %s, backend: %s&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;path&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;backend&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cond&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;eq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;backend&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;md&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;equal&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-export-current-backend&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;hugo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;format&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;[%s]({{&amp;lt; relref \&amp;#34;%s\&amp;#34; &amp;gt;}})&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;error&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Cannot export Hugo link to non-Hugo backend&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;t&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;error&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Cannot export Hugo link to non-Hugo backend&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;outro&#34;&gt;Outro&lt;/h2&gt;&#xA;&lt;p&gt;I made a &lt;a href=&#34;https://github.com/punchagan/dot-doom/blob/c45f01e6b20275ce1df943855626af5c40cb626c/config.el#L541-L564&#34;&gt;simple helper&lt;/a&gt; to make it easier to insert these cross-links with the&#xA;&lt;code&gt;hugo:&lt;/code&gt; protocol. It simply looks through all the headlines with an&#xA;&lt;code&gt;EXPORT_FILE_NAME&lt;/code&gt; property, and allows it to be inserted as a link with the&#xA;&lt;code&gt;hugo:&lt;/code&gt; protocol.&lt;/p&gt;&#xA;&lt;p&gt;Now, cross-linking posts and publishing posts with cross-links are both a&#xA;breeze. Stay tuned for the &amp;ldquo;100s of blog posts&amp;rdquo; ™ I&amp;rsquo;m going to write!&lt;/p&gt;&#xA;&lt;div style=&#34;font-size:small;&#34; class=&#34;reviewers&#34;&gt;&#xA;&lt;p&gt;Thanks to &lt;a href=&#34;http://baali.muse-amuse.in&#34;&gt;Shantanu&lt;/a&gt; and &lt;a href=&#34;https://x.com/kamalx&#34;&gt;Kamal&lt;/a&gt; for reading drafts of this post.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>GitHub Gists from Emacs Orgmode</title>
      <link>https://punchagan.muse-amuse.in/blog/ox-gist/</link>
      <pubDate>Tue, 26 Apr 2022 12:37:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/ox-gist/</guid>
      <description>&lt;p&gt;TL;DR: I released my first Emacs MELPA package &amp;ndash; &lt;a href=&#34;https://melpa.org/#/ox-gist&#34;&gt;ox-gist&lt;/a&gt; &amp;ndash; An Orgmode backend&#xA;to export and update sub-trees and buffers to GitHub gists.  It was a great&#xA;experience contributing to MELPA.&lt;/p&gt;&#xA;&lt;h2 id=&#34;motivation&#34;&gt;Motivation&lt;/h2&gt;&#xA;&lt;p&gt;I often share bits and pieces of my &lt;code&gt;journal.org&lt;/code&gt; file with others, mostly for&#xA;reading, some times for comments. The file contains different subtrees for each&#xA;day with subtrees for different topics, meetings, articles, etc.&lt;/p&gt;&#xA;&lt;p&gt;Orgmode lets you export subtrees to specific file names using the&#xA;&lt;code&gt;EXPORT_FILE_NAME&lt;/code&gt; property (and &lt;code&gt;FILE_NAME&lt;/code&gt; buffer export option when&#xA;exporting full buffers). It is easy to create these exported files on a&#xA;publicly accessible webserver using the power of &lt;a href=&#34;https://www.gnu.org/software/tramp/&#34;&gt;Emacs TRAMP mode&lt;/a&gt;.  For&#xA;instance, I often set the property to some thing like&#xA;&lt;code&gt;/ssh:muse-amuse.in:~/public_html/&amp;lt;filename&amp;gt;&lt;/code&gt; to publish stuff.&lt;/p&gt;&#xA;&lt;p&gt;But, exporting to HTML is a distraction some times because I start fiddling&#xA;with CSS and styling. Exporting to a simple org file doesn&amp;rsquo;t seem to cut it&#xA;because there&amp;rsquo;s no styling at all, and making longer exports hard to read in a&#xA;web-browser.  Exporting to a GitHub Gist is a nice middle ground because GitHub&#xA;renders Orgmode files reasonably well. Additionally, the comment functionality&#xA;is pretty handy.&lt;/p&gt;&#xA;&lt;p&gt;I could also directly use &lt;a href=&#34;https://github.com/defunkt/&#34;&gt;@defunkt&lt;/a&gt;&amp;rsquo;s excellent &lt;a href=&#34;https://github.com/defunkt/gist.el&#34;&gt;&lt;code&gt;gist.el&lt;/code&gt;&lt;/a&gt; to share stuff as&#xA;Gists.  I&amp;rsquo;ve used it in the past, and it works well when I don&amp;rsquo;t care about&#xA;having the contents of the Gist locally on my machine. It&amp;rsquo;s also quite easy to&#xA;update existing/old Gists in this scenario, since there&amp;rsquo;s a single &amp;ldquo;source of&#xA;truth&amp;rdquo; and &lt;code&gt;gist.el&lt;/code&gt; makes it quite easy to update Gists.&lt;/p&gt;&#xA;&lt;p&gt;But, this isn&amp;rsquo;t good enough when I want to have a &amp;ldquo;synced&amp;rdquo; copy of the text on&#xA;my machine.  Also, it doesn&amp;rsquo;t work very well when I want to share just a&#xA;subtree from my notes file, and not the entire file.  I&amp;rsquo;ve to export the&#xA;subtree to a temporary Orgmode buffer and then create a Gist from that buffer.&lt;/p&gt;&#xA;&lt;h2 id=&#34;hackish-wrapper-around-gist-dot-el&#34;&gt;Hackish wrapper around &lt;code&gt;gist.el&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;p&gt;A couple or so years ago, I wrote a wrapper around &lt;code&gt;gist.el&lt;/code&gt; to let me post&#xA;Orgmode subtrees as a Gist and also update them when I edited these subtrees&#xA;locally.  There was no support for exporting entire buffers since that wasn&amp;rsquo;t&#xA;my use-case.  This wrapper code was just a part of my &lt;code&gt;.emacs&lt;/code&gt; and worked&#xA;reasonably well for me.&lt;/p&gt;&#xA;&lt;p&gt;A few weeks ago, I ended up procrastinating on writing and sharing notes for a&#xA;discussion with a friend, and extracted this wrapper as a separate package &amp;ndash;&#xA;&lt;code&gt;org2gist&lt;/code&gt; &amp;ndash; to make it easy for other people to use.&lt;/p&gt;&#xA;&lt;h2 id=&#34;melpa-submission-and-feedback&#34;&gt;MELPA submission and feedback&lt;/h2&gt;&#xA;&lt;p&gt;I &lt;a href=&#34;https://github.com/melpa/melpa/pull/7940&#34;&gt;submitted&lt;/a&gt; this as a package to &lt;a href=&#34;https://melpa.org/&#34;&gt;MELPA&lt;/a&gt; while being skeptical about whether it&#xA;would be accepted.  I wasn&amp;rsquo;t sure if my thin wrapper around &lt;code&gt;gist.el&lt;/code&gt; would&#xA;meet MELPA&amp;rsquo;s criteria for a &amp;ldquo;Reasonably innovative package&amp;rdquo;:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;MELPA provides a curated set of Emacs Lisp packages, not an exhaustive list&#xA;of every single Emacs Lisp file ever created. By default, MELPA maintainers&#xA;will reject packages that duplicate functionality provided by existing&#xA;packages. Please try to improve existing packages instead of creating new&#xA;ones when possible.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;It was a pleasant surprise to get very helpful reviews from the MELPA&#xA;maintainers.  They not only thought the package was good enough to include in&#xA;MELPA, but also looked at it&amp;rsquo;s code and gave great feedback &amp;mdash; not just basic&#xA;quality checks before accepting the package into MELPA.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;m pretty sure mainting a package repository like MELPA is a lot of work, but&#xA;as an end-user it mostly just worked for me and I never really gave it much&#xA;thought.  It was eye-opening to submit the package to MELPA and see first-hand&#xA;the care and effort the maintainers put into what goes into the repository.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/riscy/&#34;&gt;@riscy&lt;/a&gt; (a MELPA maintainer) &lt;a href=&#34;https://github.com/melpa/melpa/pull/7940#issuecomment-1080036663&#34;&gt;suggested&lt;/a&gt; a different approach that I hadn&amp;rsquo;t&#xA;thought of &amp;mdash; turning the wrapper into an &lt;a href=&#34;https://orgmode.org/manual/Exporting.html&#34;&gt;Orgmode Export backend&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;current-version-ox-gist&#34;&gt;Current version: &lt;code&gt;ox-gist&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;p&gt;It turned out to be a great idea which I ended up implementing.  The user&#xA;interface became much cleaner, since it used the Orgmode Export UI.  And it&#xA;also forced me to &amp;ldquo;complete&amp;rdquo; the feature-set by adding support for exporting&#xA;entire Orgmode buffers to GitHub Gists, not just subtrees.&lt;/p&gt;&#xA;&lt;p&gt;The package now adds an Orgmode export backend that lets you export a subtree&#xA;or the whole buffer as a GitHub Gist, similar to how you&amp;rsquo;d export to HTML or&#xA;LaTeX from Orgmode. The GitHub Gist ID is saved for each exported buffer or&#xA;subtree and is to update a Gist when re-exporting an already exported subtree&#xA;or buffer.&lt;/p&gt;&#xA;&lt;h2 id=&#34;outro&#34;&gt;Outro&lt;/h2&gt;&#xA;&lt;p&gt;The package has now been added to MELPA as &lt;a href=&#34;https://github.com/punchagan/ox-gist&#34;&gt;&lt;code&gt;ox-gist&lt;/code&gt;&lt;/a&gt;.  Feel free to give it a&#xA;spin and give feedback directly to me or on the &lt;a href=&#34;https://github.com/punchagan/ox-gist/issues&#34;&gt;issue tracker&lt;/a&gt;!&lt;/p&gt;&#xA;&lt;p&gt;I don&amp;rsquo;t know if anyone else would find the package useful and use it, though,&#xA;MELPA tells me that 20-odd people atleast downloaded it.  I&amp;rsquo;m happy this code&#xA;may be to a handful of people.&lt;/p&gt;&#xA;&lt;p&gt;Also, I now have a new found appreciation for MELPA and the work put into it by&#xA;the maintainers.  I&amp;rsquo;m glad I took the time out to submit this package to MELPA.&lt;/p&gt;&#xA;&lt;div style=&#34;font-size:small;&#34; class=&#34;reviewers&#34;&gt;&#xA;&lt;p&gt;Thanks to &lt;a href=&#34;http://baali.muse-amuse.in&#34;&gt;Shantanu&lt;/a&gt; for reading drafts and helping me restructure this post.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;</description>
    </item>
    <item>
      <title>Deploying Hugo Drafts, simplified</title>
      <link>https://punchagan.muse-amuse.in/blog/deploying-hugo-drafts-simplified/</link>
      <pubDate>Sun, 31 May 2020 17:19:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/deploying-hugo-drafts-simplified/</guid>
      <description>&lt;p&gt;This is a follow-up post to my last post, &lt;a href=&#34;https://punchagan.muse-amuse.in/blog/deploying-hugo-drafts&#34;&gt;Deploying Hugo Drafts&lt;/a&gt;. Kaushal Modi,&#xA;the author of &lt;a href=&#34;https://github.com/kaushalmodi/ox-hugo&#34;&gt;ox-hugo&lt;/a&gt; (a tool that lets you compose in org-mode and use Hugo to&#xA;export), let me know about the &lt;a href=&#34;https://gohugo.io/content-management/build-options/&#34;&gt;build options&lt;/a&gt; in Hugo.&lt;/p&gt;&#xA;&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;Have you looked at the new _build options: &lt;a href=&#34;https://t.co/Nj8Uefis6Q&#34;&gt;https://t.co/Nj8Uefis6Q&lt;/a&gt;. I haven&amp;#39;t used them yet, but looks like they fit your use case.&lt;/p&gt;&amp;mdash; Kaushal (@kaushalmodi) &lt;a href=&#34;https://twitter.com/kaushalmodi/status/1266761525286653952?ref_src=twsrc%5Etfw&#34;&gt;May 30, 2020&lt;/a&gt;&lt;/blockquote&gt;&#xA;&lt;script async src=&#34;https://platform.twitter.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;&#xA;&#xA;&#xA;&lt;p&gt;The build options in Hugo let you configure building a post for different use&#xA;cases like render a post but hide it in lists, or don&amp;rsquo;t render separate pages&#xA;for posts and only show them in lists, etc.&lt;/p&gt;&#xA;&lt;p&gt;To use these build options for my use case &amp;ndash; being able to share draft post&#xA;links with friends, without them appearing in the index page or RSS feed &amp;ndash; I&#xA;just need to add the following to my draft blog posts!&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;_build&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;render&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But, how do I do this with &lt;code&gt;ox-hugo&lt;/code&gt;? I know &lt;code&gt;ox-hugo&lt;/code&gt; doesn&amp;rsquo;t yet have this&#xA;feature, for sure, because Kaushal mentioned that he hasn&amp;rsquo;t tried it out yet.&lt;/p&gt;&#xA;&lt;p&gt;I checked to see if I could use the &lt;code&gt;EXPORT_HUGO_CUSTOM_FRONT_MATTER&lt;/code&gt; property&#xA;to get it to generate this extra metadata for each blog post. But that didn&amp;rsquo;t&#xA;work. The property assumes all the arguments to it are top level front matter&#xA;keys and values, which is good enough for &amp;ldquo;normal&amp;rdquo; use cases.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;EDIT &lt;span class=&#34;timestamp-wrapper&#34;&gt;&lt;span class=&#34;timestamp&#34;&gt;[2020-05-31 Sun]&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;: I previously manually created the &lt;code&gt;drafts&lt;/code&gt; directory with&#xA;the &lt;code&gt;_index.md&lt;/code&gt;, but Kaushal pointed me to &lt;a href=&#34;https://twitter.com/kaushalmodi/status/1267066389996724229&#34;&gt;more docs&lt;/a&gt;, again! :) There&amp;rsquo;s also an&#xA;&lt;a href=&#34;https://github.com/kaushalmodi/ox-hugo/issues/358&#34;&gt;issue&lt;/a&gt; for adding an easier way to add these build options from ox-hugo.&lt;/p&gt;&#xA;&lt;p&gt;I created a subtree like this in my org file, that creates the&#xA;&lt;code&gt;drafts/_index.md&lt;/code&gt; file with the required front matter and build options.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gh&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;gs&#34;&gt; Drafts&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;:PROPERTIES:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;&lt;span class=&#34;cs&#34;&gt;:EXPORT_FILE_NAME: _index&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cs&#34;&gt;:EXPORT_HUGO_SECTION: drafts&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cs&#34;&gt;:EXPORT_HUGO_CUSTOM_FRONT_MATTER: yaml&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cs&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;:END:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;#+begin_src &lt;/span&gt;&lt;span class=&#34;cs&#34;&gt;yaml&lt;/span&gt;&lt;span class=&#34;c&#34;&gt; :front_matter_extra t&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;_build&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;render&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;publishResources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cascade&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;_build&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;render&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;#+end_src&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The build options for the index page turn off publishing and showing it in&#xA;lists. With the &lt;code&gt;cascade&lt;/code&gt; option, we can get the options to all the children &amp;ndash;&#xA;any files created in the &lt;code&gt;drafts&lt;/code&gt; directory, but also override the &lt;code&gt;render&lt;/code&gt;&#xA;option to be true. In other words, the configuration above would translate to&#xA;adding the following to &lt;em&gt;every draft post&lt;/em&gt;:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;A&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;How-to&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;on&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Hugo&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Drafts&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;_build&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;render&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;publishResources&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, I just need to make sure that all my draft posts are created in this&#xA;&lt;code&gt;drafts&lt;/code&gt; directory. &lt;code&gt;ox-hugo&lt;/code&gt; allows doing this by simply using the&#xA;&lt;code&gt;EXPORT_HUGO_SECTION&lt;/code&gt; property on my post subtree. I added this additional&#xA;property to my helper function that I use to create hugo blog posts from any&#xA;subtree.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gh&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;gs&#34;&gt; DRAFT A How-to on Hugo Drafts&lt;/span&gt;&lt;span class=&#34;ge&#34;&gt; :blogging:hack:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;:PROPERTIES:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;&lt;/span&gt;&lt;span class=&#34;cs&#34;&gt;:EXPORT_FILE_NAME: how-to-hugo-drafts&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cs&#34;&gt;:EXPORT_HUGO_SECTION: drafts&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cs&#34;&gt;:EXPORT_DATE: [2020-05-31 Sun 16:51]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cs&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;:END:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;m now all set to publish draft posts without requiring to use &lt;code&gt;rsync&lt;/code&gt; and two&#xA;&lt;code&gt;hugo&lt;/code&gt; builds. :) Publishing a draft post would need me to remove the &lt;code&gt;DRAFT&lt;/code&gt;&#xA;todo keyword, like before, but additionally also remove the&#xA;&lt;code&gt;:EXPORT_HUGO_SECTION:&lt;/code&gt; property on the subtree. This should be quite quick to&#xA;do, or pretty easy to put into an interactive function if required.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Multiple remotes with nullmailer</title>
      <link>https://punchagan.muse-amuse.in/blog/multiple-remotes-with-nullmailer/</link>
      <pubDate>Sat, 18 Nov 2017 04:50:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/multiple-remotes-with-nullmailer/</guid>
      <description>&lt;p&gt;&lt;strong&gt;UPDATE 2018-08-20&lt;/strong&gt;: Moved away from nullmailer&lt;/p&gt;&#xA;&lt;p&gt;I updated my OS and &lt;code&gt;nullmailer&lt;/code&gt; possibly got updated, and this hack no longer&#xA;works. I&amp;rsquo;ve switched to &lt;code&gt;msmtp&lt;/code&gt; with a file based queue that I implemented&#xA;myself. &lt;code&gt;msmtp&lt;/code&gt; can be invoked with the &lt;code&gt;--read-recipient-from&lt;/code&gt; argument, to&#xA;choose the correct right mail server based on the from address.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;This a reference for future-me, and possibly someone pulling off an all-nighter&#xA;trying to get &lt;code&gt;nullmailer&lt;/code&gt; to use the correct &amp;ldquo;remote&amp;rdquo;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-is-nullmailer-and-why-use-it&#34;&gt;What is nullmailer and why use it?&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/bruceg/nullmailer&#34;&gt;Nullmailer&lt;/a&gt; is a simple mail transfer agent that can forward mail to a remote&#xA;mail server (or a bunch of them).&lt;/p&gt;&#xA;&lt;p&gt;I use Emacs to send email, and it can be configured to talk to a remote SMTP&#xA;server to send email. But, this blocks Emacs until the email is sent and the&#xA;connection closed. This is annoying, and having &lt;code&gt;nullmailer&lt;/code&gt; installed locally&#xA;basically lets Emacs delegate this job without blocking.&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-multiple-remotes&#34;&gt;Why multiple remotes?&lt;/h2&gt;&#xA;&lt;p&gt;I have multiple email accounts, and I&amp;rsquo;d like to use the correct remote server&#xA;for sending email based on the FROM address.&lt;/p&gt;&#xA;&lt;p&gt;I expected &lt;code&gt;nullmailer&lt;/code&gt; to have some configuration to be able to specify this.&#xA;But, it turns out that &lt;code&gt;nullmailer&lt;/code&gt; just forwards the email to all the&#xA;configured remotes &lt;a href=&#34;https://github.com/bruceg/nullmailer/blob/master/src/send.cc#L382-L410&#34;&gt;until one of them succeeds&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;how-do-we-then-send-email-from-the-correct-remote-smtp-server&#34;&gt;How do we, then, send email from the correct remote SMTP server?&lt;/h2&gt;&#xA;&lt;p&gt;Currently, I have two remotes - my personal domain (&lt;code&gt;@muse-amuse.in&lt;/code&gt;) and GMail.&lt;/p&gt;&#xA;&lt;p&gt;Having GMail as the first remote in &lt;code&gt;nullmailer&lt;/code&gt;&amp;rsquo;s configuration wouldn&amp;rsquo;t let me&#xA;send emails from my personal domain. GMail seems to agree to send the email&#xA;coming from &lt;code&gt;@muse-amuse.in&lt;/code&gt;, but overwrite the MAIL FROM address and change it&#xA;to my GMail address.&lt;/p&gt;&#xA;&lt;p&gt;So, &lt;code&gt;@muse-amuse.in&lt;/code&gt; has to be the first remote. But, this server also seemed to&#xA;accept and send emails with a &lt;code&gt;@gmail.com&lt;/code&gt; &lt;code&gt;FROM&lt;/code&gt; address. This was causing&#xA;emails sent from my GMail ID to go into spam, as expected.&lt;/p&gt;&#xA;&lt;p&gt;I had to reconfigure this mail server to reject relaying mails that didn&amp;rsquo;t&#xA;belong to the correct domain names &amp;ndash; i.e., reject relaying emails which had&#xA;&lt;code&gt;@gmail.com&lt;/code&gt; in the &lt;code&gt;FROM&lt;/code&gt; address.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;smtpd_sender_restrictions&lt;/code&gt; had to modified to have &lt;code&gt;reject_sender_login_reject&lt;/code&gt;&#xA;along with other values, and the &lt;code&gt;smtpd_sender_login_maps&lt;/code&gt; had to be set to&#xA;allow only the &lt;code&gt;@muse-amuse.in&lt;/code&gt; domain. &lt;a href=&#34;https://serverfault.com/questions/318334/how-to-enforce-sender-address-to-be-logged-in-userexample-org-in-postfix&#34;&gt;This serverfault answer&lt;/a&gt; explains this in&#xA;more detail.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Emacs frame as a pop-up input</title>
      <link>https://punchagan.muse-amuse.in/blog/emacs-frame-as-a-pop-up-input/</link>
      <pubDate>Thu, 14 Sep 2017 22:26:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/emacs-frame-as-a-pop-up-input/</guid>
      <description>&lt;p&gt;I wanted to try using a dialog box/pop-up window as a prompt to remind me to&#xA;periodically make journal entries.  I had the following requirements:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Simple, light-weight dialog box that allows text of arbitrary length&lt;/li&gt;&#xA;&lt;li&gt;Ability to launch the dialog from the shell&lt;/li&gt;&#xA;&lt;li&gt;Ability to have some placeholder or template text, each time the dialog is shown&lt;/li&gt;&#xA;&lt;li&gt;Save the input text to a specific &lt;code&gt;org-mode&lt;/code&gt; file&lt;/li&gt;&#xA;&lt;li&gt;Write as little code of my own, as possible, to do this&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;I had initially thought about using a tool like &lt;code&gt;zenity&lt;/code&gt;, or write a simple&#xA;dialog box in Python using &lt;code&gt;Qt&lt;/code&gt;, &lt;code&gt;wx&lt;/code&gt; or even &lt;code&gt;tk&lt;/code&gt;, and then yank the input text&#xA;at the desired location. This probably wouldn&amp;rsquo;t have turned out to be too hard,&#xA;but getting things to look and work exactly the way I wanted would have required&#xA;more code than I was willing to write or maintain.&lt;/p&gt;&#xA;&lt;p&gt;After avoiding doing this for a while, I finally realized that I could simply&#xA;use Emacs with a new frame with the appropriate dimensions, and with the correct&#xA;file/buffer open to the desired location. This would&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;eliminate the need for me to write the UI myself&lt;/li&gt;&#xA;&lt;li&gt;eliminate the need to do text manipulation in code, to yank it at the right&#xA;place, in the right form. By directly opening up the editor at the required&#xA;location, the onus is on me (as a text inputting user) to put it in, the way I&#xA;want it.&lt;/li&gt;&#xA;&lt;li&gt;additionally provide me the comfort of being able to write with the full power&#xA;of Emacs - keybindings and all that jazz.&lt;/li&gt;&#xA;&lt;li&gt;let me leverage &lt;code&gt;elisp&lt;/code&gt; to do essentially whatever I want with the buffer&#xA;being displayed as the dialog box.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;I ended up with a command that looks something like this&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;emacsclient -c -n&lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;            -F &lt;span class=&#34;s1&#34;&gt;&amp;#39;((title . &amp;#34;Title&amp;#34;) (left . (+ 550)) (top . (+ 400)) (width . 110) (height . 12))&amp;#39;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;            -e &lt;span class=&#34;s1&#34;&gt;&amp;#39;(pc/open-journal-buffer)&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;figure&gt;&lt;img src=&#34;https://punchagan.muse-amuse.in/images/emacs-frame.png&#34;&gt;&#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;This worked pretty nicely, except for the fact that with gnome-shell, the pop-up&#xA;frame doesn&amp;rsquo;t always appear raised. It often gets hidden in the Emacs windows&#xA;group, and the whole idea of the pop-up acting as a reminder goes for a toss!&#xA;But, thanks to &lt;a href=&#34;https://askubuntu.com/a/288483&#34;&gt;this Ask Ubuntu post&lt;/a&gt;, I could fix this pretty easily.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;emacsclient -c -n&lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;            -F &lt;span class=&#34;s1&#34;&gt;&amp;#39;((title . &amp;#34;Title&amp;#34;) (left . (+ 550)) (top . (+ 400)) (width . 110) (height . 12))&amp;#39;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;            -e &lt;span class=&#34;s1&#34;&gt;&amp;#39;(progn (pc/open-journal-buffer) (raise-frame) (x-focus-frame (selected-frame)))&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>blog-admin and Nikola</title>
      <link>https://punchagan.muse-amuse.in/blog/blog-admin-and-nikola/</link>
      <pubDate>Sat, 21 May 2016 00:00:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/blog-admin-and-nikola/</guid>
      <description>&lt;p&gt;Another post about blogging.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/CodeFalling/blog-admin&#34;&gt;blog-admin&lt;/a&gt; now supports &lt;a href=&#34;http://getnikola.com&#34;&gt;Nikola&lt;/a&gt;, thanks to yours truly. &lt;code&gt;blog-admin&lt;/code&gt; is an Emacs&#xA;package by &lt;a href=&#34;https://twitter.com/codefalling&#34;&gt;CodeFalling&lt;/a&gt; that lets you view and manage your (static site&#xA;generated) blog from within inside Emacs.&lt;/p&gt;&#xA;&lt;p&gt;Nikola&amp;rsquo;s command line utility is pretty nifty and does a bunch of useful&#xA;things. I had a few utility functions to do common tasks like create new post&#xA;and deploy blog. This worked well, but moment I came across this &lt;code&gt;blog-admin&lt;/code&gt;&amp;rsquo;s&#xA;tabular view, I was sold!&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/punchagan/org2blog&#34;&gt;org2blog&lt;/a&gt; (a blogging tool I used previously) had a tracking file that kept&#xA;track of all the posts I made, and I used it quite a bit for navigation &amp;ndash;&#xA;thanks to &lt;code&gt;org-mode&lt;/code&gt;&amp;rsquo;s search functionality. The tabular view of &lt;code&gt;blog-admin&lt;/code&gt;&#xA;is even better!  I really like the fact that the author has tried to keep the&#xA;package generic enough to support any blog, and adding support for Nikola has&#xA;been quite easy.&lt;/p&gt;&#xA;&lt;p&gt;The filtering functionality is crude, but good enough for a start. One thing I&#xA;want to add is a preview functionality for drafts. Showing some (writing)&#xA;statistics would also be nice &amp;ndash; No. posts in the last month, total published&#xA;posts, etc.  No promises, but you may see some of these things, soon. :)&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Clock in and get-shit-done</title>
      <link>https://punchagan.muse-amuse.in/blog/clock-in-and-get-shit-done/</link>
      <pubDate>Tue, 22 Dec 2015 00:00:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/clock-in-and-get-shit-done/</guid>
      <description>&lt;p&gt;I had &lt;a href=&#34;./simple-org-clock-and-gnomepidgin-integration.html&#34;&gt;setup&lt;/a&gt; a couple of hooks about an year ago that turn off all notifications&#xA;while I&amp;rsquo;m clocking in. But, I find myself switching to the browser and jumping&#xA;to twitter, out of habit.  I&amp;rsquo;ve tried &lt;a href=&#34;https://github.com/leftnode/get-shit-done&#34;&gt;get-shit-done&lt;/a&gt; in the past to help myself&#xA;break this habit. But enabling get-shit-done manually is step that quickly&#xA;became a non-habit.&lt;/p&gt;&#xA;&lt;p&gt;So, I hooked up get-shit-done into an &lt;code&gt;org-clock-in-hook&lt;/code&gt;.  The snippet below&#xA;is what I added into a function that is added to this hook.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;with-temp-buffer&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;cd&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;/sudo::/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;shell-command&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;HOME=/home/punchagan get-shit-done work&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;get-shit-done&lt;/code&gt; needs to be run as &lt;code&gt;root&lt;/code&gt;, since it does things like modifying&#xA;&lt;code&gt;/etc/hosts&lt;/code&gt; and restarting networking.  Just calling &lt;code&gt;get-shit-done&lt;/code&gt; as a&#xA;shell command fails with the error &lt;code&gt;sudo: no tty present and no askpass program specified&lt;/code&gt;.  I found a couple of ways to fix this. The snippet above&#xA;piggy-backs on tramp to allow for a way to enter the password for &lt;code&gt;sudo&lt;/code&gt; to&#xA;use. This also means that I don&amp;rsquo;t need to enter the password, as long as the&#xA;tramp connection is alive.&lt;/p&gt;&#xA;&lt;p&gt;For someone worried about having such an easy way of running something as&#xA;&lt;code&gt;root&lt;/code&gt;, using something like &lt;code&gt;gnome-ssh-askpass&lt;/code&gt; as the askpass program might&#xA;work better.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;shell-command&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;SUDO_ASKPASS=\&amp;#34;/usr/lib/openssh/gnome-ssh-askpass\&amp;#34; get-shit-done work&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>Elfeed hook to fetch full content</title>
      <link>https://punchagan.muse-amuse.in/blog/elfeed-hook-to-fetch-full-content/</link>
      <pubDate>Sat, 19 Dec 2015 13:42:29 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/elfeed-hook-to-fetch-full-content/</guid>
      <description>&lt;p&gt;I have started to use &lt;a href=&#34;http://pinboard.in&#34;&gt;Pinboard&lt;/a&gt;&amp;rsquo;s &lt;code&gt;unread&lt;/code&gt; tag as my to-read list.  It has a&#xA;bookmark-let that works pretty well for adding stuff into my &amp;ldquo;to-read&amp;rdquo; list.  I&#xA;then catch up on this list using &lt;code&gt;elfeed&lt;/code&gt; and subscribing to the unread items&#39;&#xA;RSS feed.  The work-flow is pretty nice for adding stuff into the list, and&#xA;finding items on the list. But, when it comes to the actual reading part, the&#xA;entries in the feed don&amp;rsquo;t have the actual content I want to read, and I end up&#xA;opening the links in a browser.&lt;/p&gt;&#xA;&lt;p&gt;Inspired by a &lt;a href=&#34;https://github.com/sursh/blaggregator/pull/80#issuecomment-165849126&#34;&gt;comment from FiloSottile&lt;/a&gt;, I realized it should be pretty easy to&#xA;setup a hook that fetches the actual content to make my reading work-flow&#xA;smoother. I wrote a &lt;a href=&#34;https://github.com/punchagan/dotfiles/blob/3285e9408b91bbf5e1c78974d003be84926f9954/bin/get_article.py&#34;&gt;small script&lt;/a&gt;, using &lt;a href=&#34;https://github.com/buriy/python-readability&#34;&gt;python-readability&lt;/a&gt;, to fetch the page&#xA;content, given a URL. This script is then hooked onto &lt;code&gt;elfeed-new-entry-hook&lt;/code&gt;,&#xA;to fetch content of for new entries as they are fetched.  All the old entries&#xA;can be easily fixed with a single call to &lt;code&gt;elfeed-apply-hooks-now&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/get-url-content&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;Fetches the content for a url.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;shell-command-to-string&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;format&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;~/bin/get_article.py %s&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/get-entry-content&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;Fetches content for pinboard entries that are not tweets.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interactive&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;entry&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;elfeed-show-entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;list&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;url&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;elfeed-entry-link&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;feed-id&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;elfeed-deref&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;elfeed-entry-feed-id&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;content&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;elfeed-deref&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;elfeed-entry-content&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;when&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;s-matches?&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;feeds.pinboard.in/&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;feed-id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;               &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;s-matches?&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;twitter.com/\\|pdf$\\|png$\\|jpg$&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;               &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;string-equal&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;content&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pc/get-url-content&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setf&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;elfeed-entry-content&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;elfeed-ref&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;add-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;elfeed-new-entry-hook&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pc/get-entry-content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>Say Howdy with Emacs!</title>
      <link>https://punchagan.muse-amuse.in/blog/say-howdy-with-emacs/</link>
      <pubDate>Thu, 28 May 2015 00:00:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/say-howdy-with-emacs/</guid>
      <description>&lt;p&gt;Staying in touch with people is something I&amp;rsquo;m not very good at.  Since I am not&#xA;on popular (among my friends/family) networks &amp;ndash; FB and Whatsapp &amp;ndash; I don&amp;rsquo;t&#xA;even see random updates from people, to get some sense of being in touch.&lt;/p&gt;&#xA;&lt;p&gt;I recently read some old posts by Sacha Chua and was inspired by how much code&#xA;she had for &lt;a href=&#34;http://sachachua.com/blog/category/geek/emacs/bbdb/&#34;&gt;contact management&lt;/a&gt; in her old blog posts.  I was inspired by &lt;a href=&#34;http://sachachua.com/blog/2005/05/keeping-in-touch/&#34;&gt;this&#xA;post&lt;/a&gt; in particular to try and be more meticulous about how I stay in touch with&#xA;people. Michael Fogleman &lt;a href=&#34;https://mwfogleman.github.io/posts/08-01-2015-emacs-can-keep-in-touch.html&#34;&gt;blogged&lt;/a&gt; about his contact management work-flow using&#xA;&lt;code&gt;keepintouch&lt;/code&gt;. It seemed to do most of what I wanted, but I wanted this to be&#xA;integrated with my &lt;code&gt;org-contacts-db&lt;/code&gt; and I felt having native elisp code would&#xA;make it easier to hook up email, chat, etc. to this.&lt;/p&gt;&#xA;&lt;p&gt;I ended up writing a small utility called &lt;a href=&#34;https://github.com/punchagan/howdy/&#34;&gt;howdy&lt;/a&gt; to help me keep in touch with&#xA;people. It currently has only a couple of features:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;kbd&gt;M-x howdy&lt;/kbd&gt; lets me update the last contacted timestamp for a contact.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Shows me contacts that I&amp;rsquo;m out of touch in the agenda, once I add the&#xA;following snippet to an agenda file.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-org&#34; data-lang=&#34;org&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;​* Howdy&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  %%(howdy-howdy)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;I also have a few hooks to hook up jabber messages and email to update the db.&#xA;I&amp;rsquo;ve added them to &lt;code&gt;howdy-hooks.el&lt;/code&gt; in case anybody else wants to use them.&#xA;They can also be used as examples to write other hooks. Feel free to contribute&#xA;other hooks or suggest improvements.  The library also ships with a modest test&#xA;suite, that will hopefully make it easier for others to contribute.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;m looking forward to experimenting with this over the next few weeks and&#xA;improving it. Hopefully, it&amp;rsquo;ll help me keep in touch, better than I do now.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Playing music using mpsyt from Emacs</title>
      <link>https://punchagan.muse-amuse.in/blog/playing-music-using-mpsyt-from-emacs/</link>
      <pubDate>Mon, 20 Apr 2015 00:00:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/playing-music-using-mpsyt-from-emacs/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve started using the wonderful &lt;a href=&#34;https://github.com/np1/mps-youtube/&#34;&gt;mpsyt&lt;/a&gt; to play any music from youtube, since&#xA;I&amp;rsquo;m not really interested in the video.  But, since I use emacs for chat/IRC, I&#xA;end up getting youtube links into emacs and opening them opens them up in my&#xA;browser. I ended up writing some &lt;code&gt;elisp&lt;/code&gt; to play the songs from within an&#xA;instance of &lt;code&gt;mpsyt&lt;/code&gt; running inside an emacs buffer.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/short-url-at-point&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;Gets the short url at point.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;This function is required only because&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;`thing-at-point-url-at-point&amp;#39;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; ignores urls (without a scheme)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;that don&amp;#39;t start with www.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;bounds&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;thing-at-point-bounds-of-url-at-point&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;when&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;bounds&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;bounds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;bounds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;buffer-substring-no-properties&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;car&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;bounds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;cdr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;bounds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/mpsyt-url&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;buffer&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;current-buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;mpsyt-proc-name&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;*mpsyt*&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;;; Start a new term with *mpsyt* if there isn&amp;#39;t one&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;unless&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;get-process&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;mpsyt-proc-name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;when&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;get-buffer&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;mpsyt-proc-name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;kill-buffer&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;get-buffer&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;mpsyt-proc-name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ansi-term&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;mpsyt&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;mpsyt&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;;; Play given url in mpsyt&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;mpsyt-proc&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;get-process&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;mpsyt-proc-name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;c1&#34;&gt;;; If something is already playing, stop it and play this...&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;term-send-string&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;mpsyt-proc&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;\n\n\n&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;c1&#34;&gt;;; We wait for a bit, since looking for the prompt seems to fail, sometimes?&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;sleep-for&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;term-send-string&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;mpsyt-proc&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;c1&#34;&gt;;; Actually send the command to playurl&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;term-simple-send&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;get-process&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;mpsyt-proc-name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;format&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;playurl %s&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;switch-to-buffer&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/mpsyt-url-at-point&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;Play the URL at point using mpsyt.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interactive&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;url&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;url-get-url-at-point&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pc/short-url-at-point&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;No URL found&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;format&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Playing %s with mpsyt&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pc/mpsyt-url&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The current version of mpsyt crashes when run from inside emacs due to a bug in&#xA;the code to get the terminal size, which should be fixed once this &lt;a href=&#34;https://github.com/np1/mps-youtube/pull/247&#34;&gt;patch&lt;/a&gt; is&#xA;merged.&lt;/p&gt;&#xA;&lt;p&gt;I would&amp;rsquo;ve expected &lt;code&gt;thing-at-point-url-at-point&lt;/code&gt; to be able to find urls even&#xA;when they don&amp;rsquo;t have a schema, but it tries to guess the schema from urls and&#xA;fails to work when the url starts with &lt;code&gt;youtube.com&lt;/code&gt; instead of&#xA;&lt;code&gt;www.youtube.com&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;I started off using the command-line interface of &lt;code&gt;mpsyt&lt;/code&gt; by running it using&#xA;&lt;code&gt;shell-command&lt;/code&gt; or &lt;code&gt;start-process&lt;/code&gt;.  But, it seemed useful to have a buffer of&#xA;&lt;code&gt;mpsyt&lt;/code&gt; to switch to &amp;ndash; easier to search for new music, repeating songs, etc.&#xA;Not all tasks/actions are achievable through &lt;code&gt;mpsyt&lt;/code&gt;&amp;rsquo;s command line args.&lt;/p&gt;&#xA;&lt;p&gt;I ended up writing more code than I thought I would have to[1].  But, I&amp;rsquo;m&#xA;pretty happy with how this all works, right now.&lt;/p&gt;&#xA;&lt;p&gt;[1] - Isn&amp;rsquo;t it true, more often than not?&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>org-drill for making it stick!</title>
      <link>https://punchagan.muse-amuse.in/blog/org-drill-for-making-it-stick/</link>
      <pubDate>Sat, 17 Jan 2015 00:00:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/org-drill-for-making-it-stick/</guid>
      <description>&lt;p&gt;Those who read the &lt;a href=&#34;https://punchagan.muse-amuse.in/posts/learning-to-use-org-drill.html&#34;&gt;last&lt;/a&gt; &lt;a href=&#34;https://punchagan.muse-amuse.in/posts/learning-about-spaced-repetition-supermemo-org-drill-et-al.html&#34;&gt;few&lt;/a&gt; &lt;a href=&#34;https://punchagan.muse-amuse.in/posts/more-input-sources-for-org-drill.html&#34;&gt;posts&lt;/a&gt; here, would know that I have been&#xA;experimenting with &lt;a href=&#34;http://orgmode.org/worg/org-contrib/org-drill.html&#34;&gt;org-drill&lt;/a&gt; (a spaced repetition extension to &lt;a href=&#34;http://orgmode.org/&#34;&gt;Org mode&lt;/a&gt;).  I&#xA;have been using the system (almost) religiously for the past 2 months, and I do&#xA;find that it has helped a great deal! (in some respects).  I have also spent a&#xA;considerable amount of time trying to reduce the friction to put new stuff into&#xA;the system, and am constantly on the look out for further improvements.&lt;/p&gt;&#xA;&lt;p&gt;Using this system has definitely helped with retention, and I find that I can&#xA;recall quite a few things I have read a few weeks ago, that I would normally&#xA;have been unable to. Though, I can recall a lot of information, I have been&#xA;having a feeling of &amp;ldquo;fragmentation&amp;rdquo;: the feeling of just retaining individual&#xA;bits/fragments of information, while losing out on actually internalizing the&#xA;knowledge; not seeing the big picture, etc.&lt;/p&gt;&#xA;&lt;p&gt;Wozniak (the author of super-memo) &lt;a href=&#34;http://www.supermemo.com/articles/20rules.htm&#34;&gt;warns against&lt;/a&gt; learning without&#xA;understanding, and memorizing before actually learning stuff.  I haven&amp;rsquo;t&#xA;consciously added stuff into the system that I didn&amp;rsquo;t understand (when I added&#xA;it), but, later it does feel like I have lost some connections or the&#xA;understanding, and am only holding onto the fragments of information.&lt;/p&gt;&#xA;&lt;p&gt;The problems as explained in (read: as interpreted by me from) &lt;a href=&#34;http://www.amazon.com/Make-Stick-Science-Successful-Learning/dp/0674729013/ref=sr_1_1/188-6768042-2821103?ie=UTF8&amp;amp;qid=1421439099&amp;amp;sr=8-1&amp;amp;keywords=make+it+stick&amp;amp;pebp=1421439103302&amp;amp;peasin=674729013&#34;&gt;Make it Stick&lt;/a&gt;&#xA;appear to be:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;The understanding (if any) at the time of adding stuff into the&#xA;spaced-repetition system is untested.  It may just be familiarity&#xA;masquerading as understanding.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;The lack of any spaced repetitions for the overall concept/understanding and&#xA;actual repetitions only for individual bits doesn&amp;rsquo;t help retention of the&#xA;understanding (even if there was any, in the first place).&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;To work around this, I&amp;rsquo;m going to try adding questions that test understanding,&#xA;to the system.  The Super-memo team strongly recommends keeping the drill items&#xA;small and easy to answer.  This may be helpful in keeping each drill session&#xA;short, but I would really like to add conceptual questions to the system, and&#xA;see how it goes. I hacked &lt;code&gt;org-drill&lt;/code&gt; to allow me to type out answers, before&#xA;looking at the &amp;ldquo;correct&amp;rdquo; ones.  This is an adaptation of a system that a fellow&#xA;Hacker Schooler uses, and shared.  Also, hopefully forcing myself to type out&#xA;the answer will help me get around the problem of sometimes saying &amp;ldquo;yeah I know&#xA;that&amp;rdquo;, then looking at the answer only to reaffirm the feeling of familiarity,&#xA;rather than actually testing myself.  I&amp;rsquo;m still going to continue adding quick&#xA;and short questions that test &amp;ldquo;bits of information&amp;rdquo;, though. But, hopefully the&#xA;additional conceptual questions are going to tie things together and help fill&#xA;in the gaps.  Lets see how this goes!&lt;/p&gt;&#xA;&lt;p&gt;For those interested, my hacks to &lt;code&gt;org-drill&lt;/code&gt; below.  The code is really a&#xA;hack, and welcome any suggestions on cleaning up the code.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;advice-add&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;org-drill-presentation-prompt&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:around&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;pc/org-drill-presentation-prompt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/org-drill-presentation-prompt&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;old-fun&lt;/span&gt; &lt;span class=&#34;kp&#34;&gt;&amp;amp;rest&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fmt-and-args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;A presentation prompt that allows capturing answers.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;cb&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;current-buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;heading&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;nth&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-heading-components&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;entry-id&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-entry-get&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;point&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;ID&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;input&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;switch-to-buffer-other-window&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;*org-capture-drill-answer*&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;insert&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;# Hit C-c C-c once you are done answering!\n&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-insert-heading-respect-content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;insert&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;format&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Answer: %s&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;heading&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-entry-put&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;point&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;QUESTION_ID&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;entry-id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;goto-char&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;point-max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;insert&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;  &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-time-stamp-inactive&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;insert&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;\n\n  &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;input&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;equal&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;input&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;ignore-errors&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;execute-kbd-macro&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;input&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;read-key-sequence&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;switch-to-buffer-other-window&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;cb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;apply&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;old-fun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fmt-and-args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;advice-add&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;org-drill-reschedule&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;:around&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;pc/org-drill-reschedule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/org-drill-reschedule&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;old-fun&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;Calls the original reschedule, but also archives the answer&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;prog1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;funcall&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;old-fun&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;cb&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;current-buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;switch-to-buffer-other-window&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;*org-capture-drill-answer*&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pc/org-refile-to-datetree&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;drill.org_archive&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;buffer-name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;switch-to-buffer-other-window&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;cb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;kill-buffer&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;*org-capture-drill-answer*&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;org-datetree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/org-refile-to-datetree&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;journal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;Refile an entry to journal file&amp;#39;s date-tree&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interactive&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;fRefile to: &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;journal&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;expand-file-name&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;journal&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;date-string&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-entry-get&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;point&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;TIMESTAMP_IA&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                          &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-entry-get&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;point&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;TIMESTAMP&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;dct&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;decode-time&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;date-string&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-time-string-to-time&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;date-string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                               &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;current-time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;date&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;list&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;nth&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;dct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;nth&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;dct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;nth&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;dct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-cut-subtree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;with-current-buffer&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;find-buffer-visiting&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;journal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                             &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;find-file-noselect&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;journal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;save-excursion&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;org-datetree-file-entry-under&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-kill&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;bookmark-set&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;org-refile-last-stored&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Refiled to %s&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;journal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>How I learnt to use Emacs&#39; profiler</title>
      <link>https://punchagan.muse-amuse.in/blog/how-i-learnt-to-use-emacs-profiler/</link>
      <pubDate>Sat, 03 Jan 2015 02:01:17 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/how-i-learnt-to-use-emacs-profiler/</guid>
      <description>&lt;p&gt;I learnt to use Emacs&amp;rsquo; profiler yesterday, after many hours of yak-shaving,&#xA;trying to get &lt;a href=&#34;https://github.com/novoid/Memacs&#34;&gt;Memacs&lt;/a&gt; working.  Memacs is a &lt;a href=&#34;http://en.wikipedia.org/wiki/Memex&#34;&gt;memory extension&lt;/a&gt; system for Emacs&#xA;written by Karl Voit, that I have been meaning to try out for a long time now.&#xA;Seeing lots of review posts at the turn of the year and watching Karl&amp;rsquo;s recent&#xA;&lt;a href=&#34;http://emacslife.com/emacs-chats/chat-karl-voit.html&#34;&gt;Emacs Chat with Sacha Chua&lt;/a&gt; pushed me to try and finally set it up.&lt;/p&gt;&#xA;&lt;p&gt;I started writing a &lt;a href=&#34;https://github.com/punchagan/Memacs/blob/chrome/memacs/chromium.py&#34;&gt;module&lt;/a&gt; to create a Memacs file &amp;ndash; an org archive file &amp;ndash;&#xA;from my browser history.  It was pretty easy to write, and I had it spitting&#xA;out a huge file with 22k entries after about a couple of hours of work.  Then I&#xA;excitedly pulled up my agenda, and turned on the option to view archived&#xA;entries, only to be super-disappointed.  It turned out to be extremely slow!&#xA;Actually, the agenda never came up with the 22k entries file that I had. At&#xA;least not in 5 or so minutes, before I got impatient.  The performance was&#xA;unacceptable even when I reduced it to 5k entries.&lt;/p&gt;&#xA;&lt;p&gt;I was pretty sure it wasn&amp;rsquo;t that slow for Karl in his &lt;a href=&#34;https://www.youtube.com/watch?v=SaKPr4J0K2I#t=999&#34;&gt;demo&lt;/a&gt; and &lt;a href=&#34;https://twitter.com/punchagan/status/550723377871065088&#34;&gt;tweeted&lt;/a&gt; to him,&#xA;asking for a workaround. Meanwhile, I looked at his dot-emacs, but wasn&amp;rsquo;t able&#xA;to dig out what was needed to speed up things. He confirmed that his&#xA;performance was way better than what I was getting.&lt;/p&gt;&#xA;&lt;p&gt;First, I ruled out the possibility of it being because of the SSD, since&#xA;clearly my CPU usage was peaking, and the task was CPU bound and not I/O.&#xA;Next, I tried using the same file on a different machine (with a different&#xA;version of Emacs and org-mode), and it worked blazingly fast.  So, it was&#xA;either the version of Emacs or org-mode that I was using.&lt;/p&gt;&#xA;&lt;p&gt;I should have stopped, thought clearly, and started experimenting with org&#xA;version, but hindsight is 20-20.  I tried Ubuntu&amp;rsquo;s pre-built Emacs and agendas&#xA;were fast!  I suspected my Emacs build, since I recently started building Emacs&#xA;from git.  I built two or three other versions of Emacs, and wasted a lot of&#xA;time, before realizing that I wasn&amp;rsquo;t using the org-mode source bundled inside&#xA;Emacs for the tests, and there were two &amp;ldquo;independent&amp;rdquo; variables.&lt;/p&gt;&#xA;&lt;p&gt;Finally, I began bisecting org-mode&amp;rsquo;s source and found that all hell broke&#xA;loose with an &lt;a href=&#34;http://orgmode.org/w/?p=org-mode.git;a=commitdiff;h=b88c5464db2cb0d90d4f30e43b5e08d2b1c1fcea;hp=8cc4e09950594b2abec2502e9218318570595ac5&#34;&gt;inconspicuous change&lt;/a&gt; around release 8.2.6.  It turns out that&#xA;org-overview was broken before this, and collapsing all the trees in a newly&#xA;opened org-buffer (default option) wasn&amp;rsquo;t working. Once this bug was fixed,&#xA;opening huge org files would slow down by a great deal, in turn causing agenda&#xA;generation to be unbearably slow.&lt;/p&gt;&#xA;&lt;p&gt;All I had to do was add a &lt;code&gt;#+STARTUP: showeverything&lt;/code&gt; to the top of the file.&#xA;This speeded up things by about 50 times!  It turns out, I later found out,&#xA;that all of this is documented on &lt;a href=&#34;http://orgmode.org/worg/agenda-optimization.html&#34;&gt;Worg&lt;/a&gt;. I did try a few search engine queries,&#xA;but sadly none of them brought this up.  Adding the following to my config,&#xA;speeded up agenda generation by about 150-200 times!&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-agenda-inhibit-startup&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;;; ~50x speedup&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-agenda-use-tag-inheritance&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;;; 3-4x speedup&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the course of all this debugging, I learnt how to use Emacs&amp;rsquo; profiler.  The&#xA;profile reports along with git bisect, eventually helped me figure out what the&#xA;problem was.&lt;/p&gt;&#xA;&lt;p&gt;To profile the CPU usage, all you have to do is add a call like&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;profiler-start&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;cpu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;;; or M-x profiler-start&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;at the place where you wish to start it.  Emacs will then start collecting&#xA;information about where time is being spent, by sampling every&#xA;&lt;code&gt;sampling-interval&lt;/code&gt; seconds (default 10^6 nanoseconds = 1 milli second).&lt;/p&gt;&#xA;&lt;p&gt;You can view the information being collected, at any point of time using&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;profiler-report&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;;; or M-x profiler-report&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The report is a nice, interactive tree with the percentage of time spent in&#xA;each call. You can stop profiling by calling &lt;code&gt;(profiler-stop)&lt;/code&gt;.  If you have&#xA;more than one report, you can compare them by hitting &lt;code&gt;=&lt;/code&gt; in one of the report&#xA;buffers.  I&amp;rsquo;m definitely going to use this for other things! (like speeding up&#xA;my startup?)&lt;/p&gt;&#xA;&lt;p&gt;Now that I have Memacs working with reasonably fast agenda views, I&amp;rsquo;m looking&#xA;forward to collecting as much personal information as I can!  Thanks Karl for&#xA;writing Memacs.  I am going to be a pretty heavy user, I think!  There seem to&#xA;be a few rough edges, though, and I hope to help smoothen them out a little&#xA;bit, over the next few weeks.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Jabber message queue</title>
      <link>https://punchagan.muse-amuse.in/blog/jabber-message-queue/</link>
      <pubDate>Wed, 10 Dec 2014 00:00:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/jabber-message-queue/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve always wanted to be able to queue up messages to send to friends, until I&#xA;go online the next time.  I tried using email instead of chat a few times, or&#xA;just ended up staying online with a busy status.&lt;/p&gt;&#xA;&lt;p&gt;Finally, now that I have started using jabber-mode for chatting from within&#xA;Emacs, I took out the time to write a &amp;ldquo;queuing system&amp;rdquo; for sending chat&#xA;messages, similar to the mail queue for smtpmail.  Instead of persisting sexps,&#xA;though, I persist the messages in a JSON format and the queue is flushed every&#xA;time I connect to jabber, in a &lt;code&gt;jabber-post-connect-hook&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;To make the interface as similar to the interface available when I am online, I&#xA;hacked completion for the to ID using email addresses in my address book&#xA;(&lt;code&gt;mu4e~contact-list&lt;/code&gt;).  I really like the fact that the chat buffer opens up,&#xA;and I can type and send messages like I usually do.  Hitting &lt;kbd&gt;RET&lt;/kbd&gt; after typing&#xA;a message queues it up, instead of trying to send it. Smooth!&lt;/p&gt;&#xA;&lt;p&gt;The code is in my &lt;a href=&#34;https://github.com/punchagan/dot-emacs/blob/master/punchagan.org#jabber&#34;&gt;.emacs&lt;/a&gt;&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>erc-notifications when Emacs not in focus</title>
      <link>https://punchagan.muse-amuse.in/blog/erc-notifications-when-emacs-not-in-focus/</link>
      <pubDate>Thu, 06 Nov 2014 00:00:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/erc-notifications-when-emacs-not-in-focus/</guid>
      <description>&lt;p&gt;I have been trying to get ERC working with notifications. Julien Danjou&amp;rsquo;s&#xA;wonderful &lt;a href=&#34;https://julien.danjou.info/blog/2012/erc-notifications&#34;&gt;notifications&lt;/a&gt; module for ERC is great, but it is annoying to get&#xA;notifications even when Emacs is in focus.&lt;/p&gt;&#xA;&lt;p&gt;I had looked at &lt;a href=&#34;https://github.com/eqyiel/circe-notifications/blob/master/circe-notifications.el&#34;&gt;circe-notifications&lt;/a&gt;, which has the feature but uses xdotool and&#xA;xprop to do it.  I was looking for something simpler, though&amp;hellip; and it suddenly&#xA;struck me that I have an auto-save hook in Emacs that is run when I focus out&#xA;of it.  I wondered if I could disable and enable notifications on focus, and it&#xA;worked.&lt;/p&gt;&#xA;&lt;p&gt;In case it is useful for somebody else -&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;add-to-list&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;erc-modules&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;notifications&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;erc-notifications-mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;add-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;focus-out-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;erc-notifications-enable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;add-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;focus-in-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;erc-notifications-disable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I wonder if there are some corner cases where this doesn&amp;rsquo;t work, and that&amp;rsquo;s why&#xA;the author of circe-notifications chose the tools that he did.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>More input sources for org-drill</title>
      <link>https://punchagan.muse-amuse.in/blog/more-input-sources-for-org-drill/</link>
      <pubDate>Tue, 04 Nov 2014 00:00:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/more-input-sources-for-org-drill/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been trying to use &lt;code&gt;org-drill&lt;/code&gt; regularly for the last few weeks.  I don&amp;rsquo;t&#xA;know how well it&amp;rsquo;s been going but I have been sticking to the routine&#xA;religiously.  I haven&amp;rsquo;t yet really tried out incremental reading, but in an&#xA;attempt to make it as easy as possible, I wanted to have a pdf-reader&#xA;integration, and some kind of integration with Kindle highlights.  Browser&#xA;integration is pretty straight-forward, thanks to some &lt;a href=&#34;http://orgmode.org/worg/org-contrib/org-protocol.html#sec-6&#34;&gt;simple java-script&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;I looked for a pdf-reader with some sort of plugin support, but I found nothing&#xA;in Evince or Okular.  I thought about &lt;code&gt;pdfjs&lt;/code&gt; but it seemed slightly clunky to&#xA;open pdfs in a browser, though I might shift to this if I don&amp;rsquo;t like what I&#xA;finally ended up with.  Good old &lt;code&gt;xpdf&lt;/code&gt; seemed to be the only pdf reader that&#xA;had some support for custom keybindings that allowed users to run external&#xA;commands.  With a &lt;a href=&#34;https://github.com/punchagan/dot-emacs/blob/master/xpdf-capture&#34;&gt;little Python&lt;/a&gt;, I was able to setup a work-flow to capture&#xA;snippets from &lt;code&gt;xpdf&lt;/code&gt;, to add to org-drill. Custom key-bindings somehow don&amp;rsquo;t&#xA;seem to work on &lt;code&gt;xpdf&lt;/code&gt; bundled on Ubuntu. So, I ended up downloading and using&#xA;the binary available on the xpdf site.&lt;/p&gt;&#xA;&lt;p&gt;For Kindle highlights support, with minor updates to Thamer Mahmoud&amp;rsquo;s &lt;a href=&#34;https://github.com/punchagan/clip2org&#34;&gt;clip2org&lt;/a&gt;,&#xA;I have a simple way of getting all the &amp;ldquo;new&amp;rdquo; clippings/highlights as org-drill&#xA;headlines.  I haven&amp;rsquo;t really started using this, and once I do, I may end-up&#xA;automating even the merging of these items into the org-drill notes file.  I&amp;rsquo;m&#xA;looking forward to making better use of my Kindle, with this feature!&lt;/p&gt;&#xA;&lt;p&gt;I don&amp;rsquo;t know if it would be useful to have more context information like&#xA;section titles/chapter titles when capturing from html/pdf, but it seems like&#xA;an interesting problem to try to solve.&lt;/p&gt;&#xA;&lt;p&gt;Also, it might be easier(?) if I probably tried to have a DE level keybinding, and&#xA;some code to get selection and file name of the currently active&#xA;window/application.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Simple org-clock and gnome/pidgin integration</title>
      <link>https://punchagan.muse-amuse.in/blog/simple-org-clock-and-gnomepidgin-integration/</link>
      <pubDate>Wed, 22 Oct 2014 16:43:35 -0400</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/simple-org-clock-and-gnomepidgin-integration/</guid>
      <description>&lt;p&gt;&lt;strong&gt;See update &lt;a href=&#34;#orge999abb&#34;&gt;below&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;I have been trying to get back to using org-mode and its clocking&#xA;functionality, more often than not.  I used to use it a lot, a few years ago,&#xA;and haven&amp;rsquo;t been using it, since I had been in my last job.&lt;/p&gt;&#xA;&lt;p&gt;To help with it, I decided to integrate clocking in and out with changing&#xA;status on Pidgin, and turning notifications on and off in Gnome.  Here&amp;rsquo;s a few&#xA;lines of code that does this for me.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defadvice&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-clock-in&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;after&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/org-clock-in&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kp&#34;&gt;&amp;amp;optional&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;select&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;start-time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;Turn gnome notifications off.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;dbus-send-signal&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;nb&#34;&gt;:session&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;s&#34;&gt;&amp;#34;org.gnome.SessionManager&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;s&#34;&gt;&amp;#34;/org/gnome/SessionManager/Presence&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;s&#34;&gt;&amp;#34;org.gnome.SessionManager.Presence&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;s&#34;&gt;&amp;#34;SetStatus&amp;#34;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;shell-command&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;purple-remote setstatus?status=unavailable&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defadvice&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;org-clock-out&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;after&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/org-clock-out&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kp&#34;&gt;&amp;amp;optional&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;switch-to-state&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fail-quietly&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;at-time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;Turn gnome notifications back on.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;dbus-send-signal&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;nb&#34;&gt;:session&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;s&#34;&gt;&amp;#34;org.gnome.SessionManager&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;s&#34;&gt;&amp;#34;/org/gnome/SessionManager/Presence&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;s&#34;&gt;&amp;#34;org.gnome.SessionManager.Presence&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;s&#34;&gt;&amp;#34;SetStatus&amp;#34;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;shell-command&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;purple-remote setstatus?status=available&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;update-span-class-timestamp-wrapper-span-class-timestamp-and-lt-2014-11-01-sat-and-gt-span-span&#34;&gt;Update &lt;span class=&#34;timestamp-wrapper&#34;&gt;&lt;span class=&#34;timestamp&#34;&gt;&amp;lt;2014-11-01 Sat&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;http://baali.muse-amuse.in&#34;&gt;@baali&lt;/a&gt; tried to use my code, and it turns out it didn&amp;rsquo;t work for him, because I&#xA;forgot to mention that &lt;code&gt;(ad-activate &#39;org-clock-in)&lt;/code&gt; needs to be run, after the&#xA;&lt;code&gt;defadvice&lt;/code&gt; code.  I have no idea how it worked for me, without doing that.&#xA;May be because I have &lt;code&gt;defadvice&lt;/code&gt; for other functions?&lt;/p&gt;&#xA;&lt;p&gt;Also, while debugging this, I found that &lt;code&gt;defadvice&lt;/code&gt; is a deprecated way of&#xA;doing this, and &lt;code&gt;add-function&lt;/code&gt; is the way to go now.  But, instead of advising&#xA;the function, I decided to make use of &lt;code&gt;org-clock-in-hook&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Here is the new code.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/turn-off-notifications&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;Turn gnome notifications off.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;dbus-send-signal&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;nb&#34;&gt;:session&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;s&#34;&gt;&amp;#34;org.gnome.SessionManager&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;s&#34;&gt;&amp;#34;/org/gnome/SessionManager/Presence&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;s&#34;&gt;&amp;#34;org.gnome.SessionManager.Presence&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;s&#34;&gt;&amp;#34;SetStatus&amp;#34;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;shell-command&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;purple-remote setstatus?status=unavailable&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;pc/turn-on-notifications&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s&#34;&gt;&amp;#34;Turn gnome notifications back on.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;dbus-send-signal&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;nb&#34;&gt;:session&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;s&#34;&gt;&amp;#34;org.gnome.SessionManager&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;s&#34;&gt;&amp;#34;/org/gnome/SessionManager/Presence&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;s&#34;&gt;&amp;#34;org.gnome.SessionManager.Presence&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;s&#34;&gt;&amp;#34;SetStatus&amp;#34;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;shell-command&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;purple-remote setstatus?status=available&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;add-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;org-clock-in-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;pc/turn-off-notifications&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;add-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;org-clock-out-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;pc/turn-on-notifications&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>Learning to use Org-drill</title>
      <link>https://punchagan.muse-amuse.in/blog/learning-to-use-org-drill/</link>
      <pubDate>Tue, 14 Oct 2014 00:07:04 -0400</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/learning-to-use-org-drill/</guid>
      <description>&lt;p&gt;Org-drill is an Org-mode extension that provides spaced-repetition and&#xA;flash-card functionality.  It has a &lt;a href=&#34;http://orgmode.org/worg/org-contrib/org-drill.html&#34;&gt;wonderful documentation on Worg&lt;/a&gt;, but&#xA;somehow I couldn&amp;rsquo;t get myself to read the whole document, and setup org-drill,&#xA;until now.&lt;/p&gt;&#xA;&lt;p&gt;The setup is quite straight forward, once you have org-mode along with the&#xA;&lt;code&gt;contrib&lt;/code&gt; packages.  Just &lt;code&gt;(require &#39;org-drill)&lt;/code&gt;, and you are all set!  To add&#xA;a new card, all you need to do is add a &lt;code&gt;:drill:&lt;/code&gt; tag to the items you wish to&#xA;&amp;ldquo;Org-drill&amp;rdquo;.  You can start a review session with simply &lt;kbd&gt;M-x org-drill&lt;/kbd&gt;.  You&#xA;will be shown flash cards, and you can rate how correct and comfortable you&#xA;were, in answering the questions.  Based on your responses, the cards are&#xA;scheduled for review.  Start another review session, whenever you need one!&lt;/p&gt;&#xA;&lt;p&gt;What I could only understand once I got myself to read the whole document was&#xA;that:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;The default scope of a drill session is the current file.  But, you can start&#xA;sessions with scopes like current tree, current directory, or a specified&#xA;list of files. This is super-useful!&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;The review sessions are not automatically scheduled, based on when you&#xA;schedule failed flash-cards.  Scheduling the review for a card only sets a&#xA;due-date for them, and effects, what you are asked in your next session.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Cram mode and incremental reading are also things I want to try, as I go along.&lt;/p&gt;&#xA;&lt;p&gt;Happy Learning!&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Recurse Center, 2014-08-08</title>
      <link>https://punchagan.muse-amuse.in/recurse-center/recurse-center-2014-08-08/</link>
      <pubDate>Sat, 09 Aug 2014 20:56:22 -0400</pubDate>
      <guid>https://punchagan.muse-amuse.in/recurse-center/recurse-center-2014-08-08/</guid>
      <description>&lt;ul&gt;&#xA;&lt;li&gt;I spent the morning doing some white-boarding interview practice with a Jorge&#xA;and Brian.&lt;/li&gt;&#xA;&lt;li&gt;I spent the rest of the day, playing with PyPy and working through &lt;a href=&#34;http://morepypy.blogspot.in/2011/04/tutorial-writing-interpreter-with-pypy.html&#34;&gt;a tutorial&lt;/a&gt;&#xA;that teaches us to write a BF interpreter.&lt;/li&gt;&#xA;&lt;li&gt;I spent the Saturday revamping my Emacs config.  The main issue with my&#xA;config was having a &amp;ldquo;package&amp;rdquo; list, of all the packages that the&#xA;configuration uses, in case we are trying to duplicate it elsewhere.  I&#xA;noticed that this gets out of sync, because I install packages by hand and&#xA;never update this list.  I wrote up &lt;a href=&#34;https://github.com/punchagan/dot-emacs/blob/master/user-lisp/setup-defuns.el&#34;&gt;some code&lt;/a&gt;, that keeps this list in sync&#xA;with all the packages I have installed.  I configured el-get to play well&#xA;with my config, and am pretty happy with my setup, though I still have to add&#xA;some matching/searching features with helm/ido/whatever else.&lt;/li&gt;&#xA;&lt;li&gt;I spent the Sunday writing a patch to &lt;a href=&#34;https://github.com/punchagan/xtab/tree/kill-by-memory&#34;&gt;xtab&lt;/a&gt; to be able to limit the number of&#xA;tabs in Chromium by the memory it uses.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</description>
    </item>
    <item>
      <title>Org based posts in Nikola</title>
      <link>https://punchagan.muse-amuse.in/blog/org-based-posts-in-nikola/</link>
      <pubDate>Sun, 20 Apr 2014 00:00:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/org-based-posts-in-nikola/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://binchen.org/&#34;&gt;Chen Bin&lt;/a&gt; asked me to share my Nikola+Org work-flow, and share an&#xA;example post.&lt;/p&gt;&#xA;&lt;p&gt;The org source for any post can be found by changing the URL of a post&#xA;from &lt;code&gt;.html&lt;/code&gt; to &lt;code&gt;.org&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;I don&amp;rsquo;t have much of a work-flow, because I don&amp;rsquo;t post too often, but&#xA;here is what I typically do, to make a new post.&lt;/p&gt;&#xA;&lt;p&gt;I start off by creating a new post using&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ nikola new_post&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and then give the post a title and start editing the post in Emacs.&lt;/p&gt;&#xA;&lt;p&gt;I have a simple snippet that lets me insert tags, based on existing&#xA;tags.&lt;/p&gt;&#xA;&lt;script src=&#34;https://gist.github.com/6629020.js&#34;&gt;&lt;/script&gt;&#xA;&lt;p&gt;Once I&amp;rsquo;m happy with the content of a post, I run &lt;code&gt;nikola auto&lt;/code&gt; to&#xA;build the source and serve it locally, and see if the post &amp;ldquo;looks&amp;rdquo;&#xA;reasonable, after being rendered.&lt;/p&gt;&#xA;&lt;p&gt;Once, I&amp;rsquo;m happy with it, I commit the post and deploy it using &lt;code&gt;nikola deploy&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;I also have a plugin, that posts captured bookmarks and quotes onto&#xA;the blog, with a single command. I should probably make the sources of&#xA;my blog open, and push it onto GitHub.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Update &lt;span class=&#34;timestamp-wrapper&#34;&gt;&lt;span class=&#34;timestamp&#34;&gt;[2015-05-13 Wed]&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;I use my own &lt;a href=&#34;https://plugins.getnikola.com/#orgmode&#34;&gt;plugin&lt;/a&gt; for Nikola which lets me write posts in org-mode.  There&#xA;is a similar &lt;a href=&#34;https://github.com/redguardtoo/org2nikola&#34;&gt;plugin&lt;/a&gt; by Chen Bin, that exports posts to intermediate html,&#xA;that is then used by Nikola.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;The source for my blog is now on &lt;a href=&#34;https://github.com/punchagan/punchagan.muse-amuse.in&#34;&gt;GitHub&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;I also have &lt;a href=&#34;https://github.com/punchagan/dot-emacs/blob/master/punchagan.org#nikola-stuff&#34;&gt;custom elisp&lt;/a&gt; to be able to make a new post, and deploy the site&#xA;from within Emacs.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</description>
    </item>
    <item>
      <title>Org-mode Workshop</title>
      <link>https://punchagan.muse-amuse.in/blog/org-mode-workshop/</link>
      <pubDate>Wed, 22 Jun 2011 00:00:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/org-mode-workshop/</guid>
      <description>&lt;p&gt;Well, I&amp;rsquo;m not sure if it&amp;rsquo;s worth writing about.  I conducted my&#xA;first org-mode workshop along with Prof. Venkatesh Choppella at&#xA;IIIT-Hyderabad.  It was a 3 hour demo+talk kind of a thing, with a&#xA;small audience of about 20 people, most of whom were new to&#xA;Emacs.&lt;/p&gt;&#xA;&lt;p&gt;We covered almost all the aspects of Org-mode after giving a brief&#xA;introduction to Emacs.  Outlining and note-taking part was simple&#xA;and easy to understand, but the audience couldn&amp;rsquo;t really&#xA;appreciate the part of keeping TODO lists and agendas and other&#xA;stuff.  I&amp;rsquo;m hoping, the reason was not me taking over from&#xA;Venkatesh.&lt;/p&gt;&#xA;&lt;p&gt;I think the workshop should&amp;rsquo;ve been more hands-on and we should&amp;rsquo;ve&#xA;asked people to try out stuff on the spot, instead of showing off&#xA;the things possible with Emacs.  They probably would&amp;rsquo;ve&#xA;appreciated a few things better, that way.&lt;/p&gt;&#xA;&lt;p&gt;Hopefully, we will be doing more workshops on Org-mode and there&#xA;are surely somethings to take away from this one.  I hope at least&#xA;one of the participants, gets hooked to Org-mode.&lt;/p&gt;&#xA;&lt;p&gt;The talk outline is here.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Git powered wikis improved: My bit</title>
      <link>https://punchagan.muse-amuse.in/blog/git-powered-wikis-improved-my-bit/</link>
      <pubDate>Fri, 04 Feb 2011 00:00:00 +0530</pubDate>
      <guid>https://punchagan.muse-amuse.in/blog/git-powered-wikis-improved-my-bit/</guid>
      <description>&lt;p&gt;I accidentally came across the blog-post Git-powered wikis&#xA;improved - GitHub. And this particular paragraph caught my&#xA;eye:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;The new editor has the capability to support every markup&#xA;language that GitHub Wikis support. If you&amp;rsquo;re a fan of Markdown,&#xA;Textile, pod or RDoc, the function bar buttons (e.g. bold,&#xA;italic, underline, etc.) will now work. We&amp;rsquo;ve even written brand&#xA;new inline help for many of GitHub Wiki&amp;rsquo;s supported markup&#xA;languages.&lt;/p&gt;&#xA;&lt;p&gt;The language definitions the editor uses are JSON-based and easy&#xA;to edit. If you&amp;rsquo;d like us to support a markup language that we&#xA;don&amp;rsquo;t currently support, Gollum, GitHub&amp;rsquo;s wiki software, is&#xA;entirely open source &amp;ndash; fork our code and send us a pull request&#xA;with changes that support your choice language.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;I sent a quick patch for org-mode in the function bar, and it has&#xA;been accepted.  :)&lt;/p&gt;&#xA;&lt;p&gt;If not anything more, I hope, at least a couple of curious people&#xA;will explore org-mode and find it useful.&lt;/p&gt;&#xA;</description>
    </item>
  </channel>
</rss>
