From ee9572dd276df545dec93f79f9167d72e9c6dea2 Mon Sep 17 00:00:00 2001 From: Pig Fang Date: Thu, 11 Apr 2024 07:59:46 +0800 Subject: [PATCH] optimize formatting grid properties (close #7) (#8) --- malva/src/doc_gen/stmt.rs | 44 ++++++- malva/tests/fmt/css/grid/grid.css | 114 +++++++++++++++++ malva/tests/fmt/css/grid/grid.snap | 118 ++++++++++++++++++ .../tests/fmt/less/comments/between-decl.snap | 3 +- .../tests/fmt/scss/comments/between-decl.snap | 3 +- 5 files changed, 275 insertions(+), 7 deletions(-) create mode 100644 malva/tests/fmt/css/grid/grid.css create mode 100644 malva/tests/fmt/css/grid/grid.snap diff --git a/malva/src/doc_gen/stmt.rs b/malva/src/doc_gen/stmt.rs index cdf92ce..d073c18 100644 --- a/malva/src/doc_gen/stmt.rs +++ b/malva/src/doc_gen/stmt.rs @@ -33,21 +33,23 @@ impl<'s> DocGen<'s> for Declaration<'s> { }) ) }); - if can_break_before_value { - docs.push(Doc::line_or_space().nest(ctx.indent_width)); + let space_after_colon = if can_break_before_value { + Doc::line_or_space().nest(ctx.indent_width) } else { - docs.push(Doc::space()); - } + Doc::space() + }; docs.reserve(self.value.len() * 2); let mut pos = self.colon_span.end; - let mut iter = self.value.iter().peekable(); match &self.name { InterpolableIdent::Literal(Ident { name, .. }) if name.starts_with("--") || name.eq_ignore_ascii_case("filter") => { use raffia::token::Token; + docs.push(space_after_colon); + + let mut iter = self.value.iter().peekable(); while let Some(value) = iter.next() { let span = value.span(); docs.push( @@ -70,7 +72,39 @@ impl<'s> DocGen<'s> for Declaration<'s> { pos = span.end; } } + InterpolableIdent::Literal(Ident { name, .. }) + if name.eq_ignore_ascii_case("grid") + || name + .get(0..13) + .is_some_and(|s| s.eq_ignore_ascii_case("grid-template")) => + { + pos = self + .value + .iter() + .enumerate() + .fold(pos, |pos, (index, value)| { + let span = value.span(); + let comments = ctx.end_spaced_comments(pos, span.start).collect::>(); + + if !comments.is_empty() { + docs.push(Doc::space()); + } else if index == 0 { + docs.push(Doc::line_or_space().nest(ctx.indent_width)); + } else if ctx.line_bounds.line_distance(pos, span.start) == 0 { + docs.push(Doc::space()); + } else { + docs.push(Doc::hard_line().nest(ctx.indent_width)); + } + docs.push(Doc::list(comments).nest(ctx.indent_width)); + docs.push(value.doc(ctx)); + + span.end + }); + } _ => { + docs.push(space_after_colon); + + let mut iter = self.value.iter().peekable(); while let Some(value) = iter.next() { let span = value.span(); docs.push( diff --git a/malva/tests/fmt/css/grid/grid.css b/malva/tests/fmt/css/grid/grid.css new file mode 100644 index 0000000..b8cdb7b --- /dev/null +++ b/malva/tests/fmt/css/grid/grid.css @@ -0,0 +1,114 @@ +/* quotes */ +div { + grid-template-areas: + 'header header' + 'main sidebar' + 'footer footer'; +} + +/* numbers */ +div { + grid-template-columns: + [full-start] minmax(1.50em, 1fr) + [main-start] minmax(.40ch, 75ch) + [main-end] minmax(1em, 1.000fr) + [full-end]; +} + +/* casing */ +div { + GRID: + [top] 1fr + [middle] 1fr + bottom; + + grid-TEMPLATE: + "a a a" 200px + "b b b" 200px + / 200px 200px auto; +} + +/* break before first line if there are any breaks */ +div { + grid-template-columns: + 1fr 100px 3em; + grid: [wide-start] "header header header" 200px [wide-end] + "footer footer footer" 25px + / auto 50px auto; +} + +/** + * https://github.com/prettier/prettier/issues/2703#issuecomment-341188126 + */ +.container { + display: grid; + + /* basic template rows/columns */ + grid-template-columns: 1fr 100px 3em; + grid-template-rows: 1fr 100px 3em; + /* template rows/columns with named grid lines */ + grid-template-columns: + [wide-start] 1fr + [main-start] 500px + [main-end] 1fr + [wide-end]; + grid-template-rows: + [top] 1fr + [middle] 1fr + [bottom]; + /* template rows/columns with functions */ + grid-template-columns: minmax(1em, 1fr) minmax(1em, 80ch) minmax(1em, 1fr); + /* getting really busy with named lines + functions */ + grid-template-columns: + [full-start] minmax(1em, 1fr) + [main-start] minmax(1em, 80ch) + [main-end] minmax(1em, 1fr) + [full-end]; + + grid-template-areas: + "header header header" + "main main sidebar" + "main main sidebar2" + "footer footer footer"; + + /* Shorthand for grid-template-rows, grid-template-columns, and grid-template + areas. In one. This can get really crazy. */ + grid-template: + [row1-start] "header header header" 25px [row1-end] + [row2-start] "footer footer footer" 25px [row2-end] + / auto 50px auto; + + /* The. Worst. This one is shorthand for like everything here smashed into one. But rarely will you actually specify EVERYTHING. */ + grid: + [row1-start] "header header header" 25px [row1-end] + [row2-start] "footer footer footer" 25px [row2-end] + / auto 50px auto; + /* simpler use case: */ + grid: 200px auto / 1fr auto 1fr; + + /* Okay, the the worst of it. The simpler syntaxes: */ + + grid-row-gap: 2em; + grid-column-gap: 1em; + /* shorthand for grid-row-gap + grid-column-gap: */ + grid-gap: 2em 1em; + + grid-auto-columns: 1fr; + grid-auto-rows: 1fr; +} + +.container > .item { + grid-column-start: 1; + grid-column-end: 2; + grid-row-start: -2; + grid-row-end: -1; + + /* shorthands for the above: */ + grid-column: 1 / 2; + grid-column: main; + grid-row: -2 / span 1; + grid-row: footer; + + grid-area: main; + grid-area: 1 / main-start / 3 / main-end; +} diff --git a/malva/tests/fmt/css/grid/grid.snap b/malva/tests/fmt/css/grid/grid.snap new file mode 100644 index 0000000..4f63257 --- /dev/null +++ b/malva/tests/fmt/css/grid/grid.snap @@ -0,0 +1,118 @@ +--- +source: malva/tests/fmt.rs +--- +/* quotes */ +div { + grid-template-areas: + "header header" + "main sidebar" + "footer footer"; +} + +/* numbers */ +div { + grid-template-columns: + [full-start] minmax(1.50em, 1fr) + [main-start] minmax(0.40ch, 75ch) + [main-end] minmax(1em, 1.000fr) + [full-end]; +} + +/* casing */ +div { + grid: + [top] 1fr + [middle] 1fr + bottom; + + grid-template: + "a a a" 200px + "b b b" 200px + / 200px 200px auto; +} + +/* break before first line if there are any breaks */ +div { + grid-template-columns: 1fr 100px 3em; + grid: + [wide-start] "header header header" 200px [wide-end] + "footer footer footer" 25px + / auto 50px auto; +} + +/** + * https://github.com/prettier/prettier/issues/2703#issuecomment-341188126 + */ +.container { + display: grid; + + /* basic template rows/columns */ + grid-template-columns: 1fr 100px 3em; + grid-template-rows: 1fr 100px 3em; + /* template rows/columns with named grid lines */ + grid-template-columns: + [wide-start] 1fr + [main-start] 500px + [main-end] 1fr + [wide-end]; + grid-template-rows: + [top] 1fr + [middle] 1fr + [bottom]; + /* template rows/columns with functions */ + grid-template-columns: minmax(1em, 1fr) minmax(1em, 80ch) minmax(1em, 1fr); + /* getting really busy with named lines + functions */ + grid-template-columns: + [full-start] minmax(1em, 1fr) + [main-start] minmax(1em, 80ch) + [main-end] minmax(1em, 1fr) + [full-end]; + + grid-template-areas: + "header header header" + "main main sidebar" + "main main sidebar2" + "footer footer footer"; + + /* Shorthand for grid-template-rows, grid-template-columns, and grid-template + areas. In one. This can get really crazy. */ + grid-template: + [row1-start] "header header header" 25px [row1-end] + [row2-start] "footer footer footer" 25px [row2-end] + / auto 50px auto; + + /* The. Worst. This one is shorthand for like everything here smashed into one. But rarely will you actually specify EVERYTHING. */ + grid: + [row1-start] "header header header" 25px [row1-end] + [row2-start] "footer footer footer" 25px [row2-end] + / auto 50px auto; + /* simpler use case: */ + grid: 200px auto / 1fr auto 1fr; + + /* Okay, the the worst of it. The simpler syntaxes: */ + + grid-row-gap: 2em; + grid-column-gap: 1em; + /* shorthand for grid-row-gap + grid-column-gap: */ + grid-gap: 2em 1em; + + grid-auto-columns: 1fr; + grid-auto-rows: 1fr; +} + +.container > .item { + grid-column-start: 1; + grid-column-end: 2; + grid-row-start: -2; + grid-row-end: -1; + + /* shorthands for the above: */ + grid-column: 1 / 2; + grid-column: main; + grid-row: -2 / span 1; + grid-row: footer; + + grid-area: main; + grid-area: 1 / main-start / 3 / main-end; +} + diff --git a/malva/tests/fmt/less/comments/between-decl.snap b/malva/tests/fmt/less/comments/between-decl.snap index 6036a41..b1fb96c 100644 --- a/malva/tests/fmt/less/comments/between-decl.snap +++ b/malva/tests/fmt/less/comments/between-decl.snap @@ -17,7 +17,8 @@ selector { "sidebar content content" // "footer footer footer"; - grid-template-areas: "header header header" // + grid-template-areas: + "header header header" // "sidebar content content" // "footer footer footer"; } diff --git a/malva/tests/fmt/scss/comments/between-decl.snap b/malva/tests/fmt/scss/comments/between-decl.snap index e3b756e..f3222ce 100644 --- a/malva/tests/fmt/scss/comments/between-decl.snap +++ b/malva/tests/fmt/scss/comments/between-decl.snap @@ -17,7 +17,8 @@ selector { "sidebar content content" // "footer footer footer"; - grid-template-areas: "header header header" // + grid-template-areas: + "header header header" // "sidebar content content" // "footer footer footer"; }