Skip to content
Dan Nixon edited this page Apr 3, 2024 · 21 revisions

Welcome to the treefmt wiki!

Feel free to add more language mappings below. Or if you're using Nix, see also https://github.com/numtide/treefmt-nix.

Languages

elm

[formatter.elm]
command = "elm-format"
options = ["--yes"]
includes = ["*.elm"]

nix

[formatter.nix]
command = "alejandra"
includes = ["*.nix"]

Other tool choices: Deadnix as a linter + nixpkgs-fmt.

[formatter.nix]
command = "sh"
options = [
    "-eucx",
    """
# First deadnix
deadnix --edit "$@"
# Then nixpkgs-fmt
nixpkgs-fmt "$@"
    """,
    "--",
]
includes = [ "*.nix" ]
excludes = ["nix/sources.nix"]

haskell

[formatter.haskell]
command = "cabal-fmt"
options = ["--inplace"]
includes = ["*.cabal"]
[formatter.haskell]
command = "ormolu"
options = [
    "--ghc-opt", "-XBangPatterns",
    "--ghc-opt", "-XPatternSynonyms",
    "--ghc-opt", "-XTypeApplications",
    "--mode", "inplace",
    "--check-idempotence",
]
includes = ["*.hs"]

go

[formatter.golang]
command = "gofumpt"
options = ["-w"]
includes = ["*.go"]

python

[formatter.python]
command = "black"
includes = ["*.py"]

rust

[formatter.rust]
command = "rustfmt"
options = ["--edition", "2018"]
includes = ["*.rs"]

clojure

[formatter.clojure]
command = "sh"
options = [
  "-euc",
  """
  clj-kondo --lint "$@"
"""
]
includes = ["*.clj"]

shell

[formatter.shell]
command = "sh"
options = [
    "-eucx",
    """
# First shellcheck
shellcheck --external-sources --source-path=SCRIPTDIR "$@"
# Then format
shfmt -i 2 -s -w "$@"
    """,
    "--", # bash swallows the second argument when using -c
]
includes = ["*.sh"]
excludes = []

markdown + html/css/js etc.

Any language supported by Prettier.io can be grouped together:

[formatter.prettier]
command = "prettier"
options = ["--write"]
includes = [
    "*.css",
    "*.html",
    "*.js",
    "*.json",
    "*.jsx",
    "*.md",
    "*.mdx",
    "*.scss",
    "*.ts",
]

Note that Prettier also supports some other languages through the use of plugins. See their documentation for more info.

terraform

[formatter.terraform]
# Careful, only terraform 1.3.0 or later accept a list of files.
# see https://github.com/numtide/treefmt/issues/97
command = "terraform"
options = ["fmt"]
includes = ["*.tf"]

hcl / terraform

[formatter.hcl]
command = "hclfmt"
options = [ 
  "-w" # write in place
]
includes = ["*.hcl", "*.tf"]

cpp

[formatter.cpp]
command = "clang-format"
options = [
  "-i" # in place format
]
includes = [ "*.h", "*.cpp" ]

Using treefmt in a nix-build

{ src # src should point to the project to check the format for
, runCommandNoCC
, shfmt
, rustfmt
, treefmt
}:
runCommandNoCC "treefmt" {
  # add all your formatters here
  nativeBuildInputs = [ shfmt rustfmt treefmt ];
} ''
  # keep timestamps so that treefmt is able to detect mtime changes
  cp --no-preserve=mode --preserve=timestamps -r ${src} source
  cd source
  HOME=$TMPDIR treefmt --fail-on-change
  touch $out
''