This provides an opinionated source code formatter for the Spicy language.
$ spicy-format --help
Usage:
Arguments:
[INPUT_FILES]...
if not provided read input from stdin
Options:
-s, --skip-idempotence
skip idempotency check
-r, --reject-parse-errors
reject inputs with parse errors
-i, --inplace
format file in place
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
Navigate to the latest release and run the mentioned installation script, e.g.,
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/bbannier/spicy-format/releases/download/v0.25.0/spicy-format-installer.sh | sh
Follow the printed instructions. This will install both the formatter
spicy-format itself as well as an updater script spicy-format-update which
can be used to update to newer releases.
Alternatively you can also download prebuilt binaries and updaters on the release page.
If no binaries are available for you platform you need to install from source. This requires a Rust installation, use e.g., rustup for setting one up.
You can then install the project with
cargo install --locked --git https://github.com/bbannier/spicy-format
It is strongly suggested to use --locked to use dependency versions locked
in the project.
This formatter is implemented in Rust with
Topiary. It uses
tree-sitter-spicy for parsing
input source code into a tree-sitter CST. Formatting of that CST is done
through Topiary queries. The actual
queries are defined in src/query.scm. Most of the time
changing the formatter should not require any changes to the Rust code, but
only to the query file.
To change formatting of certain nodes it might often be sufficient to inspect
the Spicy tree-sitter
grammar
and change formatting of the nodes in src/query.scm.
To instead inspect the full parse trees of code samples check out tree-sitter-spicy and use it to parse the code, e.g.,
# Get Spicy tree-sitter grammar.
git clone https://github.com/bbannier/tree-sitter-spicy
$ cd tree-sitter-spicy
# If needed install the tree-sitter CLI.
$ npm install tree-sitter
# Use tree-sitter to parse a source file.
$ tree-sitter parse hello.spicy
(module [0, 0] - [3, 0]
entities: (module_decl [0, 0] - [0, 13]
name: (ident [0, 7] - [0, 12]
(name [0, 7] - [0, 12])))
entities: (statement [2, 0] - [2, 18]
(print [2, 0] - [2, 18]
(expression [2, 6] - [2, 17]
(string [2, 6] - [2, 17])))))
Use this information to write dedicated formatter queries.
If the grammar does not have support for constructs or incorrectly parses
them the grammar needs to be updated and bumped. The used version of the
grammar is specified in
Cargo.toml,
[dependencies]
tree-sitter-spicy = { git = "https://github.com/bbannier/tree-sitter-spicy" }
...You can specify a different repository here, or enforce a specific revision, e.g.,
tree-sitter-spicy = { git = "https://github.com/MY_FORK/tree-sitter-spicy", rev = "b9958baeda3dc77fa94af2ca2cd84723bd532d08" }In order to use a unpublished local version you can replace the dependency with a path dependency, e.g.,
tree-sitter-spicy = { path = "path/to/local/version" }To run formatting against an external corpus run the test suite with
SPICY_FORMAT_EXTERNAL_CORPUS set.
SPICY_FORMAT_EXTERNAL_CORPUS=<PATH TO SPICY CORPUS> cargo t corpus_external
The suite automatically filters out of some files in the Spicy test suite with known unsupported constructs.