Skip to content

Commit 78011b1

Browse files
PFiS1737autofix-ci[bot]ematipico
authored
fix(html/astro): don't indent Astro frontmatter (biomejs#8037)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Emanuele Stoppa <[email protected]>
1 parent c09e45c commit 78011b1

File tree

8 files changed

+142
-14
lines changed

8 files changed

+142
-14
lines changed

.changeset/vast-donuts-rescue.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@biomejs/biome": patch
3+
---
4+
5+
`indentScriptAndStyle` no longer indents the frontmatter in Astro files.

crates/biome_cli/tests/cases/handle_astro_files.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,3 +667,51 @@ fn format_astro_with_typescript_script_tag() {
667667
result,
668668
));
669669
}
670+
671+
#[test]
672+
fn dont_indent_frontmatter() {
673+
let fs = MemoryFileSystem::default();
674+
let mut console = BufferConsole::default();
675+
676+
fs.insert(
677+
"biome.json".into(),
678+
r#"{ "html": { "formatter": {"enabled": true, "indentScriptAndStyle": true}, "linter": {"enabled": true}, "experimentalFullSupportEnabled": true } }"#.as_bytes(),
679+
);
680+
681+
let astro_file_path = Utf8Path::new("file.astro");
682+
fs.insert(
683+
astro_file_path.into(),
684+
r#"---
685+
import Foo from "./Foo.astro"
686+
const bar = 123
687+
if (bar>1) {console.log(bar+1)}
688+
---
689+
<Foo>{bar}</Foo>
690+
691+
<style>
692+
#id { font-family: comic-sans } .class { background: red}
693+
</style>
694+
695+
<script>
696+
function foo(){console.log("Hello")}
697+
</script>
698+
"#
699+
.as_bytes(),
700+
);
701+
702+
let (fs, result) = run_cli(
703+
fs,
704+
&mut console,
705+
Args::from(["format", "--write", astro_file_path.as_str()].as_slice()),
706+
);
707+
708+
assert!(result.is_ok(), "run_cli returned {result:?}");
709+
710+
assert_cli_snapshot(SnapshotPayload::new(
711+
module_path!(),
712+
"dont_indent_frontmatter",
713+
fs,
714+
console,
715+
result,
716+
));
717+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
source: crates/biome_cli/tests/snap_test.rs
3+
expression: redactor(content)
4+
---
5+
## `biome.json`
6+
7+
```json
8+
{
9+
"html": {
10+
"formatter": { "enabled": true, "indentScriptAndStyle": true },
11+
"linter": { "enabled": true },
12+
"experimentalFullSupportEnabled": true
13+
}
14+
}
15+
```
16+
17+
## `file.astro`
18+
19+
```astro
20+
---
21+
import Foo from "./Foo.astro";
22+
const bar = 123;
23+
if (bar > 1) {
24+
console.log(bar + 1);
25+
}
26+
---
27+
<Foo>{bar}</Foo>
28+
29+
<style>
30+
#id {
31+
font-family: comic-sans;
32+
}
33+
.class {
34+
background: red;
35+
}
36+
</style>
37+
38+
<script>
39+
function foo() {
40+
console.log("Hello");
41+
}
42+
</script>
43+
44+
```
45+
46+
# Emitted Messages
47+
48+
```block
49+
Formatted 1 file in <TIME>. Fixed 1 file.
50+
```

crates/biome_js_syntax/src/file_source.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,10 @@ impl Language {
120120
Debug, Clone, Default, Copy, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize,
121121
)]
122122
pub enum EmbeddingKind {
123-
Astro,
123+
Astro {
124+
/// Whether the script is inside Astro frontmatter
125+
frontmatter: bool,
126+
},
124127
Vue,
125128
Svelte,
126129
#[default]
@@ -129,7 +132,10 @@ pub enum EmbeddingKind {
129132

130133
impl EmbeddingKind {
131134
pub const fn is_astro(&self) -> bool {
132-
matches!(self, Self::Astro)
135+
matches!(self, Self::Astro { frontmatter: false })
136+
}
137+
pub const fn is_astro_frontmatter(&self) -> bool {
138+
matches!(self, Self::Astro { frontmatter: true })
133139
}
134140
pub const fn is_vue(&self) -> bool {
135141
matches!(self, Self::Vue)
@@ -201,7 +207,10 @@ impl JsFileSource {
201207
}
202208

203209
pub fn astro() -> Self {
204-
Self::ts().with_embedding_kind(EmbeddingKind::Astro)
210+
Self::ts().with_embedding_kind(EmbeddingKind::Astro { frontmatter: false })
211+
}
212+
pub fn astro_frontmatter() -> Self {
213+
Self::ts().with_embedding_kind(EmbeddingKind::Astro { frontmatter: true })
205214
}
206215

207216
/// Vue file definition

crates/biome_service/src/file_handlers/html.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,8 @@ pub(crate) fn parse_astro_embedded_script(
445445
settings: &Settings,
446446
) -> Option<(EmbeddedSnippet<JsLanguage>, DocumentFileSource)> {
447447
let content = element.content_token()?;
448-
let file_source = JsFileSource::ts().with_embedding_kind(EmbeddingKind::Astro);
448+
let file_source =
449+
JsFileSource::ts().with_embedding_kind(EmbeddingKind::Astro { frontmatter: true });
449450
let document_file_source = DocumentFileSource::Js(file_source);
450451
let options = settings.parse_options::<JsLanguage>(path, &document_file_source);
451452
let parse = parse_js_with_offset_and_cache(
@@ -493,7 +494,7 @@ pub(crate) fn parse_embedded_script(
493494
}
494495
file_source
495496
} else if html_file_source.is_astro() {
496-
JsFileSource::ts().with_embedding_kind(EmbeddingKind::Astro)
497+
JsFileSource::ts().with_embedding_kind(EmbeddingKind::Astro { frontmatter: false })
497498
} else {
498499
let is_module = element.is_javascript_module().unwrap_or_default();
499500
if is_module {
@@ -672,8 +673,8 @@ fn format_embedded(
672673
let mut iter = embedded_nodes.iter();
673674
let node = iter.find(|node| node.range == range)?;
674675

675-
let wrap_document = |document: Document| {
676-
if indent_script_and_style {
676+
let wrap_document = |document: Document, should_indent: bool| {
677+
if indent_script_and_style && should_indent {
677678
let elements = vec![
678679
FormatElement::Line(LineMode::Hard),
679680
FormatElement::Tag(Tag::StartIndent),
@@ -693,27 +694,31 @@ fn format_embedded(
693694
};
694695

695696
match node.source {
696-
DocumentFileSource::Js(_) => {
697+
DocumentFileSource::Js(file_source) => {
697698
let js_options = settings.format_options::<JsLanguage>(biome_path, &node.source);
698699
let node = node.node.clone().embedded_syntax::<JsLanguage>().clone();
699700
let formatted =
700701
biome_js_formatter::format_node_with_offset(js_options, &node).ok()?;
701-
Some(wrap_document(formatted.into_document()))
702+
703+
Some(wrap_document(
704+
formatted.into_document(),
705+
!file_source.as_embedding_kind().is_astro_frontmatter(),
706+
))
702707
}
703708
DocumentFileSource::Json(_) => {
704709
let json_options =
705710
settings.format_options::<JsonLanguage>(biome_path, &node.source);
706711
let node = node.node.clone().embedded_syntax::<JsonLanguage>().clone();
707712
let formatted =
708713
biome_json_formatter::format_node_with_offset(json_options, &node).ok()?;
709-
Some(wrap_document(formatted.into_document()))
714+
Some(wrap_document(formatted.into_document(), true))
710715
}
711716
DocumentFileSource::Css(_) => {
712717
let css_options = settings.format_options::<CssLanguage>(biome_path, &node.source);
713718
let node = node.node.clone().embedded_syntax::<CssLanguage>();
714719
let formatted =
715720
biome_css_formatter::format_node_with_offset(css_options, &node).ok()?;
716-
Some(wrap_document(formatted.into_document()))
721+
Some(wrap_document(formatted.into_document(), true))
717722
}
718723
_ => None,
719724
}

crates/biome_service/src/file_handlers/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ impl Features {
814814
match language_hint {
815815
// TODO: remove match once we remove vue/astro/svelte handlers
816816
DocumentFileSource::Js(source) => match source.as_embedding_kind() {
817-
EmbeddingKind::Astro => self.astro.capabilities(),
817+
EmbeddingKind::Astro { .. } => self.astro.capabilities(),
818818
EmbeddingKind::Vue => self.vue.capabilities(),
819819
EmbeddingKind::Svelte => self.svelte.capabilities(),
820820
EmbeddingKind::None => self.js.capabilities(),

packages/@biomejs/backend-jsonrpc/src/workspace.ts

Lines changed: 12 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

xtask/rules_check/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ fn assert_lint(
285285
DocumentFileSource::Js(file_source) => {
286286
// Temporary support for astro, svelte and vue code blocks
287287
let (code, file_source) = match file_source.as_embedding_kind() {
288-
EmbeddingKind::Astro => (
288+
EmbeddingKind::Astro { .. } => (
289289
biome_service::file_handlers::AstroFileHandler::input(code),
290290
JsFileSource::ts(),
291291
),

0 commit comments

Comments
 (0)