nufmt is a formatter for Nushell scripts, built entirely on Nushell's own parsing infrastructure (nu-parser, nu-protocol). It provides:
cargo install --git https://github.com/nushell/nufmt
nix run github:nushell/nufmt
nufmt [OPTIONS] [FILES]...
Format one or more Nushell files:
# Format a single file
nufmt script.nu
# Format multiple files
nufmt file1.nu file2.nu file3.nu
# Format all .nu files in a directory
nufmt src/
| Option | Short | Description |
|---|---|---|
--dry-run | Check files without modifying them. Returns exit code 1 if files would be reformatted. | |
--stdin | Read from stdin and write formatted output to stdout. Cannot be combined with file arguments. | |
--config | -c | Path to a configuration file (NUON format). |
--help | -h | Show help and exit. |
--version | -v | Print version and exit. |
# Format files in place
nufmt *.nu
# Check if files need formatting (CI mode)
nufmt --dry-run src/
# Format stdin
echo 'let x=1' | nufmt --stdin
# Use custom config
nufmt --config nufmt.nuon src/
Create a nufmt.nuon file in your project root:
{
indent: 4
indent_char: "space"
line_length: 80
margin: 1
exclude: ["vendor/**", "target/**"]
}
Configuration options:
| Option | Type | Default | Description |
|---|---|---|---|
indent | int | 4 | Visual indentation width per level (tab width when indent_char = "tab") |
indent_char | string | "space" | Indentation character: "space" or "tab" |
line_length | int | 80 | Maximum line length (advisory) |
margin | int | 1 | Number of blank lines between top-level items |
exclude | list<string> | [] | Glob patterns for files to exclude |
| Code | Description |
|---|---|
| 0 | Success (files formatted or already formatted) |
| 1 | Dry-run mode: at least one file would be reformatted |
| 2 | Error: invalid configuration, CLI options, or parse error |
nufmt properly formats the following Nushell constructs:
let, mut, const)def, def-env, export def)if/else, match, for, while, loop)|{|x| ... })$"Hello ($name)")module, use, export)try/catch)1..10, 1..2..10)Unlike tree-sitter based formatters, nufmt uses Nushell's own nu-parser crate to parse scripts into an AST. This ensures:
The formatter walks the AST and emits properly formatted code with consistent:
nufmt has a comprehensive ground truth testing system that verifies the formatter produces correct output for all supported Nushell constructs.
The testing system uses two sets of fixture files:
tests/fixtures/input/): Contain valid Nushell code with intentional formatting issues (extra spaces, inconsistent indentation, etc.)tests/fixtures/expected/): Contain the correctly formatted version of each input fileWhen tests run, the formatter processes each input file and compares the output against the corresponding expected file. This ensures:
Important: Input files should always differ from expected files. Input files represent "what not to do" - poorly formatted but valid Nushell code that the formatter should fix.
Tests are organized by Nushell construct category:
| Category | Constructs |
|---|---|
core | let_statement, mut_statement, const_statement, def_statement |
control_flow | if_else, for_loop, while_loop, loop_statement, match_expr, try_catch, break_continue, return_statement |
data_structures | list, record, table, nested_structures |
pipelines_expressions | pipeline, multiline_pipeline, closure, subexpression, binary_ops, range, cell_path, spread |
strings_interpolation | string_interpolation, comment |
types_values | value_with_unit, datetime, nothing, glob_pattern |
modules_imports | module, use_statement, export, source, hide, overlay |
commands_definitions | alias, extern, external_call |
special_constructs | do_block, where_clause, error_make |
# Run all tests (unit + ground truth + idempotency)
cargo test
# Run only ground truth tests
cargo test --test ground_truth
# Run with verbose output
cargo test -- --nocapture
A Nushell script (tests/run_ground_truth_tests.nu) provides a more interactive testing experience:
# Build the release binary first
cargo build --release
# Run all tests
nu tests/run_ground_truth_tests.nu
# Run with verbose output (show diffs on failure)
nu tests/run_ground_truth_tests.nu --verbose
# Run only ground truth tests (skip idempotency)
nu tests/run_ground_truth_tests.nu --ground-truth
# Run only idempotency tests
nu tests/run_ground_truth_tests.nu --idempotency
# Run tests for a specific category
nu tests/run_ground_truth_tests.nu --category control_flow
# Run a single test
nu tests/run_ground_truth_tests.nu --test let_statement
# List all available tests
nu tests/run_ground_truth_tests.nu --list
# List available categories
nu tests/run_ground_truth_tests.nu --list-categories
# Check which test files exist
nu tests/run_ground_truth_tests.nu --check-files
To add a test for a new construct:
tests/fixtures/input/<construct_name>.nu with poorly-formatted but valid Nushell codetests/fixtures/expected/<construct_name>.nu with the correctly formatted versiontests/run_ground_truth_tests.nuExample input file (tests/fixtures/input/my_construct.nu):
let x = 1
let y = 2
Example expected file (tests/fixtures/expected/my_construct.nu):
let x = 1
let y = 2
Contributions are welcome! Please see our contribution guide.
If you encounter formatting issues, please:
nufmt version and Nushell versionMIT License - see LICENSE for details.
Rust
77.7%
Nushell
21.3%
nufmt is a formatter for Nushell scripts, built entirely on Nushell's own parsing infrastructure (nu-parser, nu-protocol). It provides:
cargo install --git https://github.com/nushell/nufmt
nix run github:nushell/nufmt
nufmt [OPTIONS] [FILES]...
Format one or more Nushell files:
# Format a single file
nufmt script.nu
# Format multiple files
nufmt file1.nu file2.nu file3.nu
# Format all .nu files in a directory
nufmt src/
| Option | Short | Description |
|---|---|---|
--dry-run | Check files without modifying them. Returns exit code 1 if files would be reformatted. | |
--stdin | Read from stdin and write formatted output to stdout. Cannot be combined with file arguments. | |
--config | -c | Path to a configuration file (NUON format). |
--help | -h | Show help and exit. |
--version | -v | Print version and exit. |
# Format files in place
nufmt *.nu
# Check if files need formatting (CI mode)
nufmt --dry-run src/
# Format stdin
echo 'let x=1' | nufmt --stdin
# Use custom config
nufmt --config nufmt.nuon src/
Create a nufmt.nuon file in your project root:
{
indent: 4
indent_char: "space"
line_length: 80
margin: 1
exclude: ["vendor/**", "target/**"]
}
Configuration options:
| Option | Type | Default | Description |
|---|---|---|---|
indent | int | 4 | Visual indentation width per level (tab width when indent_char = "tab") |
indent_char | string | "space" | Indentation character: "space" or "tab" |
line_length | int | 80 | Maximum line length (advisory) |
margin | int | 1 | Number of blank lines between top-level items |
exclude | list<string> | [] | Glob patterns for files to exclude |
| Code | Description |
|---|---|
| 0 | Success (files formatted or already formatted) |
| 1 | Dry-run mode: at least one file would be reformatted |
| 2 | Error: invalid configuration, CLI options, or parse error |
nufmt properly formats the following Nushell constructs:
let, mut, const)def, def-env, export def)if/else, match, for, while, loop)|{|x| ... })$"Hello ($name)")module, use, export)try/catch)1..10, 1..2..10)Unlike tree-sitter based formatters, nufmt uses Nushell's own nu-parser crate to parse scripts into an AST. This ensures:
The formatter walks the AST and emits properly formatted code with consistent:
nufmt has a comprehensive ground truth testing system that verifies the formatter produces correct output for all supported Nushell constructs.
The testing system uses two sets of fixture files:
tests/fixtures/input/): Contain valid Nushell code with intentional formatting issues (extra spaces, inconsistent indentation, etc.)tests/fixtures/expected/): Contain the correctly formatted version of each input fileWhen tests run, the formatter processes each input file and compares the output against the corresponding expected file. This ensures:
Important: Input files should always differ from expected files. Input files represent "what not to do" - poorly formatted but valid Nushell code that the formatter should fix.
Tests are organized by Nushell construct category:
| Category | Constructs |
|---|---|
core | let_statement, mut_statement, const_statement, def_statement |
control_flow | if_else, for_loop, while_loop, loop_statement, match_expr, try_catch, break_continue, return_statement |
data_structures | list, record, table, nested_structures |
pipelines_expressions | pipeline, multiline_pipeline, closure, subexpression, binary_ops, range, cell_path, spread |
strings_interpolation | string_interpolation, comment |
types_values | value_with_unit, datetime, nothing, glob_pattern |
modules_imports | module, use_statement, export, source, hide, overlay |
commands_definitions | alias, extern, external_call |
special_constructs | do_block, where_clause, error_make |
# Run all tests (unit + ground truth + idempotency)
cargo test
# Run only ground truth tests
cargo test --test ground_truth
# Run with verbose output
cargo test -- --nocapture
A Nushell script (tests/run_ground_truth_tests.nu) provides a more interactive testing experience:
# Build the release binary first
cargo build --release
# Run all tests
nu tests/run_ground_truth_tests.nu
# Run with verbose output (show diffs on failure)
nu tests/run_ground_truth_tests.nu --verbose
# Run only ground truth tests (skip idempotency)
nu tests/run_ground_truth_tests.nu --ground-truth
# Run only idempotency tests
nu tests/run_ground_truth_tests.nu --idempotency
# Run tests for a specific category
nu tests/run_ground_truth_tests.nu --category control_flow
# Run a single test
nu tests/run_ground_truth_tests.nu --test let_statement
# List all available tests
nu tests/run_ground_truth_tests.nu --list
# List available categories
nu tests/run_ground_truth_tests.nu --list-categories
# Check which test files exist
nu tests/run_ground_truth_tests.nu --check-files
To add a test for a new construct:
tests/fixtures/input/<construct_name>.nu with poorly-formatted but valid Nushell codetests/fixtures/expected/<construct_name>.nu with the correctly formatted versiontests/run_ground_truth_tests.nuExample input file (tests/fixtures/input/my_construct.nu):
let x = 1
let y = 2
Example expected file (tests/fixtures/expected/my_construct.nu):
let x = 1
let y = 2
Contributions are welcome! Please see our contribution guide.
If you encounter formatting issues, please:
nufmt version and Nushell versionMIT License - see LICENSE for details.
Rust
77.7%
Nushell
21.3%