Autoformatting Clojure Code

Are Clojure developers using autoformatting tools? If yes, which tools do you use and where do they integrate in the development workflow?

Partially triggered by https://twitter.com/marick/status/943158136365551617

In our team we want to establish a autoformat-before-save workflow, which means formatting has to be integrated into the editors. It also means it has to be fast, as you don’t want to wait a second or two for a jvm to boot up on every file save.

We decided to give zprint a shot as our formatting tool, mostly because of its flexibility and configurability (like per-toplevel sexp formatting overrides).

For Emacs/Cider, we integrate by hijacking the cider-format-* functionality (see https://github.com/clojure-emacs/cider-nrepl/issues/453 for how), and then calling cider-format-buffer in the before-save-hook. Together with the latest Cider changes this makes for a good experience.

For other editors, zprint suggests to use zprint-filter. Unfortunately, for Atom, which some in our team use, it doesn’t seem to be easy to integrate a unix-like filter on before save. There is atom-beautify, but it only supports cljfmt.

For vim we do use zprint-filter with BufWritePre, with an optimization to check for a custom socket server running to not have to boot up a JVM.

1 Like

We use cljfmt and we run it on CI (and fail the build if the code is not formatted correctly). This ensures that different developers are not committing incorrectly formatted code to master (although poorly formatted code may exist on a branch for some period of time).

The advantage of this approach is that we avoid the considerable complexity of finding a autoformatter that runs quickly for everyone and integrates with each editor used on our team.

Each developer can of course, speed up this feedback loop by either running the autoformatter locally on the command line, or installing a pre-commit hook, or connecting a compatible auto-formatter to their editor. We encourage devs to share documentation on how to set up these tools, but we don’t require that our shared standard meets this requirement.

IMHO, the biggest value is enforcing a shared standard for the code itself at the point where devs are likely to share code (for us, that’s when a branch is pushed to Github and CI is run). There is less value (and significantly more work) to enforce a common workflow on each devs machine.

1 Like

Of course, your team may have a different workflow and therefore a totally different set of tradeoffs wrt when it’s best to enforce a common style :slight_smile:

One option that doesn’t require a JVM boot is https://github.com/snoe/node-cljfmt/

1 Like