Earlier this year I wrote zsh-autoquoter, a little zsh extension that automatically quotes arguments to commands of my choice.
I’ve been using it for a few months now, and I’ve gotta say: it’s pretty nice! I wish I’d written this a long time ago. Here are a few use cases I’ve found for it so far:
1. commit messages
git
has a neat feature where you can specify a commit message directly on the command line, with the -m
flag:
$ git commit -m 'fix typo'
It’s really useful for repositories like this blog, where almost every commit is a short little memo like that. But sometimes I want to write something a little more complicated:
$ git commit -m "\"fire\" wasn't clear; rename to \"fire_the_missiles\""
Now, I like to commit “early and often,” using a patch queue workflow, and then rebase entire branches in order to get them ready for “publication” to the outside world. So I do this a lot. And it’s not that annoying to open up a vim buffer to write this, but it’s slightly more friction than just typing it directly.
2. ssh
commands
Sometimes I want to run complicated shell commands on remote servers, with globs and pipelines and quoted arguments and all sorts of things, without actually starting up an interactive session on that server.
ssh
makes this… possible. But I find it really difficult to wrangle all the nested quoting that this entails.
Here’s a simple example of what I mean:
$ ssh user@host "awk '{print $1}' file.txt"
See the problem? $1
is going to be expanded as a shell variable, and fortunately syntax highlighting makes the mistake obvious. (You do have syntax highlighting in your shell, right?)
To pass a literal $1
to awk
, you actually have to write:
ssh user@host 'awk "{print $1}" file.txt'
Except, of course, that’s still wrong. You’ve just moved the problem to the remote server. You actually actually have to write something like:
$ ssh user@host "awk '{print \$1}' file.txt"
(Or is it \\$1
?)
But with zsh-autoquoter, you don’t have to do any of that. You just type the obvious thing; the same thing you would type if you were running a local command:
$ ssh user@host awk '{print $1}' file.txt
And it will do the thing you want.
3. todo
lists
Once upon a time I wrote a little command-line todo list app to help keep track of my stack at work.
todo 'write a blog post about zsh-autoquoter'
I liked the app; I liked the interface; I liked how simple it was. But it suffered from a simple ergonomic problem: English strings are really annoying to type on the command line.
todo 'rework dackery'\''s speech about the "hex machine"'
But now I can add a zsh-autoquoter rule for it, and give it another try.
4. sd --new
A neat feature of sd
is the ability to quickly stash useful oneliners:
sd video poster --new 'ffmpeg -i "$1" -vframes 1 "${basename $1}-poster.png" -y'
That particular example happened to fit into single quotes. But I would really like to be able to stash arbitrary commands without worrying about how to escape them. Like this one, for example:
nix-env -qaA "nixpkgs.$1" --json | jq -r '.[] | .name + " " + .meta.description, "", (.meta.longDescription | rtrimstr("\n"))'
How am I supposed to quote that monstrosity? Well, with zsh-autoquoter, of course.
5. note
s to self
For many years I have been taking notes in a simple text file, using a Mac GUI application called Alfred. I press a shortcut, Alfred pops up, and I type my note:
Using Alfred for this is a little silly, and I would like to replace this “workflow” with this tiny shell script:
$ cat ~/bin/note
#!/usr/bin/env bash
set -euo pipefail
printf '%s %s\n' $(date '+%Y-%m-%d') "$1" >> ~/Dropbox/notes.txt
But these notes can be long, free-from things. It would have been a nightmare to write something like this, for example:
2022-01-08 TIL about SSH "key types" and "signature types" being different. if
i want to use this key i have to configure sshd to accept ssh-rsa-sha2-256, not
just ssh-rsa. the error message says that ssh-rsa isn't supported, but it
actually means this particular signature type
But not anymore!
those are all of the examples
Tempted? Give it a spin! The extension should work with any zsh plugin manager, and the readme explains how to configure it and enable the (optional) zsh-syntax-highlighting integration.
Apparently you’re supposed to end posts like this with a prominent call to action, so go check out this crazy moth I found on Wikipedia.