Files
Shipwright/docs/FORMATTING.md
T
David Racine d912fd2c01 docs: document clang-format 14 setup and add an opt-in pre-commit hook (#6741)
Recent distros and Homebrew ship only newer clang-format, so contributors
can't easily get the version CI uses (14, matching the OoT/MM decomp).

- docs/FORMATTING.md: how to get a 14.x binary (apt, AUR, muttleyxd static
  binaries, uvx/pipx wheel, brew) and how to run the formatter.
- run-clang-format.sh: default to clang-format-14 but honor $CLANG_FORMAT so
  any matching binary works. Any 14.x produces byte-identical output here.
- .pre-commit-config.yaml: opt-in hook to format staged C/C++ on commit.
- README: link the new doc.

The llvm@14 formula is available on Linux too, so filing it under a
macOS-only heading was too narrow.

* Support spaced paths in CLANG_FORMAT; document run-clang-format.ps1

eval the clang-format invocation so CLANG_FORMAT can carry arguments
(uvx clang-format@14) or a quoted path with spaces without one breaking
the other. The NUL-separated file list reaches xargs over the pipe, so
filenames never pass through eval.

Document the native Windows run-clang-format.ps1 path alongside the Git
Bash/WSL route.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 03:22:28 +00:00

3.0 KiB

Formatting

Shipwright's C/C++ in soh/ is formatted with clang-format 14, the version used by the OoT/MM decompilation that the vendored soh/src/ tree comes from. clang-format's output is not stable across major versions, so the major version matters: any 14.x produces identical output for this tree (verified across all formatted files), but clang-format 15+ will reformat differently and fail CI. Patch version (14.0.0 vs 14.0.6) does not matter.

Format the tree

./run-clang-format.sh

This formats every C/C++ file in soh/ in place, skipping the decompiled headers (soh/src, soh/include) and autogenerated assets (soh/assets), matching what CI checks.

The script calls clang-format-14 by default. If your clang-format 14 is named or located differently, point CLANG_FORMAT at it:

CLANG_FORMAT=clang-format              ./run-clang-format.sh   # already 14.x
CLANG_FORMAT=/path/to/clang-format     ./run-clang-format.sh   # static binary
CLANG_FORMAT="uvx clang-format@14"     ./run-clang-format.sh   # uv wheel
CLANG_FORMAT='"/path with spaces/cf"'  ./run-clang-format.sh   # quote a spaced path

CLANG_FORMAT is treated as a command line, so it can carry arguments (the uvx case) or a quoted path containing spaces.

On Windows you have two options. Run run-clang-format.ps1 from PowerShell: it downloads clang-format 14.0.6 itself (needs 7-Zip installed) and formats the same fileset, so you don't have to install clang-format or pass CLANG_FORMAT. Or run run-clang-format.sh from Git Bash (ships with Git for Windows) or WSL, since it needs a Unix shell for find/xargs; get the binary from the uvx wheel or the Windows static binary below.

Getting clang-format 14

Recent distros and Homebrew often ship only newer clang-format. Any of these gives you a 14.x binary:

  • Debian/Ubuntu: sudo apt-get install clang-format-14 (where the package still exists).
  • Arch: AUR clang-format-static-bin.
  • Any Linux/macOS/Windows, no install: download a static binary from muttleyxd/clang-tools-static-binaries (e.g. clang-format-14_linux-amd64), chmod +x, and point CLANG_FORMAT at it.
  • Any OS via a Python wheel: uvx clang-format@14 (with uv), or pipx install clang-format==14.0.6.
  • Homebrew (macOS or Linux): brew install llvm@14 and use its clang-format, or use one of the cross-platform options above.

Optional: format on commit

The repo ships a pre-commit config (.pre-commit-config.yaml) that auto-formats staged C/C++ with a pinned 14.x before each commit, so you never get caught by the CI check. With pre-commit installed, enable it once:

pre-commit install --install-hooks

--install-hooks downloads clang-format up front so your first commit isn't slowed by it.