Skip to content

blindFS/topiary-nushell

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

73 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Format nushell with Topiary

Build Status

  • Topiary: tree-sitter based uniform formatter
  • This repo contains:
    • languages.ncl: configuration that enables nushell
    • nu.scm: tree-sitter query DSL that defines the behavior of the formatter for nushell
    • stand-alone tests written in nushell

Status

  • Supposed to work well with all language features of nushell v0.107
    • Except for some known issues of tree-sitter-nu

Note

  • There're corner cases where tree-sitter-nu would fail with parsing errors, if you encounter any, feel free to report at the parser side.
  • If you encounter any style/format issue, please report in this repo.

Setup

  1. Install topiary-cli using whatever package-manager on your system (0.6.1+ required)
# e.g. installing with cargo
cargo install topiary-cli
  1. Clone this repo somewhere
# e.g. to `$env.XDG_CONFIG_HOME/topiary`
git clone https://github.com/blindFS/topiary-nushell ($env.XDG_CONFIG_HOME | path join topiary)
  1. Setup environment variables (Optional)

Warning

This is required if you want to do the formatting via vanilla topiary-cli, like in the neovim/helix settings below.

While the format.nu script in this repo just wraps that for you.

# Set environment variables according to the path of the clone
$env.TOPIARY_CONFIG_FILE = ($env.XDG_CONFIG_HOME | path join topiary languages.ncl)
$env.TOPIARY_LANGUAGE_DIR = ($env.XDG_CONFIG_HOME | path join topiary languages)

Warning

For windows users, if something went wrong the first time you run the formatter, like compiling errors, you might need the following extra steps to make it work.

Optional for Windows
  1. Install the tree-sitter-cli.
  2. Clone tree-sitter-nu somewhere and cd into it.
  3. Build the parser manually with tree-sitter build.
  4. Replace the languages.ncl file in this repo with something like:
{
  languages = {
    nu = {
      extensions = ["nu"],
      grammar.source.path = "C:/path/to/tree-sitter-nu/nu.dll",
      symbol = "tree_sitter_nu",
    },
  },
}

Usage

Using the format.nu wrapper
Helper to run topiary with the correct environment variables for topiary-nushell

Usage:
  > format.nu {flags} ...(files)

Flags:
  -c, --config_dir <path>: Root of the topiary-nushell repo, defaults to the parent directory of this script
  -h, --help: Display the help message for this command

Parameters:
  ...files <path>: Files to format

Input/output types:
  ╭───┬─────────┬─────────╮
  │ # │  input  │ output  │
  ├───┼─────────┼─────────┤
  │ 0 │ nothing │ nothing │
  │ 1 │ string  │ string  │
  ╰───┴─────────┴─────────╯

Examples:
  Read from stdin
  > bat foo.nu | format.nu

  Format files (in-place replacement)
  > format.nu foo.nu bar.nu

  Path overriding
  > format.nu -c /path/to/topiary-nushell foo.nu bar.nu
Using topiary-cli
# in-place formatting
topiary format script.nu
# stdin -> stdout
cat foo.nu | topiary format --language nu

Locally Disable Formatting for Certain Expression

If you don't like the formatted output of certain parts of your code, you can choose to disable it locally with a preceding topiary: disable comment:

...
# topiary: disable
let foo = [foo, bar
  baz, ]
...

This will keep the let assignment as it is while formatting the rest of the code.

Note

We do recommend reporting code style issues before resorting to this workaround.

Editor Integration

Neovim Format on save with conform.nvim:
-- lazy.nvim setup
{
  "stevearc/conform.nvim",
  dependencies = { "mason.nvim" },
  event = "VeryLazy",
  opts = {
    formatters_by_ft = {
      nu = { "topiary_nu" },
    },
    formatters = {
      topiary_nu = {
        command = "topiary",
        args = { "format", "--language", "nu" },
      },
    },
  },
},
Helix

To format on save in Helix, add this configuration to your helix/languages.toml.

[[language]]
name = "nu"
auto-format = true
formatter = { command = "topiary", args = ["format", "--language", "nu"] }
Zed
"languages": {
  "Nu": {
    "formatter": {
      "external": {
        "command": "/path-to-the-clone/format.nu"
      }
    },
    "format_on_save": "on"
  }
}

Contribute

Important

Help to find format issues with following method (dry-run, detects parsing/idempotence/semantic breaking):

source toolkit.nu
test_format <root-path-of-your-nushell-scripts>