<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>hi, it&#39;s mike</title>
    <link>https://mike.puddingtime.org/tags/literateprogramming/</link>
    <description>Recent content on hi, it&#39;s mike</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <managingEditor>mike@puddingtime.org (mike)</managingEditor>
    <webMaster>mike@puddingtime.org (mike)</webMaster>
    <copyright>© 2026, mike</copyright>
    <lastBuildDate>Wed, 05 Apr 2023 08:53:21 -0700</lastBuildDate>
    <atom:link href="https://mike.puddingtime.org/tags/literateprogramming/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>First stab at literate config with Doom Emacs</title>
      <link>https://mike.puddingtime.org/posts/2023-04-05-first-stab-at-literate-config/</link>
      <pubDate>Wed, 05 Apr 2023 08:53:21 -0700</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-04-05-first-stab-at-literate-config/</guid>
      <description>&lt;p&gt;My historic pattern for descending into Emacs hell has always started with the kitchen-sink init, and the path to recovery has always involved a patient refactoring into multiple files: Some kind of &amp;ldquo;the basics,&amp;rdquo; something just for org, something for odd little quality of life things, and a quarantine file where new stuff can enjoy a probation period where I can bisect it first when something goes wrong. If I add a big chunk of functionality from a new mode, that might get its own file, too.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>My historic pattern for descending into Emacs hell has always started with the kitchen-sink init, and the path to recovery has always involved a patient refactoring into multiple files: Some kind of &ldquo;the basics,&rdquo; something just for org, something for odd little quality of life things, and a quarantine file where new stuff can enjoy a probation period where I can bisect it first when something goes wrong. If I add a big chunk of functionality from a new mode, that might get its own file, too.</p>
