A fast code formatter for ChucK — the strongly-timed audio programming language.
ChucK's syntax includes unique operators like =>, @=>, <<</>>>, and --> that clang-format doesn't understand natively. chuckfmt wraps clang-format and applies ChucK-specific post-processing to fix these.
clang-format must be installed first:
# Debian/Ubuntu
sudo apt install clang-format
# Fedora
sudo dnf install clang-tools-extra
# Arch
sudo pacman -S clang
# macOS
brew install clang-format
# Windows (winget)
winget install LLVM.LLVM
# Windows (scoop)
scoop install llvmOr set CLANG_FORMAT_BIN=/path/to/clang-format to use a custom path.
brew install aik2mlj/tap/chuckfmt# use pre-built binary
paru -S chuckfmt-bin
# or if you prefer, compile from source
paru -S chuckfmtscoop bucket add aik2mlj https://github.com/aik2mlj/scoop-bucket; scoop install aik2mlj/chuckfmt# use pre-built binary
# you need to have cargo-binstall installed first
cargo binstall chuckfmt
# or compile from source
cargo install chuckfmt- Download the corresponding binary archive from Releases
- Decompress the archive file
- Move it to
$PATHfor easier access
chuckfmt uses clang-format's configuration system. This might be a good starting point:
BasedOnStyle: LLVM
ColumnLimit: 100
IndentWidth: 4
UseTab: NeverPlace this in a .clang-format file under your project root (for per-project settings) or home directory (for global settings).
To add chuckfmt as the custom formatter for ChucK files in VS Code:
-
Install the Custom Local Formatters extension
-
Open your user settings via Command Palette (
Ctrl+Shift+PorF1) →Preferences: Open User Settings (JSON), add the following and save:
"customLocalFormatters.formatters": [
{ "command": "chuckfmt", "languages": ["chuck"] }
],
"files.associations": { "*.ck": "chuck" },
"[chuck]": {
"editor.formatOnSave": true
}- Now test it by opening a
.ckfile and saving — it should be auto-formatted!
If you don't like format on save for ChucK files, set editor.formatOnSave to false in the [chuck] block. You can always manually trigger Format Document (Ctrl+Shift+I).
Using conform.nvim:
require("conform").setup({
formatters_by_ft = {
chuck = { "chuckfmt" },
},
formatters = {
chuckfmt = {
command = "chuckfmt",
stdin = true,
},
},
})# Format file to stdout
chuckfmt foo.ck
# Format multiple files to stdout
chuckfmt foo.ck bar.ck
# Format in-place
chuckfmt -i foo.ck bar.ck
# Pipe from stdin
cat foo.ck | chuckfmt
# Use a file list
chuckfmt -i --files filelist.txt
# Explicit file delimiter (useful for files starting with -)
chuckfmt -i --style=LLVM -- foo.ck bar.ckAll clang-format options are passed through. Run chuckfmt --help for details.
- Reads ChucK source code (from file or stdin)
- Applies pre-processing (e.g., temporarily modifies
@importfor clang-format compatibility) - Pipes it through
clang-formatwith appropriate options - Applies regex-based transforms to fix ChucK-specific operators (comments are preserved)
- Outputs the result (to stdout or overwrites the file with
-i)
| Operator | clang-format output | chuckfmt output |
|---|---|---|
| ChucK operator | = > |
=> |
| UnChuck operator | = < |
=< |
| At-chuck | @ => |
@=> |
| UpChucK operator | = ^ x |
=^ x |
| Time literal | 1 ::second |
1::second |
| Debug print (open) | <<<x |
<<< x |
| Debug print (close) | x>>>; |
x >>>; |
| Polar literal | % ( |
%( |
| Spork (function) | spork ~foo |
spork ~ foo |
| Gruck operator | -- > |
--> |
| Ungruck operator | -- < |
--< |
| Multiplication | 2 *b |
2 * b |
| Leading sign | - 3.14 |
-3.14 |
A test script is included to verify formatting doesn't break ChucK syntax:
python scripts/test_chuckfmt_syntax.py \
--src /path/to/chuck/examples \
--format-cmd "chuckfmt -i {}" \
--chuck /path/to/chuck \
--chuck-args=--silent \
--timeout 0.5 \
--jobs 12This runs syntax checks on all .ck files before and after formatting, reporting any regressions.
I've run this against the official ChucK examples and it passes without issues.
MIT © Lejun Min