shfmt-configuration
Use when configuring shfmt for shell script formatting including .shfmt.toml setup, EditorConfig integration, and project-specific settings.
What this skill does
# shfmt Configuration
Master shfmt configuration for consistent shell script formatting across projects, including configuration files, EditorConfig integration, and team standardization.
## Overview
shfmt is a shell parser, formatter, and interpreter that supports POSIX Shell, Bash, and mksh. Configuration allows you to define consistent formatting rules for your shell scripts.
## Configuration Methods
shfmt supports multiple configuration approaches, in order of precedence:
1. Command-line flags (highest precedence)
2. EditorConfig settings
3. `.shfmt.toml` or `shfmt.toml` file
## TOML Configuration File
### Basic Configuration
Create `.shfmt.toml` or `shfmt.toml` in your project root:
```toml
# Shell dialect (posix, bash, mksh, bats)
shell = "bash"
# Indent with spaces (0 for tabs)
indent = 2
# Binary operators at start of line
binary-next-line = true
# Switch cases indented
switch-case-indent = true
# Redirect operators followed by space
space-redirects = false
# Keep column alignment paddings
keep-padding = false
# Function opening brace on next line
func-next-line = false
```
### Configuration Options Explained
#### shell
Specifies the shell dialect for parsing:
```toml
# POSIX-compliant shell (most portable)
shell = "posix"
# Bash (default for .bash files)
shell = "bash"
# MirBSD Korn Shell
shell = "mksh"
# Bats (Bash Automated Testing System)
shell = "bats"
```
Auto-detection based on shebang if not specified:
- `#!/bin/sh` -> posix
- `#!/bin/bash` or `#!/usr/bin/env bash` -> bash
- `#!/bin/mksh` -> mksh
#### indent
Controls indentation style:
```toml
# 2 spaces (common)
indent = 2
# 4 spaces
indent = 4
# Tabs (use 0)
indent = 0
```
#### binary-next-line
Controls binary operator positioning:
```toml
# Operators at end of line (default)
binary-next-line = false
```
```bash
# Result:
if [ "$a" = "foo" ] &&
[ "$b" = "bar" ]; then
echo "match"
fi
```
```toml
# Operators at start of next line
binary-next-line = true
```
```bash
# Result:
if [ "$a" = "foo" ] \
&& [ "$b" = "bar" ]; then
echo "match"
fi
```
#### switch-case-indent
Controls case statement indentation:
```toml
# Cases at same level as switch (default)
switch-case-indent = false
```
```bash
# Result:
case "$1" in
start)
do_start
;;
stop)
do_stop
;;
esac
```
```toml
# Cases indented inside switch
switch-case-indent = true
```
```bash
# Result:
case "$1" in
start)
do_start
;;
stop)
do_stop
;;
esac
```
#### space-redirects
Controls spacing around redirections:
```toml
# No space before redirect (default)
space-redirects = false
```
```bash
# Result:
echo "hello" >file.txt
cat <input.txt
```
```toml
# Space before redirect
space-redirects = true
```
```bash
# Result:
echo "hello" > file.txt
cat < input.txt
```
#### keep-padding
Preserves alignment padding:
```toml
# Remove extra alignment spaces (default)
keep-padding = false
```
```bash
# Input with alignment:
short="value"
longer_var="another"
# Result (alignment removed):
short="value"
longer_var="another"
```
```toml
# Preserve alignment
keep-padding = true
```
```bash
# Result (alignment kept):
short= "value"
longer_var="another"
```
#### func-next-line
Controls function brace placement:
```toml
# Opening brace on same line (default)
func-next-line = false
```
```bash
# Result:
my_function() {
echo "hello"
}
```
```toml
# Opening brace on next line
func-next-line = true
```
```bash
# Result:
my_function()
{
echo "hello"
}
```
## EditorConfig Integration
shfmt respects EditorConfig settings. Create or update `.editorconfig`:
```ini
# EditorConfig is awesome: https://EditorConfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.sh]
indent_style = space
indent_size = 2
# shfmt-specific options
shell_variant = bash
binary_next_line = true
switch_case_indent = true
space_redirects = false
keep_padding = false
function_next_line = false
```
### EditorConfig Option Mapping
| shfmt flag | EditorConfig key |
|------------|------------------|
| `-i` | `indent_size` (0 for tabs) |
| `-ln` | `shell_variant` |
| `-bn` | `binary_next_line` |
| `-ci` | `switch_case_indent` |
| `-sr` | `space_redirects` |
| `-kp` | `keep_padding` |
| `-fn` | `function_next_line` |
## Command-Line Flags
### Basic Usage
```bash
# Format file in place
shfmt -w script.sh
# Show diff of changes
shfmt -d script.sh
# List files that need formatting
shfmt -l .
# Format and output to stdout
shfmt script.sh
```
### Formatting Options
```bash
# Set indent to 4 spaces
shfmt -i 4 script.sh
# Use tabs for indentation
shfmt -i 0 script.sh
# Specify shell dialect
shfmt -ln bash script.sh
# Binary operators on next line
shfmt -bn script.sh
# Indent switch cases
shfmt -ci script.sh
# Space after redirects
shfmt -sr script.sh
# Preserve padding
shfmt -kp script.sh
# Function brace on next line
shfmt -fn script.sh
```
### Combined Example
```bash
# Common configuration
shfmt -i 2 -ci -bn -w script.sh
```
## Project Configuration Patterns
### Minimal Bash Project
```toml
# .shfmt.toml
shell = "bash"
indent = 2
```
### POSIX-Compliant Scripts
```toml
# .shfmt.toml
shell = "posix"
indent = 4
binary-next-line = false
switch-case-indent = false
```
### Modern Bash with All Features
```toml
# .shfmt.toml
shell = "bash"
indent = 2
binary-next-line = true
switch-case-indent = true
space-redirects = false
func-next-line = false
```
### Team Standardization
```toml
# .shfmt.toml - enforce team standards
shell = "bash"
indent = 2
binary-next-line = true
switch-case-indent = true
keep-padding = false
```
## CI/CD Integration
### GitHub Actions
```yaml
name: Shell Format Check
user-invocable: false
on: [push, pull_request]
jobs:
shfmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install shfmt
run: |
curl -sS https://webinstall.dev/shfmt | bash
export PATH="$HOME/.local/bin:$PATH"
- name: Check formatting
run: shfmt -d .
```
### Pre-commit Hook
```yaml
# .pre-commit-config.yaml
repos:
- repo: https://github.com/scop/pre-commit-shfmt
rev: v3.8.0-1
hooks:
- id: shfmt
args: ["-w"]
```
### Makefile Target
```makefile
.PHONY: fmt-check fmt
fmt-check:
shfmt -d .
fmt:
shfmt -w .
```
## Best Practices
1. **Commit Configuration** - Always commit `.shfmt.toml` for team consistency
2. **Match Dialect** - Set `shell` to match your script shebangs
3. **EditorConfig First** - Use EditorConfig for IDE integration
4. **CI Enforcement** - Run `shfmt -d` in CI to catch formatting issues
5. **Consistent Indentation** - Pick 2 or 4 spaces and stick with it
6. **Document Choices** - Add comments explaining non-default options
7. **Version Lock** - Pin shfmt version in CI for reproducibility
## Troubleshooting
### Configuration Not Applied
Check precedence order:
1. Command-line flags override everything
2. EditorConfig in file's directory
3. `.shfmt.toml` in project root
### Wrong Shell Dialect
Verify shebang matches configuration:
```bash
# If using shell = "bash", ensure scripts have:
#!/usr/bin/env bash
# or
#!/bin/bash
```
### EditorConfig Not Detected
Ensure EditorConfig file is in parent directory chain and has correct section:
```ini
[*.sh]
shell_variant = bash
```
## When to Use This Skill
- Setting up shfmt in new projects
- Configuring team-wide formatting standards
- Integrating shfmt with CI/CD pipelines
- Troubleshooting configuration issues
- Migrating between configuration methods
- Setting up EditorConfig for shell scripts
Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.