<p>That has always helped me feel a little in control, at least.</p>
<p>I noticed Doom Emacs has a <code>literate</code> module in its <code>init.el</code>, so I did some reading. The very high level summary is that Doom lets you use <a href="https://en.wikipedia.org/wiki/Literate_programming">literate programming</a> principles via org-mode to build your <code>config.el</code> file from an org file:</p>
<ul>
<li>You enclose your actual configuration code in src blocks:</li>
</ul>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="c1">#+begin_src emacs-lisp</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="n">setq</span> <span class="n">doom</span><span class="o">-</span><span class="n">font</span> <span class="p">(</span><span class="n">font</span><span class="o">-</span><span class="n">spec</span> <span class="p">:</span><span class="n">family</span> <span class="s2">&#34;Fira Code Retina&#34;</span> <span class="p">:</span><span class="n">size</span> <span class="mi">14</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">      <span class="n">doom</span><span class="o">-</span><span class="n">variable</span><span class="o">-</span><span class="n">pitch</span><span class="o">-</span><span class="n">font</span> <span class="p">(</span><span class="n">font</span><span class="o">-</span><span class="n">spec</span> <span class="p">:</span><span class="n">family</span> <span class="s2">&#34;Fira Sans&#34;</span> <span class="p">:</span><span class="n">size</span> <span class="mi">13</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="c1">#+end_src</span></span></span></code></pre></div>
<p>&hellip; and those blocks are &ldquo;tangled&rdquo; into a <code>config.el</code> file.</p>
<p>You get to use all of org-mode&rsquo;s affordances for document structure, so you can add headings, and your comments can just be prose:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="o">**</span> <span class="n">Base</span> <span class="n">Appearance</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">***</span> <span class="n">Line</span> <span class="n">spacing</span> 
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">#+begin_src emacs-lisp</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="n">setq</span><span class="o">-</span><span class="n">default</span> <span class="n">line</span><span class="o">-</span><span class="n">spacing</span> <span class="mf">0.5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1">#+end_src</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">***</span> <span class="ne">Font</span> <span class="n">Settings</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">#+begin_src emacs-lisp</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="n">setq</span> <span class="n">doom</span><span class="o">-</span><span class="n">font</span> <span class="p">(</span><span class="n">font</span><span class="o">-</span><span class="n">spec</span> <span class="p">:</span><span class="n">family</span> <span class="s2">&#34;Fira Code Retina&#34;</span> <span class="p">:</span><span class="n">size</span> <span class="mi">14</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">      <span class="n">doom</span><span class="o">-</span><span class="n">variable</span><span class="o">-</span><span class="n">pitch</span><span class="o">-</span><span class="n">font</span> <span class="p">(</span><span class="n">font</span><span class="o">-</span><span class="n">spec</span> <span class="p">:</span><span class="n">family</span> <span class="s2">&#34;Fira Sans&#34;</span> <span class="p">:</span><span class="n">size</span> <span class="mi">13</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="c1">#+end_src</span></span></span></code></pre></div>
<p>So this morning I moved my still-pretty-simple <code>config.el</code> into <code>config.org</code> to see what I thought.</p>
<p>It&rsquo;s pretty cool!</p>
<p>The traditional ugliness of Emacs configs, for me, has always been the slow drift out of organization. Maybe for a while all the UI stuff, personalization stuff, appearance stuff is traveling together, but something makes its way in at the bottom of the file, then something else, and you&rsquo;re left with a bunch of things that aren&rsquo;t near their logical neighbors. There are the things you comment out that just become a big chunk of &hellip; something &hellip; it&rsquo;s hard to read because they aren&rsquo;t syntax highlighted anymore. There&rsquo;s verbose documentation that makes it hard to scan. etc.</p>
<p>Literate config in Emacs allows you to bring semantically meaningful structure to the configuration file: Broad categories of options can go under headings, commentary is written as prose, and you can use all of org mode&rsquo;s structure editing tools to quickly move chunks of configuration around into a more readable, logical order.</p>
<p>Doom&rsquo;s default <code>config.el</code> comes with a ton of comments. I&rsquo;m glad they&rsquo;re there when I need them, I hate having to scroll through and past them. Moving everything into <code>config.org</code> let me just move the comments into a <code>Docs</code> heading for each section, so they stay folded away unless I need them.</p>
<p>I&rsquo;ve got a few chunks of config that need some work. I can research how to use a given module, toss in reference links and sample snippets, and only allow certain code blocks to be compiled into my final <code>config.el</code>.</p>
<p>And I can also evaluate a src block by hitting <code>enter</code> on the last line of the block, so if you&rsquo;re in an iterative mode, trying things out and testing them, it&rsquo;s a few keystrokes less to make sure something evaluates cleanly, returns the value I was hoping for, etc.</p>
<p>I&rsquo;ve known about literate programming in the context of org for a while. A very long while ago, when I was first playing around with web analytics reporting, I had some simple code blocks embedded in an org file that allowed me to pull basic website numbers into my org file by getting the output of a script. That could all then be exported into a status report.  It was cool but also trivial. It didn&rsquo;t feel like a huge quality of life improvement. This feels like something that, with very little time spent getting it into basic shape, will be more maintainable over time. It&rsquo;s easy to see where to insert something in the document, so things are more likely to stay organized,  and it&rsquo;s easy to test.</p>
<p>It was very little work to set up in the Doom Emacs context:</p>
<ol>
<li>I enabled the functionality in <code>init.el</code> by uncommenting <code>literate</code></li>
<li>I copied my <code>config.el</code> file into <code>config.org</code> wholesale.</li>
<li>I put every config stanza under a level 2 heading to start.</li>
<li>Short (5 lines or fewer) comments became leading prose blocks.</li>
<li>Long comments went into level 3 <code>Docs</code> subheads.</li>
<li>I collapsed my view to headings only and  moved everything related to each other into proximity of each other with org&rsquo;s section up/down keys.</li>
<li>I added top-level headings for basic config, my more extensive org mode stuff, and utility functions.</li>
</ol>
<p>I&rsquo;m still building up my Doom config, so it didn&rsquo;t take long. Maybe 15 minutes to get to something much more easy to scan:</p>
<p><img src="/img/org-config.jpg" alt="Screenshot of an org-based config file&rsquo;s heading hierarchy"></p>
<p>Sitting here thinking about it, I guess it reminds me a little of the first time I sat down and wrote a real Puppet manifest for a real purpose and not a &ldquo;how does this thing work?&rdquo; purpose. It felt like clarity was emerging from the writing process.</p>
<p>Seems like a keeper.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
