Skip to content

Commit

Permalink
support ignore formatting specific statement
Browse files Browse the repository at this point in the history
  • Loading branch information
g-plane committed May 17, 2024
1 parent 70fcd3a commit 7ccf35b
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 49 deletions.
2 changes: 1 addition & 1 deletion malva/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,5 @@ let line_bounds = LineBounds::new(input);
assert_eq!("a {
color: red;
}
", &print_stylesheet(&stylesheet, &comments, line_bounds, Syntax::Css, &options));
", &print_stylesheet(&stylesheet, &comments, Some(input), line_bounds, Syntax::Css, &options));
```
3 changes: 2 additions & 1 deletion malva/src/ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::{array, cell::Cell, iter::Peekable, mem};
use tiny_pretty::Doc;

pub(crate) struct Ctx<'a, 's: 'a> {
pub source: Option<&'s str>,
pub syntax: Syntax,
pub options: &'a LanguageOptions,
pub comments: &'a [Comment<'s>],
Expand All @@ -20,7 +21,7 @@ impl<'a, 's> Ctx<'a, 's> {
&self,
start: usize,
end: usize,
) -> impl Iterator<Item = &Comment<'s>> {
) -> impl Iterator<Item = &Comment<'s>> + Clone {
self.comments
.iter()
.filter(move |comment| comment.span.start >= start && comment.span.end <= end)
Expand Down
107 changes: 60 additions & 47 deletions malva/src/doc_gen/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ impl<'s> DocGen<'s> for SimpleBlock<'s> {

impl<'s> DocGen<'s> for Statement<'s> {
fn doc(&self, ctx: &Ctx<'_, 's>) -> Doc<'s> {
let stmt = match self {
match self {
Statement::QualifiedRule(qualified_rule) => qualified_rule.doc(ctx),
Statement::AtRule(at_rule) => at_rule.doc(ctx),
Statement::Declaration(declaration) => declaration.doc(ctx),
Expand All @@ -266,35 +266,6 @@ impl<'s> DocGen<'s> for Statement<'s> {
sass_variable_declaration.doc(ctx)
}
Statement::UnknownSassAtRule(unknown_sass_at_rule) => unknown_sass_at_rule.doc(ctx),
};
if ctx.syntax == Syntax::Sass {
stmt
} else {
match self {
Statement::AtRule(at_rule) if at_rule.block.is_none() => {
stmt.append(Doc::text(";"))
}
Statement::Declaration(decl)
if !matches!(
decl.value.last(),
Some(ComponentValue::SassNestingDeclaration(..))
) =>
{
stmt.append(Doc::text(";"))
}
Statement::LessExtendRule(..)
| Statement::LessFunctionCall(..)
| Statement::LessMixinCall(..)
| Statement::LessVariableCall(..)
| Statement::LessVariableDeclaration(..)
| Statement::SassVariableDeclaration(..) => stmt.append(Doc::text(";")),
Statement::UnknownSassAtRule(unknown_sass_at_rule)
if unknown_sass_at_rule.block.is_none() =>
{
stmt.append(Doc::text(";"))
}
_ => stmt,
}
}
}
}
Expand Down Expand Up @@ -443,24 +414,25 @@ fn format_single_stmt<'s>(

let span = stmt.span();

let has_comments = ctx.get_comments_between(*pos, span.start).fold(
!ignore_leading_whitespace,
|has_comments, comment| {
if has_comments && *pos > outer_span.start {
match ctx.line_bounds.line_distance(*pos, comment.span.start) {
0 => docs.push(Doc::space()),
1 => docs.push(line_break_doc.clone()),
_ => {
docs.push(Doc::empty_line());
docs.push(Doc::hard_line());
let comments = ctx.get_comments_between(*pos, span.start);
let has_comments =
comments
.clone()
.fold(!ignore_leading_whitespace, |has_comments, comment| {
if has_comments && *pos > outer_span.start {
match ctx.line_bounds.line_distance(*pos, comment.span.start) {
0 => docs.push(Doc::space()),
1 => docs.push(line_break_doc.clone()),
_ => {
docs.push(Doc::empty_line());
docs.push(Doc::hard_line());
}
}
}
}
docs.push(comment.doc(ctx));
*pos = comment.span.end;
true
},
);
docs.push(comment.doc(ctx));
*pos = comment.span.end;
true
});

if has_comments && *pos > outer_span.start {
if ctx.line_bounds.line_distance(*pos, span.start) <= 1 {
Expand All @@ -470,9 +442,50 @@ fn format_single_stmt<'s>(
docs.push(Doc::hard_line());
}
}
docs.push(stmt.doc(ctx));
if comments
.last()
.and_then(|comment| comment.content.trim_start().strip_prefix("malva-ignore"))
.is_some_and(|rest| rest.is_empty() || rest.starts_with(|c: char| c.is_ascii_whitespace()))
{
if let Some(source) = ctx.source {
docs.extend(itertools::intersperse(
source[span.start..span.end].lines().map(Doc::text),
Doc::empty_line(),
));
} else {
docs.push(stmt.doc(ctx));
}
} else {
docs.push(stmt.doc(ctx));
}
*pos = span.end;

if ctx.syntax != Syntax::Sass {
match stmt {
Statement::AtRule(at_rule) if at_rule.block.is_none() => docs.push(Doc::text(";")),
Statement::Declaration(decl)
if !matches!(
decl.value.last(),
Some(ComponentValue::SassNestingDeclaration(..))
) =>
{
docs.push(Doc::text(";"));
}
Statement::LessExtendRule(..)
| Statement::LessFunctionCall(..)
| Statement::LessMixinCall(..)
| Statement::LessVariableCall(..)
| Statement::LessVariableDeclaration(..)
| Statement::SassVariableDeclaration(..) => docs.push(Doc::text(";")),
Statement::UnknownSassAtRule(unknown_sass_at_rule)
if unknown_sass_at_rule.block.is_none() =>
{
docs.push(Doc::text(";"));
}
_ => {}
}
}

ctx.get_comments_between(
*pos,
next_stmt
Expand Down
3 changes: 3 additions & 0 deletions malva/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub fn format_text(input: &str, syntax: Syntax, options: &FormatOptions) -> Resu
Ok(print_stylesheet(
&stylesheet,
&comments,
Some(input),
line_bounds,
syntax,
options,
Expand All @@ -45,13 +46,15 @@ pub fn format_text(input: &str, syntax: Syntax, options: &FormatOptions) -> Resu
pub fn print_stylesheet<'a, 's>(
stylesheet: &'a Stylesheet<'s>,
comments: &'a [Comment<'s>],
source: Option<&'s str>,
line_bounds: LineBounds,
syntax: Syntax,
options: &'a FormatOptions,
) -> String {
use tiny_pretty::{IndentKind, PrintOptions};

let ctx = Ctx {
source,
syntax,
options: &options.language,
comments,
Expand Down
19 changes: 19 additions & 0 deletions malva/tests/fmt/css/ignore/default.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
a,b{}

/* malva-ignore*/
a,b{}

/* malva-ignore for some reason */
a,b{}

a{
/* malva-ignore */
width : 0;
height : 0;
}

/* do not malva-ignore */
a,b{}

/* malva-ignore-will-not-apply */
a,b{}
22 changes: 22 additions & 0 deletions malva/tests/fmt/css/ignore/default.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
source: malva/tests/fmt.rs
---
a, b {}

/* malva-ignore*/
a,b{}

/* malva-ignore for some reason */
a,b{}

a {
/* malva-ignore */
width : 0;
height: 0;
}

/* do not malva-ignore */
a, b {}

/* malva-ignore-will-not-apply */
a, b {}
37 changes: 37 additions & 0 deletions malva/tests/fmt/scss/ignore/default.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
a,b{}

/* malva-ignore*/
a,b{}

/* malva-ignore for some reason */
a,b{}

a{
/* malva-ignore */
width : 0;
height : 0;
}

/* do not malva-ignore */
a,b{}

/* malva-ignore-will-not-apply */
a,b{}

// malva-ignore
a,b{}

// malva-ignore for some reason
a,b{}

a{
// malva-ignore
width : 0;
height : 0;
}

// do not malva-ignore
a,b{}

// malva-ignore-will-not-apply
a,b{}
40 changes: 40 additions & 0 deletions malva/tests/fmt/scss/ignore/default.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
source: malva/tests/fmt.rs
---
a, b {}

/* malva-ignore*/
a,b{}

/* malva-ignore for some reason */
a,b{}

a {
/* malva-ignore */
width : 0;
height: 0;
}

/* do not malva-ignore */
a, b {}

/* malva-ignore-will-not-apply */
a, b {}

// malva-ignore
a,b{}

// malva-ignore for some reason
a,b{}

a {
// malva-ignore
width : 0;
height: 0;
}

// do not malva-ignore
a, b {}

// malva-ignore-will-not-apply
a, b {}

0 comments on commit 7ccf35b

Please sign in to comment.