Last Action Hero

This sort of thing happens to me all the time:

$ emacs readme.md
The file readme.md does not exist.
$ touch readme.md
$ emacs readme.md

Or maybe I’m just lsing a bunch of directories and find one I need to get into:

$ ls /long/path/to/where/ever
$ cd /long/path/to/where/ever

Or I want to remind myself of what a shell function does before running it, so I run cat. But I see something’s off, so I need to make a quick update:

$ cat ~/.config/fish/functions/today.fish
$ emacs ~/.config/fish/functions/today.fish

There are three ways to create that second command:

  1. Type the whole thing out.
  2. Hit the up arrow, alt-arrow back through the path, delete the cat, type in emacs.
  3. The same as #2 but you hit ctrl-a instead of alt-arrowing.

And here’s a fourth method:

$ lah emacs

lah stands for Last Action Hero. It finds the last non-lah command in your history, replaces the executable’s name with the new name you provide, and executes that new command.

So

$ emacs readme.md
The file readme.md does not exist.
$ lah touch

will run touch readme.md, and then

$ lah emacs

will run emacs readme.md.

If you enter more than one parameter, it will append the rest to the end of the new command. So, following the above,

$ lah emacs notes todo.org

will run emacs readme.md notes todo.org.

If you want to give a gander, it’s on Github.

Notes

Lisp is wonderful. I’ve been reading Structure and Interpretation of Computer Programs and The Little Schemer and pretty much any article related to Lisp that appears on Hacker News but I haven’t yet had a reason to write anything in a Lisp beyond the exercises in the books.

So lah is my first. It works and I’m happy with it but it’s not a very good solution to the problem. Here’s a fish function to accomplish basically the same thing:

function lah
  set old_cmd $history[1]
  set old_exec (echo $old_cmd | cut -f 1 -d ' ')
  set new_cmd (echo $old_cmd | sed "s/$old_exec/$argv[1]/")
  eval $new_cmd
end

But why write six lines of fish when you could write 66 lines of Lisp?