Initial Release of zsh-dwim

| Comments

I’ve had a small idea rolling around in my head for while now. While operating in a shell, there are certain commands that often follow others. Sometimes there is a problem. You attempt to ssh into a host and it fails due to a host key mismatch, so you need to run ssh-keygen to remove the key. This happens to me fairly frequently when I am building temporary virtual machines.

Sometimes one command tends to follow another in chronological order. You might list the contents of an archive and then want to extract it. Maybe you stopped a service and want to start it back up shortly thereafter.

I thought it would be nice to bind a key to attempt to insert the next command that I’m going to be looking for. I’m sick of changing ssh to ssh-keygen, adding the -R, and removing the username@ from an ssh command to remove its host key from my ~/.ssh/known_hosts file.

What’s working so far?

The code is ugly, but I have a few useful things working. For instance, commands like these:

service apache2 stop
apt-cache show apache2

…turn into commands like these when you hit control-u:

service apache2 start
ssh-keygen -R
sudo apt-get install apache2

If the command line is empty, the previous command will be recalled from history first.

How does it work?

There’s a little zsh function that passes the command line to a Perl script. The (rather ugly) Perl script runs through a list of possible transformations and returns the new command back to zsh.

Why isn’t it all in zsh? Why is the Perl script a disorganized pile of conditionals?

The Perl half started as a quick hack just to see how workable this idea was. I enjoyed using it quite a bit, so it ballooned up fairly quickly. I started the job of porting it back into zsh before I posted the code up on github. It didn’t look like zsh’s regular expression capabilities were very advanced or easy to use. I may be wrong about this. I may have been looking in the wrong place.

That doesn’t explain why it is still if after if after if. I thought about moving all the regular expressions out to a config file, or at least setting up a dispatch table. I thought it would be best to wait and see if any more complicated transformations pop up.

Why control-u?

Why not? I wanted to use something easy to reach and the default binding for control-u was something I never use.

Where will it go from here?

I’m not sure. I mostly come up with ideas as I’m working in my shell. I’d like to set up some more circular command lists. There a group of about four or five ls commands in there now that loop back around to the beginning. I’m thinking I might do something similar for dig/ping/mtr, and I bet there are plenty of related commands like that that all take similar arguments.

I’d love to hear some ideas!

Where to get it

I uploaded the repository to github, and the README explains how to get it.

I have it set up to install directly into Prezto, but it should be pretty trivial to get it to work as an oh-my-zsh plugin or on its own without any fancy configuration framework.