Skip to content
Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
59a5f74
feat(formatter): add delimiterSpacing option to JS/JSON/CSS formatters
luisherranz Jan 29, 2026
f754e26
feat(js-formatter): implement delimiterSpacing for JavaScript and Typ…
luisherranz Jan 29, 2026
d8302de
feat(json-formatter): implement delimiterSpacing for JSON
luisherranz Jan 29, 2026
641722b
feat(css-formatter): implement delimiterSpacing for CSS
luisherranz Jan 29, 2026
6ba2609
test(formatter): update existing snapshots with delimiterSpacing option
luisherranz Jan 29, 2026
d6dcc8a
test(formatter): add delimiter-spacing tests
luisherranz Jan 29, 2026
410d399
feat(service): integrate delimiterSpacing into Biome service layer
luisherranz Jan 29, 2026
566c5c6
[autofix.ci] apply automated fixes
autofix-ci[bot] Feb 5, 2026
a91e20b
test(js-formatter): add setters with trailing commas in delimiter spa…
luisherranz Feb 9, 2026
2f33fc6
Merge remote-tracking branch 'upstream/next' into feat/delimiter-spac…
luisherranz Feb 18, 2026
bea1683
feat(migrate): update unsupported rules to mention the new delimiterS…
luisherranz Mar 12, 2026
a8764f7
[autofix.ci] apply automated fixes
autofix-ci[bot] Mar 12, 2026
ef5fe9c
feat(formatter): enhance delimiterSpacing option descriptions for cla…
luisherranz Mar 16, 2026
51143d0
fix cli snapshots
luisherranz Mar 17, 2026
6415613
fix new formatter test snapshots
luisherranz Mar 17, 2026
036ba1f
fix new formatter test snapshots
luisherranz Mar 17, 2026
8ea460f
fix improve docs to be more precise
luisherranz Mar 18, 2026
368cb01
Merge branch 'next' into feat/delimiter-spacing-option
luisherranz Mar 18, 2026
8183dfb
fix cli snapshot tests
luisherranz Mar 18, 2026
caa8629
fix: add default delimiter spacing option to SCSS snapshots
luisherranz Mar 19, 2026
40d1732
fix: add default delimiter spacing option to new CSS snapshot
luisherranz Mar 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
26 changes: 26 additions & 0 deletions .changeset/delimiter-spacing-option.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
"@biomejs/biome": minor
---

Added the `delimiterSpacing` formatter option. This option inserts spaces inside delimiters. Affects parentheses `()`, square brackets `[]`, TypeScript angle brackets `<>`, and JSX curly braces `{}`. It can be configured globally via `formatter.delimiterSpacing` or per-language via `javascript.formatter.delimiterSpacing`, `json.formatter.delimiterSpacing`, and `css.formatter.delimiterSpacing`. Defaults to false.

**JavaScript:**

```diff
- if (condition) {}
+ if ( condition ) {}
```

**JSON:**

```diff
- [1, 2, 3]
+ [ 1, 2, 3 ]
```

**CSS:**

```diff
- rgba(0, 0, 0, 1)
+ rgba( 0, 0, 0, 1 )
```
2 changes: 2 additions & 0 deletions crates/biome_cli/src/execute/migrate/prettier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ impl TryFrom<PrettierConfiguration> for biome_configuration::Configuration {
bracket_same_line: Some(value.bracket_line.into()),
attribute_position: Some(AttributePosition::default()),
bracket_spacing: Some(BracketSpacing::default()),
delimiter_spacing: None,
expand: Some(value.object_wrap.into()),
format_with_errors: Some(false.into()),
includes: None,
Expand Down Expand Up @@ -276,6 +277,7 @@ impl TryFrom<PrettierConfiguration> for biome_configuration::Configuration {
quote_style: Some(quote_style),
quote_properties: Some(value.quote_props.into()),
bracket_spacing: Some(value.bracket_spacing.into()),
delimiter_spacing: None,
jsx_quote_style: Some(jsx_quote_style),
attribute_position: Some(AttributePosition::default()),
operator_linebreak: None,
Expand Down
89 changes: 89 additions & 0 deletions crates/biome_cli/tests/commands/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ const APPLY_BRACKET_SPACING_AFTER_GRAPHQL: &str = r#"{
}
"#;

const APPLY_DELIMITER_SPACING_BEFORE: &str = r#"const arr = [1, 2, 3];
function foo(a, b) {}
"#;

const APPLY_DELIMITER_SPACING_AFTER: &str = r#"const arr = [ 1, 2, 3 ];
function foo( a, b ) {}
"#;

const APPLY_BRACKET_SAME_LINE_BEFORE: &str = r#"<Foo
className={style}
reallyLongAttributeName1={longComplexValue}
Expand Down Expand Up @@ -869,6 +877,87 @@ fn applies_custom_bracket_spacing() {
));
}

