Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .changeset/few-bees-reply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
"@biomejs/biome": minor
---

Implemented the `indentScriptAndStyle` option for vue and svelte files, with the default set to `false` to match [Prettier's `vueIndentScriptAndStyle` option](https://prettier.io/docs/options#vue-files-script-and-style-tags-indentation). When enabled, this option indents the content within `<script>` and `<style>` tags to align with the surrounding HTML structure.

It can be enabled with this configuration:

```json
{
"html": {
"formatter": {
"indentScriptAndStyle": true
}
}
}
```

Which will format this code to:
```vue
<script>
import Component from "./Component.vue";
</script>
```
4 changes: 4 additions & 0 deletions crates/biome_cli/src/execute/migrate/prettier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ pub(crate) struct PrettierConfiguration {
end_of_line: EndOfLine,
/// https://prettier.io/docs/options#object-wrap
object_wrap: ObjectWrap,
/// https://prettier.io/docs/options#vue-files-script-and-style-tags-indentation
vue_indent_script_and_style: bool,
/// https://prettier.io/docs/en/configuration.html#configuration-overrides
overrides: Vec<Override>,
}
Expand All @@ -81,6 +83,7 @@ impl Default for PrettierConfiguration {
arrow_parens: ArrowParens::default(),
end_of_line: EndOfLine::default(),
object_wrap: ObjectWrap::default(),
vue_indent_script_and_style: false,
overrides: vec![],
}
}
Expand Down Expand Up @@ -282,6 +285,7 @@ impl TryFrom<PrettierConfiguration> for biome_configuration::Configuration {
};
let html_formatter_config = HtmlFormatterConfiguration {
self_close_void_elements: Some(SelfCloseVoidElements::Always),
indent_script_and_style: Some(value.vue_indent_script_and_style.into()),
..Default::default()
};

Expand Down
232 changes: 232 additions & 0 deletions crates/biome_cli/tests/cases/indent_script_and_style.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
use crate::run_cli;
use crate::snap_test::{SnapshotPayload, assert_cli_snapshot, assert_file_contents};
use biome_console::BufferConsole;
use biome_fs::MemoryFileSystem;
use bpaf::Args;
use camino::Utf8Path;

const BIOME_CONFIG_INDENT: &str = r#"
{
"html": {
"formatter": {
"indentScriptAndStyle": true
}
}
}
"#;

const VUE_FILE_UNFORMATTED: &str = r#"<script>
import { something } from "file.vue";
statement ( ) ;
</script>
<template></template>"#;

const VUE_FILE_FORMATTED_INDENTED: &str = r#"<script>
import { something } from "file.vue";
statement();
</script>
<template></template>"#;

const VUE_FILE_FORMATTED_UNINDENTED: &str = r#"<script>
import { something } from "file.vue";
statement();
</script>
<template></template>"#;

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

let vue_file_path = Utf8Path::new("file.vue");
fs.insert(vue_file_path.into(), VUE_FILE_UNFORMATTED.as_bytes());

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

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

assert_file_contents(&fs, vue_file_path, VUE_FILE_FORMATTED_UNINDENTED);

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

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

let vue_file_path = Utf8Path::new("file.vue");
fs.insert(vue_file_path.into(), VUE_FILE_UNFORMATTED.as_bytes());

let (fs, result) = run_cli(
fs,
&mut console,
Args::from(
[
"format",
"--write",
"--html-formatter-indent-script-and-style=true",
]
.as_slice(),
),
);

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

assert_file_contents(&fs, vue_file_path, VUE_FILE_FORMATTED_INDENTED);

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

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

let vue_file_path = Utf8Path::new("file.vue");
fs.insert(vue_file_path.into(), VUE_FILE_UNFORMATTED.as_bytes());
let biome_config = Utf8Path::new("biome.json");
fs.insert(biome_config.into(), BIOME_CONFIG_INDENT.as_bytes());

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

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

assert_file_contents(&fs, vue_file_path, VUE_FILE_FORMATTED_INDENTED);

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

const SVELTE_FILE_UNFORMATTED: &str = r#"<script>
import { something } from "file.svelte";
statement ( ) ;
</script>
<div></div>"#;

const SVELTE_FILE_FORMATTED_INDENTED: &str = r#"<script>
import { something } from "file.svelte";
statement();
</script>
<div></div>"#;

