Skip to content

feat: support range formatting - #70

Merged
dsherret merged 3 commits into
mainfrom
feat_range_formatting
Sep 27, 2026
Merged

dsherret merged 3 commits into
mainfrom
feat_range_formatting

Conversation

@dsherret

Copy link
Copy Markdown
Member

Adds range formatting (ex. an editor's "format selection").

How it works

format_text_range finds the innermost object or array containing the range and the properties or elements the range touches. It formats the whole file as usual, finds the same members in the output by path (property name and occurrence, or array index), and replaces only the lines those members are on. So the first member's indentation, the separator after the last one and its trailing comment get formatted too, while everything else is left as written.

It widens further when replacing just those lines would give a wrong or inconsistent result:

  • the members are reordered (ex. package.json conventions), or the line breaks around them change (ex. an object collapsing to a single line): the member holding their object or array is replaced instead, and so on out to the whole file
  • a replaced member would gain or lose its neighbouring separator (ex. package.json conventions move it to the end): widens the same way
  • the separator is on the other side of a line break (comma-first style): replaces up to the neighbouring member instead of the line

A range reaching the root value's brackets formats the whole file, and one entirely outside the root value (ex. a leading comment) changes nothing. The replaced text uses the file's existing line endings, since changing those is a whole-file concern.

wasm_plugin.rs now passes request.range to format_text_range instead of formatting the whole file.

Tests

Spec files in tests/specs/range use the new [|/|] range markers from dprint-development 0.12 (dprint/dprint#1255). The BOM and line ending cases are unit tests since spec files can't express them.

I also ran a throwaway brute-force check of ~3.5M ranges across all spec inputs and 15 configs: no panics, results always parse to the same values, and the only non-idempotent cases come from an existing full-format bug with preferSingleLine and trailing comments, unrelated to this change.

Formats only the object properties or array elements that a range touches
within the innermost object or array containing it, leaving the rest of
the file as written. The whole object or array is formatted when its
members would be reordered (ex. package.json conventions) or the line
breaks around them change, and the whole file when the range reaches the
root value's brackets.
Replacing only the touched members left their indentation, separators and
trailing comments unformatted, so a selected line kept a wrong indent, a
multi-line member came out indented inconsistently and trailing commas
weren't added or removed. The lines of the members are replaced instead,
widening to the member holding their object or array when the line breaks
around them change and keeping the file's line endings.

Also leaves a range outside the root value unformatted.
@dsherret
dsherret merged commit fb8177f into main Sep 27, 2026
2 checks passed
@dsherret
dsherret deleted the feat_range_formatting branch September 27, 2026 22:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant