Emacs: Running Shell Commands on the Current File
I’ve long thought it was a little funny that Emacs doesn’t provide an easy way to run a shell command on the current file. It turns out it does, but it’s not as obvious as you might expect.
Emacs provides lots of great commands for conveniently running shell commands:
shell-command): executes the given shell command, displays output in a new buffer or the echo area (depending on output length). Optionally inserts the output into the current buffer when given a prefix argument.
async-shell-command): as above, but executed asynchronously.
shell-command-on-region): pass the current region as input to a shell command and display output. Optionally replaces the region when given a prefix argument.
Of course we can also run a shell within Emacs, via
eshell (a shell implemented in Emacs Lisp, with
access to Emacs Lisp functions), and
term (a more fully-featured
We also have
compile, which will run a shell command (often
streaming in the output and overlaying functionality to easily jump to
files referenced in the output (compilation warnings,
But what has always been notably missing for me, is a quick way to run a shell command on the current file. Not buffer / file contents, not region, but file.
dired-mode, we can easily do this with
!, but invoking Dired
just to run a shell command is more disruptive to my workflow than it
needs to be when I just want to run
open <current-file> or similar.
It turns out there is a built-in two-keystroke solution via the “future history” mechanism I wrote about on the CollBox Engineering blog:
If you use
shell-command) and then press
next-history-element), the current file name will be inserted into
the minibuffer with point before it. Then you just need to type the
command you want to run and hit return.
It’s a good reminder that with 46 years of history behind it, if something obvious appears to be missing from Emacs, there’s probably a good reason why.