Skip to content
Jeroen de Jong edited this page Sep 8, 2022 · 13 revisions

How fast is formatting-stack?

  • Formatting is generally ultra-fast
    • Performed fully in parallel, without spinning extra JVMs etc
  • Linting is generally very fast
    • e.g. JVM clj-kondo is just as fast as its GraalVM counterpart, because formatting-stack never spins up JVMs.
    • Notable exception: Eastwood, which is eval-based

Very importantly, formatting-stack default behavior is to perform all work in the background, so that your REPL is never blocked.

Still it can be slightly frustrating that the slowest linter (Eastwood) causes the rest of the linters' output to not be printed immediately.

You are free to remove the slower components, for somewhat repl-friendlier usage. You could leave them only for when formatting a Git branch (formatting-stack.branch-formatter ns) or your whole project (formatting-stack.project-formatter ns).

My IDE/editor doesn't automatically pick up formatting-stack's changes, giving me an annoying prompt

Fix on Emacs: (global-auto-revert-mode t)

formatting-stack.core/format! is not formatting files I expected to be formatted

By default, format! will only process files that are in your Git staging area. This is for safety, and other reasons hinted at the README.

As a tip, generally it can be good practice to carefully pay attention to what is in the staging area, and what not. Else it's unlikely that the Git commits we deliver will be atomic, and meaningful.

Of course, you are free to build your own 'stack' of defaults, supplying strategies that will format more files per invocation.

See also: branch-formatter, which formats a whole Git branch's set of files (relative to e.g. master), regardless of the staging area status.

I'm seeing No implementation of method: errors in my application code

Eastwood achieves it's accuracy via tools.analyzer, which works by performing evaluation of code.

It is a known problem that evaluating protocols and defrecords in an unlucky order can cause No implementation of method: errors.

However this problem can be addressed!

There are various approaches that work:

  • move protocols to a different source path, that is seldom reloaded
    • if you use tools.namespace.repl, exclude this source path from your refresh-dirs
  • move protocols to a different project/repo, that is never reloaded at all
  • Don't use defrecord, favoring reify and metadata-based protocol extension instead

In our experience, reify / utils.modular are rock-solid approaches. Internally, formatting-stack uses utils.modular, and developing formatting-stack itself is 100% free of this nuisance, even when we use protocols extensively.

I don't like this indentation

Generally, formatting-stack doesn't introduce any creative formatting: it merely applies cljfmt, which in turn follows quite closely the Clojure Style Guide.

It's obviously a good goal to adhere to standards and majorities.

If you're unfamiliar with the traditional Lisp indentation, as standardized by cljfmt/clojure-style-guide, you'll likely end up finding that having fine-grained rules, which distinguish macro and function indentation, in fact makes code more readable.

It's useful to be able to distinguish between functions and macro at a glance, particularly when performing code reviews.

I disagree with a certain linter

You are free to configure them (e.g. change max column count from 130 to 80) or completely remove them.

How to create custom defaults that I can reuse in multiple projects?

If you have multiple projects where you want to use formatting-stack, and also need to tweak the default stack, you can:

  • create copies of our defaults, branch-formatter, project-formatter namespaces
    • it's OK to copy them, since they are essentially logic-less
  • Bundle those custom namespaces in a tiny library that your projects would depend on.