Nathaniel Knight

Reflections, diversions, and opinions from a progressive ex-physicist programmer dad with a sore back.

Using all your tools from Emacs

I recently figured out a pair of Emacs commands, and if you do any of your work from the command line, you might find them useful too.

The commands are compile and recompile, and they let you run or test your code right from the editor. They don't require any configuration.

The compile command runs a shell command in Emacs' current directory and displays the output in a special buffer called *compilation*. You'll be prompted to edit the shell command before it runs, so you can use it to build the project, run your tests, execute the code--whatever makes sense for what you're working on.

Once you've got compile doing what you want, recompile re-runs it. It uses the same command and working directory that you ran compile with, so you can can conveniently run your tests without having to go back to your project's root directory.

For example, if I'm working on a Python project trying to track down a test failure, I would run my tests with compile by going to the project's root directory and using the following commands (written with the Emacs shortcut notation):

M-x compile <RET>
python -m unittest <RET>

Now my tests run, and any failures show up in the *compilation* buffer. I can go work on fixing them, and re-run the tests with

M-x recompile <RET>

I usually bind recompile to a function key for convenience:

M-x global-set-key <RET>
recompile <RET>

Once my tests are passing, I might want to manually inspect my program's output and see if it's what I expect. I can do that by returning to the project's root directory and running it with compile. For example:

M-x compile <RET>
python <RET>

Now the *compilation* buffer will contain my program's output, and I can re-run it as I make changes.

I've found these commands useful for working with a bunch of different programming languages. For example, Python, Rust, .NET Core, and Elm all have command line tools for building and testing code, and I've used compile with all of them using commands like these:

Test Compile/Run
Python python -m unittest python
Rust cargo test or cargo check cargo run
.NET Core dotnet build or dotnet test dotnet run
Elm elm-test elm make

If you use a different tool or programming language that has a CLI-based interface, you can probably figure out how to use it with compile and recompile.

These commands make for a pretty basic experience. It's not complicated, and the results are useful, but not as fully featured as you might want. Nevertheless, they're built into Emacs, I find it delightful that I can use the same tools for so many different tasks, that they don't require any setup, and I'll be able to apply them to whatever CLI tools I'm using in the future.