const SVELTE_FILE_FORMATTED_UNINDENTED: &str = r#"<script>
import { something } from "file.svelte";
statement();
</script>
<div></div>"#;

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

let svelte_file_path = Utf8Path::new("file.svelte");
fs.insert(svelte_file_path.into(), SVELTE_FILE_UNFORMATTED.as_bytes());

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

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

assert_file_contents(&fs, svelte_file_path, SVELTE_FILE_FORMATTED_UNINDENTED);

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

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

let svelte_file_path = Utf8Path::new("file.svelte");
fs.insert(svelte_file_path.into(), SVELTE_FILE_UNFORMATTED.as_bytes());

let (fs, result) = run_cli(
fs,
&mut console,
Args::from(
[
"format",
"--write",
"--html-formatter-indent-script-and-style=true",
]
.as_slice(),
),
);

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

assert_file_contents(&fs, svelte_file_path, SVELTE_FILE_FORMATTED_INDENTED);

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

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

let svelte_file_path = Utf8Path::new("file.svelte");
fs.insert(svelte_file_path.into(), SVELTE_FILE_UNFORMATTED.as_bytes());
let biome_config = Utf8Path::new("biome.json");
fs.insert(biome_config.into(), BIOME_CONFIG_INDENT.as_bytes());

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

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

assert_file_contents(&fs, svelte_file_path, SVELTE_FILE_FORMATTED_INDENTED);

assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"indent_svelte_by_config",
fs,
console,
result,
));
}
1 change: 1 addition & 0 deletions crates/biome_cli/tests/cases/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ mod handle_svelte_files;
mod handle_vue_files;
mod html;
mod included_files;
mod indent_script_and_style;
mod linter_domains;
mod linter_groups_plain;
mod migrate_v2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ var foo: string = "";

```block
<script context="module" lang="ts">
import Button from "./components/Button.svelte";
import { Form } from "./components/Form.svelte";
import Button from "./components/Button.svelte";
import { Form } from "./components/Form.svelte";

debugger;
statement();
var foo: string = "";
debugger;
statement();
var foo: string = "";
</script>
<div></div>
```
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ var foo: string = "";

```block
<script context="module" lang="ts">
statement();
var _foo: string = "";
statement();
var _foo: string = "";
</script>
<div></div>
```
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ const hello : string = "world";

```block
<script context="module" lang="ts">
import Button from "./components/Button.svelte";
const hello: string = "world";
import Button from "./components/Button.svelte";
const hello: string = "world";
</script>
<div></div>
```
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ const hello : string = "world";

```block
<script context="module" lang="ts">
import Button from "./components/Button.svelte";
const hello: string = "world";
import Button from "./components/Button.svelte";
const hello: string = "world";
</script>
<div></div>
```
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ file.svelte format ━━━━━━━━━━━━━━━━━━━━

1 1 │ <script>␍
2 │ - ··const·a····=·"b";␍
2 │ + const·a·=·"b";
2 │ + const·a·=·"b";
3 3 │ </script>␍
4 4 │ <div></div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ file.svelte format ━━━━━━━━━━━━━━━━━━━━
1 1 │ <script context="module" lang="ts">
2 │ - import·····Button·····from·"./components/Button.svelte";
3 │ - const·hello··:······string······=·"world";
2 │ + import·Button·from·"./components/Button.svelte";
3 │ + const·hello:·string·=·"world";
2 │ + import·Button·from·"./components/Button.svelte";
3 │ + const·hello:·string·=·"world";
4 4 │ </script>
5 5 │ <div></div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ expression: redactor(content)

```svelte
<script context="module" lang="ts">
import Button from "./components/Button.svelte";
const hello: string = "world";
import Button from "./components/Button.svelte";
const hello: string = "world";
</script>
<div></div>
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ delete a.c;

```block
<script setup lang="ts">
import * as vueUse from "vue-use";
import { Button } from "./components/Button.vue";
import * as vueUse from "vue-use";
import { Button } from "./components/Button.vue";

delete a.c;
delete a.c;
</script>
<template></template>
```
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ delete a.c;

```block
<script setup lang="ts">
delete a.c;
delete a.c;
</script>
<template></template>
```
Loading
Loading