#[test]
fn applies_global_delimiter_spacing() {
let fs = MemoryFileSystem::default();
let mut console = BufferConsole::default();

let file_path = Utf8Path::new("file.js");
fs.insert(file_path.into(), APPLY_DELIMITER_SPACING_BEFORE.as_bytes());

let (fs, result) = run_cli(
fs,
&mut console,
Args::from(
[
"format",
"--delimiter-spacing",
"true",
"--write",
file_path.as_str(),
]
.as_slice(),
),
);

assert!(result.is_ok(), "run_cli returned {result:?}");

assert_file_contents(&fs, file_path, APPLY_DELIMITER_SPACING_AFTER);

assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"applies_global_delimiter_spacing",
fs,
console,
result,
));
}

#[test]
fn language_overrides_global_delimiter_spacing() {
let fs = MemoryFileSystem::default();
let mut console = BufferConsole::default();

let config_path = Utf8Path::new("biome.json");
fs.insert(
config_path.into(),
r#"{
"formatter": {
"delimiterSpacing": true
},
"javascript": {
"formatter": {
"delimiterSpacing": false
}
}
}
"#
.as_bytes(),
);

let file_path = Utf8Path::new("file.js");
fs.insert(file_path.into(), APPLY_DELIMITER_SPACING_AFTER.as_bytes());

let (fs, result) = run_cli(
fs,
&mut console,
Args::from(["format", "--write", file_path.as_str()].as_slice()),
);

assert!(result.is_ok(), "run_cli returned {result:?}");

// JS overrides global, so no spaces should be present (delimiterSpacing: false)
assert_file_contents(&fs, file_path, APPLY_DELIMITER_SPACING_BEFORE);

assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"language_overrides_global_delimiter_spacing",
fs,
console,
result,
));
}

#[test]
fn applies_custom_bracket_same_line() {
let fs = MemoryFileSystem::default();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ The configuration that is contained inside the file `biome.json`
apply to self closing elements).
--bracket-spacing=<true|false> Whether to insert spaces around brackets in object literals.
Defaults to true.
--delimiter-spacing=<true|false> Whether to insert spaces inside delimiters. Affects
parentheses `()`, square brackets `[]`, TypeScript angle brackets
`<>`, and JSX curly braces `{}`. Defaults to false.
--expand=<auto|always|never> Whether to expand arrays and objects on multiple lines. When
set to `auto`, object literals are formatted on multiple lines if the
first property has a newline, and array literals are formatted on a
Expand Down Expand Up @@ -99,6 +102,9 @@ The configuration that is contained inside the file `biome.json`
JSX elements. Defaults to auto.
--javascript-formatter-bracket-spacing=<true|false> Whether to insert spaces around
brackets in object literals. Defaults to true.
--javascript-formatter-delimiter-spacing=<true|false> Whether to insert spaces inside
delimiters. Affects parentheses `()`, square brackets `[]`, TypeScript
angle brackets `<>`, and JSX curly braces `{}`. Defaults to false.
--javascript-formatter-expand=<auto|always|never> Whether to expand arrays and objects on
multiple lines. When set to `auto`, object literals are formatted on
multiple lines if the first property has a newline, and array literals
Expand Down Expand Up @@ -152,6 +158,8 @@ The configuration that is contained inside the file `biome.json`
Defaults to "auto".
--json-formatter-bracket-spacing=<true|false> Whether to insert spaces around brackets in
object literals. Defaults to true.
--json-formatter-delimiter-spacing=<true|false> Whether to insert spaces inside square
brackets `[]`. Defaults to false.
--json-formatter-trailing-newline=<true|false> Whether to add a trailing newline at the end
of the file.
Setting this option to `false` is **highly discouraged** because it
Expand Down Expand Up @@ -183,6 +191,8 @@ The configuration that is contained inside the file `biome.json`
super languages) files. Defaults to 80.
--css-formatter-quote-style=<double|single> The type of quotes used in CSS code. Defaults
to double.
--css-formatter-delimiter-spacing=<true|false> Whether to insert spaces inside delimiters.
Affects parentheses `()` and square brackets `[]`. Defaults to false.
--css-formatter-trailing-newline=<true|false> Whether to add a trailing newline at the end
of the file.
Setting this option to `false` is **highly discouraged** because it
Expand Down
10 changes: 10 additions & 0 deletions crates/biome_cli/tests/snapshots/main_commands_ci/ci_help.snap
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ The configuration that is contained inside the file `biome.json`
apply to self closing elements).
--bracket-spacing=<true|false> Whether to insert spaces around brackets in object literals.
Defaults to true.
--delimiter-spacing=<true|false> Whether to insert spaces inside delimiters. Affects
parentheses `()`, square brackets `[]`, TypeScript angle brackets
`<>`, and JSX curly braces `{}`. Defaults to false.
--expand=<auto|always|never> Whether to expand arrays and objects on multiple lines. When
set to `auto`, object literals are formatted on multiple lines if the
first property has a newline, and array literals are formatted on a
Expand Down Expand Up @@ -100,6 +103,9 @@ The configuration that is contained inside the file `biome.json`
JSX elements. Defaults to auto.
--javascript-formatter-bracket-spacing=<true|false> Whether to insert spaces around
brackets in object literals. Defaults to true.
--javascript-formatter-delimiter-spacing=<true|false> Whether to insert spaces inside
delimiters. Affects parentheses `()`, square brackets `[]`, TypeScript
angle brackets `<>`, and JSX curly braces `{}`. Defaults to false.
--javascript-formatter-expand=<auto|always|never> Whether to expand arrays and objects on
multiple lines. When set to `auto`, object literals are formatted on
multiple lines if the first property has a newline, and array literals
Expand Down Expand Up @@ -153,6 +159,8 @@ The configuration that is contained inside the file `biome.json`
Defaults to "auto".
--json-formatter-bracket-spacing=<true|false> Whether to insert spaces around brackets in
object literals. Defaults to true.
--json-formatter-delimiter-spacing=<true|false> Whether to insert spaces inside square
brackets `[]`. Defaults to false.
--json-formatter-trailing-newline=<true|false> Whether to add a trailing newline at the end
of the file.
Setting this option to `false` is **highly discouraged** because it
Expand Down Expand Up @@ -184,6 +192,8 @@ The configuration that is contained inside the file `biome.json`
super languages) files. Defaults to 80.
--css-formatter-quote-style=<double|single> The type of quotes used in CSS code. Defaults
to double.
--css-formatter-delimiter-spacing=<true|false> Whether to insert spaces inside delimiters.
Affects parentheses `()` and square brackets `[]`. Defaults to false.
--css-formatter-trailing-newline=<true|false> Whether to add a trailing newline at the end
of the file.
Setting this option to `false` is **highly discouraged** because it
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
source: crates/biome_cli/tests/snap_test.rs
expression: redactor(content)
---
## `file.js`

