Language support

43 languages are built in. The language is chosen from the file name, then the extension (case-insensitive, overridable with [extensions]), then, for files without an extension, the shebang interpreter (python*, sh/bash/zsh/ksh/dash, ruby, perl, node/deno/bun, lua, pwsh, Rscript).

Comment style Languages
# line python, ruby, shell, perl, r, powershell, yaml, toml, dockerfile, makefile, cmake, elixir, julia
/* block */ (preferred) c, cpp, csharp, java, kotlin, scala, swift, objc, javascript, typescript, groovy, php, css, scss/less
// line (preferred; /* */ also parsed) go, rust, dart, zig, proto, solidity
-- line sql (also parses /* */), lua, haskell
<!-- --> html, xml, vue
% line erlang, tex
;; line clojure, lisp
(* *) ocaml

Extensions: python .py .pyi .pyw, ruby .rb .rake .gemspec Rakefile Gemfile, shell .sh .bash .zsh .ksh, perl .pl .pm .t, r .r, powershell .ps1 .psm1, yaml .yml .yaml, toml .toml, dockerfile Dockerfile .dockerfile, makefile Makefile GNUmakefile .mk, cmake CMakeLists.txt .cmake, elixir .ex .exs, julia .jl, c .c .h, cpp .cc .cpp .cxx .hpp .hh .hxx, csharp .cs, java .java, kotlin .kt .kts, scala .scala .sc, swift .swift, objc .m .mm, go .go, rust .rs, dart .dart, zig .zig, proto .proto, solidity .sol, javascript .js .mjs .cjs .jsx, typescript .ts .tsx .mts .cts, groovy .groovy .gradle, php .php, css .css, scss .scss .less, sql .sql, lua .lua, haskell .hs, html .html .htm, xml .xml .xsd .xsl .xslt .svg .plist, vue .vue, erlang .erl .hrl, tex .tex .sty, clojure .clj .cljs .cljc, lisp .lisp .el .scm, ocaml .ml .mli.

JSON, Markdown and other formats without comments are not touched.

Where the header goes

The header goes after any lines that must stay first and before everything else. A blank line separates it from the code, unless a blank line is already there.

Language Kept above the header Notes
python shebang, then a PEP 263 coding line (first two lines only) The module docstring stays below the header, so it remains the first statement.
ruby shebang, encoding line, magic comments (# frozen_string_literal: true, # typed: ...)
shell, perl, r, lua, javascript, typescript, groovy shebang
php shebang, then the <?php line Files that do not start with <?php (inline HTML first) are skipped because a comment would be printed as output. declare(strict_types=1) stays the first statement, comments do not count.
xml, svg <?xml ...?> prolog
html <!DOCTYPE ...> Keeps standards mode (a comment before the doctype triggers quirks mode in old browsers).
css @charset @charset must be the very first bytes.
dockerfile # syntax= and # escape= parser directives
go nothing The header goes above //go:build / // +build lines and is always followed by a blank line, so it can never merge with a package doc comment or a build constraint. Build constraints and //go: pragmas are never mistaken for a header.

A UTF-8 BOM stays the first three bytes. Line endings: the dominant style in the file (CRLF if CRLF lines outnumber LF lines) is used for inserted lines; existing lines keep their own ending.

What is skipped

Reason Rule
excluded Config exclude globs, default vendored directories, the config file.
override-skip An [[override]] with skip = true.
generated A generated-code marker in the first 30 lines.
binary NUL byte in the first 8 KiB, or not valid UTF-8.
empty Zero bytes or whitespace only.
unplaceable PHP file not starting with <?php.
unsupported Unknown language.

Only files known to git (git ls-files --cached --others --exclude-standard) are visited inside a repository, so .gitignore is respected; outside git the tree is walked.