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.