Skip to content

About

Shell formatter as a dprint Wasm plugin

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

dprint-plugin-sh

npm version CI - Nix Status

dprint Wasm plugin for Shell Scripts using shuck-formatter.

Installation

dprint add kachick/sh

Configuration

Empty 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
  }
}

Options

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.

Indentation and Global Config

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
  }
}

Dialect Resolution

When dialect is "auto" (default), this plugin chooses the dialect in this order:

  1. Shebang: Reads the first line #!... (e.g., #!/usr/bin/env bash -> Bash, #!/usr/bin/env zsh -> Zsh).
  2. File extension:
    • .bash, .bats -> Bash
    • .zsh -> Zsh
    • .sh, .dash, .ksh -> Posix
    • .mksh -> Mksh
  3. 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.

Supported Files

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

Tips

To format code blocks in markdown, use the tags option in the official markdown plugin:

dprint add markdown

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

Acknowledgments

  • Thanks to shuck for making it easy to use as a dprint Wasm plugin.
  • Thanks to shfmt for the reference and the original formatter.

About

Shell formatter as a dprint Wasm plugin

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages