<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Blog posts on Shayne Holmes</title><link>https://shayneholm.es/blog/</link><description>Recent content in Blog posts on Shayne Holmes</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>Copyright &amp;copy; 2018-2026 Shayne Holmes</copyright><atom:link href="https://shayneholm.es/blog/index.xml" rel="self" type="application/rss+xml"/><item><title>Control sequences</title><link>https://shayneholm.es/blog/control-sequences/</link><pubDate>Wed, 15 Apr 2026 20:24:56 -0700</pubDate><guid>https://shayneholm.es/blog/control-sequences/</guid><description>&lt;p&gt;I often have &lt;a href="https://shayneholm.es/blog/writing-on-the-go/"&gt;occasion to write&lt;/a&gt; on the go, and I love the sense of flow that I get when just free-writing. I don&amp;rsquo;t even look at the screen! But sometimes I know I&amp;rsquo;ve mistyped something and want to go back and do it over. How do you do that without breaking your flow?&lt;/p&gt;&lt;p&gt;For my chosen mobile typing platform (termux + vim), I&amp;rsquo;ve found that it&amp;rsquo;s helpful to have some quick commands like &amp;ldquo;delete the last word I typed&amp;rdquo;, or even &amp;ldquo;delete the last sentence I typed&amp;rdquo;. Vim&amp;rsquo;s &lt;code&gt;^W&lt;/code&gt; will delete a word, at the cost of leaving home row; you can break out of insert mode and delete back a sentence with &lt;code&gt;^Od(&lt;/code&gt;, but this is not easy to type! How can we easily run common commands while mid-thought?&lt;/p&gt;&lt;p&gt;After a lot of experimentation, I&amp;rsquo;ve settled on overloading some digraphs as commands. These need to meet two requirements:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;They must be unused in the language you&amp;rsquo;re typing, so they aren&amp;rsquo;t triggered as you write.&lt;/li&gt;&lt;li&gt;They need to be convenient to type.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;As a Dvorak typist, &lt;code&gt;cg&lt;/code&gt; and &lt;code&gt;cb&lt;/code&gt; fit the bill:&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-vim" data-lang="vim"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;#34; Delete a word&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;noremap&lt;/span&gt;! &lt;span style="color:#a6e22e"&gt;cg&lt;/span&gt; &amp;lt;&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;-&lt;span style="color:#a6e22e"&gt;w&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;#34; Delete a sentence (in a new undo scope)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;noremap&lt;/span&gt;! &amp;lt;&lt;span style="color:#a6e22e"&gt;silent&lt;/span&gt;&amp;gt; &lt;span style="color:#a6e22e"&gt;cb&lt;/span&gt; &amp;lt;&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;-&lt;span style="color:#a6e22e"&gt;g&lt;/span&gt;&amp;gt;&lt;span style="color:#a6e22e"&gt;u&lt;/span&gt;&amp;lt;&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;-&lt;span style="color:#a6e22e"&gt;o&lt;/span&gt;&amp;gt;&lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;(&amp;lt;&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;-&lt;span style="color:#a6e22e"&gt;o&lt;/span&gt;&amp;gt;&lt;span style="color:#a6e22e"&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With these handy remappings, when I am in a free-write session and know that I&amp;rsquo;ve flubbed a word, or want to restart the current sentence, I don&amp;rsquo;t have to look up or break my flow at all!&lt;/p&gt;</description></item><item><title>Alpine backups: Home directory</title><link>https://shayneholm.es/blog/alpine-backup-homedir/</link><pubDate>Thu, 10 Dec 2020 10:38:37 -0800</pubDate><guid>https://shayneholm.es/blog/alpine-backup-homedir/</guid><description>&lt;p&gt;I set up a cheap NAS-alike using a &lt;a href="https://www.raspberrypi.org/products/raspberry-pi-3-model-b/"&gt;RaspberryPi&lt;/a&gt;. After afirst attempt using the default OS resulted in an unusable SD card, I did somedigging and decided to use &lt;a href="https://alpinelinux.org/"&gt;Alpine Linux&lt;/a&gt;, mostlybecause it runs by default in Diskless Mode.&lt;/p&gt;&lt;p&gt;In Diskless Mode, the SD card is consulted at boot time, when the entire filetree is loaded into memory (using &lt;code&gt;tmpfs&lt;/code&gt;), and then it is left alone. Alloperations that write to disk (logging, etc.) go to memory. The next time thedevice boots, it comes up the same way. This effectively turns the server intoan appliance, and makes the &lt;code&gt;reboot&lt;/code&gt; operation return to a known good state.&lt;/p&gt;&lt;p&gt;However, we do want to change &lt;em&gt;some&lt;/em&gt; things from the default, and for this,Alpine provides &lt;a href="https://wiki.alpinelinux.org/wiki/Alpine_local_backup"&gt;Alpine LocalBackup&lt;/a&gt;, which letsusers save modifications to an overlay file on the SD card, so they &amp;ldquo;survive&amp;rdquo;the next reboot.&lt;/p&gt;&lt;p&gt;By default, the only changes it &amp;ldquo;notices&amp;rdquo; are inside &lt;code&gt;/etc&lt;/code&gt;, but you caninclude more directories to &amp;ldquo;watch&amp;rdquo;.&lt;/p&gt;&lt;p&gt;This largely works as advertised, but one of the hitches I ran into was how toinclude a user&amp;rsquo;s home directory, without all the files in it.&lt;/p&gt;&lt;p&gt;Here&amp;rsquo;s how I did it.&lt;/p&gt;&lt;h2 id="the-story-so-far"&gt;The story so far&lt;/h2&gt;&lt;p&gt;Running everything as &lt;code&gt;root&lt;/code&gt; is a bad idea. Instead, I&amp;rsquo;ve created a shell userto do my day-to-day operations. (It&amp;rsquo;s called &lt;code&gt;huevo&lt;/code&gt;, &amp;lsquo;cause eggs have shells😬).&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ adduser huevo&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we explicitly include the home directory, so that it survives reboot (withthe appropriate permissions):&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ lbu include /home/huevo&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="cleaning-up"&gt;Cleaning up&lt;/h2&gt;&lt;p&gt;So far, so good. But now the home directory picks up any changes we make, whichwill include things like &lt;code&gt;.ash_history&lt;/code&gt;, &lt;code&gt;.viminfo&lt;/code&gt;, and other cruft. Toprevent inadvertent bloat of the overlay file, we don&amp;rsquo;t want to pick up thosethings by accident. Instead, we want include only those files that we&amp;rsquo;veexplicitly chosen to stick around.&lt;/p&gt;&lt;p&gt;This is where the documents aren&amp;rsquo;t directly helpful: Running &lt;code&gt;lbu exclude /home/huevo/*&lt;/code&gt; actually excludes the home directory as well.&lt;/p&gt;&lt;h2 id="the-solution"&gt;The solution&lt;/h2&gt;&lt;p&gt;It turns out that &lt;code&gt;lbu&lt;/code&gt; stores its list of added paths in&lt;code&gt;/etc/apk/protected_paths.d/lbu.list&lt;/code&gt;. After playing around with the file (andrunning &lt;code&gt;lbu ls&lt;/code&gt; a bunch), it turns out that the order matters! Switchingaround the exclude and include statements makes the problem go away:&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ cat /etc/apk/protected_paths.d/lbu.list&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-home/huevo/*&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;+home/huevo&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This pattern also works for other paths, like persisting the &lt;code&gt;~/.cache&lt;/code&gt; folderwithout any of the cached files.&lt;/p&gt;</description></item><item><title>Making Masterlocks</title><link>https://shayneholm.es/blog/making-masterlocks/</link><pubDate>Sat, 15 Feb 2020 20:15:47 -0700</pubDate><guid>https://shayneholm.es/blog/making-masterlocks/</guid><description>&lt;p&gt;Masterlock makes a few models of four-cylinder combination lock where each cylinder is a ring of ten letters. The combination has to feature one letter from each cylinder in turn, and in order.&lt;/p&gt;&lt;figure class="float-right"&gt; &lt;img src="https://shayneholm.es/blog/making-masterlocks/masterlock-1535dwd.jpg" alt="Master Lock model 1535DWD"&gt;&lt;/figure&gt;&lt;p&gt;It&amp;rsquo;s popular with escape room aficionados, since you can theme the combination by setting it to a relevant word. (It comes preset to &amp;ldquo;LOCK&amp;rdquo;.) After I recently purchased one, I immediately made a list of all the English words I could use on it.&lt;/p&gt;&lt;p&gt;But that&amp;rsquo;s not the problem I&amp;rsquo;ll cover here.&lt;/p&gt;&lt;p&gt;The &lt;em&gt;real&lt;/em&gt; problem is in pretending you&amp;rsquo;re the person putting the letters on it: Given the structural constraints, which configuration of letters enables the largest number of valid English words?&lt;/p&gt;&lt;h1 id="prior-art"&gt;Prior art&lt;/h1&gt;&lt;p&gt;Let&amp;rsquo;s first look at what Masterlock actually produced. The lock I bought has this configuration of letters:&lt;/p&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;Ring 1: L,N,B,D,M,J,P,R,S,TRing 2: O,U,Y,R,T,L,H,A,E,IRing 3: C,D,E,O,R,S,T,L,N,ARing 4: K,Y,R,S,T,L,N,E,D,H&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;First, since we&amp;rsquo;ll consider a bunch of different letter configurations in this post, let&amp;rsquo;s come up with some better notation. To make describing them less wordy, I&amp;rsquo;ll write each letter configuration out on one line:&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;[lnbdmjprst][ouyrtlhaei][cdeorstlna][kyrstlnedh]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To make it easier to compare configurations (and detect duplicates), I&amp;rsquo;ll order each ring&amp;rsquo;s letters lexically, since the order of the letters in the ring doesn&amp;rsquo;t matter to the current problem:&lt;/p&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;[bdjlmnprst][aehilortuy][acdelnorst][dehklnrsty]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Okay, we wrote it out. But how many words can we make with it?&lt;/p&gt;&lt;p&gt;This is pretty simple to compute, provided you (A) have a list of all English words and (B) know your regular expressions.&lt;/p&gt;&lt;p&gt;Throughout this doc, I&amp;rsquo;ll use a word list that I&amp;rsquo;ve had for years: the &lt;a href="http://wordlist.aspell.net/12dicts-readme/#2of12inf"&gt;2of12inf list&lt;/a&gt; from the venerable &lt;a href="http://wordlist.aspell.net/"&gt;SCOWL project&lt;/a&gt;. To find all the words that are possible with this lock configuration, one can use &lt;code&gt;grep&lt;/code&gt;:&lt;/p&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;grep &amp;#39;^[bdjlmnprst][aehilortuy][acdelnorst][dehklnrsty]$&amp;#39; 2of12inf.txt&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This yields 740 words that I can make with my lock. Pretty neat!&lt;/p&gt;&lt;p&gt;So that&amp;rsquo;s the starting point, and I&amp;rsquo;ll report all the configurations in this doc with their word counts to make it easier to compare:&lt;/p&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;[bdjlmnprst][aehilortuy][acdelnorst][dehklnrsty] 740&lt;/code&gt;&lt;/pre&gt;&lt;h1 id="naiveté"&gt;Naiveté&lt;/h1&gt;&lt;p&gt;A simple way to try is to count the letter frequencies in each position for all the four-letter words in the list, and then choose the ten most popular letters in each position.&lt;/p&gt;&lt;p&gt;This ignores knowledge of things like digrams (&amp;lsquo;g&amp;rsquo; is popular on the fourth ring only if &amp;rsquo;n&amp;rsquo; is on the third) but it already does better than the existing configuration:&lt;/p&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;[bcdfhlmpst][aehilnoruy][aeilmnorst][deklmnpsty] 854&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We&amp;rsquo;re better than the stock configuration by over a hundred words, including beauties like &amp;ldquo;FADE&amp;rdquo;. Not bad.&lt;/p&gt;&lt;p&gt;Now that we&amp;rsquo;ve trivially shown that we can do better than the existing choices, let&amp;rsquo;s actually try and get the best answer.&lt;/p&gt;&lt;h1 id="mapping-the-territory"&gt;Mapping the territory&lt;/h1&gt;&lt;p&gt;Let&amp;rsquo;s first examine the &lt;em&gt;size&lt;/em&gt; of the problem: Each ring can have any set of 10 unique letters out of the 26, for a total of 5,311,735 possibilities. That&amp;rsquo;s a pretty big number, but tractable. Unfortunately, since each ring is independent of the others, we raise that number to the fourth power, resulting in about 7.96⨉10&lt;!-- raw HTML omitted --&gt;26&lt;!-- raw HTML omitted --&gt; configurations. That is a lot gnarlier of a problem: Even if we could evaluate one configuration per nanosecond, it would take 25 billion years to go through them all.&lt;/p&gt;&lt;p&gt;Let&amp;rsquo;s find a way to tame this problem.&lt;/p&gt;&lt;p&gt;There aren&amp;rsquo;t any overlapping subproblems here that we can use to reduce the solution space. Each ring&amp;rsquo;s ideal set of letters is dependent on the letters already chosen for the other rings: If the last ring doesn&amp;rsquo;t include &amp;ldquo;S&amp;rdquo;, you can&amp;rsquo;t count &amp;ldquo;MASS&amp;rdquo; as a candidate for the other rings. That makes dynamic programming of little use here.&lt;/p&gt;&lt;p&gt;One thing that &lt;em&gt;is&lt;/em&gt; helpful is the observation that the list of valid words is much smaller than all combinations of letters: My wordlist includes about 2,500 four-letter words, compared to 26&lt;!-- raw HTML omitted --&gt;4&lt;!-- raw HTML omitted --&gt;=456,976 combinations of four letters. So the wordlist itself can be viewed as a sparse matrix representation of the full four-dimensional word space.&lt;/p&gt;&lt;h1 id="local-optimization"&gt;Local optimization&lt;/h1&gt;&lt;p&gt;My personal best here is a variant of the simplex method: Starting at a given configuration, hold three of the rings constant and find the best combination for the remaining ring. It&amp;rsquo;s not too hard to run through the wordlist and count the words we could make with each letter. For example, if the first three rings were &amp;ldquo;ht-ae-sv&amp;rdquo;, some valid words might be &amp;ldquo;have, hast, test&amp;rdquo;, making &amp;ldquo;t&amp;rdquo; and &amp;ldquo;e&amp;rdquo; are our best options for the fourth ring.&lt;/p&gt;&lt;p&gt;In fact, we can evaluate this simultaneously for all four of the rings: For each ring, imagine holding the other three rings constant, and decide which letters on the remaining ring would give us the biggest set of words. Then we can choose to change the single ring that gives us the biggest set. And then we do it again, and again, stopping only when we can&amp;rsquo;t change any single ring to get more words. This point is a local maximum.&lt;/p&gt;&lt;p&gt;This local search would be guaranteed optimal for a convex problem, which this problem isn&amp;rsquo;t. But we can try and &amp;ldquo;get a feel&amp;rdquo; for the solution space by starting several local searches at random points throughout the space, seeing if the local searches mostly converge to the same results.&lt;/p&gt;&lt;p&gt;In my tests, the randomly-seeded local searches converge on the same solution about 60% of the time, and there are other local maxima that are not quite as high. The solution is quick enough that I&amp;rsquo;ve done tens of thousands of hill climbs. That being said, there could be a better solution that I just haven&amp;rsquo;t happened upon yet &amp;ndash; stochastic methods are tricky that way.&lt;/p&gt;&lt;p&gt;Here is my best result using this method:&lt;/p&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;[bcdfhmpstw][aehilopruw][aceilnorst][deklmnpsty] 876&lt;/code&gt;&lt;/pre&gt;&lt;h1 id="closing-thoughts"&gt;Closing thoughts&lt;/h1&gt;&lt;p&gt;Masterlock could have been optimizing for something other than raw word count. Indeed, they &lt;em&gt;must&lt;/em&gt; have been, given how easy it was for us to outperform them. Here are some potential complications that they may have considered:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Word frequency: Customers probably prefer common words (&amp;ldquo;LOCK&amp;rdquo; over &amp;ldquo;PATE&amp;rdquo;)&lt;/li&gt;&lt;li&gt;Word type: Customers may prefer combinations that are nouns (&amp;ldquo;BOOK&amp;rdquo; over &amp;ldquo;GOOD&amp;rdquo;)&lt;/li&gt;&lt;li&gt;Blacklisted words: Masterlock may not want to let customers choose certain words (obscenities, or competitors&amp;rsquo; names like &amp;ldquo;ABUS&amp;rdquo;), and so may intentionally choose a suboptimal configuration to avoid those words&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;We could include this in our algorithm with custom cost functions, but that&amp;rsquo;s not an area I explored.&lt;/p&gt;&lt;p&gt;If you&amp;rsquo;re just going for raw word count, there are several better options than what comes in the box.&lt;/p&gt;&lt;div class="footnotes" role="doc-endnotes"&gt;&lt;hr&gt;&lt;ol&gt;&lt;li id="fn:1"&gt;&lt;p&gt;This notation is conveniently also a regular expression that matches all the words creatable with that configuration.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</description></item><item><title>Introducing PGP</title><link>https://shayneholm.es/blog/introducing-pgp/</link><pubDate>Fri, 07 Jun 2019 08:29:38 +0000</pubDate><guid>https://shayneholm.es/blog/introducing-pgp/</guid><description>&lt;h2 id="now-with-10-more-pgp-128272"&gt;Now with 10× more PGP! 🔐&lt;/h2&gt;&lt;p&gt;As of today my &lt;a href="https://shayneholm.es/pages/contact/"&gt;contact page&lt;/a&gt; references &lt;a href="https://shayneholm.es/shayneholmes.asc"&gt;my public PGP key&lt;/a&gt;, which is also now included on the site.&lt;/p&gt;&lt;h2 id="why-pgp"&gt;Why PGP?&lt;/h2&gt;&lt;p&gt;&lt;a href="https://www.openpgp.org/"&gt;OpenPGP&lt;/a&gt; is a venerable standard for securing communications, predominantly email. It uses standard encryption and some smarts to make the world a more secure place.&lt;/p&gt;&lt;h2 id="why-anything"&gt;Why &lt;em&gt;anything&lt;/em&gt;?&lt;/h2&gt;&lt;p&gt;Partly because privacy should be more a feature of our lives, and encryption is one way to provide that.&lt;/p&gt;&lt;p&gt;Partly, it is a hobbyist thing. PGP lets you collect signatures and apply vaguely esoteric technical knowledge with a theoretical benefit to society. In this respect, it&amp;rsquo;s strongly akin to HAM radio &amp;ndash; I don&amp;rsquo;t think it&amp;rsquo;s a coincidence that a fair number of vocal PGP advocates are also HAMs.&lt;/p&gt;&lt;p&gt;Anyway, feel free to drop me a (secure) line.&lt;/p&gt;</description></item><item><title>Writing on the go</title><link>https://shayneholm.es/blog/writing-on-the-go/</link><pubDate>Tue, 29 Jan 2019 08:05:43 -0800</pubDate><guid>https://shayneholm.es/blog/writing-on-the-go/</guid><description>&lt;p&gt;I get to work via public transit, which gives me some time to myself to think, read, and write. To make the most of it, I try to have full-featured tools at hand. For writing, a proper keyboard is crucial: It gets out of my way and lets me write down what&amp;rsquo;s on my mind with a mininumum of fuss. To avoid toting around the bulk (and the distraction) of a full laptop, I use a Bluetooth keyboard with my (Android) phone.&lt;/p&gt;&lt;h2 id="removing-distraction"&gt;Removing distraction&lt;/h2&gt;&lt;p&gt;Using a Bluetooth keyboard with phone, in a moving bus, has (at least) three headaches:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The display is small, so you either see just a few sentences, or squint at the tiny letters.&lt;/li&gt;&lt;li&gt;Bumps in the road jostle the display, making it even harder to keep tabs on what you&amp;rsquo;re writing.&lt;/li&gt;&lt;li&gt;Other passengers ogle your display.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;My solution to all three of these headaches is to just put my phone in my pocket and &amp;ldquo;type blind&amp;rdquo;. It does introduce the &lt;em&gt;additional&lt;/em&gt; headache of not being able to see what I&amp;rsquo;m typing, but that just makes my writing more stream-of-consciousness, and I&amp;rsquo;ve chosen to take that as a positive.&lt;/p&gt;&lt;p&gt;(There&amp;rsquo;s also the issue of learning to touch-type, but that wasn&amp;rsquo;t an issue for me, and is out of scope for this post.)&lt;/p&gt;&lt;h2 id="removing-surprises"&gt;Removing surprises&lt;/h2&gt;&lt;p&gt;Since I can&amp;rsquo;t see my phone while I&amp;rsquo;m typing in it, I can&amp;rsquo;t react to changes in the system state: One bump of the home button, and I&amp;rsquo;m not writing a document anymore but sending keystrokes to my homescreen, which will just ignore them (hopefully).&lt;/p&gt;&lt;p&gt;I can&amp;rsquo;t just turn off the screen (Android doesn&amp;rsquo;t seem to permit typing into an active window with the screen off), so I&amp;rsquo;ve got a touch blocker that I enable when I&amp;rsquo;m in &amp;ldquo;blind typing&amp;rdquo; mode. (I used the factotum &lt;a href="https://tasker.joaoapps.com/"&gt;Tasker&lt;/a&gt; to make it, but there are some comparable apps on the Play Store.)&lt;/p&gt;&lt;p&gt;With touch out of the picture, there are still things that can disrupt my writing. Most of the things I&amp;rsquo;ve found are software bugs in handling cursor key presses.&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; After testing over twenty different &amp;ldquo;note taking&amp;rdquo; apps, all with various quirks, I punted on them all and went all-console with &lt;a href="https://termux.com/"&gt;Termux&lt;/a&gt; and &lt;a href="https://www.vim.org/"&gt;Vim&lt;/a&gt;. Cursor focus issues begone! (As a bonus, I pulled in my .vimrc from my &lt;a href="https://github.com/shayneholmes/dotfiles"&gt;dotfiles&lt;/a&gt; and got my full vim environment working, so I can easily edit and spellcheck on the go, too.)&lt;/p&gt;&lt;h2 id="removing-friction"&gt;Removing friction&lt;/h2&gt;&lt;p&gt;With the writing experience sufficiently unsurprising, all that remained was implementing some process improvements to get writing with less fuss. First up, I used Android&amp;rsquo;s keyboard shortcuts to put &lt;code&gt;Win-X&lt;/code&gt; to Termux. And then, since most of my writing goes in a time-indexed journal, I made the following alias:&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-zsh" data-lang="zsh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;alias j&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;vim -c &amp;#34;startinsert!&amp;#34; journal-$(date +%F).txt&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, with just one &lt;code&gt;&amp;lt;M-x&amp;gt;j&amp;lt;CR&amp;gt;&lt;/code&gt;, I am off and writing!&lt;/p&gt;&lt;div class="footnotes" role="doc-endnotes"&gt;&lt;hr&gt;&lt;ol&gt;&lt;li id="fn:1"&gt;&lt;p&gt;E.g.: Go to the end of a text field, then press the right arrow. Instantly, your focus changes to a new component.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</description></item><item><title>Deep Work</title><link>https://shayneholm.es/blog/deep-work/</link><pubDate>Thu, 13 Dec 2018 13:49:20 +0000</pubDate><guid>https://shayneholm.es/blog/deep-work/</guid><description>&lt;p&gt;Cal Newport&amp;rsquo;s &lt;em&gt;Deep Work&lt;/em&gt; is a well-written overview of how to focus for fun and profit. It&amp;rsquo;s divided conceptually into two parts: &lt;em&gt;Why&lt;/em&gt; to focus deeply, and &lt;em&gt;how&lt;/em&gt; to do it.&lt;/p&gt;&lt;p&gt;Newport is a concise and direct writer, and is eminently up to the challenge of explaining both areas, using examples alongside evaluations starting from first principles, making this an effective argument for and guide to focused work.&lt;/p&gt;&lt;p&gt;For example, he outlines several reasons why one would want to focus deeply, in broad categories like &amp;ldquo;It has benefits&amp;rdquo;, and &amp;ldquo;Nobody else is doing it, so those who do have a competitive advantage&amp;rdquo;. This structure works well for the intended purpose.&lt;/p&gt;&lt;h2 id="group-therapy"&gt;Group therapy&lt;/h2&gt;&lt;p&gt;I read this as part of a group at work, and it was valuable to discuss it in that format: A lot of the friction in adopting focus-friendly behaviors is in the worry of how those behaviors will be perceived in the workplace. Talking about it in a group of co-workers is a helpful way to address challenges in a particular workplace.&lt;/p&gt;&lt;p&gt;There is also something heartening about having a group to take action with, when it involves setting expectations for behavior in the workplace: At least you won&amp;rsquo;t be the only one trying it out!&lt;/p&gt;</description></item><item><title>Disruptive behavior</title><link>https://shayneholm.es/blog/smartphones-as-disruptors/</link><pubDate>Fri, 07 Dec 2018 17:00:56 -0700</pubDate><guid>https://shayneholm.es/blog/smartphones-as-disruptors/</guid><description>&lt;p&gt;Smartphones can be both a blessing and a curse. For me, they are a &lt;em&gt;blessing&lt;/em&gt; when they help me do stuff I want to do. They are a &lt;em&gt;curse&lt;/em&gt; when they prevent me from doing something I want to do.&lt;/p&gt;&lt;p&gt;To be more specific: smartphones as &lt;em&gt;enablers&lt;/em&gt; provide me with abilities I wouldn&amp;rsquo;t otherwise have. Smartphones as &lt;em&gt;disruptors&lt;/em&gt; prevent me from focusing in on what I want to do.&lt;/p&gt;&lt;p&gt;Smartphones are prone to disrupting my flow in two key ways: obstruction and interruption.&lt;/p&gt;&lt;h3 id="obstruction"&gt;Obstruction&lt;/h3&gt;&lt;p&gt;When I turn on my phone, I have something in mind that I want to accomplish. It might be sending an e-mail. It might be reading an article. It might be looking up a word. Regardless, I don&amp;rsquo;t often turn on my phone to meander about its enticing icons and find something to do.&lt;/p&gt;&lt;p&gt;But my phone has other ideas: Red dots on app icons. Icons in the notification tray. Or even just showing me something I was looking at earlier, the moment I unlock the screen. In this way, my smartphone gets in the way of my getting things done. It is an &lt;em&gt;obstruction&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;One way of fixing this is just to get in and out more quickly. A lockscreen voice recording widget can help you record voice notes before the phone gets the chance to get in the way. Prominent homescreen shortcuts for apps that are helpful to your productivity can mean less chance for distraction, too.&lt;/p&gt;&lt;h3 id="interruption"&gt;Interruption&lt;/h3&gt;&lt;p&gt;Other times, my smartphone &lt;em&gt;shouldn&amp;rsquo;t&lt;/em&gt; be involved in what I&amp;rsquo;m doing, but it inserts itself into my consciousness. I&amp;rsquo;m reading a book, or talking with a friend, or even writing a blog post, when &amp;ndash; &lt;em&gt;beep&lt;/em&gt; &amp;ndash; hold on, lemme check this &amp;ndash; oh, just an e-mail I don&amp;rsquo;t need to respond to &amp;ndash; excuse the &lt;em&gt;interruption&lt;/em&gt;. Wait, where was I?&lt;/p&gt;&lt;p&gt;Generally, this means just disabling distractions: When I am interrupted by a chiming e-mail alert, I get excited. But after getting distracted and forgetting good ideas because I got interrupted by an e-mail message, I turned those alerts off for good, along with their attendant red dots. Do I miss them? Sometimes, if I&amp;rsquo;m awaiting a particular e-mail: but my preference here is definitely for total silence.&lt;/p&gt;&lt;p&gt;Generally, I find that smartphones arrive from the factory tuned for maximum disruption. This may be incidental (though I suspect otherwise). But in general, if you want to have a quiet, companionable smartphone, you&amp;rsquo;ll need to do some tweaks yourself.&lt;/p&gt;&lt;p&gt;Enjoy the silence!&lt;/p&gt;</description></item><item><title>Tax Efficiency</title><link>https://shayneholm.es/blog/tax-efficiency/</link><pubDate>Tue, 07 Aug 2018 09:09:43 +0000</pubDate><guid>https://shayneholm.es/blog/tax-efficiency/</guid><description>&lt;p&gt;A while ago, I watched (almost; I read the transcript) a little informational video at Vanguard, where I keep my investments. It was tax season, and so I was interested in what they had to say about tax planning, and I happened across a video. Partway through, the narrator said this:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&amp;hellip;tax efficiency is not about minimizing taxes. It&amp;rsquo;s about maximizing after-tax return.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;And it&amp;rsquo;s totally right. When tax season is imminent, it&amp;rsquo;s tempting to think about minimizing the amount of tax you&amp;rsquo;re paying. After all, shelling out that money hurts!&lt;/p&gt;&lt;p&gt;But the right way to think about it is, instead, to maximize the amount of money you&amp;rsquo;re &lt;em&gt;keeping&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Exhibit A: Mortgages. Mortgages are too often touted in the press as entitling one to the &amp;ldquo;lucrative&amp;rdquo; mortgage interest deduction. And it&amp;rsquo;s true: for every dollar you pay in mortgage interest, you can reduce the amount of money you&amp;rsquo;re taxed on by a dollar. Sweet, right?&lt;/p&gt;&lt;p&gt;Well, look at the big picture. For those in the 15% tax bracket, you save fifteen cents of income taxes for every dollar in mortgage interest you pay. While this certainly reduces the burden of mortgage payments somewhat, giving away a dollar to get fifteen cents is hardly a winning strategy. &lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&lt;p&gt;Conversely, if you pay off your mortgage, you do &amp;ldquo;lose&amp;rdquo; the mortgage interest deduction, but you also don&amp;rsquo;t have to pay any mortgage interest. Certainly there&amp;rsquo;s still an argument for keeping a mortgage alive when you can afford to pay it off, but it&amp;rsquo;s not the slam dunk often portrayed in the media. Instead, think about it clearly and run the numbers.&lt;/p&gt;&lt;p&gt;Is tax efficiency around minimizing your taxes? It shouldn&amp;rsquo;t be. Think instead about maximizing returns instead, and that will point you in the right direction.&lt;/p&gt;&lt;div class="footnotes" role="doc-endnotes"&gt;&lt;hr&gt;&lt;ol&gt;&lt;li id="fn:1"&gt;&lt;p&gt;The real impact of the deduction is to lower the effective interest rate of the mortgage, from, say, 4.0% to 3.4%, assuming that (a) you itemize more than the standard deduction already, (b) you aren&amp;rsquo;t in any credit phaseout ranges, and (c) negligible air resistance.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</description></item><item><title>Hello, world!</title><link>https://shayneholm.es/blog/hello-world/</link><pubDate>Sat, 07 Jul 2018 09:09:43 +0000</pubDate><guid>https://shayneholm.es/blog/hello-world/</guid><description>&lt;p&gt;Starting things off with a new blog can be challenging. It&amp;rsquo;s the proverbial blank piece of paper. Terrifying. But let&amp;rsquo;s get going anyway!&lt;/p&gt;</description></item></channel></rss>