#web-framework #view #formatter #macro #cli #format #format-file

app leptosfmt

view macro formatter CLI for the Leptos web framework

18 releases

new 0.1.30 Jul 23, 2024
0.1.18 Dec 22, 2023
0.1.17 Oct 10, 2023
0.1.12 Jul 31, 2023
0.1.4 Mar 27, 2023

#1 in #view

Download history 346/week @ 2024-04-05 334/week @ 2024-04-12 453/week @ 2024-04-19 207/week @ 2024-04-26 407/week @ 2024-05-03 431/week @ 2024-05-10 403/week @ 2024-05-17 431/week @ 2024-05-24 428/week @ 2024-05-31 328/week @ 2024-06-07 427/week @ 2024-06-14 667/week @ 2024-06-21 487/week @ 2024-06-28 290/week @ 2024-07-05 369/week @ 2024-07-12 482/week @ 2024-07-19

1,728 downloads per month

MIT/Apache

110KB
2.5K SLoC

leptosfmt

crates.io build security discord

A formatter for the leptos view! macro

All notable changes are documented in: CHANGELOG.md

Install

cargo install leptosfmt

or for trying out unreleased features:

cargo install --git https://github.com/bram209/leptosfmt.git

Usage

Usage: leptosfmt [OPTIONS] [INPUT_PATTERNS]...

Arguments:
  [INPUT_PATTERNS]...  A space separated list of file, directory or glob

Options:
  -m, --max-width <MAX_WIDTH>
          Maximum width of each line
  -t, --tab-spaces <TAB_SPACES>
          Number of spaces per tab
  -c, --config-file <CONFIG_FILE>
          Configuration file
  -s, --stdin
          Format stdin and write to stdout
  -r, --rustfmt
          Format with rustfmt after formatting with leptosfmt (requires stdin)
      --override-macro-names <OVERRIDE_MACRO_NAMES>...
          Override formatted macro names
  -e, --experimental-tailwind
          Format attributes with tailwind
      --tailwind-attr-names <TAILWIND_ATTR_NAMES>...
          Override attributes to be formatted with tailwind [default: class]
  -q, --quiet

      --check
          Check if the file is correctly formatted. Exit with code 1 if not
  -h, --help
          Print help
  -V, --version
          Print version

Using with Rust Analyzer

You can set the rust-analyzer.rustfmt.overrideCommand setting.

  "rust-analyzer.rustfmt.overrideCommand": ["leptosfmt", "--stdin", "--rustfmt"]

And you must configure rustfmt to use the correct edition, place a rustfmt.toml file in the root of your project:

edition = "2021"
# (optional) other config...

Note: For VSCode users, I recommend to use workpsace settings (CMD + shift + p -> Open workspace settings), so that you can only configure leptosfmt for workpsaces that are using leptos. For Neovim users, I recommend using neoconf.nvim for managing project-local LSP configuration.

Setting up with unstable directory based rust-analyzer configuration

An alternative way to configure rust-analyzer to use leptosfmt is to use directory based rust-analyzer configuration.

To do this, create a file named rust-analyzer.toml in the root of your project with the following content:

[rustfmt] 
overrideCommand = ["leptosfmt", "--stdin", "--rustfmt"]
# (optional) other config...

This method of setting up rust-analyzer is editor agnostic to any editor that uses rust-analyzer for formatting rust code

Note: This feature of rust-analyzer is currently unstable and no guarantees are made that this will continue to work across versions. You have to use a recent version of rust-analyzer (2024-06-10 or newer).

Configuration

You can configure all settings through a leptosfmt.toml file.

max_width = 100 # Maximum width of each line
tab_spaces = 4 # Number of spaces per tab
indentation_style = "Auto" # "Tabs", "Spaces" or "Auto"
newline_style = "Auto" # "Unix", "Windows" or "Auto"
attr_value_brace_style = "WhenRequired" # "Always", "AlwaysUnlessLit", "WhenRequired" or "Preserve"
macro_names = [ "leptos::view", "view" ] # Macro names which will be formatted
closing_tag_style = "Preserve" # "Preserve", "SelfClosing" or "NonSelfClosing"

# Attribute values can be formatted by custom formatters
# Every attribute name may only select one formatter (this might change later on)
[attr_values]
class = "Tailwind" # "Tailwind" is the only attribute value formatter available for now

To see what each setting does, the see configuration docs

Examples

Single file

Format a specific file by name

leptosfmt ./examples/counter/src/lib.rs

Current directory

Format all .rs files within the current directory

leptosfmt .

Directory

Format all .rs files within the examples directory

leptosfmt ./examples

Glob

Format all .rs files ending with _test.rs within the examples directory

leptosfmt ./examples/**/*_test.rs

A note on non-doc comments

Currently this formatter does not support non-doc comments in code blocks. It uses a fork of prettyplease for formatting rust code, and prettyplease does not support this. I would like to not diverge this fork too much (so I can easily keep in sync with upstream), therefore I didn't add non-doc comment support in my prettyplease fork for now. This means that you can use non-doc comments throughout your view macro, as long as they don't reside within code blocks.

A bit more context: prettyplease uses syn to parse rust syntax. According to https://doc.rust-lang.org/reference/comments.html#non-doc-comments non-doc comments are interpreted as a form of whitespace by the parser; syn basically ignores/skips these comments and does not include them in the syntax tree.

Pretty-printer algorithm

The pretty-printer is based on Philip Karlton’s Mesa pretty-printer, as described in the appendix to Derek C. Oppen, “Pretty Printing” (1979), Stanford Computer Science Department STAN-CS-79-770, http://i.stanford.edu/pub/cstr/reports/cs/tr/79/770/CS-TR-79-770.pdf. This algorithm's implementation is taken from prettyplease which is adapted from rustc_ast_pretty.

The algorithm takes from an input stream of length n and an output device with margin width m, the algorithm requires time O(n) and space O(m). The algorithm is described in terms of two parallel processes; the first scans the input stream to determine the space required to print logical blocks of tokens; the second uses this information to decide where to break lines of text; the two processes communicate by means of a buffer of size o(m). The algorithm does not wait for the entire stream to be input, but begins printing as soon as it has received a linefull of input.

Dependencies

~8–17MB
~225K SLoC