<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss"
        xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
        xmlns:media="http://search.yahoo.com/mrss/"><channel>
<title>Matt Duck</title>
<atom:link href="https://www.mattduck.com/feed.xml" rel="self" type="application/rss+xml" />
<link>https://www.mattduck.com</link>
<description><![CDATA[Feed for https://www.mattduck.com]]></description>
<language>en</language>
<pubDate>Fri, 08 Nov 2024 08:06:05 +0000</pubDate>
<lastBuildDate>Fri, 08 Nov 2024 08:06:05 +0000</lastBuildDate>
<generator>Emacs 29.3 Org-mode 9.6</generator>
<webMaster>hi@mattduck.com (Matt Duck)</webMaster>
<image>
<url>/</url>
<title>Matt Duck</title>
<link>https://www.mattduck.com</link>
</image>


<item>
<title>Why I write commit messages</title>
<link>https://www.mattduck.com/2023-09-04-git-commit-messages.html</link>
<author>hi@mattduck.com (Matt Duck)</author>
<guid isPermaLink="false">14842E3C-F162-4A54-82E0-95884B961588</guid>
<pubDate>Mon, 04 Sep 2023 13:35:00 +0100</pubDate>

<description><![CDATA[
<div id="outline-container-org031fb11" class="outline-3">
<h3 id="org031fb11"><span class="section-number-3">1.1.</span> Intro</h3>
<div class="outline-text-3" id="text-1-1">
<p>
When I'm working on professional software projects, I like to include git commit
messages for my changes. From my experience so far<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, most engineers do <i>not</i> write commit messages at
work, but I've always found it hard to see a strong argument against doing it.
</p>

<p>
What do I mean by a commit message? I <i>don't</i> mean using <code>git commit -m</code> to add
a one-line subject like <code>fix: #123 fix db null issue</code>. I mean letting <code>git
commit</code> open your <code>$EDITOR</code> and typing in sentences or bullet points to write a body for
the message, similar to how you'd include a description in your pull requests.
</p>

<p>
I've written messages for a lot of the changes I've made in my software career
so far, and I find myself doing it more as time goes on. Coming into my first
proper software job, I had read content like Tim Pope's<sup><a id="fnr.2" class="footref" href="#fn.2" role="doc-backlink">2</a></sup> post on <a href="https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html">writing well-formed commit messages</a>, and I assumed
that other engineers were going to expect this of me, because it sounded like a
sensible professional practice. This turned out to be wrong: amongst the
engineers I've worked with &#x2013; good and bad, from CTOs to interns &#x2013; hardly anyone
ever includes a message body in their commits.
</p>

<p>
This post will run through the kind of things I write about, why I find it
useful, and some arguments against writing messages.
</p>
</div>
</div>

<div id="outline-container-org1fc24b5" class="outline-3">
<h3 id="org1fc24b5"><span class="section-number-3">1.2.</span> What I write in the message</h3>
<div class="outline-text-3" id="text-1-2">
<p>
I try to focus on providing the most important context that can't quickly be
inferred from the diff. I'm writing for two audiences: the engineers I'm working
with now, and unknown readers in the future. I don't know who the future reader
will be or how much they already know, so I don't assume much existing
familiarity. I also try to lay things out clearly and explicitly, just in case
they're trying to debug a production issue late at night.
</p>
</div>

<div id="outline-container-orgbcca19a" class="outline-4">
<h4 id="orgbcca19a">Changes, context, other considerations</h4>
<div class="outline-text-4" id="text-orgbcca19a">
<p>
I usually focus on three things:
</p>

<ul class="org-ul">
<li><b>What I'm changing</b>: yes, this is <i>technically</i> described in the code, but if
your change is more than a couple of lines, it puts a lot of work on the reader
to make them figure it out from the diff, and that gets amplified if the reader
is looking at multiple commits. And, the literal code committed won't
necessarily have the impact you were trying to make, so it's helpful to describe
the <i>intent</i> of the change.</li>

<li><b>Context for why I'm making the change</b>: the "why" is often harder to infer than
the "what", so requires some description. I try not to just link to tickets,
because again that puts all the work on the reader.</li>

<li><b>Considerations for the reader or for code review</b>: the risks of merging the
change, gotchas, anything non-obvious that's worth highlighting. I
try to make it explicit if there are parts of the change that I'm unsure about
or don't understand well, or if I intend to follow up this change with further
work.</li>
</ul>

<p>
I often format the message to show the what vs why vs other considerations
separately, as this makes it easy to read at a glance, and it's also a nice
format to copy straight into a PR description.
</p>
</div>
</div>

<div id="outline-container-orgd25483c" class="outline-4">
<h4 id="orgd25483c">Examples</h4>
<div class="outline-text-4" id="text-orgd25483c">
<p>
This is the kind of thing I'll write. I've made these up, but they're inspired
by changes that I worked on in past roles:
</p>
</div>

<div id="outline-container-orgff38eb4" class="outline-5">
<h5 id="orgff38eb4">Mitigating a production issue</h5>
<div class="outline-text-5" id="text-orgff38eb4">
<pre class="example" id="org0adff1c">
fix: IM-456 change error handling order to defend OOMs and similar

Changes:
- In the main ingestion process, change the processing order to exit
  early: fetch the job, check if it's been taken off the queue more than
  3 times already, and if so bury it straight away instead of trying to
  process it.

Context:
- New payloads from account X are causing this process to OOM when we
  try to update their customer list. The way error handling was working
  was a big try/except: if it errors, catch the exception, and check if
  we've attempted the job more than 3 times, then bury it. This was
  problematic because the OOM was preventing us from ever hitting the
  "bury it" stage.

- This is currently affecting production and significantly decreasing
  throughput of the ingestion pipeline because the process keeps picking
  these messages up and OOMing. In theory burying should be our
  dead-letter solution but it's preventing that. Need to fix ASAP.

Considerations:
- One consequence I'm unsure about: we do this thing where we catch
  postgres lock exceptions and retry them indefinitely. They will now
  only retry 3 times -- what's the impact of that? We're pretty happy
  that it's safe temporarily.

- I've NOT deleted the old code as part of this. I want to minimise
  surface area of this change to reduce risk as test coverage isn't
  great.

- Alternate investigation ongoing: what is causing the OOM and how do we
  fix it. That's a bigger change.
</pre>
</div>
</div>

<div id="outline-container-orgd59f198" class="outline-5">
<h5 id="orgd59f198">A basic refactor</h5>
<div class="outline-text-5" id="text-orgd59f198">
<pre class="example" id="orgd85bc69">
refactor(corelibs): DEF-789 move functions from helpers to lib

Changes:
- Move the db and error helper files to live in the lib directory.

- Delete the helpers directory.

- While I'm here, delete a few old util functions that aren't used.

Context:
- We have three separate places that we use to store util functions. The
  duplication is confusing and it's not clear if there's a difference
  between them or where we should put new functions. Nobody is sure, so
  this removes one of them to start simplifying.

Considerations:
- More work to do here, I'm just starting it as I have a spare 30
  mins. This at least moves it in a more sensible direction.
</pre>
</div>
</div>

<div id="outline-container-org1804d3a" class="outline-5">
<h5 id="org1804d3a">A performance improvement</h5>
<div class="outline-text-5" id="text-org1804d3a">
<pre class="example" id="orga747512">
perf(shipments): ABC-123 improve latency of shipments SQL query

Changes:
- In the SQL query used to power the shipments page, pull the aggregate
  subquery up into the top-level query.

Context:
- This allows postgres to optimize by only running the JSON aggregation
  functions on the selected rows, instead of on the whole underlying
  tables.

- The result on prod data is that loading the base report on account X
  I see a decrease from ~400ms to ~40ms, and it improves the more you
  narrow the base query. If I add filtering for the "customer segment"
  attribute, the difference becomes 400ms vs 1ms.

Considerations:
- I've used `select * from old_version except select * from new_version`
  to confirm these return the same results. If tests pass I see no risk.

- We see regressions on this query sometimes - really need to get some
  performance testing in place to prevent that, but that's out of scope
  here.
</pre>
</div>
</div>
</div>

<div id="outline-container-org4c270cf" class="outline-4">
<h4 id="org4c270cf">Things not to care about</h4>
<div class="outline-text-4" id="text-org4c270cf">
<p>
Some of the more prominent commit message advice is based around formatting:
writing in a particular tense, keeping subjects at 50 characters, bodies at 72
characters, etc. Personally I like to see that consistency, but it's not where
the value is, and if anything it creates barriers to entry if you're dogmatic
about message style. You have to pick your battles when collaborating at work,
and as long as someone doesn't <i>break</i> standard git tools, then the part that's
valuable is providing the information.
</p>
</div>
</div>
</div>

<div id="outline-container-orgc7dfd94" class="outline-3">
<h3 id="orgc7dfd94"><span class="section-number-3">1.3.</span> How I find commit messages useful</h3>
<div class="outline-text-3" id="text-1-3">
<p>
So, we have a git log filled with these messages&#x2026; why is this useful? Over the
years I've seen various benefits:
</p>
</div>

<div id="outline-container-org8ce0f78" class="outline-4">
<h4 id="org8ce0f78">Knowing my past intentions</h4>
<div class="outline-text-4" id="text-org8ce0f78">
<p>
Even if nobody else read my commits, I would continue to write messages for
myself. I will <i>not</i> remember every change I worked on in a few months, let
alone a few years, so it's helpful to have those messages from the past. If I
think my old code is terrible, then I can hit git blame or read the log for that
file, and see that I articulated a particular reason for doing it that way two
years ago &#x2013; or more likely, see that there wasn't a good reason and the code
really is just terrible. Either way it helps me make better decisions.
</p>

<p>
Another consequence of this is that reading a proper description jogs my memory
a lot more than looking at a one-line link to a ticket number. Or, sometimes the
reverse happens: a colleague will ask me a question, and I won't remember the
exact answer but I'll remember that I worked on the relevant code change and I
can <i>find</i> the answer quickly by grepping the git log.
</p>
</div>
</div>

<div id="outline-container-orge171bc4" class="outline-4">
<h4 id="orge171bc4">Providing context for other engineers</h4>
<div class="outline-text-4" id="text-orge171bc4">
<p>
Commit messages scale nicely, not just through time, but also out to a lot of
people: the messages are useful for other engineers who don't know what was in
my head when I made the change.
</p>

<p>
I believe there should be professional expectation amongst software engineers
that we'll provide <i>some</i> context for our changes somewhere. There's nothing
more annoying than being confused about a piece of code that's breaking
production, and finding the author made absolutely no effort to communicate what
the change was and why it was made: no commit message, no PR description, no
detail on the ticket, no code comments, no documentation, and they left the
company last month &#x2013; great, I guess I'll spend the rest of my day figuring that
out then. Better hope this is happening at 10am and not 10pm.
</p>

<p>
My hope with my own work is that, if I'm away, and even if it's a few years on,
other engineers on the team will have an easily-accessible window into some of
my rationale and thought process: what I was trying to do, why I was trying to
do it, risks I knew about, anything I thought was non-obvious at the time. My
reasons might hold up, they might not &#x2013; what's important is that <i>other
engineers can see what I was thinking</i>.
</p>

<p>
This is especially important if the team has low confidence when making code
changes: maybe the relevant experts have left, or there's legacy sections of the
codebase that haven't been changed for a few years, or test coverage isn't good
enough to provide certainty when refactoring code, or there's an ongoing
incident and everyone is anxious about pushing the right fix. Again, the benefit
is being able to make better decisions &#x2013; quicker and with more confidence &#x2013;
because you have immediate access to information that improves your
understanding of the situation.
</p>
</div>
</div>

<div id="outline-container-orgd13cb42" class="outline-4">
<h4 id="orgd13cb42">Looking back at accomplishments</h4>
<div class="outline-text-4" id="text-orgd13cb42">
<p>
This is another personal benefit. If I run <code>git log --author=duck</code>, I see a
clear chronological list of all the code changes I've made on a project, with
much higher fidelity than I could possibly provide if I had only written a
one-line subject.
</p>

<p>
I find this a useful tool for understanding what I've actually done this
quarter, or year, or even in my time at a company<sup><a id="fnr.3" class="footref" href="#fn.3" role="doc-backlink">3</a></sup>. Whenever I've
left a job, I've always checked the git logs shortly before leaving, and each
time I've found changes that I had forgotten about but that were valuable
contributions or interesting technical items, suitable for pulling into future
interview conversations, or to include in my CV.
</p>
</div>
</div>

<div id="outline-container-org45f1cc2" class="outline-4">
<h4 id="org45f1cc2">Spreading knowledge and awareness</h4>
<div class="outline-text-4" id="text-org45f1cc2">
<p>
I'll often run <code>git log</code> to see what changes have happened in a project
recently. Usually I come away with limited information &#x2013; I can see who is
committing to a repo and some of the keywords in the commit subject lines. But
when those messages contain just a few sentences on what the change is and why
it's being made, then I build up better awareness of what's being done and I
learn more from my co-workers. Particularly in a remote-heavy environment, you
have to be explicit about building that kind of awareness in a team by repeating
the information and making it easy to find, and the git log is an ideal place to
do that because people will see it naturally.
</p>

<p>
This kind of knowledge-sharing benefit also applies to historic commits: the git
log can be a great learning resource when somebody new joins the team, as long
as it contains appropriate detail.
</p>
</div>
</div>

<div id="outline-container-orgd6ad319" class="outline-4">
<h4 id="orgd6ad319">Focusing my code changes</h4>
<div class="outline-text-4" id="text-orgd6ad319">
<p>
The act of writing a commit message forces me to think about the work: if I
can't write a concise explanation of what I'm doing and why, then maybe I
shouldn't be doing it, or maybe I need to be breaking the work into smaller
logical changes. Or, like rubber duck debugging, I might realise something new
about my implementation when I try to explain it. Or maybe I can't articulate a
message because I don't understand the technical or product details well enough,
and I need to take a step back and do some learning. By doing this in the commit
message, it forces me to confront it early and explicitly.
</p>
</div>
</div>

<div id="outline-container-org137e52a" class="outline-4">
<h4 id="org137e52a">Having the information at my fingertips</h4>
<div class="outline-text-4" id="text-org137e52a">
<p>
Some of the value I've mentioned applies to the practice of writing PR messages
more generally on a git forge service like Github or Gitlab. And, those services
do have benefits that aren't easily replicated in the git log &#x2013; eg. videos and
images, or comment threads.
</p>

<p>
But the big advantage git has is that, if you're using it, it's at your
fingertips through the whole process of writing software. I will probably check
the git log after I've run <code>pull</code>. I'll certainly check it as part of any
rebasing or merging work. If I'm curious about a line of code, I'll run <code>git
blame</code> and look at the commit that introduced it. It's there throughout the
development process, and there's value in having that extra information right in
front of you in the tool you use every day, in a way that's seamless to access.
</p>

<p>
I don't think having a merge commit that links to a PR or a ticket is an
adequate replacement. Maybe as a one-off, the few extra seconds clicking through
the link aren't a problem, but for something that I do many times per day it
adds a lot of friction. If I'm debugging a production issue and I have five
commits that I'm interested in, and they all just link out to other PRs, and
then some of those PRs just link through to other tickets, it significantly
reduces how quickly I can understand details about the codebase and its changes,
and increases the cognitive load at the exact time that I need things to be
quick and easy to understand so I can debug an urgent problem.
</p>

<p>
Another place where git has an advantage is searching: yes, I can go to Github,
search for a term, queue up browser tabs for all the found PRs, and look through
each of them individually to find what I want. But searching the git log in my
terminal is absolutely trivial and instant: I type <code>git log</code>, it opens <code>less</code> or
another pager, I hit forward slash, I type my search term, and I can page
through the entire history of the repo interactively in a few seconds. Or I can
run it through grep, or narrow it by directory or a particular set of files. The
experience isn't comparable &#x2013; it's literally 10x faster to find what I want
using git, the data is all local so I can do it offline, and we don't need any
special tools other than git itself.
</p>
</div>
</div>
</div>

<div id="outline-container-org473157a" class="outline-3">
<h3 id="org473157a"><span class="section-number-3">1.4.</span> Arguments against?</h3>
<div class="outline-text-3" id="text-1-4">
<p>
I think there are valid and less-valid arguments against including message
bodies. I'll include them roughly in order of how strong I think the argument
is:
</p>
</div>

<div id="outline-container-org5388319" class="outline-4">
<h4 id="org5388319">Production is broken, I don't have time for this</h4>
<div class="outline-text-4" id="text-org5388319">
<p>
That's fair &#x2013; if it's very urgent then link to a ticket or postmortem doc that
can be updated later. If you can spare a few minutes though, keep in mind that
production incidents are a time when clear, explicit reasoning and communication
around the code change are <i>particularly</i> important.
</p>
</div>
</div>

<div id="outline-container-org3ad71c8" class="outline-4">
<h4 id="org3ad71c8">I've already included this info in code comments</h4>
<div class="outline-text-4" id="text-org3ad71c8">
<p>
That's a pretty good reason. If my diff contains useful comments or docstrings
I'll sometimes just mention that in the commit message. You can also copy useful
info from the code comments into the commit message, the duplication isn't a
problem.
</p>
</div>
</div>

<div id="outline-container-org1fef040" class="outline-4">
<h4 id="org1fef040">Laying out my thought process is intimidating</h4>
<div class="outline-text-4" id="text-org1fef040">
<p>
For more junior engineers, I think this is understandable. The times where I've
really <i>not</i> wanted to explain myself are times where I've not entirely
understood what I'm doing or why I've been asked to make a particular change. If
I just don't leave a message, then I avoid the risk of getting it wrong and
looking silly, I don't have to admit to anyone that I don't understand, and I
won't have my ignorance encoded in writing forever. It's easier to not do it.
</p>

<p>
This is just something you have to overcome: the career involves a lot of not
knowing things and having to learn them, it's normal. For me it's become easier
over time to share when I don't know something, because I'm more secure that
there are things that I <i>do</i> know, and I've had times where I've seen the payoff
in those old messages &#x2013; the value has outweighed the embarassment.
</p>
</div>
</div>

<div id="outline-container-orgfa181ec" class="outline-4">
<h4 id="orgfa181ec">I prefer to put this information in the PR or somewhere else</h4>
<div class="outline-text-4" id="text-orgfa181ec">
<p>
This is the reason I've heard the most &#x2013; people think it's valuable to leave
some contextual information <i>somewhere</i>, but prefer to do it on the PR or in an
issue tracker.
</p>

<p>
The git log certainly has limitations. It's not a place for video or images, it
doesn't contain your review comment threads, it's not very accessible for
Product or other orgs, and it only captures state at the point in time that you
made the code change. By using a tool that's decoupled from the commit, you can
use richer media or access information that wasn't available when the commit was
made &#x2013; eg. maybe you can see deployments in your git forge tool or alongside a
ticket. That information can be extremely valuable for understanding the
particular code change and its impact, and so there are more suitable places to
put this contextual information than the git commit.
</p>

<p>
To this I'd argue: if your tooling is consistent through the team, it works and
it puts all that information in front of you instantly in the same way that
running "git log" does, then that's excellent and it's a workflow to aspire to.
</p>

<p>
But, just because PRs and other tools can hold similar information, it doesn't
make the git log useless. If you're using git to commit changes, then people
will very likely want to look at the log at some point, and it doesn't hurt to
duplicate some information so that the commits can be read more easily.
</p>

<p>
As mentioned above, I think <a href="#org137e52a">git puts the information in front of you in a more
naturally accessible way than forge tools</a> &#x2013; I don't find PRs an adequate
replacement. But even if you prefer the UX of web-based tools, there's another
argument for git: open-source version control tools are likely to outlive the
data in SaaS services. This is admittedly low down on the list of problems for
startups, but people do make repos private, they do misconfigure Jira and lose
state, git forge companies accidentally delete production databases, license or
pricing changes can force you out of a service, servers go down, accounts get
closed, companies go out of business, and sometimes you just decide to change to
another provider &#x2013; shit happens and that data can go away, or the ties between
the data and the commit can be broken. Meanwhile every engineer in the team has
their own immutable offline copy of the git history, where the commit messages
will persist for as long as the code does.
</p>
</div>
</div>

<div id="outline-container-org067a93b" class="outline-4">
<h4 id="org067a93b">I'd have to significantly change my git workflow</h4>
<div class="outline-text-4" id="text-org067a93b">
<p>
Some personal git workflows make it harder to write messages. If that's the case
for you, then that probably means the workflow also makes it hard to make and
merge useful logical commits, and I'd argue that you should consider changing
it<sup><a id="fnr.4" class="footref" href="#fn.4" role="doc-backlink">4</a></sup>.
</p>

<p>
Some team workflows also make it harder to write messages, and if you can't
influence the team to change conventions this one can be awkward to work
around. For example, if your team's tooling is forcing a squash of your commits
when the PR is merged, this will replace your deliberate commits. If that's the
case, hopefully you can disable that feature on a per-PR basis &#x2013; if not one
thing you can do is include a clear message in the merge commit description.
</p>
</div>
</div>

<div id="outline-container-orgaf13ae6" class="outline-4">
<h4 id="orgaf13ae6">I explain all this stuff over video calls or IRL</h4>
<div class="outline-text-4" id="text-orgaf13ae6">
<p>
Face to face communication can be higher-signal, and some things can be better
communicated verbally, but unless you're recording the call and providing a
transcript or notes, it's all lost the moment the call ends, and it's not
accessible beyond the participants of that one meeting. If I come across the
commit in six months time, I won't remember the full content of that discussion,
and I might not even remember that we had a meeting about this change. Writing
is more permanent and increases in value over time as people forget. At the very
least, record the video or audio and link to it.
</p>
</div>
</div>

<div id="outline-container-org18fe3d6" class="outline-4">
<h4 id="org18fe3d6">It takes a long time to write a message</h4>
<div class="outline-text-4" id="text-org18fe3d6">
<p>
If you don't want to spend 10 minutes extra writing a message for a logical code
change, I think you should reconsider as the ROI for the team is significantly
higher than that investment<sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>. If you <i>really</i> struggle and it takes
hours then this could be a valid reason. If you have a way to share screencasts
with your team, that can be an alternative solution.
</p>

<p>
If you already write notes on your PRs, then there's almost no extra cost at
all, as you're already spending time writing about the change.
</p>
</div>
</div>

<div id="outline-container-org97c2f06" class="outline-4">
<h4 id="org97c2f06">Commit messages can be wrong so you should just look at the diff</h4>
<div class="outline-text-4" id="text-org97c2f06">
<p>
Useful commit messages will highlight context that <i>can't</i> be reliably inferred
from just reading through the diff &#x2013; that's the value of them. Certainly it's
possible to write bad messages, but I don't think the potential existence of bad
messages should prevent you from trying to write a good one.
</p>
</div>
</div>

<div id="outline-container-org5d6baac" class="outline-4">
<h4 id="org5d6baac">I prefer seeing a one-line commit log without the extra noise</h4>
<div class="outline-text-4" id="text-org5d6baac">
<p>
I want that too sometimes &#x2013; there are various ways to achieve it, including
the <code>git log --oneline</code> flag.
</p>
</div>
</div>

<div id="outline-container-orgd574c44" class="outline-4">
<h4 id="orgd574c44">I see no value in the messages</h4>
<div class="outline-text-4" id="text-orgd574c44">
<p>
I do appreciate that not <i>everyone</i> will want to read messages or find them
useful, but I've seen it help myself and other engineers in the past, and I've
seen the cost and frustration when key context about a change hasn't been made
easily available. Even if you personally never want to read the messages,
there's no big cost to adding them: you're not making a tradeoff where you're
losing something by including extra information in your commit message, and
they're easier to write than code comments because you don't have to worry about
how they'll change in the future &#x2013; you just have to capture what you're
thinking now. The only thing you'll lose is a small amount of time invested in
writing and sometimes editing the messages.
</p>
</div>
</div>
</div>

<div id="outline-container-org5590f2f" class="outline-3">
<h3 id="org5590f2f"><span class="section-number-3">1.5.</span> I'm sold! How can I get started?</h3>
<div class="outline-text-3" id="text-1-5">
<p>
The short answer is just don't use the <code>-m</code> flag, write message bodies in your
editor or tool of choice, and focus on information that won't be apparent to the
reader from the diff. For me this usually falls under one of three categories:
the changes I'm making, the context of why I'm making it, and non-obvious
considerations for the reviewer or other future readers. The more you do it, the
easier it will become.
</p>

<p>
I started writing more detail on this section, but nobody wants to read a post
this long about commit messages. Maybe another time.
</p>
</div>
</div>

<div id="outline-container-org34adbe7" class="outline-3">
<h3 id="org34adbe7"><span class="section-number-3">1.6.</span> Summary</h3>
<div class="outline-text-3" id="text-1-6">
<p>
<b>TL;DR:</b> The best time to write a commit message was 20 years ago<sup><a id="fnr.6" class="footref" href="#fn.6" role="doc-backlink">6</a></sup>, the second best time is now. I find having detailed commit messages very
valuable, and encourage everyone to do it if you're collaborating on
professional software that needs maintaining. It's not much different to writing
PR descriptions &#x2013; you just put the info in the commit message body so it's
easily accessible in git commands like log and blame. The benefits include:
</p>

<ul class="org-ul">
<li>Being able to see what you were thinking months or years ago when you made a change.</li>
<li>Being able to see what <i>other</i> engineers were thinking when they made their changes.</li>
<li>Having a clear chronological log of work you can look back through.</li>
<li>General spreading of knowledge and awareness in a team.</li>
<li>Forcing you to explicitly understand what changes you're making and why by
writing it down.</li>
<li>Having this information at your fingertips in the tool we all use to manage
changes in our codebase every day, and in a format that will persist for as
long as the code does.</li>
</ul>

<p>
I've long given up thinking I can convince everyone to do this, and sometimes I
wonder if I'm missing something because I've worked with plenty of good
engineers who don't do it. Sure, it's not as important as shipping features, and
you can certainly do good work without caring about commit messages. But my view
is that the pros outweigh the cons and the ROI on writing messages for your git
log is well worth it. It doesn't cost anything, it scales well across people and
timezones, its value increases over time, and it presents useful information in
an easily-accessible way that you just don't get from just using the web tools
like Github.
</p>
</div>
</div>
]]></description>
</item>

<item>
<title>Extending use-package's :bind to support evil and keymaps</title>
<link>https://www.mattduck.com/2023-08-28-extending-use-package-bind.html</link>
<author>hi@mattduck.com (Matt Duck)</author>
<guid isPermaLink="false">D7E86F0D-75B9-4988-AEF0-677193737AFA</guid>
<pubDate>Mon, 28 Aug 2023 09:55:00 +0100</pubDate>

<description><![CDATA[<p>
<a href="https://github.com/jwiegley/use-package">Use-package</a> is a popular macro for declaring, configuring and organising
packages in your Emacs config. One of the features it offers is the <code>:bind</code>
keyword, which allows you to declare bindings like this:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(use-package org
  :bind (:map org-mode-map
              ("C-c C-y" . org-store-link)))
</pre>
</div>

<p>
This will bind <code>C-c C-y</code> to the function <code>(org-store-link)</code> in the <code>org-mode-map</code>
keymap.
</p>

<p>
There are two limitations that I've wanted to fix for a while. The first is that
I use <a href="https://github.com/emacs-evil/evil">evil</a> to provide vim-style modal bindings. Evil's use of keymaps is
slightly different to the usual Emacs convention as it contains an additional
piece of state -- the editing mode. It provides <code>(evil-define-key)</code>, which lets
you do something like...
</p>

<div class="org-src-container">
<pre class="src src-lisp">(evil-define-key 'normal org-mode-map "gk" 'outline-previous-visual-heading)
</pre>
</div>

<p>
...to bind to <code>org-mode-map</code> specifically in evil's normal state. I don't
believe it's possible to make these evil-state assignments using the <code>:bind</code>
keyword.
</p>

<p>
The second limitation is that sometimes I want to bind a key to a
keymap. Eg. maybe I want to assign <code>&lt;leader&gt;h</code> to <code>help-map</code>:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(use-package emacs
  :bind (:map my/leader-map
              ("h" . help-map)))
</pre>
</div>

<p>
This doesn't work, because when the <code>:bind</code> handler expands, it quotes all of
the values of the associations, so you end up with <code>(bind-key "h" 'help-map
my/leader-map)</code>. This gets interpretated as a function and fails -- to reference
the keymap you need to pass it in without the quote<sup><a id="fnr.7" class="footref" href="#fn.7" role="doc-backlink">7</a></sup>. Use-package does provide a <code>:bind-keymap</code> feature, but that expects
the keymap to be defined in the package you're configuring, and it doesn't allow
you to specify a <code>:map</code> -- you can only create global keymap bindings.
</p>

<div id="outline-container-org5875a2c" class="outline-3">
<h3 id="org5875a2c"><span class="section-number-3">2.1.</span> Extending use-package with new keywords</h3>
<div class="outline-text-3" id="text-2-1">
<p>
Enter: use-package extensions, which I explored yesterday for the first
time. It's pretty easy to add new keywords to use-package. You have to add three
things:
</p>

<div class="org-src-container">
<pre class="src src-lisp">;; 1. Extend use-package-keywords
(add-to-list 'use-package-keywords :my-keyword t)

;; 2. Validate and return the args passed to the keyword
(defun use-package-normalize/:my-keyword (name keyword args)
  args)

;; 3. Handle the keyword -- expand into the code you want it to run.
(defun use-package-handler/:my-keyword (name _keyword args rest state)
  (let ((body (use-package-process-keywords name rest state)))
    `((with-eval-after-load ',name)
       (message "%s" ,@args))))

;; This will print Hello, world after org has loaded.
(use-package org
  :my-keyword "Hello, world")
</pre>
</div>

<p>
If you use <code>pp-macroexpand-last-sexp</code>, you can see how the macro expands, which
makes it a lot easier to understand what use-package does under the hood. For
me, our <code>use-package</code> declaration above expands to:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(progn
  (straight-use-package 'org)
  (defvar use-package--warning46
    #'(lambda
        (keyword err)
        (let
            ((msg
              (format "%s/%s: %s" 'org keyword
                      (error-message-string err))))
          (display-warning 'use-package msg :error))))
  (condition-case-unless-debug err
      (let
          ((now
            (current-time)))
        (message "%s..." "Loading package org")
        (prog1
            (if
                (not
                 (require 'org nil t))
                (display-warning 'use-package
                                 (format "Cannot load %s" 'org)
                                 :error)
              (with-eval-after-load 'org)
              (message "%s" "Hello, world"))
          (let
              ((elapsed
                (float-time
                 (time-subtract
                  (current-time)
                  now))))
            (if
                (&gt; elapsed 0.001)
                (message "%s...done (%.3fs)" "Loading package org" elapsed)
              (message "%s...done" "Loading package org")))))
    (error
     (funcall use-package--warning46 :catch err))))
</pre>
</div>
</div>
</div>

<div id="outline-container-org7746f69" class="outline-3">
<h3 id="org7746f69"><span class="section-number-3">2.2.</span> The implementation</h3>
<div class="outline-text-3" id="text-2-2">
<p>
Back to the <code>:bind</code> issue: I don't want to modify the default behaviour of
<code>:bind</code>, but I can imagine a new keyword that provides similar
functionality. The implementation I got to was this:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(add-to-list 'use-package-keywords :md/bind t)

(defun use-package-normalize/:md/bind (name keyword args)
  "Custom use-keyword :md/bind. I use this to provide something similar to ':bind',
but with two additional features that I miss from the default implementation:

1. Integration with 'evil-define-key', so I can extend the keymap declaration
   to specify one or more evil states that the binding should apply to.

2. The ability to detect keymaps that aren't defined as prefix commands. This
   allows me to define a binding to a keymap variable, eg. maybe I want '&lt;leader&gt;h'
   to trigger 'help-map'. This fails using the default ':bind', meaning that I
   have to fall back to calling 'bind-key' manually if I want to assign a
   prefix.

The expected form is slightly different to 'bind':

((:map (KEYMAP . STATE) (KEY . FUNC) (KEY . FUNC) ...)
 (:map (KEYMAP . STATE) (KEY . FUNC) (KEY . FUNC) ...) ...)

STATE is the evil state. It can be nil or omitted entirely. If given, it should be an
argument suitable for passing to 'evil-define-key' -- meaning a symbol like 'normal', or
a list like '(normal insert)'."
  (setq args (car args))
  (unless (listp args)
    (use-package-error ":md/bind expects ((:map (MAP . STATE) (KEY . FUNC) ..) ..)"))
  (dolist (def args args)
    (unless (and (eq (car def) :map)
                 (consp (cdr def))
                 (listp (cddr def)))
      (use-package-error ":md/bind expects ((:map (MAP . STATE) (KEY . FUNC) ..) ..)"))))

(defun use-package-handler/:md/bind (name _keyword args rest state)
  "Handler for ':md/bind' use-package extension. See 'use-package-normalize/:md/bind' for docs."
  (let ((body (use-package-process-keywords name rest
                (use-package-plist-delete state :md/bind))))
    (use-package-concat
     `((with-eval-after-load ',name
         ,@(mapcan
            (lambda (entry)
              (let ((keymap (car (cadr entry)))
                    (state (cdr (cadr entry)))
                    (bindings (cddr entry)))
                (mapcar
                 (lambda (binding)
                   (let ((key (car binding))
                         (val (if (and (boundp (cdr binding)) (keymapp (symbol-value (cdr binding))))
                                  ;; Keymaps need to be vars without quotes
                                  (cdr binding)
                                  ;; But functions need to be quoted symbols
                                  `(quote ,(cdr binding)))))
                     ;; When state is provided, use evil-define-key. Otherwise fall back to bind-key.
                     (if state
                         `(evil-define-key ',state ,keymap (kbd ,key) ,val)
                         `(bind-key ,key ,val ,keymap))))
                 bindings)))
            args)))
     body))))
</pre>
</div>

<p>
If you can look past all the cars and cdrs, the main part of the handler logic
here is that, if an evil state is provided, we pass the definition to
<code>(evil-define-key)</code> instead of <code>(bind-key)</code>. And, we check to see if the passed
in variable is bound to a keymap &#x2013; and then pass it in unquoted.
</p>
</div>
</div>

<div id="outline-container-org687bf12" class="outline-3">
<h3 id="org687bf12"><span class="section-number-3">2.3.</span> The result</h3>
<div class="outline-text-3" id="text-2-3">
<p>
The result is that I can finally get all of my bindings into the use-package
declaration:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(use-package org
    :after (evil)
    :md/bind ((:map (org-mode-map) ;; Expands to (bind-key), similar to :bind
                    ("C-c C-y" . org-store-link))
              (:map (org-mode-map . normal) ;; Only bind in normal mode
                    ("gk" . outline-previous-visible-heading)
                    ("gj" . outline-next-visible-heading))
              (:map (org-mode-map . (normal insert))  ;; Bind in normal and insert mode
                    ("M-k" . org-metaup)
                    ("M-j" . org-metadown))
              (:map (md/leader-map)  ;; Bind to a keymap
                    ("h" . help-map))))
</pre>
</div>

<p>
This is a lot cleaner than what I had previously: no more calls to
<code>(evil-define-key)</code> and <code>(bind-key)</code> littered everywhere, and I can see
everything defined in one place.
</p>

<p>
One nice thing about this is that I didn't need to do any special handling to
support passing in a list of evil modes because <code>(evil-define-key)</code> supports
that by default.
</p>

<p>
This implementation isn't at feature parity with the original <code>:bind</code> keyword. I
haven't considered any kind of lazy-loading of bound commands here, and I don't
pass the arguments through to the <code>bind-keys</code> macro, meaning that lots of the
documented features aren't implemented (<code>:repeat-map</code>, <code>:prefix</code> etc.). I don't
use these things though, so I think this new implementation is actually all I
need.
</p>

<p>
The code can be found in <a href="https://github.com/mattduck/dotfiles/blob/master/emacs.2023.symlink/init.org">my dotfiles repo</a>.
</p>
</div>
</div>
]]></description>
</item>

<item>
<title>Preventing checkbox inheritance in org-mode</title>
<link>https://www.mattduck.com/2023-08-25-org-mode-checkbox-inheritance.html</link>
<author>hi@mattduck.com (Matt Duck)</author>
<guid isPermaLink="false">670E8DB5-A4D8-4AFD-B755-8F494C4D016F</guid>
<pubDate>Fri, 25 Aug 2023 15:17:00 +0100</pubDate>

<description><![CDATA[
<div id="outline-container-org53c4cee" class="outline-3">
<h3 id="org53c4cee"><span class="section-number-3">3.1.</span> Background</h3>
<div class="outline-text-3" id="text-3-1">
<p>
One feature in org-mode that I've wished I could customise for a long time is
the checkbox inheritance feature. Org's behaviour is that if I have a list like
this&#x2026;
</p>

<pre class="example" id="org06f4271">
- [ ] This is a parent item
  - [ ] This is a child nested item
</pre>

<p>
&#x2026;then, as soon as I check all the child items as <code>[X]</code>, the parent item will
automatically be updated to <code>[X]</code> too.
</p>

<p>
This doesn't fit with how I like to use nested checkboxes: generally I do use
them to represent a kind of "subtask" concept, but it's not necessarily the
<i>full</i> set of items that make up the "parent" task, and completing them doesn't
mean I'm done with the parent item. I'd prefer to be able to manually trigger
the two checkboxes independently: changing state on the child item shouldn't
affect the parent.
</p>
</div>
</div>

<div id="outline-container-orgbe24bd3" class="outline-3">
<h3 id="orgbe24bd3"><span class="section-number-3">3.2.</span> Fixing it by disabling org-list-struct-fix-box</h3>
<div class="outline-text-3" id="text-3-2">
<p>
A lot of org-mode's behaviour can be customised via variables, hooks
etc. However, this particular behaviour doesn't seem to be customisable, and
when searching I've not found any immediate solutions or ideas that people use
to achieve this.
</p>

<p>
After some poking around in the source this week, I came up with something that
seems to work for me: this checkbox behaviour is implemented in a function named
<code>org-list-struct-fix-box</code>. That's the only thing this function does, and so if
we turn this function into a no-op, then I get the behaviour that I want:
updating child checkbox items has no affect on the parent.
</p>

<p>
To achieve this, I define advice<sup><a id="fnr.8" class="footref" href="#fn.8" role="doc-backlink">8</a></sup> around the original function that prevents
the original implementation from being called:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(defadvice org-list-struct-fix-box (around md/noop last activate)
    "Turn org-list-struct-fix-box into a no-op.

By default, if an org list item is checked using the square-bracket
syntax [X], then org will look for a parent checkbox, and if all child items are
checked, it will set [X] on the parent too. This isn't how I personally use
child items -- I'll often use child checkboxes as subtasks, but it's almost
never an exhaustive list of everything that has to be done to close out the
parent -- and so I'd prefer to just control the parent checkbox state manually.

AFAICT org-mode doesn't provide a way to customise this behaviour, /but/ the
behaviour all seems to be implemented in 'org-list-struct-fix-box'. And so I'm
trying something out by turning it into a no-op. It seems to work nicely initially,
but I won't be surprised if it causes an issue at some point because it's very
hacky."
nil)
</pre>
</div>

<p>
That's it: all this time and I only had to write one line of code to achieve
what I want.
</p>
</div>
</div>

<div id="outline-container-org8f024d2" class="outline-3">
<h3 id="org8f024d2"><span class="section-number-3">3.3.</span> Why use advice over <code>defun</code>?</h3>
<div class="outline-text-3" id="text-3-3">
<p>
Instead of advice, another approach would be to just redefine the original
function using <code>defun</code>. I prefer to use advice though, so I can still see the
original function, still jump to its definition, explicitly know that it exists
and that I'm modifying it, etc. If I use <code>describe-function</code> on
<code>org-list-struct-fix-box</code>, it will tell me that the function is advised, and as
I'm using the excellent <a href="https://github.com/Wilfred/helpful">helpful package</a>, I can see additional information
including the definition of both the original function and the advice.
</p>
</div>
</div>

<div id="outline-container-org2c97a8d" class="outline-3">
<h3 id="org2c97a8d"><span class="section-number-3">3.4.</span> Isn't this pretty hacky?</h3>
<div class="outline-text-3" id="text-3-4">
<p>
Yes. I've only been using it for a few days. <code>org-list-struct-fix-box</code> doesn't
seem to be called in many places though, so hopefully nothing major will break.
The most likely issue is that I break third-party packages that depend on the
original behaviour, but I don't think any of the packages I'm using are likely
to depend on this particular function.
</p>

<p>
I think this kind of approach can be risky in a prod-environment program that
other people depend on, but as it's just my personal config, it's fine &#x2013; I'm
not sure I'd go as far to say it's encouraged, but this "advice" patching
concept is one of the tools provided by Emacs to customise a module's behaviour
for this exact kind of situation, where you otherwise don't have the ability to
achieve the behaviour you want without redefining whole functions.
</p>
</div>
</div>

<div id="outline-container-org109fef6" class="outline-3">
<h3 id="org109fef6"><span class="section-number-3">3.5.</span> Contributing upstream?</h3>
<div class="outline-text-3" id="text-3-5">
<p>
It doesn't seem far-fetched to me that this could be contributed upstream: not
as advice, but as a new custom variable that can be used to disable plain
checklist inheritance &#x2013; you might even be able to get away with an
implementation that just looks at the value of this new variable in
<code>org-list-struct-fix-box</code>.
</p>

<p>
Another more complex approach would be to support new syntax for opting into the
"inheritance" behaviour on a per-list basis, similar to how you can set your
checkbox value to <code>[/]</code> to have it automatically show the count of completed
child items.
</p>
</div>
</div>

<div id="outline-container-orgb296f75" class="outline-3">
<h3 id="orgb296f75"><span class="section-number-3">3.6.</span> Am I missing something?</h3>
<div class="outline-text-3" id="text-3-6">
<p>
If you're aware of a way to achieve this without patching, please let me know!
</p>

<p>
You can find my config in <a href="https://github.com/mattduck/dotfiles/blob/master/emacs.2023.symlink/init.org">my dotfiles repo</a>.
</p>
</div>
</div>
]]></description>
</item>

<item>
<title>Auto-show latest heading state in org-mode links</title>
<link>https://www.mattduck.com/2023-08-09-org-mode-improved-heading-links.html</link>
<author>hi@mattduck.com (Matt Duck)</author>
<guid isPermaLink="false">E0A2E310-EC30-4F53-ACE2-201379FE9777</guid>
<pubDate>Mon, 14 Aug 2023 11:55:00 +0100</pubDate>

<description><![CDATA[
<div id="outline-container-org7ce5b5e" class="outline-3">
<h3 id="org7ce5b5e"><span class="section-number-3">4.1.</span> Intro</h3>
<div class="outline-text-3" id="text-4-1">
<p>
I just added some features to my org-mode setup to easily update links to other
org headings, to pull in the current keyword and headline from the linked item.
</p>

<p>
The idea here is that I want to treat links to org items more like a current
reference to the original heading item, instead of a stale duplicate. Org-agenda
is a good example of doing this: you run the agenda command and it shows an
up-to-date view of the current items, their keyword state and tags, and you
can easily jump from the item to the original source. Links on the other hand,
have no awareness of their target item's state, and even if I copy the name of
the headline item when I create the link, it will became stale as soon as I edit
the original headline<sup><a id="fnr.9" class="footref" href="#fn.9" role="doc-backlink">9</a></sup>.
</p>

<p>
The reason I want this is because sometimes I want to build ad-hoc, informal
collections of org items regardless of their current state. Eg. maybe I want to
pull in some items that I need on hand this week, without having to formalise
what those items are with keywords or tags, and without having to keep editing
the link description to always be in sync with the original item.
</p>
</div>
</div>

<div id="outline-container-org78ea736" class="outline-3">
<h3 id="org78ea736"><span class="section-number-3">4.2.</span> Demo</h3>
<div class="outline-text-3" id="text-4-2">
<p>
To make it easier to understand, here it is in action:
</p>

<video controls/>
  <source src="2023-08-09-org-heading-links.mp4" type="video/mp4">
  This video isn't supported in your browser.
</video>
</div>
</div>

<div id="outline-container-orgacfa084" class="outline-3">
<h3 id="orgacfa084"><span class="section-number-3">4.3.</span> First: org-mode link features</h3>
<div class="outline-text-3" id="text-4-3">
<p>
Before we get to the implementation I want to run through some of the default
org link behaviour, because I don't find it intuitive.
</p>
</div>

<div id="outline-container-orgeb1863c" class="outline-4">
<h4 id="orgeb1863c">Storing text search links</h4>
<div class="outline-text-4" id="text-orgeb1863c">
<p>
There's a function <code>(org-store-link)</code>, which is the entry point for storing a link
to an object. You can call <code>(org-store-link)</code> on an org item to store it in a data
structure<sup><a id="fnr.10" class="footref" href="#fn.10" role="doc-backlink">10</a></sup>, and then use <code>(org-insert-link)</code> to insert the
link. If you imagine we've called <code>(org-store-link)</code> on an item named <i>My target
heading</i>, the result would look like this:
</p>

<pre class="example" id="org7a51c5e">
I want to link to [[*My target heading][My target heading]].
</pre>

<p>
Now if I press <code>C-c C-o</code> on that link, it will run <code>(org-open-at-point)</code>, which
will open the linked item. If you're linking to a heading in different file,
then the inserted link will contain a prefix like <code>file:/path/to/myfile.org::</code>.
</p>

<p>
This is simple, but it has a significant downside: it uses text search to
identify the target item, and it therefore depends on an exact match to the
headline. If I edit <i>My target heading</i> at all, it will break my link. This
makes it a non-starter for me because I consider all my org headlines to be
mutable.
</p>
</div>
</div>

<div id="outline-container-org65b6397" class="outline-4">
<h4 id="org65b6397">The <code>&lt;&lt;mytarget&gt;&gt;</code> ID syntax</h4>
<div class="outline-text-4" id="text-org65b6397">
<p>
One way you can get around this problem is to use the <code>&lt;&lt;mytarget&gt;&gt;</code> angle
bracket syntax to specify a target, similar to setting an ID on a HTML
element. You can reference this ID in a link. Eg.
</p>

<pre class="example" id="orga657a4a">
* TODO &lt;&lt;mytarget&gt;&gt; My target heading

* My other heading

I want to link to [[mytarget][My target heading]].
</pre>

<p>
This works, and it persists if you change the headline description, as long as
you keep the angle bracket ID the same. It can also be used to flexibly link to
any point in an org file, not just the headline. It still has a couple of
downsides though:
</p>

<ul class="org-ul">
<li>You have to manually think of your link name and make sure it's unique in the
document.</li>

<li>The <code>&lt;&lt;mytarget&gt;&gt;</code> annotations are going to be visible all over your
document. I don't really want to pollute all my headlines like that.</li>
</ul>
</div>
</div>

<div id="outline-container-org6d885bf" class="outline-4">
<h4 id="org6d885bf">The <code>:ID:</code> property</h4>
<div class="outline-text-4" id="text-org6d885bf">
<p>
A more reliable solution to this problem is provided by the included
<code>org-id</code> library. This provides a set of features based around the <code>:ID:</code>
property, which gets stored in the <code>:PROPERTIES:</code> drawer like this:
</p>

<pre class="example" id="org326cfeb">
* TODO My target heading
:PROPERTIES:
:ID:       63F85B1C-68C7-4F15-B558-BAD6810812D1
:END:
</pre>

<p>
One way you can get started with this is to call <code>(org-id-get-create)</code>, which will
generate a UUID<sup><a id="fnr.11" class="footref" href="#fn.11" role="doc-backlink">11</a></sup> if one doesn't already exist, and store it in the properties
draw.
</p>

<p>
Org maintains a map of your org files and their IDs in
<code>~/.emacs.d/.org-id-locations</code>, so that the file path doesn't have to be encoded
in the ID.
</p>

<p>
For a long time I didn't find the <code>org-id</code> package very intuitive, because it
didn't seem to play nicely with <code>(org-store-link)</code>. For example, there's an
<code>(org-id-store-link)</code> function, which automatically creates the <code>:ID:</code> property if
it doesn't exist, and presumably saves it somewhere. But then if you call
<code>(org-insert-link)</code>, it doesn't actually have awareness of the state saved by
<code>(org-id-store-link)</code>, and if you use <code>(org-store-link)</code> it still saves a
text-search version of the link.
</p>
</div>
</div>

<div id="outline-container-orgc73266c" class="outline-4">
<h4 id="orgc73266c"><code>org-id-link-to-org-use-id</code></h4>
<div class="outline-text-4" id="text-orgc73266c">
<p>
The way I solved this weird mismatch turned out to be through a variable named
<code>org-id-link-to-org-use-id</code>. If you set this to <code>t</code> or another supported value
like <code>'create-if-interactive</code>, then it tells <code>(org-store-link)</code> to always use the
<code>:ID:</code> approach, instead of the default text-search approach. <code>(org-store-link)</code>
and <code>(org-insert-link)</code> will then use the <code>:ID:</code> linking method as you'd
expect.
</p>
</div>
</div>

<div id="outline-container-org85b5e9d" class="outline-4">
<h4 id="org85b5e9d">The <code>:CUSTOM_ID:</code> property</h4>
<div class="outline-text-4" id="text-org85b5e9d">
<p>
To further confuse the situation, there's another property that org understands
named <code>:CUSTOM_ID:</code>. My understanding is that this is more like the angle
bracket ID syntax but is used to reference a headline item and stored in the
property drawer (whereas the angle bracket can be any point in the document). If
you're exporting your org document, it can be used to create readable anchors
instead of the random IDs that org gives you by default. To reference it in a
link, you have to prefix your link target with a hash character.
</p>

<p>
It seems that if <code>org-id-link-to-use-id</code> is set to a non-nil value, then
<code>(org-store-link)</code> will prefer to store a link to <code>:ID:</code>, but will fall back to
<code>:CUSTOM_ID:</code> if <code>:ID:</code> doesn't exist. You can set <code>org-id-link-to-org-use-id</code>
to <code>'create-if-interactive-and-no-custom-id</code> to only create the <code>:ID:</code> property
if <code>:CUSTOM_ID:</code> doesn't already exist. This would allow you to use
<code>:CUSTOM_ID:</code> manually where you prefer to specify it - but you have to make
sure it's a unique reference to the current document.
</p>
</div>
</div>

<div id="outline-container-org0686a6f" class="outline-4">
<h4 id="org0686a6f">Sidenote on footnotes</h4>
<div class="outline-text-4" id="text-org0686a6f">
<p>
Not strictly a link feature, but I only recently looked into the <a href="https://orgmode.org/manual/Creating-Footnotes.html">footnotes feature</a>
for the first time. This allows you to use syntax like <code>[fn::Here's my inline footnote]</code>
to define a footnote inline, or <code>[fn:1]</code> to link to a footnote definition that
you put somewhere else in the file.
</p>
</div>
</div>
</div>

<div id="outline-container-org282aabe" class="outline-3">
<h3 id="org282aabe"><span class="section-number-3">4.4.</span> What I'm implementing</h3>
<div class="outline-text-3" id="text-4-4">
<p>
The main thing I want is a function which, if my cursor is on a link, will
update the description/contents of the link to reflect the current headline and
its current todo keyword, overwriting whatever the previous description was. I
want to somehow hook this into <code>C-c C-c</code>, because I'm used to pressing that to
update different things in org.
</p>

<p>
Additionally, I want configuration and bindings to:
</p>

<ul class="org-ul">
<li>Use org <code>:ID:</code> links automatically instead of the default text search method.</li>
<li>Easily store an <code>:ID:</code> link in org-mode and org-agenda-mode.</li>
<li>Easily insert the stored <code>:ID:</code> link in org-mode.</li>
</ul>
</div>
</div>

<div id="outline-container-org2ef4cb4" class="outline-3">
<h3 id="org2ef4cb4"><span class="section-number-3">4.5.</span> Implementation</h3>
<div class="outline-text-3" id="text-4-5">
</div>
<div id="outline-container-org7e2c3ed" class="outline-4">
<h4 id="org7e2c3ed">Using IDs instead of text match</h4>
<div class="outline-text-4" id="text-org7e2c3ed">
<p>
This part is easy - I just have to do:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(setq org-id-link-to-org-use-id 'create-if-interative)
</pre>
</div>

<p>
Now <code>(org-store-link)</code> will automatically generate and use <code>:ID:</code> links.
</p>

<p>
I could set also this to <code>t</code>. The documentation suggests there are circumstances
where it might not be desirable to always do this though - something to do with
<code>(org-capture)</code>, so I'm starting out by keeping it interactive-only.
</p>
</div>
</div>

<div id="outline-container-org2e0a9ba" class="outline-4">
<h4 id="org2e0a9ba">Updating the link state</h4>
<div class="outline-text-4" id="text-org2e0a9ba">
<p>
Now I want my function which, if the cursor is on an org link, will lookup the
linked headline and update the link to match it. To start I'm only going to
support <code>:ID:</code> links, because that's what I intend to use and I don't yet want
to spend time handling other link types.
</p>

<p>
The function ended up looking like this:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(defun md/org-link-sync ()
    "Sync an org-link to show the target headline as the contents.

When the cursor is on an org-link that uses the ID type, lookup the current state of the linked
headline, and replace the link contents with the current headline value.

For example, an \"outdated\" link like this:

    [[id:3C5473CB-3DCF-4A9B-9387-750730DAEB7B][My link contents description]]

Might be replaced by an up-to-date link like this:

    [[id:3C5473CB-3DCF-4A9B-9387-750730DAEB7B][DONE [#A] The current description of the headline]]"
  (interactive)
  (let* ((link-context (org-element-context))
         (type (org-element-property :type link-context))
         (path (org-element-property :path link-context))
         (point-begin (org-element-property :contents-begin link-context))
         (point-end (org-element-property :contents-end link-context)))
    (when (and path (equal type "id"))
      (let ((new-link-text
             (md/with-widened-buffer (md/find-file-buffer (org-id-find-id-file path))
                                     (save-window-excursion
                                       (org-open-at-point)
                                       (org-get-heading t nil nil nil)))))
        (goto-char point-begin)
        (delete-region point-begin point-end)
        (insert new-link-text))
      (goto-char point-begin))))
</pre>
</div>

<p>
Putting aside <code>(md/with-widened-buffer)</code> for a second, the steps in the function are:
</p>

<ul class="org-ul">
<li>Use <code>(org-element-context)</code> and <code>(org-element-property)</code> to retrieve
information about the link. This includes the type of link (we want "id"
links), the path (ie. the ID value itself), and the point begin and end values
which denote where the link description starts and ends (this is the part we
want to overwrite).</li>

<li>Use <code>(org-open-at-point)</code> to follow the link, and <code>(org-get-heading t)</code> to
save our new heading description, which will include keywords but not tags<sup><a id="fnr.12" class="footref" href="#fn.12" role="doc-backlink">12</a></sup>. <code>(save-window-excursion)</code> prevents our visible
windows from changing when <code>(org-open-at-point)</code> is called.</li>

<li>Use <code>(delete-region point-begin point-end)</code> to delete the existing contents
portion of the link. We prefix this with <code>(goto-char point-begin)</code> to
put the cursor in the right place for insert.</li>

<li>With the cursor in the right place, we call <code>(insert new-link-text)</code> with the
contents. We then call <code>(goto-char point-begin)</code> again - this is just a quick
way to put the cursor in a useful place, although it would be nicer if this
could attempt to keep the cursor in the same place as it was originally, and
only move it if it's now out of bounds of the new description.</li>
</ul>

<p>
That's it - the broad approach is pretty easy.
</p>
</div>
</div>

<div id="outline-container-org2069a1c" class="outline-4">
<h4 id="org2069a1c">Handling narrowed buffers</h4>
<div class="outline-text-4" id="text-org2069a1c">
<p>
The one complication here is narrowed/restricted buffers. If you've narrowed the
buffer that the link points to, then <code>(org-open-at-point)</code> will open the right
buffer but won't jump to the right place because the buffer contents will be
restricted, and <code>(org-get-heading)</code> will then return the wrong
information. AFAIK org just doesn't handle following links to a narrowed buffer.
</p>

<p>
Emacs does provide a <code>(save-restriction)</code> macro, which works like
<code>(save-excursion)</code> or <code>(save-window-excursion)</code> but for restoring any current
buffer restrictions. So the goal here is that we'll need to jump to the buffer
that the link points to, save the restriction, widen that buffer, <i>then</i> go back
to the original buffer, and call <code>(org-open-at-point)</code> to follow the link - and
it should always hit the correct heading because it will have access to the full
widened buffer. And then then the <code>(save-restriction)</code> macro should exit and
restore any restrictions in the linked buffer.
</p>

<p>
The ordering of these operations is a bit awkward, because <code>(save-restriction)</code>
operates on the current buffer at time of calling. And so I encapsulated it in a
macro <code>(md/with-widened-buffer)</code>, which accepts a buffer object (or name of the
buffer) that you want to widen and restore.
</p>

<div class="org-src-container">
<pre class="src src-lisp">  (defmacro md/with-widened-buffer (buffer-or-name &amp;rest body)
    "Widen the given BUFFER-OR-NAME, execute BODY in the context of your current buffer, and restore restrictions on the given buffer.

This allows the calling code to not have to worry about manually handling
narrowed vs widened state."
    (let ((orig-buffer (gensym "orig-buffer")))
      `(let ((,orig-buffer (current-buffer)))
         (with-current-buffer ,buffer-or-name
           (save-restriction
             (save-excursion
               (widen)
               (with-current-buffer ,orig-buffer
                 ,@body)))))))
</pre>
</div>

<p>
One detail here is that we use <code>(gensym)</code> to ensure that our <code>orig-buffer</code>
variable is unique and doesn't leak into the outer code.
</p>

<p>
The final detail is that we need to grab the source file from the org link
<i>before</i> we call <code>(org-open-at-point)</code>, so we can jump to that buffer and widen
it first. <code>org-id</code> provides the <code>(org-id-find-id-file)</code> function to grab the
file path associated with a particular UUID. We then need to convert the
returned file path to a buffer object in order to pass it to our macro. The
<code>(md/find-file-buffer)</code> helper function handles this:
</p>

<div class="org-src-container">
<pre class="src src-lisp">  (defun md/find-file-buffer (path)
    "Get or create a buffer visiting PATH without affecting current windows.

This is useful in situations where you have functions that accept a buffer object but you
only have the file path."
    (save-window-excursion
      (find-file path)
      (current-buffer)))
</pre>
</div>

<p>
Arguably this could just be inlined somewhere but I figured it won't be the only
time I need to do this and I don't like having to manually manage the restore
macros like <code>(save-window-excursion)</code> in the calling code.
</p>
</div>
</div>

<div id="outline-container-org03f38f5" class="outline-4">
<h4 id="org03f38f5">Hooking into C-c C-c</h4>
<div class="outline-text-4" id="text-org03f38f5">
<p>
With the function in place, how do we call it? I want to hook into <code>C-c C-c</code>,
which feels intuitive because it's the binding you hit in org-mode to update
various different elements.
</p>

<p>
I thought this would require advising <code>(org-ctrl-c-ctrl-c)</code>, but org actually
provides a hook named <code>org-ctrl-c-ctrl-c-hook</code>, which is designed exactly for
this - it lets you extend <code>C-c C-c</code> to support your own behaviour. The function
has to lookup the current org element/context, do whatever it wants to do, and
then return <code>t</code> if it did something, and <code>nil</code> if it didn't.
</p>

<div class="org-src-container">
<pre class="src src-lisp">  (defun md/org-ctrl-c-ctrl-c ()
    "I use this to add custom handlers and behaviour to C-c C-c.

For example, C-c- C-c is often used to update the state of org elements, and so
it feels like a natural way for me to call md/org-link-sync, because that
function updates the state of a ID link to be in sync with the target heading."
    (condition-case nil
        (let* ((link-context (org-element-context))
               (type (org-element-property :type link-context)))
          (cond
           ((and (eq (car link-context) 'link) (equal type "id"))
            (md/org-link-sync)
            t)  ; Returning t tells org-ctrl-c-ctrl-c that we did something
           (t nil)))  ; Tell org-ctrl-c-ctrl-c there was no match
      (error nil)))  ; Catch any errors in case org-element-context failed

  (add-hook 'org-ctrl-c-ctrl-c-hook 'md/org-ctrl-c-ctrl-c)
</pre>
</div>

<p>
The implementation looks similar to the link update function - we use
<code>(org-element-context)</code> and <code>(org-element-property)</code> to detect if we're on a
supported element, and if so we call <code>(md/org-link-sync)</code>. Now if I hit <code>C-c
C-c</code> on an ID link, it will call the function and update the link to show the
latest keyword and headline.
</p>
</div>
</div>

<div id="outline-container-org2d8d71d" class="outline-4">
<h4 id="org2d8d71d">Bindings</h4>
<div class="outline-text-4" id="text-org2d8d71d">
<p>
The last thing I wanted was some bindings - these aren't very interesting. I
mapped <code>(org-store-link)</code> to be accessible via <code>C-c y</code> in both org-mode and
org-agenda-mode, and I mapped <code>C-c L</code> to run <code>(org-insert-last-stored-link)</code>,
which I find nicer than <code>(org-insert-link)</code> as I never actually need the menu of
choices that <code>(org-insert-link)</code> forces you to choose from.
</p>
</div>
</div>
</div>

<div id="outline-container-org7cc3293" class="outline-3">
<h3 id="org7cc3293"><span class="section-number-3">4.6.</span> Next steps - informal org agendas?</h3>
<div class="outline-text-3" id="text-4-6">
<p>
This all seems to work well and I think it's a nice improvement that makes links
more useful for me. There are a few things I could look into next:
</p>

<ul class="org-ul">
<li>You could take the "mini informal org-agenda" idea further, and update keyword
or tag state from the link in the same way you can with org agenda. Eg. maybe
if I press <code>C-c C-t</code> on an org link, it could update the keyword state on the
linked item.</li>

<li>You could automatically update multiple links at once, or update links on
save, rather than requiring the links to be updated manually - this way they
become live references to other heading items.</li>

<li><code>(org-insert-last-stored-link)</code> inserts a newline after the link, and doesn't
include the keyword. It would be nice if I could insert the link and
automatically call <code>(md/org-link-sync)</code> to see the keyword, instead of having
to insert the link and immediately call the function.</li>

<li><code>(md/org-link-sync)</code> is inserting the target headline into the mark ring and
posting a message about it - not sure that I really need this.</li>

<li>Supporting <code>:CUSTOM_ID:</code> links could be useful.</li>
</ul>

<p>
You can find the code I'm actually using in <a href="https://github.com/mattduck/dotfiles/blob/master/emacs.2023.symlink/init.org#core-vanilla-org">my dotfiles</a>.
</p>
</div>
</div>
]]></description>
</item>

<item>
<title>Firefox extension updates, thoughts on ChatGPT</title>
<link>https://www.mattduck.com/2023-08-05-firefox-gpt-thoughts.html</link>
<author>hi@mattduck.com (Matt Duck)</author>
<guid isPermaLink="false">B04D6061-68D3-4B3B-BB1F-B7449F891198</guid>
<pubDate>Sat, 05 Aug 2023 21:13:00 +0100</pubDate>

<description><![CDATA[
<div id="outline-container-org9176e43" class="outline-3">
<h3 id="org9176e43"><span class="section-number-3">5.1.</span> Fixing a Firefox extension</h3>
<div class="outline-text-3" id="text-5-1">
<p>
I just fixed an issue in a <a href="https://github.com/mattduck/firefox-sdwh">Firefox extension</a> that I built a few years ago. The
extension itself is not particularly interesting: it lets me press <code>Cmd-Shift-L</code>
to highlight any selected text, and then I can copy all the highlights to the
clipboard. It's very basic but feels intuitive to me and I often use it to
highlight things as I'm reading through web pages.
</p>

<p>
Unfortunately, it has a notable problem: it just wraps the selected text in a
single <code>span</code> element, and this immediately breaks down as soon as you select
text that spans multiple elements. It's <i>too</i> basic.
</p>

<p>
For example, selecting text within a single <code>&lt;p&gt;</code> element would work fine:
</p>
<pre class="example" id="org7c37bf3">
  This works
 #-----------&gt;
+-------------+ -  -  -  -  -  -  -  -  -  -
|....&lt;p/&gt;.....|     &lt;p/&gt;          &lt;div/&gt;
|.............|              |              |
+-------------++  -  -  -  -  +  -  -  -  -
</pre>

<p>
But selecting text across multiple elements would fail to highlight anything:
</p>
<pre class="example" id="orgaac3d47">
  This fails as we cross elements
 #-----------------------------------------&gt;
+-------------++-------------++-------------+
|....&lt;p/&gt;...........&lt;p/&gt;..........&lt;div/&gt;....|
|...........................................|
+-------------++-------------++-------------+
</pre>

<p>
The root problem is that I didn't think very hard when I built it: I did it in
an hour or two of Stack Overflow-driven development, searching for how to make
a Firefox extension and any relevant browser APIs, and changing the code until
it worked. It did work, but barely.
</p>
</div>
</div>

<div id="outline-container-org2ace30b" class="outline-3">
<h3 id="org2ace30b"><span class="section-number-3">5.2.</span> From Stack Overflow to ChatGPT</h3>
<div class="outline-text-3" id="text-5-2">
<p>
Three years later, instead of Stack Overflow, I'm using ChatGPT to fix the
code. It was interesting as it felt like a comparable exercise to when I first
built the extension. It's still not production-grade code, I'm still the only one
using it, I still don't need to understand all the implementation details in
depth, and I still don't want to spend much time on it: I just want something
that I can get to work within a couple of hours, without much effort.
</p>

<p>
I copied my old code into ChatGPT, described the problem, and it came back with
an initial approach. From there I iterated it and asked for changes and fixes:
</p>

<ul class="org-ul">
<li>It initially wanted to replace whole parts of the DOM, which wasn't working and
seemed like a rabbit hole - so I suggested we just take our initial approach
of wrapping text in a <code>span</code> element, but parse the DOM and apply it to all
the elements in the selection.</li>

<li>There were then a few parsing errors that had to be corrected.</li>

<li>It was adding unnecessary spans to elements with no text content, which I
asked to remove.</li>

<li>I realised I wanted to skip any highlighted text that wasn't visible to the
user but that existed in the underlying DOM.</li>

<li>When testing, I was confused why my range wasn't going beyond a particular
<code>svg</code> element. I asked about this, and it helped me figure out that I needed
to use the selection's <code>rangeCount</code> along with
<code>document.getSelection().getRangeAt(i)</code>, because certain elements break up the
cursor selection state into multiple ranges, which you have to operate on
individually.</li>
</ul>

<p>
It wasn't perfect: I had to prompt it to fix things a fair bit, tell it what
approach I wanted to take, do some console logging to check why something wasn't
working, make some manual corrections, tidy up the code myself, etc.
</p>

<p>
Overall though, there was a notable contrast in how far I could get in a couple
of hours compared to three years ago when I was using search engines and Stack
Overflow for this exact same task. I can't imagine a more basic implementation
than the one I arrived at last time. This time around, with similar amounts of
laziness, we're doing things that I didn't achieve before<sup><a id="fnr.13" class="footref" href="#fn.13" role="doc-backlink">13</a></sup>: traversing the DOM, checking range boundary points, handling edge
cases, etc.
</p>

<p>
I think the big differentiator is in how detailed and tailored the inputs and
outputs are. Using Stack Overflow I tend to be focused on very narrow generic
questions - how do I do X in Javascript? I don't think I've ever <i>actually</i>
copy-pasted code from Stack Overflow, because the code is always small enough to
type, and often needs customising. But with ChatGPT it's more specifically
tailored to your situation and a copy-paste workflow can actually get you
started off ok: confirm the code looks safe to run, check the output, and
iterate from there.
</p>
</div>
</div>

<div id="outline-container-org28a9823" class="outline-3">
<h3 id="org28a9823"><span class="section-number-3">5.3.</span> Conclusion</h3>
<div class="outline-text-3" id="text-5-3">
<p>
Obviously there are downsides to this approach<sup><a id="fnr.14" class="footref" href="#fn.14" role="doc-backlink">14</a></sup>. I didn't think about the problem or solution deeply, I didn't learn
anything reliable, I've certainly missed other edge cases. If I did all my
coding like this then I'd be missing out on a lot of understanding, shipping a
lot of bad code, and I'd probably get into a state where I can't debug problems
because I don't understand my code well enough. I'm glad these capabilities
weren't around when I was a junior engineer, because the temptation to operate
in copy-paste mode instead of thinking properly or reading the docs would have
been very strong.
</p>

<p>
But, for this kind of situation where I don't care about understanding the
problem or solution well, I'm not putting anything into production, I'm not
doing anything novel, I just want something done quickly that appears to work -
then unquestionably I can get there faster and with less effort using ChatGPT
than I used to be able to via other tools. I don't have strong opinions
on the future of LLMs yet, but I agree with the view that someone who uses these
tools is going to have the capability to do certain things more quickly and
effectively than before, and for me personally I'm finding it pretty useful -
not to write all the code for me, but as a much more capable Stack Overflow-type
tool.
</p>
</div>
</div>
]]></description>
</item>

<item>
<title>Reorganising my encrypted partitions and backups</title>
<link>https://www.mattduck.com/2021-11-linux-backups.html</link>
<author>hi@mattduck.com (Matt Duck)</author>
<guid isPermaLink="false">5ca7e99d-b4d6-41b2-a6b0-3ea664c59384</guid>
<pubDate>Fri, 12 Nov 2021 23:41:00 +0000</pubDate>

<description><![CDATA[<p>
These notes give a high-level overview of some work I did to restructure how I
was backing up data at home. <b>YMMV - these aren't optimal decisions and the tools I'm using here will result in data loss if used incorrectly, so always be
careful if you're doing anything similar</b>.
</p>

<div id="outline-container-org0e71269" class="outline-3">
<h3 id="org0e71269"><span class="section-number-3">6.1.</span> My setup</h3>
<div class="outline-text-3" id="text-6-1">
<p>
My main home machine is a <a href="https://www.lenovo.com/gb/en/laptops/thinkpad/t-series/t450s/">Thinkpad T450s</a> running Arch. It has a single disk. The
vast majority of my user data (around 1TB) is stored on one partition encrypted
using <a href="https://en.wikipedia.org/wiki/Linux_Unified_Key_Setup">LUKS</a>, and for a few years I've been using Duplicity to make two separate
backups of this data - one to S3, and one to a local disk.
</p>

<p>
This has worked OK so far, but if I ever need to make another full
(ie. non-incremental) backup with Duplicity it's extremely slow, and I suspected
that some of this data didn't actually need to be in an incremental backup
system because either (1) it wasn't going to change again, or (2) I didn't
actually need it in the first place. So I wanted to check what data I had and
make some changes.
</p>
</div>

<div id="outline-container-org01a7984" class="outline-4">
<h4 id="org01a7984">Analysing disk usage with <code>duc</code></h4>
<div class="outline-text-4" id="text-org01a7984">
<p>
There are lots of tools that let you analyse disk usage, but I particularly like
<a href="https://duc.zevv.nl/">duc</a>, as you can run <code>duc index</code> to build up the database and then query separately
it without having to wait. The interactive visualisations provided by <code>duc gui</code>
also look nice:
</p>

<img src="duc.gif" alt="the most exciting thing on the page"/>
</div>
</div>

<div id="outline-container-org855b615" class="outline-4">
<h4 id="org855b615">The changes</h4>
<div class="outline-text-4" id="text-org855b615">
<p>
From the duc results I found some data that I was happy to delete. More
significantly though, I realised that I only actually had a few GB of active
working files, and hundreds of gigs of old files that I'm <i>not going to change
again</i>. The storage and usage requirements of these files was different enough
that it didn't make sense to use the same backup system for both.
</p>

<p>
So the plan was:
</p>

<ul class="org-ul">
<li>Split my main data partition into two. Move the old files that aren't going to
change to a new encrypted partition and mount it as readonly.</li>

<li>Take some one-off backups of this "readonly" partition.</li>

<li>Ensure my future Duplicity backups ignore this readonly data.</li>

<li>While I'm here, securely delete the data on some old hard drives that I have
lying around - as I've been putting this off for ages.</li>
</ul>
</div>
</div>
</div>

<div id="outline-container-orgf4c25e3" class="outline-3">
<h3 id="orgf4c25e3"><span class="section-number-3">6.2.</span> Resizing a LUKS-encrypted partition with gparted</h3>
<div class="outline-text-3" id="text-6-2">
<p>
I had to decrease the size of my main data partition to make space on the disk
for the new "readonly" partition. At first my web-searching led to <a href="https://wiki.archlinux.org/title/Resizing_LVM-on-LUKS">this Arch
wiki page on resizing LVM on LUKS</a>. I thought this might be applicable, but I'm
not actually using LVM (see <a href="https://en.wikipedia.org/wiki/Logical_volume_management">Logical Volume Management</a> for background on what LVM
is - it basically provides virtual partitions that exist as an abstraction
separately from the physical partitions on disk).
</p>

<p>
All I really needed to do was to decrease the partition size in a way that was
compatible with the LUKS encrypted volume. It turns out that <a href="https://gparted.org/">gparted</a> does all of
this for you.
</p>

<p>
You first have to make sure the encrypted partition is decrypted, so that
gparted can see that it's not full (otherwise it will prevent you from
decreasing the partition size):
</p>

<pre class="example" id="org336ef63">
$ export EXAMPLE_DEVICE=/dev/sdb1
$ cryptsetup open $EXAMPLE_DEVICE mydevice
</pre>

<p>
From there the "resize" feature in gparted just works. If you look at the logs it
produces you can see what operations it applies, which are:
</p>

<ul class="org-ul">
<li>Decrease the partition size.</li>
<li><code>e2fsck -f -y -v -C 0 $EXAMPLE_DEVICE</code> - check the filesystem on the decreased
partition.</li>
<li><code>resize2fs -p /dev/mapper/mydevice 1044475904K</code> - resize the filesystem.</li>
<li><code>cryptsetup -v --size 2088951808 resize 'mydevice'</code> - resize the LUKS volume (if
you were doing this manually this step wouldn't necessarily be required - LUKS
calculates the volume size automatically whenever the volume is decrypted, so
the resize command is only useful for a "live" resize).</li>
</ul>
</div>
</div>

<div id="outline-container-orgd092129" class="outline-3">
<h3 id="orgd092129"><span class="section-number-3">6.3.</span> Creating a new partition with cryptsetup</h3>
<div class="outline-text-3" id="text-6-3">
<p>
Once the main partition had been shrunk, I could use gparted to create a new
partition in the now-unallocated space.
</p>

<p>
To set up the new LUKS volume, you can use <code>cryptsetup</code>:
</p>

<pre class="example" id="orgf0065a6">
$ export MY_NEW_PARTITION=/dev/sda6
$ cryptsetup luksFormat -y -v --type luks2 $MY_NEW_PARTITION
</pre>

<p>
This sets up the encrypted volume, prompting you for a passphrase.
</p>

<p>
You can then use <code>cryptsetup open $MY_NEW_PARTITION mynewpartition</code>, and it will
appear as <code>/dev/mapper/mynewpartition</code>.
</p>

<p>
With the volume decrypted, you then need to create a filesystem:
</p>

<pre class="example" id="orge71d8e0">
$ mkfs.ext4 /dev/mapper/mynewpartition
mke2fs 1.46.4 (18-Aug-2021)
Creating filesystem with 2555904 4k blocks and 638976 inodes
Filesystem UUID: 2ea513e3-4cd2-479e-9ac2-1288cb99eb22
Superblock backups stored on blocks:
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632
</pre>

<p>
You can then mount this to confirm it works:
</p>

<pre class="example" id="orga8ad937">
$ mkdir /mnt/test
$ mount /dev/mapper/mynewpartition /mnt/test
</pre>

<p>
With this mounted, I could move the desired files onto the new partition.
</p>
</div>
</div>

<div id="outline-container-org6eab456" class="outline-3">
<h3 id="org6eab456"><span class="section-number-3">6.4.</span> Mounting the partition as readonly in fstab</h3>
<div class="outline-text-3" id="text-6-4">
<p>
By default Arch uses <a href="https://wiki.archlinux.org/title/systemd-boot">systemd-boot</a>. Assuming that you've got the <code>sd-encrypt</code> hook
configured in <code>/etc/mkinitcpio.conf</code>, you can configure the boot loader to decrypt
a volume on startup by editing <code>/boot/loader/entries/$myfile.conf</code> (for non-root
partitions you can also configure <code>/etc/crypttab</code>, but as my root
partition is encrypted I need to do that one here anyway, and so for consistency
I've got the other partitions configured here too).
</p>

<p>
For me the boot loader config looks something like this:
</p>

<pre class="example" id="org70823fc">
$ cat /boot/loader/entries/arch.conf
title Arch Linux
machine-id b4f148a3b61e89219feec13da2c5cfe6
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux.img
options rd.luks.name=29e50f84-592e-4dd7-bba5-5a91132341df=arch root=/dev/mapper/arch rootfstype=ext4 rw rd.luks.name=b385ad32-233d-403b-a1a4-6599d4586f30=mynewpartition
</pre>

<p>
The significant part here is
<code>rd.luks.name=b385ad32-233d-403b-a1a4-6599d4586f30=mynewpartition</code>. This will map
the device with the ID <code>b385ad32-233d-403b-a1a4-6599d4586f30</code> to
<code>/dev/mapper/mynewpartition</code>. To find the right ID for your partition, you can use
<code>lsblk</code>, eg:
</p>

<pre class="example" id="org3317e4c">
$ lsblk -f
NAME     FSTYPE      FSVER LABEL UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
sda
├─sda1   vfat        FAT32       41EA-BC5D                               484M    12% /boot
├─sda2   swap        1           a099ba9d-ab55-4e04-8308-79482bbcdf14
├─sda3   crypto_LUKS 2           29e5af84-592e-4d03-be85-5811957011df
│ └─arch ext4        1.0         da6db103-d6a5-43e8-a19b-a1d280184baa   13.2G    60% /
├─sda4   crypto_LUKS 2           b385ad32-233d-403b-a1a4-6599d4586f30
│ └─test ext4        1.0         e099b20-d45c-44e2-8ea1-31fcfa93ee58  823.2G    42% /f
└─sda5   ext4        1.0         08bacd07-b586-415c-b498-7105c41bdf4e
</pre>

<p>
To mount the filesystem on boot, you can then edit <code>/etc/fstab</code> to add an entry
for the partition, which will look something like this:
</p>

<pre class="example" id="orgd07eb30">
/dev/mapper/mynewpartition      /readonly       ext4        discard,ro,nofail      0 2
</pre>

<p>
This will mount the decrypted volume to <code>/readonly</code>. It can be set as readonly just by
providing the <code>ro</code> option.
</p>
</div>
</div>

<div id="outline-container-org46ce31a" class="outline-3">
<h3 id="org46ce31a"><span class="section-number-3">6.5.</span> Copying the partition to another disk with pv</h3>
<div class="outline-text-3" id="text-6-5">
<p>
Now that my "readonly" partition contains the data I want and automatically
decrypts on boot (if I enter the passphrase), I want to backup the data to
external disks. I want to do a block-level copy of the encrypted partition as
this is simple and gives me some guarantees that the data is the same.
</p>

<p>
The first step here is to create an appropriate partition on the target disk.
Gparted asks for the desired partition size in <a href="https://simple.wikipedia.org/wiki/Mebibyte">Mebibytes</a> (MiB). This means I
need to know the source partition size in MiB. I couldn't find a command
that provided this directly, so had to figure it out using the byte value
returned by <code>blockdev</code>:
</p>

<pre class="example" id="org0f97dc3">
$ echo $(($(sudo blockdev --getsize64 /dev/sda7) / 1048576))
600000
</pre>

<p>
There are various ways to then copy from one device to another. I used <a href="https://linux.die.net/man/1/pv">pv</a>, as it
provides useful feedback on progress:
</p>

<pre class="example" id="org8d4b874">
$ export MY_SOURCE_DEVICE=/dev/sda123
$ export MY_TARGET_DEVICE=/dev/sdb456
$ pv --timer --rate --progress --fineta -s "$(blockdev --getsize64 $MY_SOURCE_DEVICE)" $MY_SOURCE_DEVICE &gt; $MY_TARGET_DEVICE
</pre>

<p>
The <code>-s</code> argument is useful - it tells <code>pv</code> how many bytes to expect, so that it can
display accurate progress information.
</p>

<p>
Once it's done, you can check that the partitions are the same, and verify that
it worked by opening the new partition with <code>cryptsetup</code> and mounting it again.
</p>
</div>
</div>

<div id="outline-container-orgc659e01" class="outline-3">
<h3 id="orgc659e01"><span class="section-number-3">6.6.</span> Backing up LUKS headers</h3>
<div class="outline-text-3" id="text-6-6">
<p>
LUKS volumes contain a metadata header. It's useful to backup this header to
avoid data loss. Quoting from the cryptsetup manpage:
</p>

<blockquote>
<p>
If the header of a LUKS volume gets damaged, all data is permanently lost unless
you have a header-backup. If a key-slot is damaged, it can only be restored from
a header-backup or if another active key-slot with known passphrase is
undamaged. Damaging the LUKS header is something people manage to do with
surprising frequency. This risk is the result of a trade-off between security
and safety, as LUKS is designed for fast and secure wiping by just overwriting
header and key-slot area.
</p>
</blockquote>

<p>
To support this, <code>cryptsetup</code> provides both a <code>luksHeaderBackup</code> command and a
<code>luksHeaderRestore</code> command.
</p>
</div>
</div>

<div id="outline-container-org20b5d78" class="outline-3">
<h3 id="org20b5d78"><span class="section-number-3">6.7.</span> Erasing old disks</h3>
<div class="outline-text-3" id="text-6-7">
<p>
I also wanted to securely erase some old disks I had. There are a few ways to do
this, but I just looked at two:
</p>
</div>

<div id="outline-container-org354eb0c" class="outline-4">
<h4 id="org354eb0c">Using secure erase</h4>
<div class="outline-text-4" id="text-org354eb0c">
<p>
It's possible to issue a Secure Erase ATA instruction to supported devices. This
does a firmware-level erase, which can offer advantages over just writing bits
to disk (eg. it can be significantly faster, and can erase things that can't be
erased by writing to the device, like bad sectors).
</p>

<p>
You can check whether your device supports secure erase by using <code>hdparm</code>:
</p>

<pre class="example" id="org722d573">
$ sudo hdparm -I /dev/sda | grep -i erase
                supported: enhanced erase
        4min for SECURITY ERASE UNIT. 8min for ENHANCED SECURITY ERASE UNIT.

$ sudo hdparm -I /dev/sdb | grep -i erase
                supported: enhanced erase
        396min for SECURITY ERASE UNIT. 396min for ENHANCED SECURITY ERASE UNIT.
</pre>

<p>
If your disk does support this, then you can use <code>hdparm</code> to issue the erase in a
couple of commands - see <a href="https://ata.wiki.kernel.org/index.php/ATA_Secure_Erase">ATA Secure Erase</a> for instructions.
</p>
</div>
</div>

<div id="outline-container-org68918ed" class="outline-4">
<h4 id="org68918ed">Using pv (or similar)</h4>
<div class="outline-text-4" id="text-org68918ed">
<p>
If your disk doesn't support secure erase, then there are various options that
basically involve writing bytes to the disk using either a dedicated erase tool
like <code>shred</code>, or by coping bytes to the device manually using a tool <code>dd</code> or
<code>cat</code>. For these disks I used <code>pv</code> again as I just wanted to do something simple and
(relatively) fast - eg. I'm not worried about doing multiple iterations.
</p>

<p>
One choice here is what your source data should be. There are basically two
sensible candidates:
</p>

<ul class="org-ul">
<li><code>/dev/zero</code>: write zeros to the disk. This is often fine, but can supposedly be
undone on older disks by amplifying the signal coming from the disk head to
differentiate a "zero" that used to store 1 from one that used to store 0.</li>

<li><code>/dev/urandom</code>: write random data to the disk. Slower than <code>/dev/zero</code>, but safer
if your security model involves protecting against that read amplification
attack. I'm curious <i>how</i> much slower this is in practice, but haven't tested
it.</li>
</ul>
</div>
</div>
</div>

<div id="outline-container-org3e01b5a" class="outline-3">
<h3 id="org3e01b5a"><span class="section-number-3">6.8.</span> Monitoring my duplicity backup status</h3>
<div class="outline-text-3" id="text-6-8">
<p>
With these changes done I took the opportunity to swap my duplicity
backup to a new S3 bucket, to remove any dependency on the old data.
</p>

<p>
My duplicity script runs on a cron schedule, and essentially just does this:
</p>

<div class="org-src-container">
<pre class="src src-sh">#!/bin/bash
set -e

echo "$$ | Starting job: $0"

# See man flock for this snippet. It locks so only one version of the script can
# run at once.
[ "${FLOCKER}" != "$0" ] &amp;&amp; exec env FLOCKER="$0" flock --verbose -en "$0" "$0" "$@" || :
echo "$$ | Obtained flock"

# Run the backup
duplicity /mysource boto3+s3://mybucket \
          --name mybackupname \
          --s3-use-ia \
          --archive-dir=/myarchivedir \
          --exclude-filelist=/mylist.exclude \
          --full-if-older-than 365D

# Then some cleanup steps that I'll ignore

# Store the last time the backup finished
date --iso-8601=seconds &gt; /last_success
</pre>
</div>

<p>
It would be easy for me to not notice if the backup stopped working, so I
display the time of last success in my i3/exwm status bar:
</p>

<img src="duplicity-i3.png" alt="i3 status icon"/>

<p>
This means the "S3" backup last succeeded 7 minutes ago. The logic for building
this string is something like:
</p>

<div class="org-src-container">
<pre class="src src-sh">if test -f /last_success; then
    DUP_S3_DATE=$(cat /last_success)
    DUP_S3_SECONDS_AGO=$(( ( $(date +%s) - $(date -d "$DUP_S3_DATE" +%s) )))
    DUP_S3_MINUTES_AGO=$(($DUP_S3_SECONDS_AGO / 60))
    DUP_S3_HOURS_AGO=$(($DUP_S3_SECONDS_AGO / (60 * 60)))
    DUP_S3_DAYS_AGO=$(($DUP_S3_SECONDS_AGO / (24 * 60 * 60)))
    if [ $DUP_S3_DAYS_AGO -gt 1 ]; then DUP_S3_MSG="${DUP_S3_DAYS_AGO}d";
    elif [ $DUP_S3_HOURS_AGO -gt 1 ]; then DUP_S3_MSG="${DUP_S3_HOURS_AGO}h";
    elif [ $DUP_S3_MINUTES_AGO -gt 1 ]; then DUP_S3_MSG="${DUP_S3_MINUTES_AGO}m";
    elif [ $DUP_S3_SECONDS_AGO -gt 1 ]; then DUP_S3_MSG="${DUP_S3_SECONDS_AGO}s";
    else DUP_S3_MSG="?";
    fi
else DUP_S3_MSG="[nofile]";
fi

</pre>
</div>

<p>
Thinking about it, it wouldn't be much work to also do an automatic restore to
make sure I'm still able to recover, and to display that time too.
</p>
</div>
</div>

<div id="outline-container-org3dffa01" class="outline-3">
<h3 id="org3dffa01"><span class="section-number-3">6.9.</span> Backups are hard</h3>
<div class="outline-text-3" id="text-6-9">
<p>
My macbook was stolen a few years back, and at the time I was just running one
regular backup to S3 - so I had no other copies of my non-cloud data. I hadn't
tested restoring this backup from any machine other than the macbook itself, and
when I did need to access the data in an emergency it was pretty stressful not
knowing if I had all the right credentials accessible and if the restore was
going to work. It was a big relief when it did work (thanks <a href="https://www.arqbackup.com/">Arq</a>).
</p>

<p>
We're approaching 2022 and I think backups for personal data are still hard to
get right, even for technical users. Sure, I make things more complicated by
using linux and being more conservative than a lot of people are about sharing
private data with cloud services. But I don't think my requirements are too
outrageous:
</p>

<ul class="org-ul">
<li>I have local data which doesn't natively belong to a cloud service, in the
order of single-digit TBs.</li>

<li>I want my data to be protected if I accidentally erase something or if my
hardware dies.</li>

<li>I want my data to be protected in case of house theft or fire - so I need at
least one off-site copy.</li>

<li>I use my laptop on the sofa and other places where it's inconvenient to have
an external drive connected via cable.</li>

<li>For a cloud service, I need to be able to control the encryption myself, or
the provider needs to be very reputable so I'm comfortable that they can't
access my data.</li>

<li>I don't want to be locked in to a single cloud service provider.</li>
</ul>

<p>
There's a lot to figure out to achieve this - it's not common knowledge and it's
a big enough topic that it can't be self-taught in a quick web search. You have
to think about choice of backup software, cost analysis of cloud services,
purchasing disks and/or NAS devices, waiting days for the initial backups to
run, doing maintenance to confirm that restore process actually works,
potentially <i>changing</i> a cloud provider which means another long transfer process,
etc.
</p>

<p>
I can't speak for Windows, but at least on MacOS this doesn't "just work". Time
Machine is nice if you have an external disk connected, but I'd have to do some
research to figure out how to set it up with a network drive, and then solve the
"offsite" backup problem myself separately - and Time Machine isn't even enabled
by default (probably as it requires an external drive).
</p>

<p>
I don't think this problem can be solved without requiring <i>some</i> thought from the
user, but it feels like the default behaviour for consumer-facing OSes could be
better - because I think most people I know don't go out of their way to back up
anything at all. Which can be fine - in practice you can go for many years
without losing data, and many people nowadays may not even <i>have</i> much data that
doesn't already live in a cloud service. But it sucks if you do lose something
important.
</p>

<p>
I think the closest I've seen to a multi-backend, set-and-forget solution is
Arq, which is very nice but sadly doesn't support linux, and still requires some
work to figure out your backend configurations. <a href="https://www.tarsnap.com/">Tarsnap</a> and Backblaze also have
their uses - I have memories of very slow upload speeds for Backblaze but
I suspect that's better now through some combination of disk/network/software
performance.
</p>
</div>
</div>
]]></description>
</item>

<item>
<title>Capturing screenshots and recordings with exwm</title>
<link>https://www.mattduck.com/2021-06-exwm-screenshots.html</link>
<author>hi@mattduck.com (Matt Duck)</author>
<guid isPermaLink="false">9526da4d-1a5c-4946-9b60-6ee618a3d327</guid>
<pubDate>Fri, 18 Jun 2021 12:41:00 +0100</pubDate>

<description><![CDATA[<p>
I've been using <code>exwm</code> as my window manager for a while now. I like the approach
but there are a few rough edges. One of these was that I needed to implement
something to take simple screenshots and screen recordings. Here's how I got it
working.
</p>

<div id="outline-container-org9a27e11" class="outline-3">
<h3 id="org9a27e11"><span class="section-number-3">7.1.</span> The result</h3>
<div class="outline-text-3" id="text-7-1">
<video autoplay loop controls/>
  <source src="exwm-screenshot-example.mp4" type="video/mp4">
  This video isn't supported in your browser.
</video>

<p>
This image shows me pressing <code>super-shift-4</code> to capture a screenshot by running a
function <code>md/screenshot-image-selection</code>. After capture the image is automatically
opened in firefox.
</p>

<p>
The video itself was taken by pressing <code>super-shift-5</code> to trigger a function
<code>md/screenshot-video-selection-start</code>, and then another key to run
<code>md/screenshot-video-stop</code> to stop recording.
</p>
</div>
</div>


<div id="outline-container-org36d9630" class="outline-3">
<h3 id="org36d9630"><span class="section-number-3">7.2.</span> The exwm bindings</h3>
<div class="outline-text-3" id="text-7-2">
<p>
I wanted something similar to the MacOS <code>cmd-shift-4/5</code> bindings, so I added them
to <code>exwm-input-global-keys</code>:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(setq exwm-input-global-keys
      `(;; Various other keys...

        ;; Prompt for a selection and take a screenshot
        (,(kbd "s-$") . md/screenshot-image-selection)
        ;; Prompt for a selectoin and start a video
        (,(kbd "s-%") . md/screenshot-video-selection-start)
        ;; Stop the video
        (,(kbd "s-^") . md/screenshot-video-stop)))
</pre>
</div>
</div>
</div>

<div id="outline-container-org7a96bdb" class="outline-3">
<h3 id="org7a96bdb"><span class="section-number-3">7.3.</span> The elisp functions</h3>
<div class="outline-text-3" id="text-7-3">
<p>
The functions themselves just call out to a script I wrote named <code>,screenshot</code>:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(defun md/screenshot-image-selection ()
  (interactive)
  (shell-command ",screenshot --image-selection"))

(defun md/screenshot-video-selection-start ()
  (interactive)
  (shell-command ",screenshot --video-selection-start"))

(defun md/screenshot-video-stop ()
  (interactive)
  (shell-command ",screenshot --video-stop"))
</pre>
</div>
</div>
</div>

<div id="outline-container-orgbbb314b" class="outline-3">
<h3 id="orgbbb314b"><span class="section-number-3">7.4.</span> The script</h3>
<div class="outline-text-3" id="text-7-4">
<p>
The <code>,screenshot</code> script implements shell equivalents of all three elisp
functions. This could easily be moved inline to the elisp code rather than in a
separate script, but I wanted to be able to use it elsewhere:
</p>

<div class="org-src-container">
<pre class="src src-sh">#!/bin/bash
#
# Features for capturing the screen as image or video.

_THIS_DATE="$(date --iso-8601=second)"
_IMAGE_OUTPUT="/f/inbox/screenshots/${_THIS_DATE}.png"
_VIDEO_OUTPUT="/f/inbox/screenshots/${_THIS_DATE}.mp4"

function image-selection () {
    maim -s &gt;"$_IMAGE_OUTPUT" &amp;&amp; firefox "$_IMAGE_OUTPUT"
}

function video-selection-start () {
    # Use slop to grab screen area
    slop=$(slop -f "%x %y %w %h %g %i") || exit 1
    read -r X Y W H G ID &lt; &lt;(echo "$slop")

    # make the width + height divisble by 2 so ffmpeg doesn't error
    if ! [ $((W%2)) -eq 0 ]; then W=$((W+1)); fi
    if ! [ $((H%2)) -eq 0 ]; then H=$((H+1)); fi

    # start capturing video.
    # We use yuv420p here otherwise it can't be played by Firefox.
    # See https://bugzilla.mozilla.org/show_bug.cgi?id=1368063
    ffmpeg -f x11grab -s "$W"x"$H" -r 60 -i :0.0+"$X","$Y" -vcodec h264 -crf 18 -pix_fmt yuv420p -y "$_VIDEO_OUTPUT"  &gt;&gt; /tmp/ffmpg-record.log 2&gt;&amp;1 &amp;

    # store pid
    echo $! &gt;/tmp/ffmpeg-record.pid
    echo "$_VIDEO_OUTPUT" &gt;/tmp/ffmpeg-record.filename
}

function video-stop() {
   pkill --signal INT --pidfile /tmp/ffmpeg-record.pid &amp;&amp; firefox "$(cat /tmp/ffmpeg-record.filename)"
}

case "$1" in
    --image-selection) image-selection;;
    --video-selection-start) video-selection-start;;
    --video-stop) video-stop;;
    *) echo "argument invalid or not provided, exiting." &amp;&amp; exit 1
esac
</pre>
</div>
</div>

<div id="outline-container-orgc02552c" class="outline-4">
<h4 id="orgc02552c">How screenshots work</h4>
<div class="outline-text-4" id="text-orgc02552c">
<p>
The <code>image-selection</code> function calls out to simple terminal tool called <a href="https://github.com/naelstrof/maim">maim</a>,
which prompts you for a selection/window and takes the screenshot.
</p>
</div>
</div>

<div id="outline-container-orgd08c484" class="outline-4">
<h4 id="orgd08c484">How videos work</h4>
<div class="outline-text-4" id="text-orgd08c484">
<p>
The <code>video-selection-start</code> function uses <code>ffmpeg</code> with <code>x11grab</code> as the input source.
<code>ffmpeg</code> doesn't provide an easy way to choose what part of the screen to record -
you instead have to pass coordinates as arguments. So we use <a href="https://github.com/naelstrof/slop">slop</a> to make a
selection on the screen and extract the coordinates, and then pass those to
<code>ffmpeg</code>.
</p>

<p>
Unlike screenshots, videos also need a stop instruction. <code>ffmpeg</code> expects to
receive a SIGINT to stop recording. So we write two files to <code>/tmp</code>:
</p>

<ol class="org-ol">
<li>A pid file. This allows us to stop the video by doing <code>pkill --signal INT
   --pidfile /tmp/ffmpeg-record.pid</code></li>

<li>The output path of the video. This allows us to automatically open the video
with firefox.</li>
</ol>
</div>
</div>
</div>


<div id="outline-container-org442e80a" class="outline-3">
<h3 id="org442e80a"><span class="section-number-3">7.5.</span> FFmpeg gotchas</h3>
<div class="outline-text-3" id="text-7-5">
<p>
I ran into a few issues configuring <code>ffmpeg</code>:
</p>
</div>

<div id="outline-container-org53de364" class="outline-4">
<h4 id="org53de364">Firefox doesn't recognise the video format</h4>
<div class="outline-text-4" id="text-org53de364">
<p>
The default ffmpeg video output was failing to play on Firefox - <i>"Video can't
be played because the file is corrupt"</i>.
</p>

<p>
The problem turned out not to be that the file was corrupt, but that <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1368063">Firefox
doesn't support ffmpeg's default YUV444 chroma subsampling setting</a> for
H.264. A workaround is to specify <code>-pix_fmt yuv420p</code>. (I'm not sure whether this
affects codecs other than H.264).
</p>
</div>
</div>

<div id="outline-container-orgbb2869e" class="outline-4">
<h4 id="orgbb2869e">Dimensions must be divisible by 2</h4>
<div class="outline-text-4" id="text-orgbb2869e">
<p>
Sometimes <code>slop</code> would produce an odd number for the input height, which is
invalid for H.264 and causes <code>ffmpeg</code> to throw a <i>"height not divisible by 2"</i>
error. There are a few solutions suggested <a href="https://stackoverflow.com/questions/20847674/ffmpeg-libx264-height-not-divisible-by-2">on this thread</a>, but for now I'm just
adding 1 to my width/height if they're not even because I don't need the values
to be exact.
</p>
</div>
</div>

<div id="outline-container-org307b9f0" class="outline-4">
<h4 id="org307b9f0">Screen tearing</h4>
<div class="outline-text-4" id="text-org307b9f0">
<p>
Finally I had an issue where during playback I was seeing screen tearing in the
video. This wasn't specific to exwm or ffmpeg - it also occurred when I was
using i3 and other video recording tools.
</p>

<p>
I was using <a href="https://wiki.archlinux.org/title/Picom">picom</a> as an X compositor, and was able to isolate the issue to only
occur when picom was running with the <code>glx</code> backend and <code>vsync=true</code>. There seem to
be a few options to fixing it - eg. setting <code>vsync=false</code> in picom, switching to
the <code>xrender</code> backend instead of <code>glx</code>, or even disabling picom entirely. Right now
I'm disabling it entirely as I don't notice much difference when it's on.
</p>

<p>
With this fixed everything is working well. You can find the code in my
<a href="https://github.com/mattduck/dotfiles/blob/7176f532a556ae124483bbef480417c30eed8def/bin/%2Cscreenshot">dotfiles</a>.
</p>
</div>
</div>
</div>
]]></description>
</item>

<item>
<title>A fun problem with fzf-tab-completion and echo</title>
<link>https://www.mattduck.com/2021-05-fzf-tab-completion.html</link>
<author>hi@mattduck.com (Matt Duck)</author>
<guid isPermaLink="false">97996325-712d-4cbf-874f-e71dc68ea717</guid>
<pubDate>Sun, 09 May 2021 16:25:00 +0100</pubDate>

<description><![CDATA[<p>
<a href="https://github.com/junegunn/fzf">Fzf</a> is great, but I've always thought the bash tab completion wasn't as polished
as it could be. I want to be able to hit <code>&lt;TAB&gt;</code> and have fzf pop up to navigate
the candidates, but it doesn't hook into bash completion like you'd
expect. Instead, there are special implementations of completion for different
commands - eg. you might have to call <code>_fzf_setup_completion dir tree</code> to
configure an fzf completion that prompts you for directories when you run
<code>tree</code>. In addition to requiring extra setup, it also doesn't provide support for
ad-hoc flags, so it's pretty limited.
</p>

<p>
Yesterday I was looking for a better way to do this, and came across <a href="https://github.com/lincheney">lincheney's</a>
<a href="https://github.com/lincheney/fzf-tab-completion">fzf-tab-completion</a>. This seems to work pretty well, but I had to fix a couple of
things to get it working properly.
</p>

<div id="outline-container-org1885a0d" class="outline-3">
<h3 id="org1885a0d"><span class="section-number-3">8.1.</span> First - macOS support</h3>
<div class="outline-text-3" id="text-8-1">
<p>
You can check the github page for instructions on how to use
fzf-tab-completion - basically you just source a bash script which defines
a function <code>fzf_bash_completion</code>, and then you use <code>bind</code> to run <code>fzf_bash_completion</code>
on a particular keypress (eg. <code>&lt;TAB&gt;</code>).
</p>

<p>
I tried this on macOS and hit a common problem: the GNU and BSD versions of
certain utils aren't compatible - they have various differences in their
flags/behaviour, and the bash script is assuming the GNU versions of <code>sed</code> and
<code>awk</code>. On macOS you can <code>brew install coreutils</code> to get the GNU versions, but they
get prefixed with <code>g</code> to avoid breaking anything that assumes the default BSD
versions.
</p>

<p>
There are a few approaches to fixing this. I just opted for the one that
required the least work - changing the script to prefer <code>gawk</code> and <code>gsed</code> if they're
available.
</p>
</div>
</div>

<div id="outline-container-org3b43d2b" class="outline-3">
<h3 id="org3b43d2b"><span class="section-number-3">8.2.</span> The main event - why doesn't kubectl complete namespaces</h3>
<div class="outline-text-3" id="text-8-2">
<p>
After that it seemed to be working:
</p>

<img src="fzf-tab-completion-1.png" alt="fzf-tab-completion git checkout"/>

<img src="fzf-tab-completion-2.png" alt="fzf-tab-completion git checkout completed"/>

<p>
I could type <code>git checkout &lt;TAB&gt;</code> and use fzf to complete the branch names, or <code>ls
--&lt;TAB&gt;</code> and select a long flag. It even seems I can complete multiple
flags at once by adding <code>--multi</code> to <code>FZF_COMPLETION_OPTS</code>.
</p>

<p>
One place where I wanted to use fzf for completion was <code>kubectl</code>. There are
various tools that add fzf features to kubectl or that provide nice replacements
for kubectl commands, but I'd find it useful to have fzf completion that "just
works" when I'm running ad-hoc kubectl commands.
</p>

<p>
I tried this for a bit and it did work:
</p>

<ul class="org-ul">
<li><code>kubectl get pod &lt;TAB&gt;</code> - completes pod names</li>

<li><code>kubectl get &lt;TAB&gt;</code> - completes resources</li>

<li><code>kubectl -n foo rollout restart deployment &lt;TAB&gt;</code> - completes deployments in the "foo" namespace</li>
</ul>

<p>
Then I hit a problem running <code>kubectl get pod -n &lt;TAB&gt;</code>. This is supposed to
complete namespaces, but it was giving me a list of pods. I double-checked that
the standard kubectl bash completion <i>does</i> complete namespaces as expected in
this situation, so it looked like something might be wrong with the fzf
completion.
</p>
</div>
</div>

<div id="outline-container-org095fde7" class="outline-3">
<h3 id="org095fde7"><span class="section-number-3">8.3.</span> Debugging</h3>
<div class="outline-text-3" id="text-8-3">
<p>
After trying a few variations I realised that the fzf completion <i>would</i> work if I
specified the namespace flag as <code>-n=&lt;TAB&gt;</code> instead of <code>-n &lt;TAB&gt;</code>. I knew the bash
script contained a decent amount of regex/parsing logic, so wondered if
something could be wrong with how it handled flags.
</p>

<p>
I started decorating the script with debug lines like <code>echo "some_variable:
$SOME_VARIABLE" &gt;&gt; /tmp/debug.log</code>, or <code>| tee -a /tmp/debug.log</code>. It turned out
there were certain lines where a flag would usually be printed, but if I used
<code>-n</code>, it would be missing. For example:
</p>

<pre class="example" id="orgcaec3a9">
# (some printed output with -n=)
line: k get pod -n=
SHELL SPLIT ----
line: -n=
buffer:
line: pod
buffer:
line: get
buffer:
line: k
buffer:
COMP_WORDS: k get pod -n=
COMP_CWORD: 3
</pre>

<pre class="example" id="org5c1ee00">
# (some printed output with -n)
line: k get pod -n
SHELL SPLIT ----
line: -n
buffer:
line: pod
buffer:
line: get
buffer:
line: k
buffer:
COMP_WORDS: k get pod  # &lt;-- where did -n go?
COMP_CWORD: 3
</pre>

<p>
I continued to try different inputs and then noticed that <code>-e</code> was also
affected. At this point I ran through the whole lowercase alphabet&#x2026; and <code>-n</code> and
<code>-e</code> were the only flags that didn't work.
</p>

<p>
I wanted to narrow down where the flags were being stripped in the script. The
<code>-n</code> and <code>-e</code> flags should have been a clue but I was still thinking about regex at
this point, so I started by commenting out some of the regex/sed code, and also
calling some of the intermediate functions manually.
</p>

<p>
Eventually I narrowed it to this function which gets called on each argument:
</p>

<div class="org-src-container">
<pre class="src src-sh">$ printf '%s\n' '-a' | _fzf_bash_completion_flatten_subshells
&gt;&gt; -a

$ printf '%s\n' '-n' | _fzf_bash_completion_flatten_subshells
&gt;&gt;
</pre>
</div>

<p>
From there it was easy to find the offending line. It was this:
</p>

<div class="org-src-container">
<pre class="src src-sh">echo "$line$buffer"
</pre>
</div>

<p>
This looks harmless enough, but <code>$buffer</code> was an empty variable, and <code>$line</code>
contained our flag, so this was executing <code>echo "-n"</code> or <code>echo "-e"</code>. <code>-n</code> and <code>-e</code> are
echo flags: echo essentially interprets this as <code>echo -n ""</code> or <code>echo -e ""</code>, and
prints an empty line. This is why only these particular flags were affected.
</p>

<p>
(Had I tried capital letters, I'd have found that <code>-E</code> also gets stripped. I think
there can be issues with other input too but I haven't delved into it).
</p>
</div>
</div>

<div id="outline-container-org1ff816b" class="outline-3">
<h3 id="org1ff816b"><span class="section-number-3">8.4.</span> The solution: printf</h3>
<div class="outline-text-3" id="text-8-4">
<p>
Weirdly, there doesn't seem to be a way to print the literal <code>-n</code> using echo. I'm
sure there are various alternative ways to solve this, but I opted for replacing
the invocations of <code>echo "$foo"</code> with <code>printf '%s\n' "$foo"</code>. <code>printf</code> is a coreutils
command similar to C's <code>printf</code> function. It's commonly available and was already
used elsewhere in the fzf-tab-completion script, so it was an obvious choice.
</p>

<p>
After that it worked! I've tried various combinations of flags and everything
is completing nicely so far. It's not as instant as using the standard bash
completion, but it's going to be a lot nicer for certain commands, and is much
more useful for me than the builtin tab completion that comes with fzf.
</p>
</div>
</div>

<div id="outline-container-org89de452" class="outline-3">
<h3 id="org89de452"><span class="section-number-3">8.5.</span> What version of echo was this?</h3>
<div class="outline-text-3" id="text-8-5">
<p>
Running <code>which echo</code> or <code>man echo</code> might point to the GNU echo program, but when you
run <code>echo</code> in bash then by default you'll be using bash's builtin echo
function. There are slight differences between the two, but both are affected by
this issue. You can test this by doing <code>enable -n echo</code> to disable bash's builtin
echo.
</p>

<p>
The GNU version has an additional fun (but easier to debug) problem: if I had
been using this program and included the flag <code>--help</code>, it would have printed the
help text instead of the literal <code>--help</code> value.
</p>
</div>
</div>

<div id="outline-container-orga20b5a6" class="outline-3">
<h3 id="orga20b5a6"><span class="section-number-3">8.6.</span> Why is the GNU echo program/bash function designed like this?</h3>
<div class="outline-text-3" id="text-8-6">
<p>
I'm curious about this - I think I had come across this problem before but I
didn't have it in mind when I was debugging this issue. It's obviously a gotcha
that many people will be aware of, but it seems like bad design from a couple of
angles:
</p>

<ol class="org-ol">
<li>If you're unlucky enough to not know about this issue, it will violate
expectations - we have a function that prints <i>almost</i> everything except when
your string happens to clash with echo's own flags.</li>

<li>It's implicit and doesn't give feedback to the user. The risk isn't
documented in the GNU manpage or the bash help text, and there's nothing in
the output of the command that hints to the user that this issue may have
occurred or why it happened.</li>
</ol>

<p>
One sign that it's easy to forget this issue is that even when I was thinking
about this problem and trying to debug the script, I was using <code>echo</code> out of
habit, and nearly fell into the exact same problem by doing <code>echo
"$variable_that_can_potentially_hold_-n".</code>
</p>

<p>
I'm sure there are some historical/standards design reasons for it being this
way, but I haven't looked into it yet.
</p>
</div>
</div>

<div id="outline-container-org3693458" class="outline-3">
<h3 id="org3693458"><span class="section-number-3">8.7.</span> Lesson - don't use echo to print variables</h3>
<div class="outline-text-3" id="text-8-7">
<p>
This is something I'll be conscious to pick up in code reviews and my own
scripts going forwards. It seems wise to avoid echo for anything that handles
user input, and particularly anything related to parsing command-line args.
</p>

<p>
fzf-tab-completion is available <a href="https://github.com/lincheney/fzf-tab-completion">on github</a>. Hopefully these fixes (or similar)
can be made available for everybody upstream at some point, but if not you
should be able to find them via that page.
</p>
</div>
</div>
]]></description>
</item>

<item>
<title>Upgrading to Emacs 28.0 for native compilation</title>
<link>https://www.mattduck.com/2021-05-upgrading-to-emacs-28.html</link>
<author>hi@mattduck.com (Matt Duck)</author>
<guid isPermaLink="false">158e063d-a8b5-4c22-b34a-9957cec07df6</guid>
<pubDate>Sat, 08 May 2021 10:11:00 +0100</pubDate>

<description><![CDATA[<p>
This is a record of how I built Emacs 28 with native compilation on macOS
(Intel), and the issues I encountered upgrading my config from 26.3. I'm
primarily writing this for myself in case I run into similar problems in the
future, but hopefully it can be useful for somebody else too.
</p>

<div id="outline-container-orge1ff64a" class="outline-3">
<h3 id="orge1ff64a"><span class="section-number-3">9.1.</span> Why I wanted to upgrade</h3>
<div class="outline-text-3" id="text-9-1">
</div>
<div id="outline-container-org044b079" class="outline-4">
<h4 id="org044b079">Emacs 27.1 - faster JSON with libjansson</h4>
<div class="outline-text-4" id="text-org044b079">
<p>
Emacs 27.1 was released in August 2020. One of the changes was that it
introduced was support for <a href="https://github.com/akheron/jansson">libjansson</a>, a C library for working with JSON, which is
significantly faster than <code>json.el</code>. A place where this is particularly beneficial
is for LSP performance, as the LSP clients and servers communicate using JSON.
</p>
</div>
</div>

<div id="outline-container-org9c5a4b1" class="outline-4">
<h4 id="org9c5a4b1">Emacs 28 - faster everything with libgccjit</h4>
<div class="outline-text-4" id="text-org9c5a4b1">
<p>
This was my motivation for the upgrade. <a href="https://lists.gnu.org/archive/html/emacs-devel/2021-04/msg01175.html">2 weeks ago</a> the native compilation branch
(led by Andrea Corallo and previously named <a href="http://akrl.sdf.org/gccemacs.html">gccemacs</a>) was merged into master
(the development branch for what will later become Emacs 28.1). This project
uses <a href="https://gcc.gnu.org/onlinedocs/jit/">libgccjit</a> to perform ahead-of-time compilation of emacs-lisp bytecode (<code>.elc</code>
files) to native code (new <code>.eln</code> files), which adds general latency improvements
to Emacs across the board.
</p>
</div>
</div>
</div>

<div id="outline-container-orgf68c1eb" class="outline-3">
<h3 id="orgf68c1eb"><span class="section-number-3">9.2.</span> Install steps for MacOS</h3>
<div class="outline-text-3" id="text-9-2">
<p>
I used jimeh's <a href="https://github.com/jimeh/build-emacs-for-macos">build-emacs-for-macos</a> script, which does most of the work for
you. I ran:
</p>

<ol class="org-ol">
<li><code>brew bundle</code> - this installs all the dependencies contained in the Brewfile.</li>
<li><code>./build-emacs-for-macos --no-frame-refocus --git-sha
   83a915d3dfafd5f3d737afe1e13b75e4dd3aef96 master</code> - this compiles Emacs.</li>
<li><code>cd builds &amp;&amp; tar -xjf Emacs.app-\[master\]\[2021-04-25\]\[83a915d\]\[macOS-10.15\]\[x86_64\].tbz</code> - this
extracts the compiled Emacs.app from the builds directory.</li>
<li><code>./Emacs.app/Contents/MacOS/Emacs --debug-init</code> - start Emacs and see what
issues occur.</li>
<li>After fixing a lot of new errors I replaced <code>/Applications/Emacs.app</code> with the new <code>Emacs.app</code>.</li>
</ol>

<p>
Some notes on the flags for the build script:
</p>

<ul class="org-ul">
<li>I chose commit <code>83a915d3dfafd5f3d737afe1e13b75e4dd3aef96</code> because it was the most
recent commit in jimeh's <a href="https://github.com/jimeh/build-emacs-for-macos/issues/6">list of known good commits for native-comp</a>.</li>

<li>Native compilation is controlled by the <code>--with-native-comp</code> flag, but is enabled by default.</li>

<li><code>--no-frame-refocus</code> prevents Emacs from raising another frame when a frame is
closed. See <a href="https://xenodium.com/no-emacs-frame-refocus-on-macos/">Álvaro Ramírez's post on this</a>.</li>
</ul>
</div>
</div>

<div id="outline-container-orgd8eec68" class="outline-3">
<h3 id="orgd8eec68"><span class="section-number-3">9.3.</span> Enabling native compilation</h3>
<div class="outline-text-3" id="text-9-3">
<p>
Native compilation should be enabled by default. Some site elisp files will have
been compiled during Emacs' compilation, but other libraries will be compiled
asynchronously when you load them (which means you don't get all the benefits
straight away - after starting Emacs you have to wait for libraries to be
compiled).
</p>

<p>
It was immediately clear to me that this compilation was executing, as my
<code>*Warnings*</code> buffer started to fill with warnings. Some were harmless, like
<i>"assignment to free variable"</i> when compiling my <code>init.el</code>, and others were actual
errors.
</p>

<p>
I only had to make one change to enable something related to native
compilation. I had a couple of places where I was using <code>(load-file)</code> rather than
<code>(require)</code>, and these didn't seem to be compiled automatically, so I did:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(when (fboundp 'native-compile-async)
  (native-compile-async "path-to-my-file.el"))
</pre>
</div>
</div>
</div>

<div id="outline-container-org5373916" class="outline-3">
<h3 id="org5373916"><span class="section-number-3">9.4.</span> Things that went wrong</h3>
<div class="outline-text-3" id="text-9-4">
<p>
I ended up having to fix a lot of small issues before I could run my existing
<code>init.el</code> without it failing on startup (or on native compilation). Most of the
problems were due to upgrading Emacs and individual package versions rather than
native compilation itself.
</p>
</div>

<div id="outline-container-org850a4fb" class="outline-4">
<h4 id="org850a4fb">jka-compr recursive load issue when opening Emacs.app</h4>
<div class="outline-text-4" id="text-org850a4fb">
<p>
For some reason this did not affect Emacs when <code>Emacs.app/Contents/MacOS/Emacs</code> was
executed from the terminal - only when opened as an application. Whenever a
package had a dependency on <code>jka-compr</code>, it would hit a recursive load error:
</p>

<pre class="example" id="orgca729ef">
Error (use-package): evil/:catch: Recursive load: "/Applications/Emacs.app/Contents/Resources/lisp/jka-compr.el.gz", "/Applications/Emacs.app/Contents/Resources/lisp/jka-compr.el.gz", "/Applications/Emacs.app/Contents/Resources/lisp/jka-compr.el.gz", "/Applications/Emacs.app/Contents/Resources/lisp/jka-compr.el.gz", "/Applications/Emacs.app/Contents/Resources/lisp/jka-compr.el.gz", "/Applications/Emacs.app/Contents/Resources/lisp/rect.el.gz", "/Users/mattduck/.emacs.d/eln-cache/28.0.50-6e08c520/evil-common-4cbe422e-ef770841.eln", "/Users/mattduck/.emacs.d/elpa/evil-20210424.1855/evil.elc"
</pre>

<p>
There turned out be various issues reported for this (eg. <a href="https://github.com/bbatsov/prelude/issues/1134">here</a>). It's caused by
<code>load-prefer-newer</code>, which is a variable that controls what happens if Emacs finds
multiple versions of the same file (<code>.el</code>, <code>elc</code>, <code>.so</code>). When true, Emacs will load
the newest one.
</p>

<p>
The workaround was to disable <code>load-prefer-newer</code> before loading jka-compr:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(setq load-prefer-newer nil)
(require 'jka-compr)
(setq load-prefer-newer t)
</pre>
</div>

<p>
This worked fine, but I'm not sure what the root cause is, or why I can find
examples of this error going back a few years but I've never seen it before now.
</p>
</div>
</div>

<div id="outline-container-org1392684" class="outline-4">
<h4 id="org1392684">package-refresh-packages hangs when using Marmalade</h4>
<div class="outline-text-4" id="text-org1392684">
<p>
I was having issues with <code>package-refresh-packages</code> hanging, but
they disappeared when I removed Marmalade from <code>package-archives</code>. I'm not
sure if this was related to the upgrade or not. Either way I've hardly ever used
Marmalade so I just removed it from my <code>package-archives</code> definition.
</p>
</div>
</div>

<div id="outline-container-org5c52acd" class="outline-4">
<h4 id="org5c52acd">wrong number of arguments window&#x2013;display-buffer 5</h4>
<div class="outline-text-4" id="text-org5c52acd">
<p>
The signature of the builtin function <code>window--display-buffer</code> changed in 27.1 -
it removed the fifth argument <code>DEDICATED</code>. For me this broke my fork of <a href="https://github.com/wasamasa/shackle">shackle</a>,
which uses this function in a couple of places. It's fixed in the upstream repo
at <a href="https://depp.brause.cc/shackle/">https://depp.brause.cc/shackle/</a>, so I just pulled in the fix.
</p>
</div>
</div>

<div id="outline-container-orgb88dbba" class="outline-4">
<h4 id="orgb88dbba">pyvenv-tracking-mode slowing everything down</h4>
<div class="outline-text-4" id="text-orgb88dbba">
<p>
This was a weird one. I set <code>pyvenv-workon</code> globally in my <code>init.el</code>, but I also had
had a dir-locals setting for a project that was setting <code>pyvenv-workon</code> to a
project-specific virtualenv using a symbol like this:
</p>

<div class="org-src-container">
<pre class="src src-lisp">((python-mode
  (pyvenv-workon . foo\.bar)))
</pre>
</div>

<p>
After upgrading, when <code>pyvenv-tracking-mode</code> was enabled, python buffers were
extremely slow to respond to input. I pinned the issue down to pyvenv and
upgraded pyvenv to <code>20201227.1623</code>, which didn't help. I eventually realised that
pyvenv was constantly switching between my dir-locals virtualenv and my global
virtualenv.
</p>

<p>
The reason for the constant virtualenv switching was that <code>pyvenv-tracking-mode</code>
runs a function called <code>pyvenv-track-virtualenv</code> on <code>post-command-hook</code>, and this
command was comparing <code>pyvenv-virtual-env-name</code> as a string ("foobar") to the
dir-locals declaration for <code>pyvenv-workon</code> as a symbol (<code>foo\.bar</code>). Because the
string wasn't equal to the symbol, the virtualenv would keep getting reset every
time a command was run in the buffer.
</p>

<p>
Updating the dir-locals declaration to use a string fixed it. I'm not sure what
changed to make this issue start occurring now, as it wasn't anything
specifically in my setup or pyvenv.
</p>
</div>
</div>

<div id="outline-container-orga5f18a4" class="outline-4">
<h4 id="orga5f18a4">An org-eldoc "wrong-number-of-arguments" error</h4>
<div class="outline-text-4" id="text-orga5f18a4">
<p>
This error appeared on init:
</p>

<pre class="example" id="org3fb9f9c">
eldoc error: (wrong-number-of-arguments (lambda nil Return breadcrumbs when on a headline, args for src block header-line,
  calls other documentation functions depending on lang when inside src body. (or (org-eldoc-get-breadcrumb) (org-eldoc-get-src-header) (let ((lang (org-eldoc-get-src-lang))) (cond ((or (string= lang emacs-lisp) (string= lang elisp)) (if (fboundp 'elisp-eldoc-documentation-function) (elisp-eldoc-documentation-function) (let (eldoc-documentation-function) (eldoc-print-current-symbol-info)))) ((or (string= lang c) (string= lang C)) (if (require 'c-eldoc nil t) (progn (c-eldoc-print-current-symbol-info)))) ((string= lang css) (if (require 'css-eldoc nil t) (progn (css-eldoc-function)))) ((string= lang php) (if (require 'php-eldoc nil t) (progn (php-eldoc-function)))) ((or (string= lang go) (string= lang golang)) (if (require 'go-eldoc nil t) (progn (go-eldoc--documentation-function)))) (t (let ((doc-fun (org-eldoc-get-mode-local-documentation-function lang))) (if (functionp doc-fun) (progn (funcall doc-fun))))))))) 1)
</pre>

<p>
It was coming from <code>org-eldoc</code>, which is part of <code>org-plus-contrib</code>. It went away
when I upgraded from <code>org-plus-contrib</code> version <code>20200518</code> to <code>20210426</code> (in the org
package repo).
</p>
</div>
</div>

<div id="outline-container-org90a5320" class="outline-4">
<h4 id="org90a5320">lua-mode/:catch: Unknown rx form ‘symbol’</h4>
<div class="outline-text-4" id="text-org90a5320">
<p>
I ran into <a href="https://github.com/immerrr/lua-mode/issues/155">this error in lua-mode</a>:
</p>

<pre class="example" id="org947ddf3">
lua-mode/:catch: Unknown rx form ‘symbol’ Disable showing Disable logging
</pre>

<p>
It can be fixed by removing the existing <code>lua-mode.elc</code> file.
</p>
</div>
</div>


<div id="outline-container-org5830fe1" class="outline-4">
<h4 id="org5830fe1">Error: Wrong number of arguments (3 . 4)</h4>
<div class="outline-text-4" id="text-org5830fe1">
<p>
This "wrong number of arguments" error appeared when loading various packages. I
didn't even look into where this was occurring as it disappeared as soon as I
upgraded the packages. The upgrades were:
</p>

<table border="0">


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

<col  class="org-right" />

<col  class="org-right" />
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Package</th>
<th scope="col" class="org-right">Old version</th>
<th scope="col" class="org-right">New version</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">projectile</td>
<td class="org-right">20200329.1908</td>
<td class="org-right">20210407.707</td>
</tr>

<tr>
<td class="org-left">dockerfile-mode</td>
<td class="org-right">20200106.2126</td>
<td class="org-right">20210404.2224</td>
</tr>

<tr>
<td class="org-left">lsp-mode</td>
<td class="org-right">20200425.434</td>
<td class="org-right">20210501.508</td>
</tr>

<tr>
<td class="org-left">evil</td>
<td class="org-right">20200417.1238</td>
<td class="org-right">20210424.1855</td>
</tr>
</tbody>
</table>
</div>
</div>

<div id="outline-container-org6348089" class="outline-4">
<h4 id="org6348089">LSP dependencies needed upgrading</h4>
<div class="outline-text-4" id="text-org6348089">
<p>
After upgrading LSP, my Python setup stopped working (eg. the language server
would return errors that it couldn't find various modules for my python
projects). This was fixed by upgrading to the latest versions of
python-language-server, pyls-black, pyls-mypy and plys-isort.
</p>
</div>
</div>

<div id="outline-container-orgba95e76" class="outline-4">
<h4 id="orgba95e76">powerline.el: Error: List contains a loop ("22", . #0)</h4>
<div class="outline-text-4" id="text-orgba95e76">
<p>
During native compilation, this warning is displayed for powerline:
</p>

<pre class="example" id="orgca6a1f2">
Warning (comp): /Users/mattduck/.emacs.d/elpa/powerline-20200105.2053/powerline.el: Error: List contains a loop ("22", . #0)
</pre>

<p>
This is an <a href="https://github.com/milkypostman/powerline/issues/187">outstanding issue for powerline</a>. For now the fix is to not compile
it by doing <code>(setq comp-deferred-compilation-deny-list '("powerline")).</code>
</p>
</div>
</div>

<div id="outline-container-orga13c07d" class="outline-4">
<h4 id="orga13c07d">use-package's :pin feature doesn't work</h4>
<div class="outline-text-4" id="text-orga13c07d">
<p>
This was another strange one. In my <code>init.el</code> I was using the <code>use-package</code> <code>:pin</code>
argument to pin org-mode to use the org package archive instead of
melpa. I had got to the point where everything would work OK when loading Emacs
the first time. But after native-compiling <code>init.el</code>, the next time I opened Emacs
it would skip my use-package declaration for org-mode. It turned out that this
only happened when I included the <code>:pin</code> argument.
</p>

<p>
Removing <code>:pin</code> fixed the issue, and didn't have any detrimental effect for me
because I don't have multiple org versions installed anymore. I'm curious what
this <code>use-package</code> issue is though and whether it's specific to my setup.
</p>
</div>
</div>

<div id="outline-container-orge59fc1e" class="outline-4">
<h4 id="orge59fc1e">Loading an external elisp file failed if compiled</h4>
<div class="outline-text-4" id="text-orge59fc1e">
<p>
I was using <code>:load-path</code> with use-package to load some elisp related to managing
windows and buffers, which I keep in a separate repo. The first time I opened
Emacs this worked fine, but if I opened Emacs after native-compiling, some of my
config would error because it referenced void symbols from this external file.
</p>

<p>
I'm not sure what this problem was - I just copied the contents of the external
file inline to <code>init.el</code> to workaround it. This was acceptable for me as I had
been planning to move that code inline anyway.
</p>
</div>
</div>

<div id="outline-container-org45072ef" class="outline-4">
<h4 id="org45072ef">SVG support didn't work</h4>
<div class="outline-text-4" id="text-org45072ef">
<p>
I tried to call <code>build-emacs-for-macos</code> with the <code>--rsvg</code> flag, which is supposed to
provide svg support via <code>librsvg</code>. The log output suggested that it was being
compiled as expected, but when I opened Emacs svg wasn't supported. I didn't fix
this, and haven't looked into what it is yet.
</p>
</div>
</div>
</div>

<div id="outline-container-orgf35b4f3" class="outline-3">
<h3 id="orgf35b4f3"><span class="section-number-3">9.5.</span> Too many errors?</h3>
<div class="outline-text-3" id="text-9-5">
<p>
I think this is an unacceptable amount of work for the majority of people. There
were a lot of separate issues that I had to investigate, and most of them remain
a mystery to me - it just wasn't practical to invest time in understanding all
the causes. Fortunately there were easy workarounds and I didn't have to disable
anything that I actually use.
</p>

<p>
Some of this is on me: I have a lot of config code which has been hacked
together over 7+ years, tons of packages installed, I hadn't upgraded for a
while, I used master rather than a stable release, etc. But I think some of it
is just the nature of Emacs and the ecosystem - packages are supported by a
small number of contributors, breaking changes are reasonably common, you won't
always find issues reported when you encounter a problem.
</p>

<p>
I'd expect this to be slightly easier if you're using a distribution like
Spacemacs or Doom, because of their popularity and because a large chunk of the
configuration is managed for you. But if you're starting with vanilla Emacs and
you want to customise it with a lot of packages, the reality is that you're
going to have spend time debugging problems like this, and you probably have to
be invested in DIY editors, Emacs, Lisp etc. for it to be worth it.
</p>

<p>
For me upgrading has been a nice improvement. Emacs feels noticeably quicker
than I've experienced before, and more aligned with what you'd expect in a
modern IDE. It will be pretty cool when native compilation gets a proper release
in 28.1.
</p>

<p>
You can find my config <a href="https://github.com/mattduck/dotfiles">on github</a>, and you can watch Andrea talk more about
native compilation <a href="https://www.youtube.com/watch?v=zKHYZOAc_bQ">here</a>.
</p>
</div>
</div>
]]></description>
</item>

<item>
<title>A philosophy of software design - John Ousterhout</title>
<link>https://www.mattduck.com/2021-04-a-philosophy-of-software-design.html</link>
<author>hi@mattduck.com (Matt Duck)</author>
<guid isPermaLink="false">fe973115-67df-4761-8748-c9bd55b92a15</guid>
<pubDate>Wed, 07 Apr 2021 22:15:00 +0100</pubDate>

<description><![CDATA[<p>
I read <i>A Philosophy of Software Design</i> about 18 months back. It's a
well-structured, concise read about managing complexity in software design. I
don't think the suggested approaches are applicable in all situations (and John
Ousterhout says this himself IIRC), but I recognised a lot of the problems
described in the book and found it provided some useful ways to articulate
concepts during code reviews (eg. whether adding a shallow function is
increasing complexity in a codebase, if complexity can be pulled down into an
implementation, or where it's useful to have consistency in the code).
</p>

<p>
Below are the notes I made on takeaways from the book and my thoughts on a
couple of the ideas (minus some fun references to real code that I've worked
on). I'm publishing the notes as it's a nice way for me to re-read them and
retain the information. This doesn't cover all the content in the book, and it's
possible that I misrepresent the author in some of my paraphrasing. If you're
interested in the content I definitely recommend buying a copy - it's not
expensive and it's an easy read.
</p>

<p>
<i>If anyone connected to the author thinks this is sharing too much detail then
I'm happy to take it down</i>.
</p>

<div id="outline-container-orgeef79ca" class="outline-3">
<h3 id="orgeef79ca"><span class="section-number-3">10.1.</span> Summary</h3>
<div class="outline-text-3" id="text-10-1">
<p>
When building software systems, the core challenge is managing
complexity. Complexity makes it more difficult for a programmer to understand
and change software, it increases the rate of errors, it slows development
velocity, and has other negative affects.
</p>

<p>
Software design is one of the key tools for managing complexity. Ousterhout
discusses the different types and causes of complexity, and then various
software design considerations and their relationship to complexity - patterns,
antipatterns, questions to ask, etc.
</p>
</div>
</div>

<div id="outline-container-orga3efc78" class="outline-3">
<h3 id="orga3efc78"><span class="section-number-3">10.2.</span> The nature of complexity</h3>
<div class="outline-text-3" id="text-10-2">
<p>
Ultimately, complexity makes it more expensive to modify a program: changes are
more difficult, take longer, and are more likely to introduce errors to a
program.
</p>

<p>
Ousterhout identifies three general ways that complexity manifests itself:
</p>

<ol class="org-ol">
<li>Change amplification: where a seemingly simple change requires code
modifications in many different places.</li>

<li>Cognitive load: where a developer needs to know a large number of things in
order to complete a task.</li>

<li>Unknown unknowns: where it's unclear what to do, or whether a proposed
solution will even work.</li>
</ol>

<p>
The overall complexity of a system can be determined by the complexity of each
part, weighted by the fraction of time developers spend working on that part. If
you isolate complexity in a place where it will never be seen, then that's
almost as good as eliminating it entirely.
</p>
</div>
</div>

<div id="outline-container-org1f1b75b" class="outline-3">
<h3 id="org1f1b75b"><span class="section-number-3">10.3.</span> Causes of complexity</h3>
<div class="outline-text-3" id="text-10-3">
<p>
Ousterhout recognises two main causes of complexity.
</p>

<ol class="org-ol">
<li>Dependencies between software components, which can lead to change
amplification and a high cognitive load. Dependencies are a fundamental part
of software and can't be eliminated, but one of the goals of software design
is to eliminate dependencies where possible, and to make the dependencies
that remain as simple and obvious as possible.</li>

<li>Obscurity - when important information is not obvious. This creates unknown
unknowns, and also contributes to cognitive load.</li>
</ol>
</div>
</div>

<div id="outline-container-orgd82deba" class="outline-3">
<h3 id="orgd82deba"><span class="section-number-3">10.4.</span> Tactical vs strategic programming</h3>
<div class="outline-text-3" id="text-10-4">
<p>
Ousterhout advocates for a strategic approach to software development, rather
than a wholly tactical approach. This essentially just means ongoing, regular
investment of some of your development time towards system design, rather than
just working code.
</p>

<p>
One pitfall is that complexity in software development is incremental. A single
shortcut or tactical decision that adds complexity won't have much impact, but
small decisions can accumulate to dozens or hundreds of things that do have an
impact. Then refactoring becomes a big task that you can't easily schedule with
the business, so you look for quick patches, and this creates yet more
complexity, which requires more patches, and so forth.
</p>

<p>
Once a codebase gets complex enough, it is nearly impossible to fix, and you
will probably pay high development costs for the rest of its life.
</p>
</div>

<div id="outline-container-orgdd8b997" class="outline-4">
<h4 id="orgdd8b997">Agile does not encourage strategic programming</h4>
<div class="outline-text-4" id="text-orgdd8b997">
<p>
"Agile" and similar approaches to software development tend to be focused on
small, tactical changes. It's easy in this environment to forget about investing
in the codebase, especially in startup companies that have a lot of pressure to
deliver features.
</p>
</div>
</div>
</div>

<div id="outline-container-org8cafbf0" class="outline-3">
<h3 id="org8cafbf0"><span class="section-number-3">10.5.</span> Write code for the reader, not the writer</h3>
<div class="outline-text-3" id="text-10-5">
<p>
If someone says your code is not obvious, then it isn't. This is stated a few
times through the book.
</p>
</div>
</div>

<div id="outline-container-org5aa31ca" class="outline-3">
<h3 id="org5aa31ca"><span class="section-number-3">10.6.</span> Deep modules are less complex than shallow modules</h3>
<div class="outline-text-3" id="text-10-6">
<p>
This is one of the core themes in the book. A software system is usually
decomposed into a collection of modules that are relatively independent. Modules
inevitably have dependencies between them - they work together by calling each
other, and therefore must know about each other. In order to manage these
dependencies, we think about a module in two parts: an <i>interface</i> (what the
module does), and an <i>implementation</i> (how it does it).
</p>

<p>
The idea of <i>abstraction</i> is closely related to modules. An abstraction is a
simplified view of an entity which omits unimportant details, making it easier
for us to think about and manipulate complex things.
</p>

<p>
Ousterhout argues that the best modules are those that provide powerful
functionality, but have a simple interface. He describes these as <i>deep</i> modules,
in contrast to <i>shallow</i> modules, which have a complex interface but not much
functionality, thereby not hiding significant complexity.
</p>

<p>
The file I/O interface provided by Unix is a good example of a deep interface -
the API only has a few system calls (<code>open</code>, <code>read</code>, <code>write</code>, <code>seek</code>, <code>close</code>), but hides
a huge amount of complexity around implementation of files, directories,
permissions, concurrent access, etc.
</p>
</div>

<div id="outline-container-org3458b9d" class="outline-4">
<h4 id="org3458b9d">Programmers are often encouraged to write small modules</h4>
<div class="outline-text-4" id="text-org3458b9d">
<p>
Ousterhout says that the conventional wisdom is to write <i>small</i> components
(keeping the LoC low in each method) rather than deep components, but this
results in large numbers of shallow classes and methods, which add to overall
system complexity.
</p>

<p>
I have seen this myself, and also contributed to this problem. People often
break a routine into multiple functions for the purpose of making it "easier" to
read, or to avoid some code duplication, or to lower a cyclomatic complexity
score. This kind of decomposition has a different purpose to designing
public interfaces, but sometimes get added to the public API of a class or
module.
</p>
</div>
</div>
</div>

<div id="outline-container-orgd62c372" class="outline-3">
<h3 id="orgd62c372"><span class="section-number-3">10.7.</span> General-purpose modules are deeper</h3>
<div class="outline-text-3" id="text-10-7">
<p>
This doesn't mean "generalised" implementations that support extra features that
you don't need - it means writing methods that are not overly specialised. The
sweet spot is a somewhat general-purpose approach, which hopefully provides a
simpler and deeper interface.
</p>

<p>
<i>"If you reduce the number of methods in an API without reducing its overall
capabilities, then you are probably creating more general-purpose methods."</i>
</p>
</div>
</div>

<div id="outline-container-orgc26a38e" class="outline-3">
<h3 id="orgc26a38e"><span class="section-number-3">10.8.</span> Pass-through variables add complexity</h3>
<div class="outline-text-3" id="text-10-8">
<p>
Pass-through variables add complexity because they force intermediate methods to
be aware of their existence, even though the methods have no use for the
variables.
</p>

<p>
Eliminating this anti-pattern can be very difficult. The two main approaches are
to see if you can add the pass-through state onto an object that is already
shared between the top and bottom methods, or to make it a global
variable. These can have their own problems.
</p>

<p>
Ousterhout's most often-used approach to this problem is to introduce a context
object, which stores the application's global state - anything that would
otherwise be a pass-through or global variable. They are not an ideal solution
because they have a lot of the disadvantages of global variables, but they can
reduce the complexity of a method's signature.
</p>
</div>
</div>


<div id="outline-container-orgc8e9dde" class="outline-3">
<h3 id="orgc8e9dde"><span class="section-number-3">10.9.</span> Pass-through methods are shallow and add complexity</h3>
<div class="outline-text-3" id="text-10-9">
<p>
A pass-through method is one that does little except invoke another method with
a similar signature. This increases the interface complexity of a module,
without increasing the total functionality of the system. It can indicate that
there is confusion over the division of responsibility between modules or
classes.
</p>

<p>
This is not <i>always</i> bad - the important thing is that each new method should
contribute significant functionality. For example, a dispatcher method is a
pass-through method that can be very useful.
</p>

<p>
Decorators are often shallow pass-through methods that add a lot of boilerplate
without adding much new functionality.
</p>
</div>
</div>

<div id="outline-container-org1bf065a" class="outline-3">
<h3 id="org1bf065a"><span class="section-number-3">10.10.</span> Pull complexity downwards</h3>
<div class="outline-text-3" id="text-10-10">
<p>
It's more important for a module to have a simple interface than a simple
implementation. If you have complexity that is closely related to your module's
functionality, you should consider pulling that complexity into the module's
implementation.
</p>

<p>
One example Ousterhout provides is configuration parameters, which are an
example of moving complexity upwards rather than down. Consider a network
protocol that has to deal with lost packets: one way to determine an appropriate
retry interval is to introduce a configuration parameter to provide control to
the user. However, it may be preferable to compute a reasonable retry value
automatically during runtime (by eg. measuring the response time). This approach
pulls system complexity downwards.
</p>
</div>
</div>

<div id="outline-container-orga094421" class="outline-3">
<h3 id="orga094421"><span class="section-number-3">10.11.</span> Define errors out of existence</h3>
<div class="outline-text-3" id="text-10-11">
<p>
<i>"Exception handling is one of the worst sources of complexity in software
systems"</i>. They can leak abstraction details upwards, making for a more shallow
abstraction. Programmers are often taught that they need to handle exceptional
cases, leading for an over-defensive programming style.
</p>

<p>
There are two main ways to handle exceptions, each with their own
complexity. The first is to complete the work in spite of the exception, and the
second is to report the exception upwards (perhaps also running some unwinding /
handling logic).
</p>

<p>
Ousterhout argues in favour of defining errors out of existence, by
automatically handling certain cases. He contrasts the behaviour of deleting a
file on Windows vs Unix. On Windows, if a process is using the file to be
deleted, an error is raised. In the Unix implementation, if another process is
using the file, the file is internally marked for deletion and the operation
returns successfully. Unix actually deletes the file when the other process
has finished using it. Errors are avoided in both the process that initiated
the deletion, and the other process that was using the file. Another common
example is when accessing a substring by index: you could raise an out of
bounds error, or you could just return the whole string.
</p>

<p>
Where you must handle exceptions, you should prefer to handle many exceptions
with a single piece of code.
</p>
</div>
</div>

<div id="outline-container-org7f4cd40" class="outline-3">
<h3 id="org7f4cd40"><span class="section-number-3">10.12.</span> A thoughtful approach to code comments</h3>
<div class="outline-text-3" id="text-10-12">
<p>
Ousterhout shares a few opinions on comments:
</p>

<ul class="org-ul">
<li>A programming language can't capture all of the important information that was
in the mind of the developer when the code was written. Comments should be
used to describe things that aren't obvious from the code.</li>

<li><i>"Developers should be able to understand the abstraction provided by a module
without reading any code other than its externally visible declarations."</i>
If you want code that presents good abstractions, you must document those
abstractions with comments.</li>

<li>Write comments early, because they can help to improve the system
design. Comments are likely to be low-quality if you write them as a token
gesture at the end of a piece of work.</li>

<li>Comments can indicate complexity: if a method or variable describes a long
comment, it is a red flag that you don't have a good abstraction.</li>

<li>Comments should not repeat the code. Could somebody who has never seen the
code write your comment just by looking at the code? If so, the comment is
worthless.</li>

<li>Comments should be written at a different level of detail to the code - either
higher (eg. concerned with top-level behaviour), or lower (concerned with
specific details that are not obvious by reading the code). Comments are
easier to maintain if they are higher-level and more abstract than the
code. This is because they're less likely to be affected by minor changes in
the code.</li>

<li>Comments should occur close to the code that they describe. This increases the
ease of reading and updating them. It's more important that comments are in
the code, than in the commit log. This is because it's significantly easier to
find the comments if they're close to the code - finding the right log message
is difficult.</li>

<li>Try to document each design decision exactly once. If information is already
documented outside your program, don't repeat the documentation <i>inside</i> the
program, just reference the external documentation.</li>
</ul>
</div>

<div id="outline-container-orgdacee26" class="outline-4">
<h4 id="orgdacee26">Refuting arguments against comments</h4>
<div class="outline-text-4" id="text-orgdacee26">
<ul class="org-ul">
<li>"Good code is self documenting": to this, Ousterhout argues that there are
many things that can't be described in the code, such as the rationale for a
particular design decision, or the conditions under which it makes sense to
call a particular method. More importantly, if there are no comments
accompanying the interface of a method, then there is no abstraction: you must
read the method's code, and all of its complexity is exposed.</li>

<li>"I don't have time": good comments shouldn't add more than 10% to your
development time. The benefits of having good documentation should quickly
offset this cost.</li>

<li>"Comments become out of date and misleading": keeping comments up to date is
not an enormous effort - it should be flagged in code reviews. Large changes
to documentation should only be required if there are large changes to the
codebase. You do have to take some care to structure comments to be useful
though.</li>

<li>"All the comments I have seen are worthless": Ousterhout agrees that most
documentation is <i>"so-so at best".</i></li>
</ul>
</div>
</div>


<div id="outline-container-orgbfca945" class="outline-4">
<h4 id="orgbfca945">Different types of comments</h4>
<div class="outline-text-4" id="text-orgbfca945">
<p>
Ousterhout identifies some different types of comments:
</p>

<ol class="org-ol">
<li><b>Interface</b>: a comment block that goes with the declaration of a class, data
structure, function, or method. They describe the thing's interface - the
overall behaviour, arguments and return values, any side effects or
exceptions, and other requirements that the caller must satisfy. They can
also fill in missing details: the units for a variable, whether null values
are permitted, whether boundary conditions are inclusive or exclusive, etc.</li>

<li><b>Data structure member</b>: a comment next to the declaration of a field,
describing what it represents.</li>

<li><b>Implementation</b>: a comment describe how a piece of code works.</li>

<li><b>Cross-module</b>: a comment describing dependencies that cross module boundaries.</li>
</ol>

<p>
It's important not to mix up these purposes. Comments describing the interface
of a component should not have to share any implementation details: this is
information leakage, and it adds complexity for the reader. If interface
comments must also describe the implementation, then the class or method is
shallow.
</p>
</div>
</div>

<div id="outline-container-org5e92127" class="outline-4">
<h4 id="org5e92127">Comments and programming fluency</h4>
<div class="outline-text-4" id="text-org5e92127">
<p>
My own thought on this is that in order to write and work with high-quality
comments, you need to be at a certain level of fluency. When I started
programming, I had to use comments liberally to describe to myself what certain
lines of code meant, because it was significantly faster for me to understand an
English description than to read a block of 4-5 lines of code.
</p>

<p>
I suspect that some of the "bad" comments where the comment just duplicates the
information in the code fall under this category: for some people, those
comments are helpful, but for others who are more fluent in the programming
language, they're less useful. In a professional environment there should
ideally be a base level of understanding and verbose comments that duplicate
what the code is doing should not be required often.
</p>
</div>
</div>
</div>

<div id="outline-container-org26d1708" class="outline-3">
<h3 id="org26d1708"><span class="section-number-3">10.13.</span> Naming is important</h3>
<div class="outline-text-3" id="text-10-13">
<p>
Good names are a form of documentation, and another place where all programmers
have seen incremental complexity: a single bad name does not hurt a program, but
a program full of poorly-named components can be very difficult to use.
</p>

<p>
Names should be precise (you usually want to avoid overly-general names like
<code>data</code>), and consistent - if a name is used in multiple places it should refer to
the same thing. If the same name is used to refer to different concepts, then at
some point a reader will be confused, which is likely to introduce errors to the
program.
</p>
</div>
</div>

<div id="outline-container-org2158557" class="outline-3">
<h3 id="org2158557"><span class="section-number-3">10.14.</span> Whitespace can help break up code into logical blocks</h3>
<div class="outline-text-3" id="text-10-14">
<p>
One way to make code more obvious to the reader is to have blank lines between
parts that are logically separate, and maybe to preface the code block with an
implementation comment.
</p>
</div>
</div>

<div id="outline-container-org98e7151" class="outline-3">
<h3 id="org98e7151"><span class="section-number-3">10.15.</span> TDD focuses on features rather than abstractions and design</h3>
<div class="outline-text-3" id="text-10-15">
<p>
<i>"The problem with test-driven development is that it focuses on getting specific
features working, rather than finding the best design."</i> Ousterhout argues that
the unit of development should be abstractions rather than features, and that
once you discover the need for an abstraction, you should design it all at once.
</p>

<p>
He says that TDD does make sense when fixing bugs (which aligns with my experience).
</p>
</div>
</div>

<div id="outline-container-org945861c" class="outline-3">
<h3 id="org945861c"><span class="section-number-3">10.16.</span> Consistency is important</h3>
<div class="outline-text-3" id="text-10-16">
<p>
Consistency minimises complexity because it provides cognitive leverage: you
learn how something is done in one place, and you can immediately understand
other places that use the same approach. If a system is not implemented
consistently, then developers must learn about each situation separately, which
takes more time.
</p>

<p>
Consistency also reduces mistake: if a system is not consistent, two situations
that appear the same may actually be different.
</p>

<p>
Consistency can be considered in things like:
</p>

<ul class="org-ul">
<li>Naming.</li>

<li>Coding style.</li>

<li>Interfaces.</li>

<li>Design patterns.</li>

<li>Invariants - cases that are always true. For example, a data structure storing
lines of text might enforce an invariant that each line is terminated by a
newline character. The programmer can then always assume this to be true.</li>
</ul>

<p>
There are things you can do to ensure consistency:
</p>

<ul class="org-ul">
<li>Write conventions down.</li>

<li>Enforce conventions, ideally automatically through tools.</li>

<li>"When in Rome&#x2026;" follow existing conventions. Having a better idea is not a
sufficient excuse to introduce inconsistencies. Is your new approach so much
better that it's worth taking the time to update all of the old uses?</li>
</ul>
</div>
</div>

<div id="outline-container-org96bb9cc" class="outline-3">
<h3 id="org96bb9cc"><span class="section-number-3">10.17.</span> Implementation inheritance increases complexity</h3>
<div class="outline-text-3" id="text-10-17">
<p>
Implementation inheritance creates dependencies between the parent class and
each of its subclasses, results in information leakage between the parent and
child classes, and makes it hard to modify one class in the hierarchy without
looking at the other.
</p>

<p>
Ousterhout suggests composition can be a less-complex alternative to
inheritance.
</p>

<p>
The first example that jumps to mind personally is Django - the class hierarchy
always seemed to add more complexity than it solved in a lot of cases. In
general I think it's very easy for the complexity of inheritance to outweigh the
utility.
</p>
</div>
</div>

<div id="outline-container-org577c121" class="outline-3">
<h3 id="org577c121"><span class="section-number-3">10.18.</span> Event-driven programming makes code less obvious</h3>
<div class="outline-text-3" id="text-10-18">
<p>
Event-driven programming makes it hard to follow the flow of control. This is
because handler functions aren't invoked directly - it depends on which handlers
were registered at runtime.
</p>

<p>
This doesn't mean that there is no use-case for event-driven programming, but
care should be taken to mitigate this complexity.
</p>
</div>
</div>
<div id="outline-container-org5cfd1f4" class="outline-3">
<h3 id="org5cfd1f4"><span class="section-number-3">10.19.</span> Design it twice</h3>
<div class="outline-text-3" id="text-10-19">
<p>
You'll end up with a much better result if you consider multiple options for
each major design decision. There isn't much to say about this, other than that
I intuitively agree.
</p>
</div>
</div>
]]></description>
</item>

<item>
<title>Filtering Django querysets without re-querying the database</title>
<link>https://www.mattduck.com/2021-01-django-orm-result-cache.html</link>
<author>hi@mattduck.com (Matt Duck)</author>
<guid isPermaLink="false">7af9d4c4-8c35-4d76-aa3a-7e4be35a3699</guid>
<pubDate>Sun, 31 Jan 2021 16:26:00 +0000</pubDate>

<description><![CDATA[
<div id="outline-container-org4513e55" class="outline-3">
<h3 id="org4513e55"><span class="section-number-3">11.1.</span> ORM problems</h3>
<div class="outline-text-3" id="text-11-1">
<p>
I think most ORM patterns I've seen present a bad abstraction. Rather than
providing an interface that safely hides the details of the underlying SQL, they
make it extremely easy to trip yourself up by writing OOP code which looks
conventional but is actually problematic when translated to relational data
access patterns. One impact this has for users of your program is increased
latency, as the impedance mismatch between SQL and the ORM code causes time to
be wasted on:
</p>

<ul class="org-ul">
<li>Issuing many more queries to the database than required (See the N+1 problem).</li>
<li>Reading columns over the wire that aren't actually used in the application
(<code>SELECT * FROM mytable</code>).</li>
<li>Querying the same data multiple times in a request.</li>
<li>Loading excess rows into the application to do processing that could easily
have been pushed into the database.</li>
</ul>

<p>
(This doesn't mean ORMs don't have a place - the downsides may be worth it in
situations where you can work much quicker with ORM classes than with SQL,
performance isn't a concern, you have a very small dataset, etc.).
</p>
</div>
</div>

<div id="outline-container-org0237967" class="outline-3">
<h3 id="org0237967"><span class="section-number-3">11.2.</span> Django ORM and the QuerySet cache</h3>
<div class="outline-text-3" id="text-11-2">
<p>
Django's ORM suffers from these problems. Unlike SQLAlchemy, it doesn't provide
a core API to compose SQL - you're forced to deal with Django's Model and
QuerySet interfaces. It's very easy to end up in a place where your functions
and SQL queries are mismatched, with queries fired off at various arbitrary
points in the request path.
</p>

<p>
One of the ways that Django attempts to mitigate this problem is through the
queryset result cache. Querysets try to be smart about not re-querying the
database to answer basic questions that they already have the answer to. For
example, if I iterate over a queryset multiple times, the results will be
cached:
</p>


<div class="org-src-container">
<pre class="src src-python">users = User.objects.all()
for user in users:  # SQL: SELECT id, name, etc FROM users
    print(user)

for user in users:  # Does not issue SQL
    print(user)
</pre>
</div>

<p>
Similarly, if I iterate over the queryset and later call <code>.count()</code>, the queryset
will return the length of the cached results, instead of issuing <code>SELECT count(*)
FROM users</code>:
</p>

<div class="org-src-container">
<pre class="src src-python">users = User.objects.all()
for user in users:  # SQL: SELECT id, name, etc FROM users
    print(user)

print(users.count())  # Does not issue SQL
</pre>
</div>
</div>
</div>

<div id="outline-container-orga1c12ad" class="outline-3">
<h3 id="orga1c12ad"><span class="section-number-3">11.3.</span> How the result cache is implemented</h3>
<div class="outline-text-3" id="text-11-3">
<p>
The QuerySet class stores the cache on <code>self._result_cache</code>. When populated, this
object appears to just be a list of model instances. It gets initialised to <code>None</code>
when building a new queryset:
</p>

<div class="org-src-container">
<pre class="src src-python">class QuerySet:
    """Represent a lazy database lookup for a set of objects."""

    def __init__(self, model=None, query=None, using=None, hints=None):
        self.model = model
        self._db = using
        self._hints = hints or {}
        self._query = query or sql.Query(self.model)
        self._result_cache = None
        # ...
</pre>
</div>

<p>
You can read the Django source code on <a href="https://github.com/django/django/blob/6822aa5c6c3fbec7c5393a05e990865ba59fe167/django/db/models/query.py#L183">Github</a> (these snippets are copied from
master at time of writing). Here's the full implementation of <code>.count()</code>, which
will only issue a <code>COUNT(*)</code> statement if the result cache is empty:
</p>

<div class="org-src-container">
<pre class="src src-python">def count(self):
    """
    Perform a SELECT COUNT() and return the number of records as an
    integer.
    If the QuerySet is already fully cached, return the length of the
    cached results set to avoid multiple SELECT COUNT(*) calls.
    """
    if self._result_cache is not None:
        return len(self._result_cache)

    return self.query.get_count(using=self.db)
</pre>
</div>

<p>
<code>self._result_cache</code> is mentioned 23 times in <code>django/db/models/query.py</code>. In
addition to the <code>count()</code> implementation, it's used:
</p>

<ul class="org-ul">
<li>In <code>exists()</code>, <code>__len__()</code>, <code>__iter__()</code>, <code>__bool__()</code> and <code>__getitem__()</code> - these all operate on the
cache if it's populated.</li>
<li>In <code>_fetch_all()</code> - this queries the database to populate the cache if it isn't
already populated, and is called by methods like <code>__len__()</code>.</li>
<li>In <code>delete()</code> and <code>update()</code> - these both clear the cache.</li>
<li>In <code>__deepcopy__()</code> - this explicitly ignores the cache so it isn't copied to
new querysets.</li>
</ul>
</div>
</div>

<div id="outline-container-org4ae4d43" class="outline-3">
<h3 id="org4ae4d43"><span class="section-number-3">11.4.</span> When the cache is cleared</h3>
<div class="outline-text-3" id="text-11-4">
<p>
There are two main places where the result cache is invalidated:
</p>

<ol class="org-ol">
<li>After writes, and</li>

<li>when returning a clone of the queryset, which happens after calling common
functions like <code>.filter()</code>.</li>
</ol>
</div>

<div id="outline-container-orgd53d064" class="outline-4">
<h4 id="orgd53d064">Avoid using <code>.all()</code></h4>
<div class="outline-text-4" id="text-orgd53d064">
<p>
Something to watch out for is that calling <code>.all()</code> returns a new queryset without
any cached results. The code below looks very similar to the first snippet, but
issues a redundant query:
</p>

<div class="org-src-container">
<pre class="src src-python">users = User.objects.all()
for user in users:  # SQL: SELECT id, name, etc FROM users
    print(user)

for user in users.all():  # SQL: SELECT id, name etc FROM users
    print(user)
</pre>
</div>

<p>
These additional queries can add up fast in real-world cases - particularly if
you've used <code>select_related()</code> and <code>prefetch_related()</code> in an attempt to avoid N+1
problems, in which case calling <code>.all()</code> again could issue multiple queries to
populate your pre-fetching.
</p>
</div>
</div>
</div>

<div id="outline-container-orgdaba4ea" class="outline-3">
<h3 id="orgdaba4ea"><span class="section-number-3">11.5.</span> Where the cache breaks downs</h3>
<div class="outline-text-3" id="text-11-5">
<p>
There are times where it seems like Django <i>could</i> re-use the cached results, but
doesn't. For example, imagine we have already retrieved all the users, and we
want to narrow the queryset further:
</p>

<div class="org-src-container">
<pre class="src src-python">users = User.objects.all()
for user in users:  # SQL: SELECT id, name, etc FROM users
    print(user)

narrowed_users = users.filter(id__in=[1, 2, 3])
for user in narrowed_users:   # SELECT id, name, etc FROM users WHERE id IN (1, 2, 3)
    print(user)
</pre>
</div>

<p>
For complex filters that mimic SQL operations, we of course want to push that
into the database. But it's easy to imagine how this particular filter could be
implemented in Python - we know the rows are already cached in memory, and the
filter we're applying can be done in one line of Python (<code>[row for row in
result_cache if row.id in (1, 2, 3)])</code>. But <code>filter()</code> returns a new QuerySet with
our new <code>IN</code> clause and re-fetches the matching User rows from the database.
</p>
</div>
</div>

<div id="outline-container-orge90b53a" class="outline-3">
<h3 id="orge90b53a"><span class="section-number-3">11.6.</span> Why doesn't the QuerySet provide an API to support this?</h3>
<div class="outline-text-3" id="text-11-6">
<p>
It would be nice to have an additional API to filter against cached data if the
queryset has already fetched rows from the database. It must be pretty common
that Django codebases end up with business logic split between different parts
of the codebase - sometimes operating on querysets, sometimes on model
instances, sometimes issuing new queries, etc. Eg. I can imagine a code path
like:
</p>

<ol class="org-ol">
<li>You do some expensive pre-fetching at the top of your request path, and
you pass the queryset along to some other code.</li>

<li>You need to call a method on your model instances which returns a value that
you want to use to narrow the queryset further. Iterating your queryset to
call each model instance is OK because you're re-using the cache. But then&#x2026;</li>

<li>You have to call a third-party library which expects to operate on a
QuerySet. You can give it a new queryset using
<code>.filter(myfield__in=my_matching_row_ids)</code>, but this is going to hit the
database again and re-run all your expensive prefetching queries.</li>
</ol>

<p>
For this case, it would be useful if you could pass a queryset to the third
party API which contains a narrowed view of the queryset that you already
fetched from the database in step 1, with the cache already populated.
</p>

<p>
There are definitely arguments against offering an API like this - eg. it could
introduce confusion around whether data is up to date or not, and "ideally" you
should have structured your code using the right patterns to not get into these
problems. But when that ship has already sailed I think a tool like this would
have uses.
</p>
</div>
</div>

<div id="outline-container-org6514b14" class="outline-3">
<h3 id="org6514b14"><span class="section-number-3">11.7.</span> Hacking the result cache to avoid hitting the database</h3>
<div class="outline-text-3" id="text-11-7">
<p>
One way we can implement this behaviour is by overriding the result cache
ourselves. For example:
</p>

<div class="org-src-container">
<pre class="src src-python"># Build the root queryset and fetch the data
users = User.objects.all()
for user in users:  # SQL: SELECT id, name, etc FROM users
    print(user)

# Narrow your models to a list
narrowed_users = [u for u in users if u.id in (1, 2, 3)]

# Build your filtered queryset
narrowed_queryset = users.filter(id__in=[u.id for u in narrowed_users])

# Set the cache on the queryset
narrowed_queryset._result_cache = narrowed_users

# Iterate the queryset freely
for user in narrowed_users:   # Does not re-issue the query
    print(user)

# Further filtering will issue a new queryset that includes our filter
registered_users = narrowed_queryset.filter(is_registered=True)
for user in register_users:   # SELECT id, name, etc FROM users WHERE is_registered=true AND id IN (1, 2, 3)
    print(user)
</pre>
</div>

<p>
This solves the problem we had - now we can call some Model/OOP functions to get
the IDs of the rows we care about, and pass a new QuerySet downstream which
matches on those IDs without re-fetching rows we already had from the
database. They will only be re-fetched if the downstream code needs to further
modify the queryset.
</p>
</div>

<div id="outline-container-orgb0b5ad0" class="outline-4">
<h4 id="orgb0b5ad0">Is this terrible?</h4>
<div class="outline-text-4" id="text-orgb0b5ad0">
<p>
I searched for a bit and couldn't find examples of people doing this. I wouldn't
expect it to be "supported" behaviour and it isn't something I'd want to do
without a good test suite around my program to catch any changes in how QuerySet
uses <code>self._result_cache</code>. You also want to be careful about using <code>IN</code> for large
result sets. But it does seem to work nicely for some cases.
</p>
</div>
</div>
</div>

<div id="outline-container-orge088205" class="outline-3">
<h3 id="orge088205"><span class="section-number-3">11.8.</span> Further reading</h3>
<div class="outline-text-3" id="text-11-8">
<p>
There are a few Django libraries that provide different solutions for ORM
caching. I don't think any of them would be helpful in this exact situation, but
it's probably worth understanding what they can do.
</p>

<p>
You can find the QuerySet source code at <code>django/db/models/query.py</code>. Here it is
on <a href="https://github.com/django/django/blob/6822aa5c6c3fbec7c5393a05e990865ba59fe167/django/db/models/query.py">Github</a>. It's quite readable, and is useful for understanding what a queryset
does.
</p>

<p>
There are many articles about ORM pitfalls. I think a good starting point is Cal
Paterson's <a href="http://calpaterson.com/activerecord.html">The troublesome "Active Record" pattern</a> and the pages linked
there.
</p>
</div>
</div>
]]></description>
</item>

<item>
<title>Questions about AWS Transfer</title>
<link>https://www.mattduck.com/2021-01-aws-transfer-questions.html</link>
<author>hi@mattduck.com (Matt Duck)</author>
<guid isPermaLink="false">c8fda5ff-35c1-4f16-99b0-bad0873ebd8b</guid>
<pubDate>Sun, 24 Jan 2021 21:41:00 +0000</pubDate>

<description><![CDATA[<p>
AWS Transfer Family is an AWS product that provides hosted FTP services as a
frontend to manage files in S3 (or in EFS, newly added in January 2021, which
I'm ignoring for this post). This is just me exploring a few of the options and
concepts involved in configuring a transfer server.
</p>

<div id="outline-container-org892e748" class="outline-3">
<h3 id="org892e748"><span class="section-number-3">12.1.</span> What decisions are required when setting up a transfer server?</h3>
<div class="outline-text-3" id="text-12-1">
<p>
There are a few things to consider, including:
</p>

<ul class="org-ul">
<li>How to design and configure your S3 bucket(s).</li>

<li>Choosing the protocol(s) to use - FTP, SFTP or FTPS, and authentication
methods (eg. whether to hook into external services like Active Directory).</li>

<li>Network design - whether this is an internet-facing or internal service,
whether you need a fixed IP, DNS configuration, any ingress network security
rules, or running on a non-standard port (eg. SFTP listening on something
other than port 22).</li>

<li>Designing the IAM role setup, and the mapping of FTP users to home
directories, to control the S3 paths that users have access to.</li>
</ul>

<p>
I'm primarily interested in configuring a public-facing SFTP service, so will
focus on that.
</p>
</div>
</div>

<div id="outline-container-orgb3a5809" class="outline-3">
<h3 id="orgb3a5809"><span class="section-number-3">12.2.</span> How are IP addresses assigned to my server?</h3>
<div class="outline-text-3" id="text-12-2">
<p>
This depends on the type of "endpoint" chosen for your transfer service. There
are two endpoint types: <i>public</i> and <i>VPC</i>. Public endpoints are only accessible
over the internet. They have fewer network configuration choices to think about,
but come with limitations. One of these limitations is that IPs are assigned by
AWS and subject to change.  This makes public endpoints unsuitable for cases
where the FTP client is on a network with IP-based firewall rules.
</p>

<p>
If you want to assign a static IP to the FTP server, you must choose the VPC
endpoint type, which means access to the server will be controlled by VPC
security groups.
</p>
</div>
</div>

<div id="outline-container-orgc0af9ca" class="outline-3">
<h3 id="orgc0af9ca"><span class="section-number-3">12.3.</span> If I use a public endpoint type,  will the server IP be in a known range?</h3>
<div class="outline-text-3" id="text-12-3">
<p>
AWS publishes a <a href="https://ip-ranges.amazonaws.com/ip-ranges.json">list of IP ranges</a> used by its services and regions.  It's not
immediately clear to me which "service" the Transfer product corresponds to - I
guess <i>S3</i>. These ranges can change, so if you want to make use of this
information you have to be able to handle updates. AWS publishes updates as an
<a href="https://docs.aws.amazon.com/general/latest/gr/aws-ip-ranges.html#subscribe-notifications">SNS topic</a>, which enables people to do this programmatically. I'm not sure how
often these updates are published. If your only use-case is setting up an FTP
service, it will be significantly simpler to use a static IP for the service
than to worry about IP ranges.
</p>
</div>
</div>

<div id="outline-container-org068dace" class="outline-3">
<h3 id="org068dace"><span class="section-number-3">12.4.</span> What other features depend on the endpoint type?</h3>
<div class="outline-text-3" id="text-12-4">
<p>
There are a few differences. For example, public endpoints must use the SFTP
protocol, and have no way to configure an allow-list of client IPs, or to change
the port used for the FTP service.
</p>

<p>
AWS recommends using the VPC endpoint type as it provides more security
features. I haven't seen any features that you get with the public endpoint type
that can't be replicated with the VPC endpoint type. The AWS docs include a <a href="https://aws.amazon.com/premiumsupport/knowledge-center/aws-sftp-endpoint-type/">comparison of
the different endpoint types</a>.
</p>
</div>
</div>

<div id="outline-container-orgc0a58e7" class="outline-3">
<h3 id="orgc0a58e7"><span class="section-number-3">12.5.</span> What's a VPC?</h3>
<div class="outline-text-3" id="text-12-5">
<p>
Virtual Private Cloud is Amazon's "virtual network" abstraction - it's what
provides your networking configuration. It's a logically-isolated network that
you define with traditional network features configuration features like
subnets, routing tables and internet gateways.
</p>

<p>
VPC isn't a feature that you can opt out of - certain AWS resources (eg. EC2
instances) must be launched into this network. If you don't specifically
configure a VPC, AWS will initialise a "default" VPC when you first provision
EC2 resources.
</p>

<p>
Security groups (which control the traffic that is allowed in/out of an EC2
instance) and network ACLs (which control traffic entering and exiting a subnet)
are both features of the VPC.
</p>
</div>
</div>

<div id="outline-container-org079d9fe" class="outline-3">
<h3 id="org079d9fe"><span class="section-number-3">12.6.</span> How do I assign a static IP to a VPC-hosted transfer server?</h3>
<div class="outline-text-3" id="text-12-6">
<p>
VPC-hosted transfer servers can either be internal to the VPC, or
internet-facing. To be internet-facing, they must be allocated an Elastic IP.
</p>

<p>
Elastic IPs are public IPv4 addresses that you can associate with resources in
your AWS account. You have the option of importing your own address range, or
receiving an address from Amazon's IPv4 pool. There are limits on the number of
IPs you can request from Amazon (the default limit is 5).
</p>

<p>
If you're using the AWS console to create your transfer server, the endpoint
details are pretty self-explanatory - there are dropdown fields to select a
VPC, subnet and Elastic IP.
</p>

<p>
If you're using Terraform's <a href="https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/transfer_server">aws_transfer_server</a> to create the transfer server,
you have to provide the VPC details as <code>endpoint_details</code>. This gives you the
option of specifying the VPC ID, subnet, and a list of <code>address_allocation_ids</code>,
which point to Elastic IPs. Allocations IDs are essentially just IDs used to
identify an Elastic IP - you can see them clearly in the Elastic IP section of
the console.
</p>
</div>
</div>

<div id="outline-container-orgb2e9a48" class="outline-3">
<h3 id="orgb2e9a48"><span class="section-number-3">12.7.</span> Why does the AWS console prompt me for a custom hostname?</h3>
<div class="outline-text-3" id="text-12-7">
<p>
If you're using Route53 to manage DNS for your domain, you can configure an
"alias" record, which is a Route53-specific feature to automatically route
traffic to an AWS resource.
</p>

<p>
In the AWS console, if you select to use "other DNS" instead of Route53, the
transfer server form still contains a field for filling in the hostname - eg. I
can enter <i>ftp.mattduck.com</i>. This confused me initially as I wasn't sure the
purpose of entering a hostname if your DNS is configured externally. It turned
out that this will create a new public zone in Route53 for the domain that you
enter (<i>mattduck.com</i>), with a CNAME record (<i>ftp</i>) pointing to the auto-generated
AWS hostname of the server.
</p>

<p>
Although this is a public zone, Route53 isn't the authoritative nameserver for
mattduck.com, so it has no affect if I try to access ftp.mattduck.com on my
laptop. I believe EC2 images are configured by default to use AWS nameservers,
and that the CNAME entry <i>would</i> be resolved on an EC2 box within the VPC (subject
to some VPC settings like <code>enableDnsSupport</code>).
</p>
</div>
</div>

<div id="outline-container-orgfcbe3fc" class="outline-3">
<h3 id="orgfcbe3fc"><span class="section-number-3">12.8.</span> How do I configure an external DNS entry to resolve to the transfer server?</h3>
<div class="outline-text-3" id="text-12-8">
<p>
You just create a CNAME record where the value is the public hostname of the
transfer server. I'm not aware of any approaches other than this.
</p>
</div>
</div>

<div id="outline-container-orgc05aec9" class="outline-3">
<h3 id="orgc05aec9"><span class="section-number-3">12.9.</span> What types of server-side encryption does S3 support? How are these supported in AWS Transfer?</h3>
<div class="outline-text-3" id="text-12-9">
<p>
This is very surface-level, but there are three kinds of server-side encryption in S3:
</p>

<ul class="org-ul">
<li><i>SSE-S3</i>: this is where AWS encrypts each object with a unique key, which it
stores to automatically decrypt the object on read. Each key is itself
encrypted with a master key, for which AWS manages rotation. If your
bucket/objects use SSE-S3 encryption, then the only consideration is making
sure the policy associated with the FTP user has the appropriate S3 read/write
permissions - there's nothing extra to worry about.</li>

<li><i>SSE-KMS</i>: KMS stands for <i>Key Management Service</i>. Instead of Amazon's master
keys, encryption uses <i>Customer Master Keys</i>, which are managed in your account,
and which have some additional features like being limited via policies and
having audit trails for access. For buckets/objects that are encrypted with
KMS, the policy associated with the FTP user must have some additional
permissions for the relevant key - <code>kms:Decrypt</code>, <code>kms:ReEncrypt</code>,
<code>kms:GenerateDataKey</code> and <code>kms:DescribeDataKey</code>.</li>

<li><i>SSE-C</i>: in this option, the user must provide an encryption key when uploading
an object to S3, and then that same key must be provided in subsequent requests to
retrieve the object. This is <b>not</b> supported in AWS Transfer - which makes sense
because FTP doesn't provide a way to specify this key.</li>
</ul>
</div>
</div>

<div id="outline-container-org1648129" class="outline-3">
<h3 id="org1648129"><span class="section-number-3">12.10.</span> How do SFTP users map to policies in AWS?</h3>
<div class="outline-text-3" id="text-12-10">
<p>
This is pretty simple, particularly using Terraform - you create an
<a href="https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/transfer_user">aws_transfer_user</a>, assign them a role with the appropriate policy, and then
create an <a href="https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/transfer_ssh_key">aws_transfer_ssh_key</a>. The user can then authenticate with the SFTP
server and perform the actions granted by the policy.
</p>
</div>
</div>

<div id="outline-container-org246c4e9" class="outline-3">
<h3 id="org246c4e9"><span class="section-number-3">12.11.</span> How do you limit FTP users to particular directories?</h3>
<div class="outline-text-3" id="text-12-11">
<p>
This is probably the most involved / fiddly part to get right (at least if you
want to support multiple isolated users with their own directories). There are a
two types of home directory - <code>PATH</code> and <code>LOGICAL</code>.  With the path-type, you're
dependent on IAM policies to control bucket access. With the logical-type,
you can create a map of the user's FTP directories to particular S3 targets.
</p>

<p>
The IAM policies support some user-relative variables like <code>${Transfer:UserName}</code>
and <code>${Transfer:HomeDirectory}</code>, to make it easier to reuse policies. I haven't
dived into this but I think there are some limitations on where they can be
used - eg. only on roles but not users (or vice-versa).
</p>
</div>
</div>

<div id="outline-container-orgb29d2f3" class="outline-3">
<h3 id="orgb29d2f3"><span class="section-number-3">12.12.</span> Does the SFTP server support 4096-bit RSA keys?</h3>
<div class="outline-text-3" id="text-12-12">
<p>
Yes. I was curious about this. The <a href="https://docs.aws.amazon.com/transfer/latest/userguide/API_ImportSshPublicKey.html">docs</a> state that the public key has a maximum
length of 2048. I wondered if this meant the key size when using <code>ssh-keygen</code>
would be limited to 2048. In fact, the concept of ssh key sizes (when specifying
the number of bytes via eg. <code>ssh-keygen -b 3072</code>) refers to the length of the
modulus value used to compute the RSA key pair - it's not directly related to the
size of the files. When decoded, the files themselves contain the modulus,
respective public/private values and some other data.
</p>

<p>
I think the AWS public key length just refers to the number of characters in the
public key. When I use default <code>ssh-keygen</code> options with <code>-b 4096</code> this comes out
at 735.
</p>
</div>
</div>
]]></description>
</item>

<item>
<title>Building a Firefox extension to highlight text</title>
<link>https://www.mattduck.com/a-super-dumb-web-highlighter.html</link>
<author>hi@mattduck.com (Matt Duck)</author>
<guid isPermaLink="false">c8fda5ff-35c1-4f16-99b0-bad0873ebd8b</guid>
<pubDate>Sat, 27 Jun 2020 16:08:00 +0100</pubDate>

<description><![CDATA[<p>
When I'm reading technical books on paper, I often highlight takeaways as I
go, and then come back later to skim the highlighted passages and write notes.
</p>

<p>
For a while now I've wanted to be able to do this when reading long web pages,
but browsers don't provide this as a feature, and I couldn't find a suitable
Firefox extension, so <a href="https://github.com/mattduck/firefox-sdwh">I wrote one</a>:
</p>

<img src="sdwh-1.jpg" alt="Screenshot of the highlighting"/>

<p>
<i>(If you're dying to find out how the text in the screenshot ends, you can <a href="https://docs.sqlalchemy.org/en/13/orm/session_basics.html#when-do-i-construct-a-session-when-do-i-commit-it-and-when-do-i-close-it">find out here</a>.)</i>
</p>

<p>
If you press <code>Ctrl + Shift + L</code> when some text is selected, it will be highlighted
as in the screenshot. If you press <code>Ctrl + Shift + :</code>, then all highlighted
snippets on the page will be copied to the clipboard. Both these functions are
also available through the right-click context menu.
</p>

<p>
That's it. Highlighting is not persisted between page visits.
</p>

<div id="outline-container-org215e340" class="outline-3">
<h3 id="org215e340"><span class="section-number-3">13.1.</span> Existing solutions</h3>
<div class="outline-text-3" id="text-13-1">
<p>
There <i>are</i> some existing Firefox extensions that provide highlighting features
(eg. <a href="https://addons.mozilla.org/en-US/firefox/addon/textmarkerpro/">Textmarker)</a>, but they tend to either:
</p>

<ol class="org-ol">
<li>have a lot of features that I don't want to manage,</li>

<li>not have keyboard shortcuts,</li>

<li>not offer clipboard export, and/or</li>

<li>have very few users, in which case I prefer not to use them, because
highlighting features like this require permissions to view all website data.</li>
</ol>
</div>
</div>

<div id="outline-container-org4078e5c" class="outline-3">
<h3 id="org4078e5c"><span class="section-number-3">13.2.</span> Learning how to write Firefox extensions</h3>
<div class="outline-text-3" id="text-13-2">
<p>
I hadn't done any webextensions work previously, but I suspected that it
wouldn't be much effort to build these features. I needed to find out:
</p>
</div>

<div id="outline-container-orged614f8" class="outline-4">
<h4 id="orged614f8">How to layout an extension and get it to run locally</h4>
<div class="outline-text-4" id="text-orged614f8">
<p>
This is covered in Mozilla's <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension">your first extension</a> tutorial. Ultimately I just needed
three files:
</p>

<ol class="org-ol">
<li><code>manifest.json</code>, which contains some metadata about the extension,</li>
<li><code>content.js</code> which runs in the context of a each web page, and</li>
<li><code>background.js</code>, which runs independently of any particular pages or windows.</li>
</ol>

<p>
These files have to be bundled into a zip folder, which can be installed
directly using Firefox Developer Edition.
</p>
</div>
</div>

<div id="outline-container-orge04f8ea" class="outline-4">
<h4 id="orge04f8ea">What permissions configuration would be required</h4>
<div class="outline-text-4" id="text-orge04f8ea">
<p>
<code>&lt;all_urls&gt;</code> was required to run on all web pages, <code>contextMenus</code> was required to
add items to the right-click menu, and <code>clipboardWrite</code> was required to write to
the clipboard.
</p>
</div>
</div>

<div id="outline-container-orgcdf6c0e" class="outline-4">
<h4 id="orgcdf6c0e">How to add keyboard shortcuts</h4>
<div class="outline-text-4" id="text-orgcdf6c0e">
<p>
This was accomplished through the usual JS event listeners for <code>keydown</code>.
</p>
</div>
</div>

<div id="outline-container-org479097d" class="outline-4">
<h4 id="org479097d">How to write to the clipboard</h4>
<div class="outline-text-4" id="text-org479097d">
<p>
There is a <code>navigator.clipboard</code> API, which worked fine.
</p>
</div>
</div>

<div id="outline-container-org149186f" class="outline-4">
<h4 id="org149186f">How to highlight text</h4>
<div class="outline-text-4" id="text-org149186f">
<p>
This part I already knew - it's trivial to add some CSS styling.
</p>
</div>
</div>

<div id="outline-container-org85da632" class="outline-4">
<h4 id="org85da632">How to add right-click context menus</h4>
<div class="outline-text-4" id="text-org85da632">
<p>
This required using the background script, and sending messages between
<code>background.js</code> and <code>content.js</code>.
</p>
</div>
</div>

<div id="outline-container-org8a8c760" class="outline-4">
<h4 id="org8a8c760">How to get the extension signed so I could run it on Firefox</h4>
<div class="outline-text-4" id="text-org8a8c760">
<p>
I wanted to do this without having to go through the audit process for AMO and
publishing it publicly. Once I had read the docs it was simple: you sign up at
<a href="https://addons.mozilla.org">https://addons.mozilla.org</a>, upload an extension, choose the option to <i>not</i>
publish a public version, and then wait for the automated signing process to
run. After a few minutes you receive an email, and a new "approved" version will
appear on the addon page in your account. You can click to install the new
version in Firefox.
</p>
</div>
</div>
</div>

<div id="outline-container-org33c7e68" class="outline-3">
<h3 id="org33c7e68"><span class="section-number-3">13.3.</span> The result: a super dumb web highlighter</h3>
<div class="outline-text-3" id="text-13-3">
<p>
You can find the code on Github: <a href="https://github.com/mattduck/firefox-sdwh">https://github.com/mattduck/firefox-sdwh</a>. It's
not very good, but it (mostly) works, and I'm finding it helpful.
</p>

<p>
I haven't made it downloadable publicly. I may do that later when I've used it
for a while, am confident there aren't any issues, and have put the time in to
let users customise it (eg. right now the keyboard shortcuts are
hard-coded).
</p>
</div>
</div>


<div id="outline-container-orgd372c09" class="outline-3">
<h3 id="orgd372c09"><span class="section-number-3">13.4.</span> Extending your tools is fun and useful</h3>
<div class="outline-text-3" id="text-13-4">
<p>
I'm pretty fluent at extending typical developer tools (the shell, Emacs etc.),
but hadn't applied this to the browser before. Now that I've done it once, it
will be trivial to add small features in the future.
</p>

<p>
I think this is one of the major benefits of knowing how to code - having the
ability to build and customise your software tools in a way that makes sense for you
personally. If you have any ideas for features that you wish were included in
Firefox, I recommend finding some boilerplate from the Mozilla docs and giving
it a go.
</p>
</div>
</div>
]]></description>
</item>

<item>
<title>Getting started with lsp-mode for Python</title>
<link>https://www.mattduck.com/lsp-python-getting-started.html</link>
<author>hi@mattduck.com (Matt Duck)</author>
<guid isPermaLink="false">59b12532-3f26-43e2-b4ca-a5f78d0db961</guid>
<pubDate>Tue, 28 Apr 2020 08:20:00 +0100</pubDate>

<description><![CDATA[<p>
<a href="https://microsoft.github.io/language-server-protocol/">Language Server Protocol</a> is a JSON-RPC protocol that allows text editors and IDEs to
delegate language-aware features (such as autocomplete, or
jump-to-definition) to a common server process. It means that editors can
support smart language features just by implementing a generic LSP client.
</p>

<p>
I'm migrating my Emacs config to use LSP, starting with Python support. It's
more powerful than my old setup, and I expect it will only improve over time, as
language servers will benefit from more community attention than the long tail
of Emacs packages.
</p>

<p>
Although there was not much configuration required to get LSP working in Emacs,
it wasn't always obvious what I needed to do, and I couldn't find many examples
of a full Python configuration to get started.
</p>

<p>
Here are a few questions and issues I encountered.
</p>

<div id="outline-container-orgfcfab55" class="outline-3">
<h3 id="orgfcfab55"><span class="section-number-3">14.1.</span> What do I need to install?</h3>
<div class="outline-text-3" id="text-14-1">
<p>
The most popular LSP client for Emacs is <a href="https://github.com/emacs-lsp/lsp-mode">lsp-mode</a> (although <a href="https://github.com/joaotavora/eglot">eglot</a> is also in
active development). <code>lsp-mode</code> tries to integrate with sensible existing tools to
minimise user configuration - it supports popular language servers, and it hooks
into Emacs packages like Flycheck and Company.
</p>

<p>
You will at least want to install <code>lsp-mode</code>, and probably also <code>lsp-ui</code> (which
is focused on UI-altering features like popups and "sideline" information).
</p>

<p>
For Python support, there are two main language servers - <a href="https://github.com/palantir/python-language-server">pyls</a> and <a href="https://github.com/Microsoft/python-language-server">Microsoft
Python Language Server</a>. I have used <code>pyls</code>. You have two options for installing
<code>pyls</code> and its dependencies:
</p>

<ol class="org-ol">
<li><code>pip install python-language-server[all]</code>. This will install <code>pyls</code>, and also
install its various dependencies that provide particular features: <code>rope</code> for
renaming, <code>pyflakes</code> for detecting errors, <code>mccabe</code> for complexity, etc.</li>

<li><code>pip install python-language-server</code>, and install the dependencies you want
directly.</li>
</ol>
</div>
</div>

<div id="outline-container-orgd936d3b" class="outline-3">
<h3 id="orgd936d3b"><span class="section-number-3">14.2.</span> Fixing a Jedi compatibility issue with pyls</h3>
<div class="outline-text-3" id="text-14-2">
<p>
At time of writing, <code>python-language-server</code> is not compatible with <code>jedi</code> version
0.16. Make sure you adhere to <code>jedi&lt;0.16,&gt;=0.14.1</code>.
</p>
</div>
</div>

<div id="outline-container-org94885c1" class="outline-3">
<h3 id="org94885c1"><span class="section-number-3">14.3.</span> How do I enable <code>lsp-mode</code> for Python?</h3>
<div class="outline-text-3" id="text-14-3">
<p>
For the base <code>lsp-mode</code>, the only required config is to call <code>(lsp)</code> when in
python-mode:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(use-package lsp-mode
  :hook
  ((python-mode . lsp)))
</pre>
</div>

<div class="org-src-container">
<pre class="src src-lisp">(use-package lsp-ui
  :commands lsp-ui-mode)
</pre>
</div>
</div>
</div>

<div id="outline-container-org0437c63" class="outline-3">
<h3 id="org0437c63"><span class="section-number-3">14.4.</span> pyls plugins: mypy, isort and black</h3>
<div class="outline-text-3" id="text-14-4">
<p>
Some integrations are not available by default in <code>pyls</code>, but are supported by
plugins. You can install these with <code>pip install pyls-black pyls-isort pyls-mypy</code>.
</p>

<p>
To then enable them in <code>lsp-mode</code>, you can use <code>(lsp-register-custom-settings)</code>:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(use-package lsp-mode
  :config
  (lsp-register-custom-settings
   '(("pyls.plugins.pyls_mypy.enabled" t t)
     ("pyls.plugins.pyls_mypy.live_mode" nil t)
     ("pyls.plugins.pyls_black.enabled" t t)
     ("pyls.plugins.pyls_isort.enabled" t t)))
  :hook
  ((python-mode . lsp)))
</pre>
</div>
</div>
</div>

<div id="outline-container-org23e258a" class="outline-3">
<h3 id="org23e258a"><span class="section-number-3">14.5.</span> Fixing a pyls-mypy issue</h3>
<div class="outline-text-3" id="text-14-5">
<p>
At time of writing, the <code>mypy</code> plugin has an issue due to a missing <code>future</code>
import. It can be resolved by <code>pip install future</code>. See <a href="https://github.com/tomv564/pyls-mypy/issues/37">pyls-mypy #37</a>.
</p>
</div>
</div>

<div id="outline-container-org1a78d21" class="outline-3">
<h3 id="org1a78d21"><span class="section-number-3">14.6.</span> What about flake8?</h3>
<div class="outline-text-3" id="text-14-6">
<p>
<code>flake8</code> is not mentioned in the <a href="https://github.com/palantir/python-language-server">pyls README</a>, but it is supported.  There are two
options to enable it:
</p>

<p>
You can use <code>(lsp-register-custom-settings)</code> as before:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(lsp-register-custom-settings
 '(("pyls.plugins.flake8.enabled" t t)))
</pre>
</div>

<p>
Alternatively, <code>lsp-mode</code> automatically turns some configuration parameters into
custom variables, including the flake8 parameters. So:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(setq lsp-pyls-plugins-flake8-enabled t)
</pre>
</div>
</div>
</div>

<div id="outline-container-org7866baa" class="outline-3">
<h3 id="org7866baa"><span class="section-number-3">14.7.</span> What other options does <code>pyls</code> support?</h3>
<div class="outline-text-3" id="text-14-7">
<p>
I'm not sure if there is a standard way to retrieve all supported configuration
options from a language server. There is a pretty long list of <code>pyls</code> options in
the <a href="https://github.com/palantir/python-language-server/blob/develop/vscode-client/package.json">vscode-client</a>.
</p>
</div>
</div>

<div id="outline-container-orgd3f0ca5" class="outline-3">
<h3 id="orgd3f0ca5"><span class="section-number-3">14.8.</span> How do I inspect what lsp-mode is doing?</h3>
<div class="outline-text-3" id="text-14-8">
<p>
There are a few places you can look for info:
</p>

<ul class="org-ul">
<li>The <code>*pyls::stderr*</code> buffer. If something isn't working as expected, this may
help identify the problem - eg. it will show issues loading particular
plugins.</li>

<li><code>(setq lsp-log-io t)</code> - this will log messages between the lsp client and server
to a buffer. You can view the buffer by calling <code>(lsp-workspace-show-log)</code>.</li>

<li>The <code>lsp-client-settings</code> variable. This contains all the <code>lsp-mode</code> settings for
different language servers, and seems to be what you eventually modify when
you run <code>(lsp-register-custom-settings)</code>.</li>

<li><code>(lsp-describe-session)</code> shows the capabilities of the current session. See the
<a href="https://github.com/emacs-lsp/lsp-mode#troubleshooting">troubleshooting section of the lsp-mode README</a>.</li>
</ul>
</div>
</div>

<div id="outline-container-org13c638f" class="outline-3">
<h3 id="org13c638f"><span class="section-number-3">14.9.</span> How do I support multiple projects?</h3>
<div class="outline-text-3" id="text-14-9">
<p>
Python projects often use virtual environments to manage project
dependencies. My understanding is that <code>pyls</code> has to be installed in the project's
virtualenv, in order to access dependencies for project-aware features like
checking symbol references.
</p>

<p>
Neither <code>lsp-mode</code> nor <code>pyls</code> seem to provide features to manage multiple projects -
the appropriate virtualenv needs to be managed separately.
</p>

<p>
In the past I've used <code>pyvenv</code> for this with some success. For various reasons
<code>pyvenv</code> is only able to set a single global virtualenv at a time, but it does
have a "tracking" mode, which can automatically change the global virtualenv
using dir-locals.
</p>

<p>
I use a default "emacs" virtualenv as a fallback for editing things like
org-mode Python buffers.
</p>

<div class="org-src-container">
<pre class="src src-lisp">(use-package pyvenv
  :demand t
  :config
  (setq pyvenv-workon "emacs")  ; Default venv
  (pyvenv-tracking-mode 1))  ; Automatically use pyvenv-workon via dir-locals
</pre>
</div>

<p>
You can use <code>(add-dir-local-variable)</code> to set <code>pyvenv-workon</code> for a particular
project.
</p>
</div>
</div>

<div id="outline-container-org49a514f" class="outline-3">
<h3 id="org49a514f"><span class="section-number-3">14.10.</span> The final code</h3>
<div class="outline-text-3" id="text-14-10">
<p>
My initial config for <code>lsp-mode</code> also included a few other settings. It looked
roughly like this:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(use-package lsp-mode
  :config
  (setq lsp-idle-delay 0.5
        lsp-enable-symbol-highlighting t
        lsp-enable-snippet nil  ;; Not supported by company capf, which is the recommended company backend
        lsp-pyls-plugins-flake8-enabled t)
  (lsp-register-custom-settings
   '(("pyls.plugins.pyls_mypy.enabled" t t)
     ("pyls.plugins.pyls_mypy.live_mode" nil t)
     ("pyls.plugins.pyls_black.enabled" t t)
     ("pyls.plugins.pyls_isort.enabled" t t)

     ;; Disable these as they're duplicated by flake8
     ("pyls.plugins.pycodestyle.enabled" nil t)
     ("pyls.plugins.mccabe.enabled" nil t)
     ("pyls.plugins.pyflakes.enabled" nil t)))
  :hook
  ((python-mode . lsp)
   (lsp-mode . lsp-enable-which-key-integration))
  :bind (:map evil-normal-state-map
              ("gh" . lsp-describe-thing-at-point)
              :map md/leader-map
              ("Ff" . lsp-format-buffer)
              ("FR" . lsp-rename)))

(use-package lsp-ui
  :config (setq lsp-ui-sideline-show-hover t
                lsp-ui-sideline-delay 0.5
                lsp-ui-doc-delay 5
                lsp-ui-sideline-ignore-duplicates t
                lsp-ui-doc-position 'bottom
                lsp-ui-doc-alignment 'frame
                lsp-ui-doc-header nil
                lsp-ui-doc-include-signature t
                lsp-ui-doc-use-childframe t)
  :commands lsp-ui-mode
  :bind (:map evil-normal-state-map
              ("gd" . lsp-ui-peek-find-definitions)
              ("gr" . lsp-ui-peek-find-references)
              :map md/leader-map
              ("Ni" . lsp-ui-imenu)))

(use-package pyvenv
  :demand t
  :config
  (setq pyvenv-workon "emacs")  ; Default venv
  (pyvenv-tracking-mode 1))  ; Automatically use pyvenv-workon via dir-locals
</pre>
</div>

<p>
This is not perfect and will definitely require future work, but it's a useful
start. In theory, adding support for a new language should only require
installing the language server and adding a couple of lines of elisp to enable
the new language.
</p>

<p>
I'll be updating my config <a href="https://github.com/mattduck/dotfiles/blob/master/emacs.d.symlink/init.org#lsp-base-packages">on github</a>.
</p>
</div>
</div>
]]></description>
</item>

<item>
<title>Some Emacs Lisp exercises</title>
<link>https://www.mattduck.com/some-emacs-lisp-exercises.html</link>
<author>hi@mattduck.com (Matt Duck)</author>
<guid isPermaLink="false">83a6da30-a9b2-40fc-8e6d-33043f24aae2</guid>
<pubDate>Thu, 05 Mar 2020 15:15:00 +0000</pubDate>

<description><![CDATA[
<div id="outline-container-org4b24936" class="outline-3">
<h3 id="org4b24936"><span class="section-number-3">15.1.</span> Background: emacs.london</h3>
<div class="outline-text-3" id="text-15-1">
<p>
Since mid-last year I've been helping to organise a monthly Emacs event. It's a
pretty low-key affair: we hang out in a room, sometimes do hands-on coding,
sometimes share things on a screen, and then sometimes go to the pub afterwards.
</p>

<p>
Our usual format doesn't include speakers. This is partly because the best part
of the meetup for us is meeting other attendees - presentations can be
hit-or-miss. But it's also because it's a lot of work to arrange speakers for a
monthly event, and a low-maintenance format means we can reliably keep it running.
</p>

<p>
Sometimes though, it can be <i>too</i> unstructured, and it would be nice to be given
some direction on what to work on. We thought it would be fun to write some
Emacs Lisp exercises to help with these situations, in the spirit of <a href="http://www.4clojure.com/problems">4clojure</a>.
</p>
</div>
</div>

<div id="outline-container-orgc8384ed" class="outline-3">
<h3 id="orgc8384ed"><span class="section-number-3">15.2.</span> The exercises</h3>
<div class="outline-text-3" id="text-15-2">
<p>
You can find the most recent exercises on at
<a href="https://emacs.london/dojo.html">https://emacs.london/dojo.html</a>. They're written as a single org-mode file, which
you can get <a href="https://github.com/london-emacs-hacking/london-emacs-hacking.github.io">directly from github</a>.
</p>
</div>
</div>

<div id="outline-container-org37ca07d" class="outline-3">
<h3 id="org37ca07d"><span class="section-number-3">15.3.</span> How it works</h3>
<div class="outline-text-3" id="text-15-3">
<p>
The idea is similar to the 4clojure exercises: you should fill in the function
labelled <code>__</code>, so that when you execute it, the <code>Pass:</code> message shows <code>t</code>.
</p>

<p>
Here's the very first exercise. You just have to write a function that
transforms the given string into uppercase:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(defun __ (s))

(let* ((result (__ "helloworld"))
       (pass (string= result "HELLOWORLD")))
  (format "Pass:%S\n%S" pass result))
</pre>
</div>

<p>
The above code snippet can be executed in org-mode by pressing <code>C-c C-c.</code> When you
do this, you'll see the results message added to the buffer:
</p>

<pre class="example" id="org654c431">
#+RESULTS:
: Pass:nil
: nil
</pre>

<p>
The <code>Pass:nil</code> indicates that the test failed. The second line shows us the value
that our function returned - in this case also <code>nil</code>.
</p>

<p>
Let's plug in a solution that uses the standard <code>upcase</code> function:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(defun __ (s)
  (upcase s))

(let* ((result (__ "helloworld"))
       (pass (string= result "HELLOWORLD")))
  (format "Pass:%S\n%S" pass result))
</pre>
</div>

<p>
Now on execution we see:
</p>

<pre class="example" id="org19078fc">
#+RESULTS:
: Pass:t
: "HELLOWORLD"
</pre>

<p>
This time we're good.
</p>
</div>
</div>

<div id="outline-container-orge0bced4" class="outline-3">
<h3 id="orge0bced4"><span class="section-number-3">15.4.</span> You can contribute on <a href="https://github.com/london-emacs-hacking/london-emacs-hacking.github.io">on github</a></h3>
<div class="outline-text-3" id="text-15-4">
<p>
We're still in the early stages of building these materials - we may or may not
find them useful over time. More exercises would be welcome though, and I'm sure
there are some easy improvements or mistakes that can be corrected.
</p>

<p>
If you're interested in any of this then you'll be very welcome <a href="https://emacs.london/">at the meetup</a>.
</p>
</div>
</div>
]]></description>
</item>

<item>
<title>More Emacs fuzzy integrations</title>
<link>https://www.mattduck.com/emacs-fuzzy-launcher-part-two.html</link>
<author>hi@mattduck.com (Matt Duck)</author>
<guid isPermaLink="false">84f266c9-fe78-45c2-8f20-233eba60bc64</guid>
<pubDate>Tue, 03 Mar 2020 16:14:00 +0000</pubDate>

<description><![CDATA[<p>
A week ago I wrote about using a Helm pop-up frame as fuzzy launcher, to provide
an Alfred-like interface for launching programs, running system commands and
making web searches.
</p>

<p>
Since then, I've added some new integrations that I'm finding really useful, and
I'm wondering why I didn't write them a long time ago.
</p>

<div id="outline-container-orgcfaeece" class="outline-3">
<h3 id="orgcfaeece"><span class="section-number-3">16.1.</span> How it looks</h3>
<div class="outline-text-3" id="text-16-1">
<p>
Everything below is using the Emacs theme named <code>intellij</code>.
</p>
</div>

<div id="outline-container-orgfe215c2" class="outline-4">
<h4 id="orgfe215c2">Opening org-mode headlines</h4>
<div class="outline-text-4" id="text-orgfe215c2">
<p>
This opens a headline matching a particular keyword in a popup frame, using an
indirect buffer:
</p>

<img src="alfred-org-keywords.gif" alt="Emacs Alfred gif"/>
</div>
</div>

<div id="outline-container-org6a705dc" class="outline-4">
<h4 id="org6a705dc">Running org-capture from anywhere</h4>
<div class="outline-text-4" id="text-org6a705dc">
<p>
This displays a frame which is automatically closed when the capture is
finished:
</p>

<img src="alfred-org-capture.gif" alt="Emacs Alfred gif"/>
</div>
</div>

<div id="outline-container-orgb3f59c3" class="outline-4">
<h4 id="orgb3f59c3">Stopping the org-mode clock from anywhere</h4>
<div class="outline-text-4" id="text-orgb3f59c3">
<p>
I always found it awkward that I had to open an org-mode buffer in Emacs just to
clock out:
</p>

<img src="alfred-org-clock.gif" alt="Emacs Alfred gif"/>
</div>
</div>

<div id="outline-container-org9d6c0f2" class="outline-4">
<h4 id="org9d6c0f2">Serving a particular directory</h4>
<div class="outline-text-4" id="text-org9d6c0f2">
<p>
There isn't much to see here, but in the background it's starting a
webserver in a pre-configured directory:
</p>

<img src="alfred-webserver.gif" alt="Emacs Alfred gif"/>
</div>
</div>

<div id="outline-container-org6c1fc4e" class="outline-4">
<h4 id="org6c1fc4e">Listing and killing processes</h4>
<div class="outline-text-4" id="text-org6c1fc4e">
<p>
This could easily be extended to add other actions, eg. yanking the PID:
</p>

<img src="alfred-processes.gif" alt="Emacs Alfred gif"/>
</div>
</div>

<div id="outline-container-org7be3e5a" class="outline-4">
<h4 id="org7be3e5a">Opening directories with a file browser</h4>
<div class="outline-text-4" id="text-org7be3e5a">
<p>
This uses <code>fd</code> to find directories:
</p>

<img src="alfred-directories.gif" alt="Emacs Alfred gif"/>
</div>
</div>

<div id="outline-container-org52675d7" class="outline-4">
<h4 id="org52675d7">Opening files with their default program</h4>
<div class="outline-text-4" id="text-org52675d7">
<p>
This uses <code>fd</code> to find files, and <code>xdg-open</code> to open them:
</p>

<img src="alfred-files.gif" alt="Emacs Alfred gif"/>
</div>
</div>
</div>

<div id="outline-container-org3f334c2" class="outline-3">
<h3 id="org3f334c2"><span class="section-number-3">16.2.</span> Emacs features now feel natural from anywhere</h3>
<div class="outline-text-3" id="text-16-2">
<p>
Certain Emacs features are core to how I work. I don't mean coding features, but
managing my work: capturing notes quickly in meetings, checking my outstanding
notes for the day, recording time spent on particular tasks, etc.
</p>

<p>
I want these features to be available at all times, and I want invoking them to
feel second nature. Not because it saves any substantial amount of time, but
because it minimises interruption, and keeps me focused on the content of my
work.
</p>

<p>
Although I've always been very quick at invoking commands in Emacs, it hasn't
always felt like a <i>natural</i> interaction. I have to bring up Emacs in my window
manager, potentially mess up my existing buffer arrangement, and display
unrelated work side-by-side (eg. my org-capture window will appear alongside the
code that I was working on).
</p>

<p>
This popup frame approach fixes that: I'm now one global keybinding and a couple
of letters away from whatever I need. It feels much better, and I expect it to
become a permanent part of my workflow.
</p>
</div>
</div>

<div id="outline-container-orgcea5785" class="outline-3">
<h3 id="orgcea5785"><span class="section-number-3">16.3.</span> The code</h3>
<div class="outline-text-3" id="text-16-3">
<p>
You can find the code for everything above <a href="https://github.com/mattduck/dotfiles/blob/master/emacs.d.symlink/init.org#alfred">in my dotfiles</a>. It's all very similar
to <a href="emacs-fuzzy-launcher.html">my previous post</a>, which covers the base "Alfred" code in more depth,
including the <code>i3</code> settings to create a global key binding and configure floating
frames.
</p>
</div>
</div>
]]></description>
</item>

<item>
<title>Emacs as a fuzzy launcher and Alfred-replacement</title>
<link>https://www.mattduck.com/emacs-fuzzy-launcher.html</link>
<author>hi@mattduck.com (Matt Duck)</author>
<guid isPermaLink="false">9941b49e-4858-4421-b59c-0f54820b5fda</guid>
<pubDate>Tue, 25 Feb 2020 00:00:00 +0000</pubDate>

<description><![CDATA[<p>
When I was using MacOS, I used to like <a href="https://www.alfredapp.com/">Alfred</a>, the multi-purpose fuzzy
finder/program-launcher. If you haven't used it, it's similar nowadays to
Spotlight, which is built-in and accessed by pressing <code>cmd+space</code>.
</p>

<p>
On Linux, the closest thing I've used to Alfred is <a href="https://github.com/albertlauncher/albert">Albert</a>, which has a lot of
the same functionality. It's a good project, and I was happy with it for a
while.
</p>

<p>
Sometime last year though I read <a href="http://xenodium.com/emacs-utilities-for-your-os/">a great post</a> by Álvaro Ramírez, demonstrating a
proof of concept for building a similar interface in Emacs, using Ivy and
Hammerspoon (on MacOS).
</p>

<p>
For six months or so I've been using my own version of this to launch programs,
run system commands and perform searches:
</p>
<img src="alfred-intro.gif" alt="Emacs Alfred gif"/>

<div id="outline-container-org504ae10" class="outline-3">
<h3 id="org504ae10"><span class="section-number-3">17.1.</span> How?</h3>
<div class="outline-text-3" id="text-17-1">
<p>
Most of the credit goes to Álvaro. I just adapted his frame-managing code to
work with Helm and i3, and wrote some Helm sources to implement the features
that I want.
</p>
</div>
</div>

<div id="outline-container-orgc00eb98" class="outline-3">
<h3 id="orgc00eb98"><span class="section-number-3">17.2.</span> Tell me more</h3>
<div class="outline-text-3" id="text-17-2">
<p>
<a href="https://github.com/emacs-helm/helm">Helm</a> is a popular fuzzy completion framework for Emacs. I use it for many things
already (selecting buffers, <code>M-x</code> commands, help commands, etc.), so it's the
natural choice for me to implement any kind of fuzzy matching feature.
</p>

<p>
The entry point is the <code>md/alfred</code> function below, which does a few things:
</p>

<ol class="org-ol">
<li>Create a buffer named <code>*alfred*</code>.</li>

<li>Make a new "frame" (ie. a new X window) for this buffer, applying some
parameters to resize and bring it into focus.</li>

<li>Set variables to disable the mode-line and the message area, and apply some
Helm styling parameters.</li>

<li>Call Helm with a list of custom "sources" (which we'll get to next), telling
it to use our new buffer.</li>

<li>After Helm is done, delete the new frame and kill our <code>*alfred*</code> buffer.</li>
</ol>

<div class="org-src-container">
<pre class="src src-lisp">(defun md/alfred ()
  (interactive)
  (with-current-buffer (get-buffer-create "*alfred*")
    (let ((frame (make-frame '((name . "alfred")
                               (window-system . x)
                               (auto-raise . t) ; focus on this frame
                               (height . 10)
                               (internal-border-width . 20)
                               (left . 0.33)
                               (left-fringe . 0)
                               (line-spacing . 3)
                               (menu-bar-lines . 0)
                               (right-fringe . 0)
                               (tool-bar-lines . 0)
                               (top . 48)
                               (undecorated . nil) ; enable to remove frame border
                               (unsplittable . t)
                               (vertical-scroll-bars . nil)
                               (width . 110))))
          (alert-hide-all-notifications t)
          (inhibit-message t)
          (mode-line-format nil)
          (helm-mode-line-string nil)
          (helm-full-frame t)
          (helm-display-header-line nil)
          (helm-use-undecorated-frame-option nil))
      (helm :sources (list (md/alfred-source-system)
                           (md/alfred-source-apps)
                           (md/alfred-source-search))
            :prompt ""
            :buffer "*alfred*")
      (delete-frame frame)
      ;; If we don't kill the buffer it messes up future state.
      (kill-buffer "*alfred*")
      ;; I don't want this to cause the main frame to flash
      (x-urgency-hint (selected-frame) nil))))
</pre>
</div>
</div>
</div>
<div id="outline-container-orgfbb052a" class="outline-3">
<h3 id="orgfbb052a"><span class="section-number-3">17.3.</span> Helm sources</h3>
<div class="outline-text-3" id="text-17-3">
<p>
The code above provides a pop-up window that runs Helm, but that's it. To
implement useful functionality, we need to write some Helm "sources", which
control the input and output integrations with Helm.
</p>
</div>
</div>

<div id="outline-container-org95e89f4" class="outline-3">
<h3 id="org95e89f4"><span class="section-number-3">17.4.</span> System commands: lock, sleep, restart, shutdown</h3>
<div class="outline-text-3" id="text-17-4">
<img src="alfred-system.gif" alt="Emacs Alfred system commands gif"/>

<p>
Sleep, restart and shutdown are all features of <code>systemctl</code>. Lock features are
also accessible via the command line. This means we just have to build a Helm
source that runs an external command when we enter a particular word.
</p>

<p>
There are two parameters to <code>helm-build-sync-source</code> that make this easy:
<code>:candidates</code> and <code>:action</code>.
</p>

<div class="org-src-container">
<pre class="src src-lisp">(defun md/alfred-source-system ()
  (helm-build-sync-source "System"
    :multimatch nil
    :requires-pattern nil
    :candidates '(("Lock" . "xset dpms force off")  ;; turns laptop screen off and triggers i3lock
                  ("Sleep" . "systemctl suspend -i")
                  ("Restart" . "systemctl reboot -i")
                  ("Shutdown" . "systemctl poweroff -i"))
    :action '(("Execute" . (lambda (candidate)
                             (shell-command (concat candidate " &gt;/dev/null 2&gt;&amp;1 &amp; disown") nil nil))))))
</pre>
</div>

<p>
Each item in <code>:candidates</code> is an alist where the car (the left side) represents
the displayed value in Helm, and the cdr (the right side) represents the value
that gets passed to our action.
</p>

<p>
<code>:action</code> defines a lambda which operates on these right-side values when
selected. We just have to use <code>(shell-command)</code> to execute the selected
command. We redirect all output to <code>/dev/null</code> so it doesn't display anywhere, and
also run <code>disown</code> so that the process is no longer owned by the shell - this will
let you close Emacs without affecting any program that you've executed with
Helm.
</p>
</div>
</div>

<div id="outline-container-orgc3769c6" class="outline-3">
<h3 id="orgc3769c6"><span class="section-number-3">17.5.</span> Launching programs</h3>
<div class="outline-text-3" id="text-17-5">
<img src="alfred-apps.gif" alt="Emacs Alfred launching programs gif"/>

<p>
This has a similar solution to our system commands implementation, with one
extra step: where do we find the list of GUI programs to launch? You could
define this manually, but it would be nice if we could automatically retrieve
them, Alfred-style.
</p>

<p>
On Arch Linux, you can find a list of <code>.desktop</code> files installed in
<code>/usr/share/applications</code>. These <a href="https://wiki.archlinux.org/index.php/Desktop_entries">Desktop entries</a> implement the <a href="https://specifications.freedesktop.org/menu-spec/menu-spec-latest.html">XDG Desktop Menu
specification</a>, which tells environments like GNOME and KDE how to launch GUI
programs, what name to display in a launcher menu, what icons to use, etc.
</p>

<p>
In theory, we could parse these files to get the user-friendly name for the
program (maybe by using <code>lsdesktop</code>). Instead, I've done something worse but much
quicker to implement: we just list all the <code>.desktop</code> files in the directory, and
then pass them to <code>gtk-launch</code> to execute them.
</p>

<p>
As above, just make sure to <code>disown</code> the process, so that it isn't coupled to
Emacs:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(defun md/alfred-source-apps ()
  (helm-build-sync-source "Apps"
    :multimatch nil
    :requires-pattern nil
    :candidates (lambda ()
                  (-map
                   (lambda (item)
                     (s-chop-suffix ".desktop" item))
                     (-filter (lambda (d) (not (or (string= d ".") (string= d ".."))))
                              (directory-files "/usr/share/applications"))))
    :action '(("Launch" . (lambda (candidate)
                            (shell-command (concat "gtk-launch " candidate " &gt;/dev/null 2&gt;&amp;1 &amp; disown") nil nil))))))
</pre>
</div>
</div>
</div>

<div id="outline-container-orgae6556e" class="outline-3">
<h3 id="orgae6556e"><span class="section-number-3">17.6.</span> Web search</h3>
<div class="outline-text-3" id="text-17-6">
<img src="alfred-search.gif" alt="Emacs Alfred browser search gif"/>

<p>
Web search is a bit different, as we're not directly launching programs - we
instead need to build a URL with the typed search term.
</p>

<p>
I also want one more feature from Alfred: key prefixes to trigger particular
searches. Typing <code>d my search term</code> should open a search in DuckDuckGo, and typing
<code>g my search term</code> should search Google.
</p>

<p>
So let's again define a <code>:candidates</code> list, with the displayed value as the car
and the actual value as the cdr. This time though, our "value" is itself going to be an
alist, containing the letter prefix, and the URL structure for that search:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(defvar md/alfred-source-search-candidates
  '(("DuckDuckGo" . ("d" . "https://www.duckduckgo.com/?q=%s"))
    ("Google" . ("g" . "https://www.google.co.uk/search?q=%s"))))
</pre>
</div>

<p>
In our previous Helm sources, we would type something, and Helm would match it
against the display value of our candidate: eg. if I typed "Loc", it would put
me on the entry named "Lock". This time, we're going to use <code>:match</code> to define a
custom matching function, which will look up the assigned letter for each
candidate.
</p>

<div class="org-src-container">
<pre class="src src-lisp">...
  ;; Count it as a match if the prefix matches, eg. "d ..."
  :match '((lambda (candidate)
             (string= (car (cdr (assoc candidate md/alfred-source-search-candidates)))
...                    (car (split-string helm-pattern)))))
</pre>
</div>

<p>
This should work, but we can make it a bit nicer to use: instead of just
displaying "<i>DuckDuckGo</i>" as the selected item in Helm, we could display
"<i>DuckDuckGo: my current search term</i>". This can be done with
<code>:filtered-candidate-transformer</code>, which transforms the displayed value for our
currently-narrowed list of candidates:
</p>

<div class="org-src-container">
<pre class="src src-lisp">...
  ;; Instead of displaying the exact thing that you type, display "DuckDuckGo: %s..."
  :filtered-candidate-transformer '((lambda (candidates source)
                                      (map 'list (lambda (c)
                                                   (cons (format "%s: %s" (car c)
                                                                 (md/strip-first-word helm-pattern)) (cdr c)))
                                           candidates)))
...
</pre>
</div>

<p>
Finally, we have the <code>:action</code> stage. This is simple: it will just build and
encode the URL, and use <code>(browse-url)</code> to open it in our preferred browser.
</p>

<p>
Overall, it looks like this:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(defvar md/alfred-source-search-candidates
  '(("DuckDuckGo" . ("d" . "https://www.duckduckgo.com/?q=%s"))
    ("Google" . ("g" . "https://www.google.co.uk/search?q=%s"))))

(defun md/strip-first-word (s)
  "Remove the first word from a string"
  (string-remove-prefix (format "%s " (car (split-string s))) s))

(defun md/alfred-source-search ()
  (helm-build-sync-source "Search"
    :nohighlight t
    :nomark t
    :multimatch nil
    :requires-pattern t
    :candidates md/alfred-source-search-candidates
    ;; Count it as a match if the prefix matches, eg. "d ..."
    :match '((lambda (candidate)
               (string= (car (cdr (assoc candidate md/alfred-source-search-candidates)))
                        (car (split-string helm-pattern)))))
    :fuzzy-match nil
    ;; Instead of displaying the exact thing that you type, display "DuckDuckGo: %s..."
    :filtered-candidate-transformer '((lambda (candidates source)
                                        (map 'list (lambda (c)
                                                     (cons (format "%s: %s" (car c)
                                                                   (md/strip-first-word helm-pattern)) (cdr c)))
                                             candidates)))
    ;; Build the URL, replacing %s with your input. Open it with browse-url.
    :action '(("Search" . (lambda (candidate)
                            (browse-url (format (cdr candidate) ;; the url
                                                (url-hexify-string
                                                 ;; This removes the "g " part from the string
                                                 (md/strip-first-word helm-pattern)))))))))
</pre>
</div>
</div>
</div>

<div id="outline-container-orgb870946" class="outline-3">
<h3 id="orgb870946"><span class="section-number-3">17.7.</span> Launching <code>(md/alfred)</code> with i3</h3>
<div class="outline-text-3" id="text-17-7">
<p>
We now have all the above functionality inside Emacs. It can be launched with
<code>(md/alfred)</code>. However, to properly take advantage of these features, we need a
global keybinding.
</p>

<p>
My window manager is <code>i3</code>, which allows you to configure keybindings by
editing <code>~/.config/i3/config</code>. We can add a binding like this:
</p>

<div class="org-src-container">
<pre class="src src-bash">bindsym $mod+space fullscreen disable; exec "emacsclient -ne '(call-interactively (quote md/alfred))'"
</pre>
</div>

<p>
When I press <code>$mod+space</code>, it will now disable fullscreen, execute Emacs and call
<code>(md/alfred)</code>. I use emacsclient because it's significantly faster than starting a
new Emacs instance.
</p>
</div>

<div id="outline-container-org3e4f4ab" class="outline-4">
<h4 id="org3e4f4ab">Floating window</h4>
<div class="outline-text-4" id="text-org3e4f4ab">
<p>
To ensure that the window doesn't get tiled by i3, I set frames marked as
"alfred" to be floating:
</p>

<div class="org-src-container">
<pre class="src src-bash">for_window [class="^Emacs$" instance="^alfred$"] floating enable
</pre>
</div>

<p>
You can also use this selection to enable other custom parameters for the
frame. For example, I can set a border width:
</p>

<div class="org-src-container">
<pre class="src src-bash">for_window [class="^Emacs$" instance="^alfred$"] border pixel 1
</pre>
</div>
</div>
</div>
</div>

<div id="outline-container-org9131836" class="outline-3">
<h3 id="org9131836"><span class="section-number-3">17.8.</span> The end</h3>
<div class="outline-text-3" id="text-17-8">
<p>
That's it. I've been happily using the described setup for six months now (with
a couple of extra features).
</p>
</div>
</div>

<div id="outline-container-org0fd2c7c" class="outline-3">
<h3 id="org0fd2c7c"><span class="section-number-3">17.9.</span> Why?</h3>
<div class="outline-text-3" id="text-17-9">
<p>
Aside from the mega fun we just had, I think there are some genuine upsides:
</p>

<ul class="org-ul">
<li>It can support cross platform. Having the same launcher and fuzzy features
between OSes seems really useful. It will require <i>some</i> platform-specific code
(eg. to launch programs appropriately), but that's not a huge amount of work.</li>

<li>Compared to Spotlight, Alfred, and even Albert, it's really easy to edit. I
can even do it on the fly - just eval something in Emacs and I'll see the
result immediately. You have close control over appearance if that's important
to you: you can set Helm faces, frame parameters, etc. You also have fully
customisable keybindings - it's Emacs, so you can do whatever you want there.</li>

<li>When I used Alfred, I found myself installing it on different machines, and
having to manually set up my preferred searches etc. each time. Now it's just
part of my dotfiles and works automatically.</li>

<li>It means one less program to care about.</li>
</ul>
</div>
</div>

<div id="outline-container-orgc3c1b35" class="outline-3">
<h3 id="orgc3c1b35"><span class="section-number-3">17.10.</span> Next steps</h3>
<div class="outline-text-3" id="text-17-10">
<p>
There are a few features that I'd like to expand:
</p>

<ul class="org-ul">
<li>A proper <code>.desktop</code>-aware program launcher.</li>

<li>A calculator that can eval basic math on the fly (without me having to write
it as lisp).</li>

<li>A dictionary lookup feature. A workaround is to add a search feature for a
dictionary website, but something more native would be nice.</li>

<li>A clipboard manager: this has the most unknowns for me. Alfred had features
where it could retrieve clipboard history, but I'm not sure if this is
achievable via Emacs. If anybody has any pointers then I'd be very happy to
hear them.</li>
</ul>

<p>
You can <a href="https://github.com/mattduck/dotfiles/blob/master/emacs.d.symlink/init.org#alfred">look through my init.el</a> to see more details of my implementation.
</p>
</div>
</div>
]]></description>
</item>

<item>
<title>Undo implementations in classic text editors</title>
<link>https://www.mattduck.com/undo-redo-text-editors.html</link>
<author>hi@mattduck.com (Matt Duck)</author>
<guid isPermaLink="false">f49a5c3b-b718-4219-b25b-92bc43168c83</guid>
<pubDate>Tue, 28 Jan 2020 00:00:00 +0000</pubDate>

<description><![CDATA[<p>
I wanted to add undo/redo support to my version of the kilo text editor. I wrote
some <a href="undo-redo-in-kilo.html">separate notes on that here</a>. As part of
that work I had a look at how undo features are implemented in Nano, Emacs and
Neovim.
</p>

<div id="outline-container-orgacd76bd" class="outline-3">
<h3 id="orgacd76bd"><span class="section-number-3">18.1.</span> Common patterns for undo</h3>
<div class="outline-text-3" id="text-18-1">
<p>
I think undo/redo can be considered a solved problem. It has been implemented
many times in different types of software, and there are a few standard
solutions that people go to.
</p>

<p>
One solution is the <b>command pattern</b>. The idea is that for each action in your
program, you can execute a corresponding undo action. For example, for an action
like "insert these 5 characters at cursor position xy", the undo action might be
"delete 5 characters at cursor position xy". You store these commands on
respective undo and redo stacks. When the user wants to undo an action, you
perform the undo operation and pop the original action onto the redo stack.
</p>

<p>
The most written-about alternative (in my experience reading online) is often
named the <b>memento pattern</b>. The key difference is that rather than storing an
undo command that can mutate state, you store the past state itself (eg. the
state of the rows). Your undo operation can then just restore the previous
state.
</p>

<p>
Both these patterns are described in the GoF <i>Design Patterns</i> book - I suspect
this has popularised the terminology that I see online. There are many ways you
can implement undo features that roughly follow the described patterns, but
don't strictly adhere to the class structure or functions in the book.
</p>

<p>
Broadly though we have two approaches - one that stores <b>actions that can be
reversed later</b>, and one that stores <b>state that can be restored</b>.
</p>
</div>
</div>

<div id="outline-container-org445d71a" class="outline-3">
<h3 id="org445d71a"><span class="section-number-3">18.2.</span> How do the classic text editors do it?</h3>
<div class="outline-text-3" id="text-18-2">
<p>
These programs have been undoing for decades, so they must be doing something
right.
</p>
</div>
</div>

<div id="outline-container-org02c544a" class="outline-3">
<h3 id="org02c544a"><span class="section-number-3">18.3.</span> Nano</h3>
<div class="outline-text-3" id="text-18-3">
<p>
Nano clearly follows the reverse-an-action approach. <a href="https://git.savannah.gnu.org/cgit/nano.git/tree/src/nano.h#n165">nano.h</a> describes an enum of
supported undo actions, named <code>undo_type</code>. Actions have labels like <code>INSERT</code>,
<code>JOIN</code>, and <code>COMMENT</code> - these are specific, granular actions that have dedicated
undo operations.
</p>

<p>
A history item is represented by the
<a href="https://git.savannah.gnu.org/cgit/nano.git/tree/src/nano.h#n308">undostruct</a>
type, which stores the action and some associated data (this includes a <code>*next</code>
pointer to go further back in time):
</p>

<div class="org-src-container">
<pre class="src src-c">typedef struct undostruct {
	undo_type type;
		/* The operation type that this undo item is for. */
	int xflags;
		/* Some flag data to mark certain corner cases. */
	ssize_t lineno;
		/* The line number where the operation began or ended. */
	size_t begin;
		/* The x position where the operation began or ended. */
	char *strdata;
		/* String data to help restore the affected line. */
	size_t wassize;
		/* The file size before the action. */
	size_t newsize;
		/* The file size after the action. */
	groupstruct *grouping;
		/* Undo info specific to groups of lines. */
	linestruct *cutbuffer;
		/* A copy of the cutbuffer. */
	ssize_t mark_begin_lineno;
		/* Mostly the line number of the current line; sometimes something else. */
	size_t mark_begin_x;
		/* The x position corresponding to the above line number. */
	struct undostruct *next;
		/* A pointer to the undo item of the preceding action. */
} undostruct;
</pre>
</div>

<p>
Throughout the codebase, there are calls to a function <code>add_undo()</code>, which
accepts an <code>undo_type</code>, creates an <code>undostruct</code> with the appropriate metadata,
and sets it to a field named <code>undotop</code>, which represents the top of the undo
history.
</p>

<p>
The <code>do_undo()</code> function then executes appropriate logic in a switch to reverse
an action. Here's a snippet of the main switch statement in <code>do_undo()</code> (from
<a href="https://git.savannah.gnu.org/cgit/nano.git/tree/src/text.c">text.c</a>):
</p>

<div class="org-src-container">
<pre class="src src-c">	case INDENT:
		handle_indent_action(u, TRUE, TRUE);
		undidmsg = _("indent");
		break;
	case UNINDENT:
		handle_indent_action(u, TRUE, FALSE);
		undidmsg = _("unindent");
		break;
#ifdef ENABLE_COMMENT
	case COMMENT:
		handle_comment_action(u, TRUE, TRUE);
		undidmsg = _("comment");
		break;
	case UNCOMMENT:
		handle_comment_action(u, TRUE, FALSE);
		undidmsg = _("uncomment");
		break;
#endif
</pre>
</div>

<p>
It's pretty easy to read the undo code in Nano - most of it can be found in the
linked files.
</p>
</div>
</div>

<div id="outline-container-orge64b1ec" class="outline-3">
<h3 id="orge64b1ec"><span class="section-number-3">18.4.</span> Emacs</h3>
<div class="outline-text-3" id="text-18-4">
<p>
Emacs also has an action-oriented implementation, although it's a much bigger
codebase.
</p>

<p>
The Emacs source code consists of a smaller C core which implements some central
components and the emacs-lisp interpreter. Most of the code is then written in
emacs-lisp. Undo features span both of these layers. We start at <a href="https://github.com/emacs-mirror/emacs/blob/master/src/undo.c">undo.c</a>.
</p>

<p>
<i>Fun fact alert: using git blame, parts of <code>undo.c</code> go back to a version labelled "Initial revision" from April 1991 (29 years ago! According to Wikipedia the first GNU Emacs release was 1985, so I'm not sure the significance of this exact commit).</i>
</p>

<p>
In <code>undo.c</code>, we can see a structure named <code>undo_list</code>, which stores the undo history
for a buffer. Like with Nano, multiple action types are supported. One
difference to the Nano implementation is that <code>undo_list</code> can store a <code>nil</code> value as
a "boundary". The boundary is used to group multiple actions into a single undo
operation.
</p>

<p>
In the elisp layer, <code>undo_list</code> is represented by the <code>buffer-undo-list</code>
variable. If you're in Emacs and you call <code>(describe-variable 'buffer-undo-list)</code>
you'll see an excellent overview of the types of data in this file, and you can
also see its current state. Here's a snippet of <code>buffer-undo-list</code> for the Emacs
buffer that I'm using to write this post:
</p>

<div class="org-src-container">
<pre class="src src-lisp">(nil
 (4720 . 4721)  ;; insertion at point
 4719  ;; cursor movement ?
 nil  ;; boundary
 (4697 . 4702)  ;; insertion at point
 (#("w" 0 1  ;; ?? this one isn't obvious. Maybe a deletion or property change.
    (fontified t))
  . -4697)
 (#&lt;marker at 4721 in undo-redo.org&gt; . -1)  ;; changes to a "marker" point in the file
 (#&lt;marker at 4697 in undo-redo.org&gt; . -1)
 (#&lt;marker at 4697 in undo-redo.org&gt; . -1)
 ...)
</pre>
</div>

<p>
My history continues for about 2000 lines just in this buffer. There is a global undo
limit (defined as 80,000 for me in the C source). According to the <code>undo-limit</code>
documentation, old undo history gets cleaned up in garbage collection.
</p>

<p>
<code>undo.c</code> describes some functions that add state to the <code>undo_list</code>. For example,
<code>record_point()</code> ("point" means cursor position), <code>record_insert()</code>,
<code>record_delete()</code>, etc.  These <code>record_$thing()</code> functions are called in a few
places in the C code to store actions to later undo (for example in <a href="https://github.com/emacs-mirror/emacs/blob/78ec68e18f07a90a9ad400683b973ff51baa80e1/src/insdel.c">insdel.c</a>).
I'm sure there are some similar functions in the elisp layer too, but I haven't
looked in depth.
</p>

<p>
The actual execution of the undo actions also happens in the elisp layer, in
<a href="https://github.com/emacs-mirror/emacs/blob/f18af6cd5cb7dbbf7420ec2d3efed4e202c4f0dd/lisp/simple.el#L2549">(primitive-undo)</a>. The comments make it reasonably clear to understand. For
example, in order to undo a text insert, it does <code>(delete-region beg end)</code>. The
snippet below is from the equivalent of Nano's switch statement:
</p>

<div class="org-src-container">
<pre class="src src-lisp">---
;; Element (nil PROP VAL BEG . END) is property change.
(`(nil . ,(or `(,prop ,val ,beg . ,end) pcase--dontcare))
 (when (or (&gt; (point-min) beg) (&lt; (point-max) end))
   (error "Changes to be undone are outside visible portion of buffer"))
 (put-text-property beg end prop val))
...
;; Element (BEG . END) means range was inserted.
(`(,(and beg (pred integerp)) . ,(and end (pred integerp)))
 (when (or (&gt; (point-min) beg) (&lt; (point-max) end))
   (error "Changes to be undone are outside visible portion of buffer"))
 ;; Set point first thing, so that undoing this undo
 ;; does not send point back to where it is now.
 (goto-char beg)
 (delete-region beg end))
...
;; Element (apply FUN . ARGS) means call FUN to undo.
...
</pre>
</div>

<p>
You can see that one of the action types is an arbitrary function that gets
applied when executing the undo. I haven't looked at exactly where this is used,
but I assume that one of the use-cases is so third-party extensions can
integrate with the undo feature.
</p>

<p>
I'm sure there is a lot of undo-related code through the codebase that I haven't
mentioned here, especially in the lisp parts. I think these cover the basics though.
</p>
</div>
</div>

<div id="outline-container-orga0bb2eb" class="outline-3">
<h3 id="orga0bb2eb"><span class="section-number-3">18.5.</span> Neovim</h3>
<div class="outline-text-3" id="text-18-5">
<p>
Neovim's implementation is the most daunting to jump into - its
<a href="https://github.com/neovim/neovim/blob/master/src/nvim/undo.c">undo.c comes in
at 3000 lines</a>. It has similarities to the other implementations, but stores
and restores some general state fields, with less explicit differentiation
between types of user actions.
</p>

<p>
The undo functions and data structures are prefixed with <code>u_</code>. The first main struct
(defined in
<a href="https://github.com/neovim/neovim/blob/master/src/nvim/undo_defs.h">undo_defs.h</a>)
is <code>u_header</code>, which holds pointers to manage the undo history, and also holds
some buffer state like cursor position.
</p>

<p>
<code>u_header</code> also stores the time of the undo action. This is used to support the
handy time-based command <b>:earlier</b>, which lets you revert back to previous state
by time (eg. <code>:earlier 2h</code> will undo back to the state recorded 2 hours ago). As
far as I'm aware neither Nano nor Emacs support this.
</p>

<p>
The second important struct is <code>u_entry_T</code>, which stores an array of text lines
in <code>**ue_array</code> (which is used to restore buffer text), and some other
metadata. I've copied <code>u_entry_T</code> below:
</p>

<div class="org-src-container">
<pre class="src src-c">typedef struct u_entry u_entry_T;
struct u_entry {
  u_entry_T   *ue_next;         /* pointer to next entry in list */
  linenr_T ue_top;              /* number of line above undo block */
  linenr_T ue_bot;              /* number of line below undo block */
  linenr_T ue_lcount;           /* linecount when u_save called */
  char_u      **ue_array;       /* array of lines in undo block */
  long ue_size;                 /* number of lines in ue_array */
#ifdef U_DEBUG
  int ue_magic;                 /* magic number to check allocation */
#endif
};
</pre>
</div>

<p>
<code>undo.c</code> defines a few functions to record an undo, such as <code>u_save()</code>,
<code>u_save_cursor()</code> and <code>u_savedel()</code>, although most of the logic is delegated to
<code>u_savecommon()</code>, which generates new <code>u_entry_T</code> and <code>u_header</code> instances where
appropriate. These functions are then called in various places in the codebase
where the buffer is modified, such as <code>ops.c</code>, <code>edit.c</code>, <code>normal.c</code> and
<code>ex_cmds.c</code>.
</p>

<p>
There are a couple of entry points to perform an undo operation. The handler for
pressing <code>u</code> in normal mode is <a href="https://github.com/neovim/neovim/blob/d3a9d75c0462fea7b00e639d1b324bcf08a8b02d/src/nvim/normal.c#L5815">nv_undo()</a>. This calls a chain of functions:
<code>nv_kundo()</code> -&gt; <code>u_undo()</code> (back in <code>undo.c</code>) -&gt; <code>u_doit()</code> -&gt; <code>u_undoredo()</code>.
</p>

<p>
<a href="https://github.com/neovim/neovim/blob/master/src/nvim/undo.c#L2126">u_undoredo()</a> is where the main undo logic is applied. Some of the more
significant lines are the calls to <code>ml_delete()</code>, <code>ml_replace()</code> and <code>ml_append()</code>,
which delete or update text lines (all defined in <code>memline.c</code>). The text state is
retrieved from <code>u_entry_T-&gt;ue_array</code>. For example:
</p>

<div class="org-src-container">
<pre class="src src-c">/* insert the lines in u_array between top and bot */
if (newsize) {
  for (lnum = top, i = 0; i &lt; newsize; ++i, ++lnum) {
    /*
     * If the file is empty, there is an empty line 1 that we
     * should get rid of, by replacing it with the new line
     */
    if (empty_buffer &amp;&amp; lnum == 0) {
      ml_replace((linenr_T)1, uep-&gt;ue_array[i], true);
    } else {
      ml_append(lnum, uep-&gt;ue_array[i], (colnr_T)0, false);
    }
    xfree(uep-&gt;ue_array[i]);
  }
  xfree((char_u *)uep-&gt;ue_array);
 }
</pre>
</div>

<p>
Reading <code>u_undoredo()</code>, it's clear that Vim's implementation is more generalised
than in Nano and Emacs, which both have clear switch-like statements that say
"if you find item <code>x</code> on the undo history, apply operation <code>y</code>". In Nano
different actions are represented by an enum, and in Emacs different actions
have different lisp structures.
</p>

<p>
In Vim, regardless of the type of user action performed, general buffer state is
stored and restored using <code>u_header_T</code>, <code>u_entry_T</code> and <code>visualinfo_T</code>. The data
they contain looks quite general - I don't see anything action-specific here,
like the <code>JOIN</code> type in Nano, or the custom function that you can store in
Emacs. Emacs' items are comparatively simple as they only record state that is
needed - eg. an insertion can just be represented in the undo history by <code>(BEG
. END)</code>.
</p>

<p>
It looks like there is a lot more to uncover in this implementation, but
hopefully that describes some of the basic points. Let's look at something
different.
</p>
</div>
</div>

<div id="outline-container-org04c5d7e" class="outline-3">
<h3 id="org04c5d7e"><span class="section-number-3">18.6.</span> A reusable solution that copies state: Redux</h3>
<div class="outline-text-3" id="text-18-6">
<p>
I'm not super fluent in modern JS frameworks, but I knew that <a href="https://redux.js.org/introduction/getting-started">Redux</a> was based
around <b>reducers</b> that operate on immutable state, and that there were generalised
undo solutions that could implement undo/redo by keeping a copy of that state.
</p>

<p>
The Redux documentation actually <a href="https://redux.js.org/recipes/implementing-undo-history/">describes an implementation for using Redux to
implement undo</a> by restoring past state. Coding this from scratch isn't required
though as there is a popular implementation: <a href="https://github.com/omnidan/redux-undo">Redux Undo</a>.
</p>

<p>
Redux Undo is a generalised implementation of the restore-past-state approach:
you only need to decorate specific reducers as undoable, and it will store all
the state changes for you.
</p>

<p>
The advantage here is that you can add undo/redo behaviour to components without
having to do any specific work to record or reverse particular operations: the
actions are the same for any use-case as you're just copying and restoring your
state.
</p>

<p>
At its most basic, you can start recording your state history in a few lines of
code (There are more features and various configuration <a href="https://github.com/omnidan/redux-undo">documented in the README</a>):
</p>

<div class="org-src-container">
<pre class="src src-javascript">// context: 'counter' is a reducer that increments or decrements a number.

import { combineReducers } from 'redux'; // Redux util functions.
import undoable from 'redux-undo'; // the undoable higher-order reducer.
combineReducers({
  counter: undoable(counter, {
    limit: 10 // set a limit for the size of the history.
  })
})

// See https://github.com/omnidan/redux-undo for more details.
</pre>
</div>
</div>
</div>

<div id="outline-container-orgb153f12" class="outline-3">
<h3 id="orgb153f12"><span class="section-number-3">18.7.</span> What's the catch?</h3>
<div class="outline-text-3" id="text-18-7">
<p>
This sounds exciting - it looks like much less work to implement than even
Nano's undo feature. The ease of implementation doesn't come for free
though. The main cost I see is that state copies will need to be stored in
memory. Whereas with a command-based approach you could have said "delete the
characters at position xy to reverse the user's insert action", you're now
storing the old state in order to restore it. This means you need to be
conscious that you're not copying extra state when it hasn't changed, and that
you have sensible limits on your undo history.
</p>

<p>
I'm not sure how often this is an issue with Redux Undo in practice. I did read
<a href="https://github.com/omnidan/redux-undo/issues/36">this redux-undo issue
discussion</a> about using diffs between states to reduce the memory overhead. It
led me to a couple of small projects that suggest it has been a concern at least
for some people:
</p>

<ul class="org-ul">
<li><a href="https://github.com/JannicBeck/undox">Undox</a> is like Redux Undo but uses actions instead of storing state, to reduce
the memory cost.</li>

<li><a href="https://github.com/stephan83/redux-undo-stack">Redux Undo Stack</a> is like Redux Undo but stores incremental changes instead of
entire states.</li>
</ul>

<p>
I doubt that a third-party solution like this would work for a
performance-conscious text editor, but it's definitely a valuable tool.
</p>
</div>
</div>

<div id="outline-container-org0207df8" class="outline-3">
<h3 id="org0207df8"><span class="section-number-3">18.8.</span> Conclusions</h3>
<div class="outline-text-3" id="text-18-8">
<p>
I'm not sure we learned anything profound here, but it's cool to see a few
different approaches to a common software feature.
</p>

<p>
I'd like to look at the Vim implementation more as I've only scratched the
surface.
</p>

<p>
I think it's worth reading through parts of the Nano/Vim/Emacs
codebases. They're three ubiquitous text-editing programs that have been around
for ages and are all written in C (at least partially), but that have some major
differences. Nano is the easiest place to start unless you're particular
enamoured with one of the others, because it's smaller and you don't need to
learn about editor-specific concepts to follow it.
</p>
</div>
</div>
]]></description>
</item>

<item>
<title>Adding undo/redo to kilo (and debugging memory usage)</title>
<link>https://www.mattduck.com/undo-redo-in-kilo.html</link>
<author>hi@mattduck.com (Matt Duck)</author>
<guid isPermaLink="false">24d3583c-679a-4f38-a4f7-5b0ca9467114</guid>
<pubDate>Tue, 28 Jan 2020 00:00:00 +0000</pubDate>

<description><![CDATA[<p>
I add a naive undo feature to kilo and then go on a detour to investigate memory
usage.
</p>

<div id="outline-container-org72dd17b" class="outline-3">
<h3 id="org72dd17b"><span class="section-number-3">19.1.</span> The code</h3>
<div class="outline-text-3" id="text-19-1">
<p>
The code is <a href="https://github.com/mattduck/kilo">on github</a>. The important
context is that we have a couple of structs, <code>editorConfig</code>, which represents
the global state of our editor, and <code>erow</code>, which represents a row of text and
some associated data:
</p>

<div class="org-src-container">
<pre class="src src-c">typedef struct erow {
  int idx;  // which row in the buffer it represents
  int size;  // the row length
  char *chars;  // the characters in the line
  char *render;  // the "rendered" characters in the line, where eg. \t will expand to spaces
  int rsize;  // the length of the "rendered" line
  unsigned char *hl;  // the highlight property of a character
  int hl_open_comment;  // whether this line is part of a multiline comment
} erow;

typedef struct editorConfig {
  int cx, cy;  // cursor position
  int rx;  // render index, as some chars are multi-width (eg. tabs)
  int rowoff; // file offset
  int coloff; // same as above
  int screenrows; // size of the terminal
  int screencols; // size of the terminal
  int numrows;  // size of the buffer
  erow *row;  // current row
  int dirty;  // is modified?
  char *filename;  // name of file linked to the buffer
  char statusmsg[80];  // status message displayed on at bottom of buffer
  time_t statusmsg_time;  // how long ago status message was written, so we can make it disappear
  struct editorSyntax *syntax;  // the syntax rules that apply to the buffer
  struct termios orig_termios;  // the terminal state taken at startup; used to restore on exit
  int mode;  // vim-like normal/insert mode
} editorConfig;
</pre>
</div>
</div>
</div>

<div id="outline-container-org7bc3c3f" class="outline-3">
<h3 id="org7bc3c3f"><span class="section-number-3">19.2.</span> The approach</h3>
<div class="outline-text-3" id="text-19-2">
<p>
A common undo solution is to store the user action, and then perform an
equivalent reverse operation when the user presses "undo". For example, if the
user inserts 5 characters at cursor position xy, we later may want to delete 5
characters at cursor position xy.
</p>

<p>
I wanted something more general though: this a toy editor and I'd like to be
able to hack arbitrary features onto it without having to code a corresponding undo
feature. I started with the easiest possible approach: just copy and restore all
the global state. This could be done with relatively few changes:
</p>
</div>
</div>

<div id="outline-container-org780cf3f" class="outline-3">
<h3 id="org780cf3f"><span class="section-number-3">19.3.</span> Turn our <code>editorConfig</code> value into a pointer</h3>
<div class="outline-text-3" id="text-19-3">
<p>
The editor stores a global <code>editorConfig</code> in a variable <code>E</code>. This holds state
like the cursor position and pointers to the <code>erows</code> that make up the buffer. I
wanted to be able to swap this out for an older version, so I turned it into a
pointer that represents the <i>current</i> global state.
</p>

<p>
I also added <code>undo</code> and <code>redo</code> pointers to the <code>E</code> struct. This could be used to
link a linear branch of undo/redo states.
</p>
</div>
</div>

<div id="outline-container-orgde2f445" class="outline-3">
<h3 id="orgde2f445"><span class="section-number-3">19.4.</span> Write a <code>history_push()</code> function</h3>
<div class="outline-text-3" id="text-19-4">
<p>
&#x2026;which uses <code>malloc()</code> and <code>memcpy()</code> to clone <code>editorConfig</code> and the <code>erow</code>
structs that make up all the global state.
</p>

<p>
I can then update <code>E</code> to be a pointer to the <i>current</i> state, and
set <code>E-&gt;undo</code> and <code>E-&gt;undo-&gt;redo</code> to point to the right versions of state based
on the undo history.
</p>

<p>
I added a keyboard handler so I could manually invoke <code>history_push()</code> to test it.
</p>
</div>
</div>

<div id="outline-container-orgcbbcacb" class="outline-3">
<h3 id="orgcbbcacb"><span class="section-number-3">19.5.</span> Add <code>history_undo()</code> and <code>history_redo()</code></h3>
<div class="outline-text-3" id="text-19-5">
<p>
These functions just return the appropriate <code>E-&gt;undo/redo</code> values. I added
vim-compatible <code>u</code> and <code>R</code> keybindings to invoke these.
</p>
</div>
</div>

<div id="outline-container-org422312d" class="outline-3">
<h3 id="org422312d"><span class="section-number-3">19.6.</span> Behold:</h3>
<div class="outline-text-3" id="text-19-6">
<img src="kilo-undo.gif" alt="The undo UI."/>

<p>
That's about it. We have an undo feature.
</p>
</div>
</div>

<div id="outline-container-org3f59b45" class="outline-3">
<h3 id="org3f59b45"><span class="section-number-3">19.7.</span> Job done?</h3>
<div class="outline-text-3" id="text-19-7">
<p>
I suspect not! My biggest concern is that this is surely very memory
inefficient. Let's validate that.
</p>
</div>
</div>

<div id="outline-container-org60d3c60" class="outline-3">
<h3 id="org60d3c60"><span class="section-number-3">19.8.</span> Snapshotting process memory changes with <code>pmap</code></h3>
<div class="outline-text-3" id="text-19-8">
<p>
I want to see how the editor's memory usage changes when I run my my
<code>history_push()</code> function. I'm sure there are heap-profiling or C-debugging
tools I can use to inspect state as it changes, but for speed I'm just going to
take some snapshots using <code>pmap</code>.
</p>

<p>
To see the delta in subsequent <code>pmap</code> calls we can write to a tempfile and
use <code>diff</code>:
</p>

<div class="org-src-container">
<pre class="src src-sh">#!/bin/bash
#
# pmap-diff.sh
#
# Snapshot the results of pmap to a file, then diff it on
# subsequent calls. Scope per PID.
ARG="$1"
if [ -z "$ARG" ]; then exit 1; fi
pidof "$ARG" || exit 1;
PROCESSPID="$(pidof $ARG)"
F="/tmp/pmap-$ARG.$PROCESSPID"

if [ ! -f "$F" ]; then
    # pmap hasn't been called yet for this PID. Display the whole output.
    pmap "$(pidof $ARG)" -x &gt; "$F";
    cat "$F";
    exit 0;
else
    # pmap has been called. Display the diff
    mv "$F" "$F".previous;
    pmap "$(pidof $ARG)" -x &gt; "$F";
    head -n 2 "$F";
    diff "$F".previous "$F" &amp;&amp; echo "no change";
    rm "$F".previous;
fi
</pre>
</div>
</div>
</div>

<div id="outline-container-org786faff" class="outline-3">
<h3 id="org786faff"><span class="section-number-3">19.9.</span> The test</h3>
<div class="outline-text-3" id="text-19-9">
<p>
I have an example text file that we can use for this. It's about 28.7KB:
</p>

<div class="org-src-container">
<pre class="src src-nohighlight">$ wc kilo-org.c
 1056  3826 28722 kilo-org.c
</pre>
</div>

<p>
I open this file with the editor:
</p>

<div class="org-src-container">
<pre class="src src-sh">./kilo kilo-org.c
</pre>
</div>

<p>
When I run <code>./pmap-diff.sh kilo</code> for the first time, I see the full output of <code>pmap</code>:
</p>

<div class="org-src-container">
<pre class="src src-nohighlight">Address           Kbytes     RSS   Dirty Mode  Mapping
00005652b5815000       8       8       0 r---- kilo
00005652b5817000      24      24       0 r-x-- kilo
00005652b581d000       8       8       0 r---- kilo
00005652b581f000       4       4       4 r---- kilo
00005652b5820000       4       4       4 rw--- kilo
00005652b67a1000     288     216     216 rw---   [ anon ] // this is the heap
00007f486d32b000     148     148       0 r---- libc-2.30.so
00007f486d350000    1332     888       0 r-x-- libc-2.30.so
00007f486d49d000     296     128       0 r---- libc-2.30.so
00007f486d4e7000       4       0       0 ----- libc-2.30.so
00007f486d4e8000      12      12      12 r---- libc-2.30.so
00007f486d4eb000      12      12      12 rw--- libc-2.30.so
00007f486d4ee000      24      24      24 rw---   [ anon ]
00007f486d52e000       8       8       0 r---- ld-2.30.so
00007f486d530000     124     124       0 r-x-- ld-2.30.so
00007f486d54f000      32      32       0 r---- ld-2.30.so
00007f486d558000       4       4       4 r---- ld-2.30.so
00007f486d559000       4       4       4 rw--- ld-2.30.so
00007f486d55a000       4       4       4 rw---   [ anon ]
00007ffc63ea8000     136      20      20 rw---   [ stack ]
00007ffc63f00000      12       0       0 r----   [ anon ]
00007ffc63f03000       4       4       0 r-x--   [ anon ]
ffffffffff600000       4       0       0 --x--   [ anon ]
---------------- ------- ------- -------
total kB            2496    1676     304
</pre>
</div>

<p>
I have a lot to learn about the intricacies of measuring process memory usage,
but I know that RSS represents memory that is held in RAM, and Kbytes is the
total usage include virtual memory, paging etc.
</p>

<p>
The row at address <code>00005652b67a1000</code> is the heap (you can confirm this by
running <code>pmap -X</code> to see more verbose output):
</p>

<div class="org-src-container">
<pre class="src src-nohighlight">00005652b67a1000     288     216     216 rw---   [ anon ]
</pre>
</div>

<p>
Out of curiosity, if I run kilo without opening a file, the heap size is about
156KB smaller:
</p>

<div class="org-src-container">
<pre class="src src-nohighlight">00005601d9ca8000     132       4       4 rw---   [ anon ]
</pre>
</div>

<p>
Back on the version of kilo that has my example file open, if I invoke
<code>history_push()</code> and run my pmap script again, I just see the diff since last
time:
</p>

<div class="org-src-container">
<pre class="src src-nohighlight">Address           Kbytes     RSS   Dirty Mode  Mapping
8c8
&lt; 00005652b67a1000     288     216     216 rw---   [ anon ]
---
&gt; 00005652b67a1000     420     400     400 rw---   [ anon ]
27c27
&lt; total kB            2496    1676     304
---
&gt; total kB            2628    1860     488 // +132, +184, +184
</pre>
</div>

<p>
The only change is the heap size. My total heap memory has increased by
132K, and the RSS by 184K. That's not a great start considering my whole file is
less than 29K.
</p>

<p>
Let's see what happens after a few more invocations of <code>history_push()</code>. Below
are the changes. Each row is a diff against the row above it:
</p>

<table border="0">


<colgroup>
<col  class="org-right" />

<col  class="org-right" />

<col  class="org-right" />
</colgroup>
<thead>
<tr>
<th scope="col" class="org-right">num calls</th>
<th scope="col" class="org-right">Heap Kbytes</th>
<th scope="col" class="org-right">Heap RSS</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-right">start</td>
<td class="org-right">288</td>
<td class="org-right">216</td>
</tr>

<tr>
<td class="org-right">1</td>
<td class="org-right">+132</td>
<td class="org-right">+184</td>
</tr>

<tr>
<td class="org-right">2</td>
<td class="org-right">+288</td>
<td class="org-right">+188</td>
</tr>

<tr>
<td class="org-right">3</td>
<td class="org-right">+132</td>
<td class="org-right">+192</td>
</tr>

<tr>
<td class="org-right">4</td>
<td class="org-right">+132</td>
<td class="org-right">+192</td>
</tr>

<tr>
<td class="org-right">5</td>
<td class="org-right">+312</td>
<td class="org-right">+192</td>
</tr>

<tr>
<td class="org-right">10</td>
<td class="org-right">+836 (avg 167.2)</td>
<td class="org-right">+956 (avg 191.2)</td>
</tr>

<tr>
<td class="org-right">end</td>
<td class="org-right">2120</td>
<td class="org-right">2120</td>
</tr>
</tbody>
</table>

<p>
So it looks like our RSS memory allocation increases consistently by 192KB with
every state copy. The first couple of calls instead increase by 184 and 188
respectively, but I'm ignoring this as I think it's easily explainable by the
editor behaviour. However, I <i>do</i> wonder why sometimes our total heap size
increases by 132, and other times it's more.
</p>
</div>
</div>

<div id="outline-container-org8245a82" class="outline-3">
<h3 id="org8245a82"><span class="section-number-3">19.10.</span> Where is this memory going?</h3>
<div class="outline-text-3" id="text-19-10">
<p>
We can reason about some of this heap increase by looking at the size of our
data. Using <code>sizeof()</code> on our copied structs, I can see the following:
</p>

<table border="0">


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

<col  class="org-right" />
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">type</th>
<th scope="col" class="org-right">size (bytes)</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">struct editorConfig</td>
<td class="org-right">232</td>
</tr>

<tr>
<td class="org-left">struct termios</td>
<td class="org-right">60</td>
</tr>

<tr>
<td class="org-left">struct erow</td>
<td class="org-right">48</td>
</tr>
</tbody>
</table>

<p>
We only make one copy of <code>editorConfig</code> and <code>termios</code>, so their footprint should
be negligible. However, although <code>erow</code> is only 48 bytes, a new <code>erow</code> is put on
the heap for each line in the file. There are 1056 lines, so <code>(sizeof(erow) *
1056)</code> immediately accounts for 50.6KB.
</p>

<p>
The char array for each row is stored in <code>erow-&gt;chars</code>. This stores all the text
in the file, and we know the sum of all <code>erow-&gt;chars</code> arrays should come to
about 29KB (because that's the file size). But there are two other char arrays
of approximately the same size: <code>erow-&gt;render</code> and <code>erow-&gt;hl</code>, which
respectively store a pretty-rendered version of the row and the syntax
highlighting data for the row. Taking these into account is <code>3 * 28.7</code> = ~86KB.
</p>

<p>
We can now account for roughly 135KB between the size of the <code>erow</code> struct, and
the contents of the <code>erow</code> arrays. I was initially expecting it might be close
to 192KB, as we see the 192KB increase consistently. 135KB doesn't exactly match
to anything, although it is close to the 132KB total memory increases that we see.
</p>
</div>
</div>

<div id="outline-container-orgc1573d5" class="outline-3">
<h3 id="orgc1573d5"><span class="section-number-3">19.11.</span> What about the other increases?</h3>
<div class="outline-text-3" id="text-19-11">
<p>
Why do we consistently see +192KB in RSS? I'm actually not sure without diving
into some more detailed profiling. There isn't any obvious new data being
allocated to the heap in the code. I ran a test where I disabled most of the
editor's code other than <code>history_push()</code>, and still saw this +192KB pattern. I
wonder if the copying logic makes the program move some other data that was
already allocated to memory into RSS.
</p>

<p>
I have no good ideas about the total memory heap increases that are higher than
132KB - I think the most likely explanation is that I need to run <code>valgrind</code> and
make sure I have no memory issues. I'm also curious why sometimes the total
heap memory and the RSS memory are the same size, but sometimes they're
different - that's a whole separate investigation though.
</p>
</div>
</div>

<div id="outline-container-orgd0ea238" class="outline-3">
<h3 id="orgd0ea238"><span class="section-number-3">19.12.</span> How can we make this feature more efficient?</h3>
<div class="outline-text-3" id="text-19-12">
<p>
I have a few questions about those memory numbers, but regardless we have some
useful information: each copy of history will cost a fixed 48 bytes per row for
the <code>erow</code> struct, and then an extra 3x the actual text size of the row (for
<code>row-&gt;chars</code>, <code>row-&gt;render</code> and <code>row-&gt;hl</code> respectively). For our example file,
that's <code>((1056 * 48bytes) + (28.7KB * 3))</code>, which in total is about 135KB.
</p>

<p>
If I want to keep 50 of these revisions, it will cost at least ~6.75MB, and in
practice it will be higher (as we have these unaccounted-for memory increases).
</p>

<p>
There are various ways we could try to reduce this cost. Some that immediately
come to mind:
</p>
</div>

<div id="outline-container-orgefd7c8f" class="outline-4">
<h4 id="orgefd7c8f">Stop storing the <code>erow-&gt;render</code> and <code>erow-&gt;hl</code> fields</h4>
<div class="outline-text-4" id="text-orgefd7c8f">
<p>
&#x2026;and instead just re-compute them on restore, as they can be completely recreated
from the <code>erow-&gt;chars</code> state. This is cheap to implement, and will reduce the
cost of storing the text data by 3x.
</p>
</div>
</div>

<div id="outline-container-orgd06ab52" class="outline-4">
<h4 id="orgd06ab52">Don't store an <code>erow</code> struct at all in our undo state</h4>
<div class="outline-text-4" id="text-orgd06ab52">
<p>
All of the state in the <code>erow</code> can be recomputed based on the contents of
our text. Every <code>erow</code> struct costs 48 bytes, but in our example text
file, we average at 27.2 bytes per line. It would be cheaper to just store the
entire contents of the file and recreate the <code>erows</code> later based on the
text contents.
</p>
</div>
</div>

<div id="outline-container-org9be6f81" class="outline-4">
<h4 id="org9be6f81">Shallow copy instead of deep copy</h4>
<div class="outline-text-4" id="text-org9be6f81">
<p>
We're deep copying everything, even for parts of the buffer that don't
change. This isn't necessary - we could just create pointers to rows that
haven't changed. This could prevent a lot of duplicate storage.
</p>
</div>
</div>

<div id="outline-container-org6e7e319" class="outline-4">
<h4 id="org6e7e319">Serialize and compress the state history</h4>
<div class="outline-text-4" id="text-org6e7e319">
<p>
If we <i>have</i> to store the editor state, maybe we can make it smaller. Gzip can
compress our example text file with ratios between 2.8:1 (quickest compression
level) and 3.4:1 (slowest compression level). This is something that I could
prototype in a few lines of Python or Go, but in C I'm not familiar with the
ecosystem, so it might take some time to develop.
</p>
</div>
</div>

<div id="outline-container-org144f15e" class="outline-4">
<h4 id="org144f15e">Compute a delta between different states</h4>
<div class="outline-text-4" id="text-org144f15e">
<p>
&#x2026;and use it to recreate state on restore. This is a similar situation to
serialization/compression for me - it's a lot more work to do this than to
just write individual undo operations for the commands in the editor.
</p>
</div>
</div>
</div>

<div id="outline-container-orgf59f4df" class="outline-3">
<h3 id="orgf59f4df"><span class="section-number-3">19.13.</span> Rethink the generalised state-restore approach entirely?</h3>
<div class="outline-text-3" id="text-19-13">
<p>
Ultimately there are cases where all of these approaches can fall down,
especially when dealing with very large files, or files with very long
lines. There are also tradeoffs to make on whether we can compute the values
that we're no longer storing in memory within a latency that's suitable for the
user.
</p>

<p>
For any performance-conscious use case I think it will be more efficient to just
store specific undo operations for each action that you want to undo -
ie. follow the command pattern.
</p>
</div>
</div>

<div id="outline-container-orgedf4fd0" class="outline-3">
<h3 id="orgedf4fd0"><span class="section-number-3">19.14.</span> Next steps</h3>
<div class="outline-text-3" id="text-19-14">
<p>
I could have implemented shallow copy (as that sounds interesting), or even just
written specific undo actions for all my editor operations.
</p>

<p>
Instead, I went on a massive tangent to <a href="undo-redo-text-editors.html">see
how Emacs, Vim and Nano implemented their undo features</a>.
</p>
</div>
</div>
]]></description>
</item>

<item>
<title>"Build your own text editor"</title>
<link>https://www.mattduck.com/build-your-own-text-editor.html</link>
<author>hi@mattduck.com (Matt Duck)</author>
<guid isPermaLink="false">19483b48-889a-4bdd-8b17-fa7ab28a560e</guid>
<pubDate>Wed, 22 Jan 2020 00:00:00 +0000</pubDate>

<description><![CDATA[<p>
I recently followed snaptoken's <a href="https://viewsourcecode.org/snaptoken/kilo/index.html">build your own text editor</a> booklet, which talks
you through building a basic text editor in about 1000 lines of C (the <a href="http://antirez.com/news/108">kilo</a>
editor, written by Antirez). It was fun, and I'd recommend it to anybody who
either (1) is interested in how graphical terminal programs work, or (2) wants
to play a bit with C.
</p>


<img src="kilo4.gif" alt="the kilo editor"/>

<div id="outline-container-org75b8337" class="outline-3">
<h3 id="org75b8337"><span class="section-number-3">20.1.</span> What was in the chapters?</h3>
<div class="outline-text-3" id="text-20-1">
<p>
Roughly in order, the steps were:
</p>

<ul class="org-ul">
<li>Write a main loop that uses <code>read()</code> to respond to input from <code>stdin</code>.</li>

<li>Put the terminal into "raw" mode - disable echoing, read one keypress at a
time, etc. Save and restore the terminal configuration on program exit.</li>

<li>Add cursor movement.</li>

<li>Add file I/O and the ability to view files.</li>

<li>Add scrolling for when the file is bigger than the screen size.</li>

<li>Add a "rendering" translation layer which case be used to eg. display <code>\t</code> as a
fixed number of spaces.</li>

<li>Add a status bar that shows the filename, current line etc. Also add a message
area that can display user messages.</li>

<li>Add the ability to insert and delete text, with a "dirty" flag that tell the
user if the buffer has been modified since last save.</li>

<li>Add a generic prompt, and then use it to implement incremental search.</li>

<li>Add basic syntax highlighting, which is triggered by filetype detection. This
only supports C files, but can be extended.</li>
</ul>
</div>
</div>


<div id="outline-container-org1d3b69c" class="outline-3">
<h3 id="org1d3b69c"><span class="section-number-3">20.2.</span> The program structure</h3>
<div class="outline-text-3" id="text-20-2">
<p>
It was quite simple. There were two main data structures: the global <b>editor</b>, and
the <b>row</b>. The editor kept an array of pointers to rows, each row representing a
single line of text (plus some metadata, eg. the row size). The editor also kept
track of the cursor position, the file offset for scrolling, the current status
message, etc.
</p>

<p>
The program roughly just did:
</p>

<pre class="example" id="org61563b7">
main loop:
  read keypress;
  in response to keypress:
    update global editor state and row state;
    maybe quit if "q" was pressed;
  refresh screen with latest state;
</pre>

<p>
The terminal interaction and cursor movement is all done using <a href="http://www.termsys.demon.co.uk/vtansi.htm">VT100 terminal escape
sequences</a>. I'm not sure how portable this is, but in practice I think it works
for the few terminal emulators that I use.
</p>

<p>
The syntax highlighting has one feature that can tokenize across multiple lines: it
recognises when comments begin and end. It is otherwise pretty naive, just
matching keywords, strings and numbers. Having said that, at a glance it looks
pretty similar to the highlighting I see in Vim.
</p>

<p>
Many of the functions operate on the global editor state. If I was going to
seriously work on this project, I'd want to rewrite some of them to accept the
editor as an argument rather than all mutating a single variable.
</p>
</div>
</div>

<div id="outline-container-orgf1e914f" class="outline-3">
<h3 id="orgf1e914f"><span class="section-number-3">20.3.</span> It was easy to extend the project</h3>
<div class="outline-text-3" id="text-20-3">
<p>
I added a few features that I use in Vim and Emacs (<a href="https://github.com/mattduck/kilo">see Github</a>):
</p>

<ul class="org-ul">
<li>Splitting user input into <code>normal</code> and <code>insert</code> modes.</li>
<li>Word-based cursor movement that is normally found with <code>w/W/b/B</code></li>
<li>A new prompt to simulate <code>:wq</code> and <code>:q!</code>.</li>
<li>Standard cursor movement with <code>hjkl</code>, <code>^/$</code>, <code>C-f/C-b</code>, <code>gg</code> and <code>G</code>.</li>
<li>Using <code>dd</code> to remove lines, and <code>J</code> to join lines.</li>
<li>Adding the <code>jj</code> and <code>jk</code> bindings that I use in <code>insert</code> mode to exit to <code>normal</code> mode
(which means waiting for a follow-up key to <code>j</code>, and inserting it into the row
if it doesn't come after a set timeout).</li>
</ul>

<p>
I was surprised at how much it felt like my usual environment for file browsing
and basic editing. Although my implementation wasn't extensible or composable,
most of the time I just rely on the same few bindings.
</p>

<p>
Given that my <a href="https://github.com/mattduck/dotfiles/blob/master/emacs.d.symlink/init.org">personal Emacs config</a> has grown to about 5x the size of this
program, it almost seems worth just writing the features I want from scratch!
</p>
</div>
</div>


<div id="outline-container-org9b11563" class="outline-3">
<h3 id="org9b11563"><span class="section-number-3">20.4.</span> I did it as literate programming with org-mode</h3>
<div class="outline-text-3" id="text-20-4">
<p>
I wanted to try writing notes alongside the code as I progressed, using
org-mode. I compiled kilo from <a href="https://github.com/mattduck/kilo/blob/master/README.org">my README.org</a> file, which can be done in a
couple of lines of lisp:
</p>

<div class="org-src-container">
<pre class="src src-lisp">;; Don't ask me to confirm each time I evaluate the file
(setq-local org-confirm-babel-evaluate nil)
;; concatenate all embedded C snippets to kilo-org.c
(org-babel-tangle nil "kilo-org.c" "c")
;; run make
(compile "make")
</pre>
</div>

<p>
In the end I didn't find it very useful - it hid the actual source code too
much, which made it harder to refactor and jump between sections of code
quickly. I wonder if the org-mode approach is more useful for detailing one-off
scripts and troubleshooting.
</p>
</div>
</div>


<div id="outline-container-org99c69bb" class="outline-3">
<h3 id="org99c69bb"><span class="section-number-3">20.5.</span> What similar projects exist?</h3>
<div class="outline-text-3" id="text-20-5">
<p>
<a href="https://github.com/practicalswift/openemacs">openemacs</a> is a small fork of kilo that implements some Emacs navigation
features, which is worth reading if you're interested in modifying kilo.
</p>

<p>
The other good "build something from scratch" project that I've followed was <a href="https://www.nand2tetris.org/">The
Elements of Computing Systems</a>, where you build a (virtual) computer from first
principles.
</p>

<p>
The <a href="https://www.destroyallsoftware.com/screencasts/catalog">Destroy All Software</a> "From Scratch" screencasts follow the same idea, and
are pretty enjoyable.
</p>

<p>
I'm interested to know what else is out there. Although not so interested to
have ever searched for it. If you know of anything good, let me know.
</p>
</div>
</div>
]]></description>
</item>

<item>
<title>pytest-it: a plugin for building BDD test specs</title>
<link>https://www.mattduck.com/pytest-it.html</link>
<author>hi@mattduck.com (Matt Duck)</author>
<guid isPermaLink="false">2e45825c-4c6c-4a7a-8d45-329156def5f7</guid>
<pubDate>Sun, 21 Jul 2019 00:00:00 +0100</pubDate>

<description><![CDATA[<p>
I recently published <a href="https://github.com/mattduck/pytest-it">pytest-it</a>. It's a <code>pytest</code> plugin to decorate tests with
markers inspired by <a href="http://rspec.info">Rspec</a> (<code>describe</code>, <code>context</code>, <code>it</code>). These markers are used in the
<code>pytest</code> test reporting to display a plaintext spec of the features under test:
</p>

<div class="org-src-container">
<pre class="src src-python">from pytest import mark as m

@m.describe("The test function report format")
class TestPytestItExample(object):

    @m.context("When @pytest.mark.it is used")
    @m.it("Displays an '- It: ' block matching the decorator")
    def test_it_decorator(self):
        pass
</pre>
</div>

<div class="org-src-container">
<pre class="src src-nohighlight">pytest --it
...

* tests/test_pytest_it.py...

- Describe: The test function report format...
  - ✓ It: Displays a test pass using '- ✓ '
  - ✓ It: Displays a test fail using '- F '
  - ✓ It: Displays a test skip using '- s '
  - ✓ It: Displays the pytest ID for parameterised tests
  - ✓ It: Does not use the docstring in the test name

  - Context: When @pytest.mark.it is used...
    - ✓ It: Displays an '- It: ' block matching the decorator

    - ...when -v is higher than 0...
      - ✓ It: Displays the full module::class::function prefix to the test

  - Context: When @pytest.mark.it is not used...
    - ✓ It: Displays the test function name

    - ...but the test name starts with 'test_it_'...
      - ✓ It: Prettifies the test name into the 'It: ' value

  - Context: When multiple @pytest.mark.it markers are used...
  - ✓ It: Uses the lowest decorator for the 'It : ' value
</pre>
</div>

<p>
We use <code>pytest</code> extensively at <a href="https://www.ometria.com/careers/">Ometria</a>. It provides a lot of features
(eg. composable fixtures, parameterised tests, <code>assert</code> rewrites) that make it
easy and pleasant to write test code in Python.  So why is <code>pytest-it</code> useful?
</p>

<div id="outline-container-org56046af" class="outline-3">
<h3 id="org56046af"><span class="section-number-3">21.1.</span> The problem</h3>
<div class="outline-text-3" id="text-21-1">
<p>
Software gets complex, and clear communication is crucial to mitigate
this. Tests are a critical tool for reducing unwanted changes in
software behaviour, and in some cases they will be the only spec you
have for legacy software.
</p>

<p>
Conventional Python test code (including <code>pytest</code>) has up to three
levels of hierarchy:
</p>

<div class="org-src-container">
<pre class="src src-python"># Level 1 - module
"""
test_my_module.py
"""

# Level 2 - class
class TestMyClass(object):

    # Level 3 - method
    def test_my_method(self):
        """
        This is a test.
        """
        assert 2 + 2 == 4
</pre>
</div>

<p>
Under these constraints, it requires a lot of discipline to communicate
clearly to the reader, especially as software evolves and requirements
change over time:
</p>

<ul class="org-ul">
<li>Is there clear separation between setup, test and teardown code?</li>

<li>What input situations are tested?</li>

<li>What is the output behaviour under test? Is it logic that should only
be changed in coordination with the business, or is it a side-effect?</li>

<li>Are multiple business rules tested by the same test function?</li>

<li>What business logic is <i>not</i> covered by tests?</li>
</ul>

<p>
Despite their importance, tests tend to receive less attention than the
main program code (in my experience), with copy/paste approaches being
more common, and less care given to structure, naming and documentation.
</p>

<p>
These are problems that BDD and other testing tools (including
<code>pytest-it</code>) try to mitigate.
</p>
</div>
</div>

<div id="outline-container-org4698182" class="outline-3">
<h3 id="org4698182"><span class="section-number-3">21.2.</span> Trivial to adopt</h3>
<div class="outline-text-3" id="text-21-2">
<p>
There are various methods to help improve test clarity and bring it
closer to business logic. For example:
</p>

<ol class="org-ol">
<li>Rewrite the test code using a BDD framework that provides tools for
this purpose (eg. Behave, Mamba).</li>

<li>Rewrite the program code to facilitate better test structure.</li>

<li>Write a spec of component behaviours that exist separately to the
system and test code.</li>
</ol>

<p>
Decorating an existing pytest codebase with <code>pytest-it</code> is an
incremental step. It's cheap to adopt compared to the above solutions,
as it can be retroactively applied to a test suite without requiring any
other changes - the decorators only provide the spec, they don't alter
the behaviour of the test.
</p>

<p>
This is also a good way to introduce BDD thinking to a Python codebase
(or team) without requiring a major change in tooling or workflow.
</p>
</div>
</div>

<div id="outline-container-org7615d4d" class="outline-3">
<h3 id="org7615d4d"><span class="section-number-3">21.3.</span> More expressive</h3>
<div class="outline-text-3" id="text-21-3">
<p>
I often see test names or docstrings that describe the context of the
test input (eg. <code>test_new_customer_with_one_order</code>), but not the
<i>output</i>. I can see that the test expects the output of a function to be
<code>3</code>, but what does that represent?
</p>

<p>
The Rspec semantics provide a framework to specifically communicate
these concepts, and by using decorators to apply these states to a test,
we can display them clearly in the test report. This is significantly
more expressive than trying to convey that information in a function
name, and the decorators make it easier to parse compared to using a
docstring.
</p>
</div>
</div>

<div id="outline-container-org58582a0" class="outline-3">
<h3 id="org58582a0"><span class="section-number-3">21.4.</span> Behaviour at a glance</h3>
<div class="outline-text-3" id="text-21-4">
<p>
Even in well-structured test suites, it can be difficult to scan the
behaviour under test, because docstrings are scattered throughout the
file(s). Pulling this state into a plain-text spec makes it easier to
read, think about and modify.
</p>
</div>
</div>

<div id="outline-container-orgfa9cd53" class="outline-3">
<h3 id="orgfa9cd53"><span class="section-number-3">21.5.</span> Org-mode</h3>
<div class="outline-text-3" id="text-21-5">
<p>
For those who use org-mode, the spec output can be copied straight into
an org buffer to work with. This is the killer feature for me, as it
means I can focus on the behaviour of the program: where tests need to
be added, deleted or moved, and where program behaviour needs to be
clarified with the business.
</p>
</div>
</div>

<div id="outline-container-org2ee2fe5" class="outline-3">
<h3 id="org2ee2fe5"><span class="section-number-3">21.6.</span> Habit forming</h3>
<div class="outline-text-3" id="text-21-6">
<p>
Introducing a framework to structure tests can encourage care around
test code and communication. The semantics provide a sensible default
that can be implemented without requiring a lot of extra tooling or
thought. Integrating with <code>pytest</code> also provides an easy way to evaluate
the tradeoffs of BDD approaches compared to the classic Python unittest
structure.
</p>
</div>
</div>

<div id="outline-container-org986d00e" class="outline-3">
<h3 id="org986d00e"><span class="section-number-3">21.7.</span> Further information</h3>
<div class="outline-text-3" id="text-21-7">
<p>
You can try <code>pytest-it</code> by running:
</p>

<div class="org-src-container">
<pre class="src src-shell">pip install pytest-it
pytest --it
</pre>
</div>

<p>
See <a href="https://github.com/mattduck/pytest-it">Github</a> for more information.
</p>
</div>
</div>
]]></description>
</item>
<div id="footnotes">
<h2 class="footnotes">Notes: </h2>
<div id="text-footnotes">

<p class="footdef box"><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1.</a> I've worked at fairly
small startups: Engineering teams of 20 or less, using git for version control,
and standard PR workflows via Gitlab or similar services. I think my sentiment
here is broadly transferable, but it might not apply to environments that are
significantly different.</p>
<p class="footdef box"><a id="fn.2" class="footnum" href="#fnr.2" role="doc-backlink">2.</a> Vim legend, author
of <a href="https://github.com/tpope">many Vim plugins.</a></p>
<p class="footdef box"><a id="fn.3" class="footnum" href="#fnr.3" role="doc-backlink">3.</a> There's a lot more to a
job than writing code, but this captures the code parts nicely.</p>
<p class="footdef box"><a id="fn.4" class="footnum" href="#fnr.4" role="doc-backlink">4.</a> Personally I rewrite my own history by amending commits while my change
is still in progress, and my PRs usually only include one or two logical
commits, so it's easy to write messages for them. Breaking history isn't a
concern as nobody depends on that branch yet.</p>
<p class="footdef box"><a id="fn.5" class="footnum" href="#fnr.5" role="doc-backlink">5.</a> One thing I will admit is that I'm someone who
writes a lot in their work as it helps me to think, and that's not true of
everyone -- so that probably biases both how easy I find it to write messages
and the value I get from reading them.</p>
<p class="footdef box"><a id="fn.6" class="footnum" href="#fnr.6" role="doc-backlink">6.</a> In case
you're wondering like I was... git isn't quite 20 yet, it was released in
2005.</p>
<p class="footdef box"><a id="fn.7" class="footnum" href="#fnr.7" role="doc-backlink">7.</a> If you explicitly call
something like <code>(fset 'help-map help-map)</code> to create the function symbol, it
will work, but that seems hacky and isn't something I want to have to do
manually.</p>
<p class="footdef box"><a id="fn.8" class="footnum" href="#fnr.8" role="doc-backlink">8.</a> "Advice" is Emac's concept for patching
functions to modify their behaviour.</p>
<p class="footdef box"><a id="fn.9" class="footnum" href="#fnr.9" role="doc-backlink">9.</a> Meaning, if I update the headline on the original item,
my link will still show the description that I used when I created the link, and
so it won't give an explicit description of what item the link refers to - I
have to just remember what one it is myself.</p>
<p class="footdef box"><a id="fn.10" class="footnum" href="#fnr.10" role="doc-backlink">10.</a> Actually two variables?  <code>org-stored-links</code> and <code>org-store-link-plist</code>. Not
sure the difference between them.</p>
<p class="footdef box"><a id="fn.11" class="footnum" href="#fnr.11" role="doc-backlink">11.</a> This can also be other, non-UUID formats - see
<code>org-id-method</code>.</p>
<p class="footdef box"><a id="fn.12" class="footnum" href="#fnr.12" role="doc-backlink">12.</a> This
could easily be changed to include tags or otherwise customise the format,
I just wanted the keyword.</p>
<p class="footdef box"><a id="fn.13" class="footnum" href="#fnr.13" role="doc-backlink">13.</a> The reader may
wonder, is this because I've become a better programmer?  In this particular
case, the answer is... no</p>
<p class="footdef box"><a id="fn.14" class="footnum" href="#fnr.14" role="doc-backlink">14.</a> and I don't mean the wider
social implications here - I just mean downsides for me in the context of this
work.</p>

</div>
</div></channel>
</rss>