dprint Wasm plugin for Shell Scripts using shuck-formatter.
dprint add kachick/shEmpty works as default
{
"sh": {
}
}Customize if necessary
{
"sh": {
"dialect": "auto",
"indentWidth": 8,
"useTabs": true,
"binaryNextLine": false,
"switchCaseIndent": false,
"spaceRedirects": false,
"keepPadding": false,
"functionNextLine": false,
"neverSplit": false,
"simplify": false,
"minify": false
}
}This plugin directly uses default options from the upstream shuck-formatter crate.
Current defaults are shown below:
| Option | Type | Default | Description |
|---|---|---|---|
dialect |
string | "auto" |
Shell dialect: "auto", "bash", "posix", "mksh", "zsh". |
indentWidth |
number | 8 |
Number of spaces for indent. Inherits dprint global config if set, or falls back to 8. |
useTabs |
boolean | true |
Indent with tabs. Inherits dprint global config if set, or falls back to true. |
binaryNextLine |
boolean | false |
Put binary operators (&&, ||, |) at start of next line instead of end. |
switchCaseIndent |
boolean | false |
Indent case pattern arms under the case statement. |
spaceRedirects |
boolean | false |
Put a space between redirect operators and target (e.g. > file instead of >file). |
keepPadding |
boolean | false |
Keep column alignment spaces between tokens. |
functionNextLine |
boolean | false |
Put function opening brace { on a new line (Allman style). |
neverSplit |
boolean | false |
Keep statements on a single line where possible. |
simplify |
boolean | false |
Rewrite redundant syntax to simpler forms (e.g. ${foo} to $foo). |
minify |
boolean | false |
Remove comments and extra whitespace to make code small. |
In dprint, top-level settings in dprint.json (such as "indentWidth": 2 and "useTabs": false) apply to all plugins by default.
If your project sets global options for other languages (like TypeScript or JSON), this plugin inherits them. If you want shell scripts to keep the standard shfmt style (tabs), override them in the "sh" block:
{
"indentWidth": 2,
"useTabs": false,
"sh": {
"useTabs": true
}
}When dialect is "auto" (default), this plugin chooses the dialect in this order:
- Shebang: Reads the first line
#!...(e.g.,#!/usr/bin/env bash-> Bash,#!/usr/bin/env zsh-> Zsh). - File extension:
.bash,.bats-> Bash.zsh-> Zsh.sh,.dash,.ksh-> Posix.mksh-> Mksh
- Fallback: Files without an extension (like
.envrc) default to Bash.
Note
.sh files without a shebang resolve to posix by default.
If your .sh file uses Bash syntax (such as [[ ]]), parsing will fail in posix mode.
To fix this, set "dialect": "bash" in your configuration or add a #!/usr/bin/env bash shebang line.
- File extensions:
.sh,.bash,.zsh,.ksh,.mksh,.dash,.bats - File names:
.envrc,.bashrc,.bash_profile,.bash_login,.bash_aliases,.bash_logout,.profile,.zshrc,.zshenv,.zprofile,.zlogin,.zlogout
Unix tools often use shell scripts in extensionless files like dotfiles.
This repository covers some popular file names above, but does not plan to keep adding more default file names.
When formatting other extensionless scripts for your use case, use dprint's shebangs configuration first:
{
"shebangs": {
"#!/bin/sh": "sh",
"#!/usr/bin/env bash": "bash",
"#!/usr/bin/env zsh": "zsh"
}
}Warning
Upstream shuck-formatter only infers dialects from shebangs and file extensions, falling back to Bash for extensionless files.
This plugin bridges this gap by detecting known Zsh dotfiles (like .zshrc) and passing zsh dialect upstream.
This workaround is heuristic. If you encounter unexpected formatting behavior, set "dialect": "zsh" explicitly.
Non-shell files such as Makefile are not supported.
To format code blocks in markdown, use the tags option in the official markdown plugin:
dprint add markdownIn tags:
- Key: The code block language tag in Markdown (e.g.
bash). - Value: The target file extension (without a period) that tells this plugin how to format the code.
For example, .envrc is a file name, not an extension. So map "envrc" to "bash".
{
"markdown": {
"tags": {
"sh": "sh",
"bash": "bash",
"zsh": "zsh",
"envrc": "bash",
"shell": "sh",
"shell-script": "sh"
}
}
}This list satisfies linguist mapping.