shuck

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 = false

The 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.sh

Boolean 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 --dialect for a one-off override:

shuck format --dialect bash script
shuck format --dialect zsh .zshrc

Accepted values are bash, posix, mksh, and zsh.

[format].dialect is intentionally not supported in config files. Use file names, shebangs, or the per-run --dialect flag instead.

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.sh

Both 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.sh

Formatting 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.