```js
const arr = [ 1, 2, 3 ];
function foo( a, b ) {}

```

# Emitted Messages

```block
Formatted 1 file in <TIME>. Fixed 1 file.
```
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ Generic options applied to all files
apply to self closing elements).
--bracket-spacing=<true|false> Whether to insert spaces around brackets in object literals.
Defaults to true.
--delimiter-spacing=<true|false> Whether to insert spaces inside delimiters. Affects
parentheses `()`, square brackets `[]`, TypeScript angle brackets
`<>`, and JSX curly braces `{}`. Defaults to false.
--expand=<auto|always|never> Whether to expand arrays and objects on multiple lines. When
set to `auto`, object literals are formatted on multiple lines if the
first property has a newline, and array literals are formatted on a
Expand Down Expand Up @@ -75,6 +78,9 @@ Formatting options specific to the JavaScript files
JSX elements. Defaults to auto.
--javascript-formatter-bracket-spacing=<true|false> Whether to insert spaces around
brackets in object literals. Defaults to true.
--javascript-formatter-delimiter-spacing=<true|false> Whether to insert spaces inside
delimiters. Affects parentheses `()`, square brackets `[]`, TypeScript
angle brackets `<>`, and JSX curly braces `{}`. Defaults to false.
--javascript-formatter-expand=<auto|always|never> Whether to expand arrays and objects on
multiple lines. When set to `auto`, object literals are formatted on
multiple lines if the first property has a newline, and array literals
Expand Down Expand Up @@ -147,6 +153,8 @@ Options that changes how the CSS formatter behaves
super languages) files. Defaults to 80.
--css-formatter-quote-style=<double|single> The type of quotes used in CSS code. Defaults
to double.
--css-formatter-delimiter-spacing=<true|false> Whether to insert spaces inside delimiters.
Affects parentheses `()` and square brackets `[]`. Defaults to false.
--css-formatter-trailing-newline=<true|false> Whether to add a trailing newline at the end
of the file.
Setting this option to `false` is **highly discouraged** because it
Expand Down Expand Up @@ -293,6 +301,8 @@ Available options:
Defaults to "auto".
--json-formatter-bracket-spacing=<true|false> Whether to insert spaces around brackets in
object literals. Defaults to true.
--json-formatter-delimiter-spacing=<true|false> Whether to insert spaces inside square
brackets `[]`. Defaults to false.
--json-formatter-trailing-newline=<true|false> Whether to add a trailing newline at the end
of the file.
Setting this option to `false` is **highly discouraged** because it
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
source: crates/biome_cli/tests/snap_test.rs
expression: redactor(content)
---
## `biome.json`

