Shell typo aliases

Published on

There are some commands I run so often that I find it useful to assign them to single-character aliases. This has turned out to be a source of great convenience but also the cause of further problems (namely, one specific typo).

First, a list of the aliases I've defined:

alias g='git'
alias j='jump' # A `cd` bookmark script I have
alias k='kubectl'
alias l='ls'
alias t='task'
alias z='zoxide'

Brief aside about built-ins

To make the previous list of my aliases, I ran this script:

for c in {a..z}; do
    which "$c"
done

In addition to the ones I expected, I also saw that there were some pre-existing one-letter bindings:

  • r: man zshbuiltins says this is the same as fc -e -, whose explanation is still as impenetrable as when this StackOverflow question was asked and answered.
  • w: A real command! man w says "Show who is logged on and what they are doing." On almost any computer I use nowadays, this returns jdkaplan on tty1 (me) or root on pts/0 (also me).

While in man zshbuiltins, I was reminded that "one symbol" technically counts as "one character". And these are the one-symbol commands that zsh provides:

  • -: Run the following command with - prefixed to its name in argv[0].
  • .: Source a file into the current environment
  • :: Do nothing and succeed
  • [: "Like the system version of test", which is a regular command! It requires the closing ] if-and-only-if you run it as [. (I do also have /usr/bin/[ present.)

Aliases for subcommands

In addition to aliasing my frequent top-level commands, I also alias some of those commands' subcommands. The ones I can show easily are for git:

git config -l | rg '^alias\..='
alias.b=branch
alias.c=commit
alias.d=diff
alias.f=fetch
alias.s=status

My laziness has not (yet?) spread to sub-sub-commands, thankfully.

That means I can get to explaining the typo now!

The one typo

Conveniently, l=ls and g=git mean I'm not susceptible to sl or gti.

But the presence of g s for git status means I find myself typing gs (hitting the space too early), which launches Ghostscript!

So I now maintain these two aliases to defend myself from myself:

# I have never actually meant to start Ghostscript, but I'm sure that I'll want
# to be able to someday.
alias gs='git status'
alias ghostscript="command gs"

The other typo

But this is not the only place I type a space too early! My shell history is filled with carg obuild, carg oc, and carg ot.

So I now have this script that lives as carg on my PATH:

#!/usr/bin/env bash

# This program should be installed as `carg`. It fixes typos like
#
#   carg oc -> cargo c
#   carg obuild -> cargo build
#
# It unconditionally removes one leading `o` from its first argument and then
# runs the corrected `cargo` subcommand with the rest of the arguments.

set -euo pipefail

sub="$1"; shift;
sub="${sub#o}"

exec cargo "$sub" "$@"

I really hope I don't end up having to do this a third time!