Formatting
shuck format rewrites shell scripts using Shuck's parser and formatter. It is useful for project-wide formatting, CI checks, and one-off cleanup before reviewing script changes.
Basic usage
# Format the current project in place
shuck format .
# Format specific files
shuck format scripts/deploy.sh scripts/build.sh
# Check whether files are already formatted
shuck format --check .
# Print a unified diff without changing files
shuck format --diff .When no path is passed, shuck format formats the current directory. It only formats standalone shell files; embedded shell snippets inside YAML or other host files are skipped.
Standard input
Pass - to read from stdin and write the formatted result to stdout:
printf 'if true; then echo ok; fi\n' | shuck format -Use --stdin-filename when the file name matters for dialect inference or project config discovery:
printf 'print $ZSH_VERSION\n' | shuck format --stdin-filename .zshrc -In --check mode, stdin exits successfully if the input is already formatted and exits non-zero if it would change. In --diff mode, stdin prints a unified diff.
Project settings
Formatter settings live in the [format] section of shuck.toml or .shuck.toml:
[format]
indent-style = "space"
indent-width = 2
binary-next-line = true
switch-case-indent = true
space-redirects = true
keep-padding = true
function-next-line = false
never-split = falseThe defaults are tab indentation with width 8, compact inline function braces, unspaced redirection targets, and ordinary formatter-controlled splitting.
CLI flags override config values for that run:
shuck format --indent-style space --indent-width 2 .
shuck format --function-next-line --space-redirects script.shBoolean formatter flags also have hidden --no-... forms for overriding config values from the command line:
shuck format --no-function-next-line .Dialect selection
By default, the formatter infers dialect from the source text, shebang, and file path. Use the shared top-level table for files whose names cannot be inferred:
[per-file-shell]
"dot_z*" = "zsh"
"scripts/**/*.sh" = "bash"The mapping applies to direct files, stdin with --stdin-filename, and LSP
formatting. Use --dialect for a one-off override:
shuck format --dialect bash script
shuck format --dialect zsh .zshrcAccepted values are bash, posix, mksh, and zsh.
[format].dialect is intentionally not supported in config files. The per-run
--dialect flag takes precedence over [per-file-shell]; unmatched files
continue to use normal inference.
POSIX shells have no (( ... )) arithmetic command, so in a file formatted as
posix (for example a .sh file without a bash shebang) ((x = 1)) is read as
two nested subshells. Because such files are often run by bash, where the same
text is arithmetic, the formatter leaves any subshell written with an adjacent
(( exactly as it appears in the source rather than respelling it as ( (.
Line endings
The formatter writes \r\n line endings only when every line in the file
already ends with \r\n. Files that mix styles are written with \n line
endings outside of heredoc bodies and quoted strings, whose bytes are always
preserved.
Simplify and minify
--simplify applies safe syntax simplifications before formatting:
shuck format --simplify script.sh--minify emits a compact form and drops ordinary comments while preserving meaningful shell structure:
shuck format --minify script.shBoth options are CLI-only today.
Caching and file selection
Formatting uses Shuck's project discovery and cache plumbing. Use --no-cache when debugging formatter behavior:
shuck format --no-cache .The standard file-selection flags are available:
shuck format --exclude vendor --extend-exclude testdata .
shuck format --force-exclude scripts vendor/script.shFormatting respects ignore files by default, matching shuck check.
Editor status
The LSP server advertises whole-document and selected-range formatting. Once shuck server is attached, use your editor's normal LSP format command or format-on-save integration.
Use shuck format directly for CI, pre-commit, project-wide rewrites, and one-off command-line formatting. See LSP Server for editor setup.