```json
{
"formatter": {
"delimiterSpacing": true
},
"javascript": {
"formatter": {
"delimiterSpacing": false
}
}
}
```

## `file.js`

```js
const arr = [1, 2, 3];
function foo(a, b) {}

```

# Emitted Messages

```block
Formatted 1 file in <TIME>. Fixed 1 file.
```
7 changes: 6 additions & 1 deletion crates/biome_configuration/src/css.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::bool::Bool;
use biome_deserialize_macros::{Deserializable, Merge};
use biome_formatter::{
IndentStyle, IndentWidth, LineEnding, LineWidth, QuoteStyle, TrailingNewline,
DelimiterSpacing, IndentStyle, IndentWidth, LineEnding, LineWidth, QuoteStyle, TrailingNewline,
};
use bpaf::Bpaf;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -101,6 +101,11 @@ pub struct CssFormatterConfiguration {
#[serde(skip_serializing_if = "Option::is_none")]
pub quote_style: Option<QuoteStyle>,

/// Whether to insert spaces inside delimiters. Affects parentheses `()` and square brackets `[]`. Defaults to false.
#[bpaf(long("css-formatter-delimiter-spacing"), argument("true|false"))]
#[serde(skip_serializing_if = "Option::is_none")]
pub delimiter_spacing: Option<DelimiterSpacing>,

/// Whether to add a trailing newline at the end of the file.
///
/// Setting this option to `false` is **highly discouraged** because it could cause many problems with other tools:
Expand Down
15 changes: 13 additions & 2 deletions crates/biome_configuration/src/formatter.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::bool::Bool;
use biome_deserialize_macros::{Deserializable, Merge};
use biome_formatter::{
AttributePosition, BracketSameLine, BracketSpacing, Expand, IndentStyle, IndentWidth,
LineEnding, LineWidth, TrailingNewline,
AttributePosition, BracketSameLine, BracketSpacing, DelimiterSpacing, Expand, IndentStyle,
IndentWidth, LineEnding, LineWidth, TrailingNewline,
};
use bpaf::Bpaf;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -64,6 +64,13 @@ pub struct FormatterConfiguration {
#[serde(skip_serializing_if = "Option::is_none")]
pub bracket_spacing: Option<BracketSpacing>,

/// Whether to insert spaces inside delimiters. Affects parentheses `()`,
/// square brackets `[]`, TypeScript angle brackets `<>`, and JSX curly
/// braces `{}`. Defaults to false.
#[bpaf(long("delimiter-spacing"), argument("true|false"))]
#[serde(skip_serializing_if = "Option::is_none")]
pub delimiter_spacing: Option<DelimiterSpacing>,

/// Whether to expand arrays and objects on multiple lines.
/// When set to `auto`, object literals are formatted on multiple lines if the first property has a newline,
/// and array literals are formatted on a single line if it fits in the line.
Expand Down Expand Up @@ -136,6 +143,10 @@ impl FormatterConfiguration {
self.bracket_spacing.unwrap_or_default()
}

pub fn delimiter_spacing_resolved(&self) -> DelimiterSpacing {
self.delimiter_spacing.unwrap_or_default()
}

pub fn expand_resolved(&self) -> Expand {
self.expand.unwrap_or_default()
}
Expand Down
10 changes: 8 additions & 2 deletions crates/biome_configuration/src/javascript/formatter.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::bool::Bool;
use biome_deserialize_macros::{Deserializable, Merge};
use biome_formatter::{
AttributePosition, BracketSameLine, BracketSpacing, Expand, IndentStyle, IndentWidth,
LineEnding, LineWidth, QuoteStyle, TrailingNewline,
AttributePosition, BracketSameLine, BracketSpacing, DelimiterSpacing, Expand, IndentStyle,
IndentWidth, LineEnding, LineWidth, QuoteStyle, TrailingNewline,
};
use biome_js_formatter::context::{
ArrowParentheses, OperatorLinebreak, QuoteProperties, Semicolons,
Expand Down Expand Up @@ -108,6 +108,12 @@ pub struct JsFormatterConfiguration {
#[serde(skip_serializing_if = "Option::is_none")]
pub bracket_spacing: Option<BracketSpacing>,

// it's also a top-level configurable property.
/// Whether to insert spaces inside delimiters. Affects parentheses `()`, square brackets `[]`, TypeScript angle brackets `<>`, and JSX curly braces `{}`. Defaults to false.
#[bpaf(long("javascript-formatter-delimiter-spacing"), argument("true|false"))]
#[serde(skip_serializing_if = "Option::is_none")]
pub delimiter_spacing: Option<DelimiterSpacing>,

/// Whether to expand arrays and objects on multiple lines.
/// When set to `auto`, object literals are formatted on multiple lines if the first property has a newline,
/// and array literals are formatted on a single line if it fits in the line.
Expand Down
Loading
Loading