diff --git a/packages/autofmt/src/component.rs b/packages/autofmt/src/component.rs index 8cf36811d..1eea2eba2 100644 --- a/packages/autofmt/src/component.rs +++ b/packages/autofmt/src/component.rs @@ -67,7 +67,7 @@ impl Writer<'_> { } // multiline handlers bump everything down - if attr_len > 1000 { + if attr_len > 1000 || self.out.indent.split_line_attributes() { opt_level = ShortOptimization::NoOpt; } @@ -158,7 +158,7 @@ impl Writer<'_> { while let Some(field) = field_iter.next() { if !sameline { - self.out.indented_tabbed_line()?; + self.out.indented_tabbed_line().unwrap(); } let name = &field.name; @@ -206,7 +206,7 @@ impl Writer<'_> { if let Some(exp) = manual_props { if !sameline { - self.out.indented_tabbed_line()?; + self.out.indented_tabbed_line().unwrap(); } self.write_manual_props(exp)?; } diff --git a/packages/autofmt/src/element.rs b/packages/autofmt/src/element.rs index 48077fa16..1354666f3 100644 --- a/packages/autofmt/src/element.rs +++ b/packages/autofmt/src/element.rs @@ -103,7 +103,7 @@ impl Writer<'_> { } // multiline handlers bump everything down - if attr_len > 1000 { + if attr_len > 1000 || self.out.indent.split_line_attributes() { opt_level = ShortOptimization::NoOpt; } @@ -262,7 +262,6 @@ impl Writer<'_> { } ElementAttrValue::EventTokens(tokens) => { let out = self.retrieve_formatted_expr(tokens).to_string(); - let mut lines = out.split('\n').peekable(); let first = lines.next().unwrap(); @@ -327,6 +326,10 @@ impl Writer<'_> { beginning.is_empty() } + pub fn is_empty_children(&self, children: &[BodyNode]) -> bool { + children.is_empty() + } + // check if the children are short enough to be on the same line // We don't have the notion of current line depth - each line tries to be < 80 total // returns the total line length if it's short diff --git a/packages/autofmt/src/indent.rs b/packages/autofmt/src/indent.rs index 2cce7cf1e..f7d514865 100644 --- a/packages/autofmt/src/indent.rs +++ b/packages/autofmt/src/indent.rs @@ -8,10 +8,11 @@ pub enum IndentType { pub struct IndentOptions { width: usize, indent_string: String, + split_line_attributes: bool, } impl IndentOptions { - pub fn new(typ: IndentType, width: usize) -> Self { + pub fn new(typ: IndentType, width: usize, split_line_attributes: bool) -> Self { assert_ne!(width, 0, "Cannot have an indent width of 0"); Self { width, @@ -19,6 +20,7 @@ impl IndentOptions { IndentType::Tabs => "\t".into(), IndentType::Spaces => " ".repeat(width), }, + split_line_attributes, } } @@ -62,11 +64,15 @@ impl IndentOptions { } indent } + + pub fn split_line_attributes(&self) -> bool { + self.split_line_attributes + } } impl Default for IndentOptions { fn default() -> Self { - Self::new(IndentType::Spaces, 4) + Self::new(IndentType::Spaces, 4, false) } } @@ -77,31 +83,31 @@ mod tests { #[test] fn count_indents() { assert_eq!( - IndentOptions::new(IndentType::Spaces, 4).count_indents("no indentation here!"), + IndentOptions::new(IndentType::Spaces, 4, false).count_indents("no indentation here!"), 0 ); assert_eq!( - IndentOptions::new(IndentType::Spaces, 4).count_indents(" v += 2"), + IndentOptions::new(IndentType::Spaces, 4, false).count_indents(" v += 2"), 1 ); assert_eq!( - IndentOptions::new(IndentType::Spaces, 4).count_indents(" v += 2"), + IndentOptions::new(IndentType::Spaces, 4, false).count_indents(" v += 2"), 2 ); assert_eq!( - IndentOptions::new(IndentType::Spaces, 4).count_indents(" v += 2"), + IndentOptions::new(IndentType::Spaces, 4, false).count_indents(" v += 2"), 2 ); assert_eq!( - IndentOptions::new(IndentType::Spaces, 4).count_indents("\t\tv += 2"), + IndentOptions::new(IndentType::Spaces, 4, false).count_indents("\t\tv += 2"), 2 ); assert_eq!( - IndentOptions::new(IndentType::Spaces, 4).count_indents("\t\t v += 2"), + IndentOptions::new(IndentType::Spaces, 4, false).count_indents("\t\t v += 2"), 2 ); assert_eq!( - IndentOptions::new(IndentType::Spaces, 2).count_indents(" v += 2"), + IndentOptions::new(IndentType::Spaces, 2, false).count_indents(" v += 2"), 2 ); } diff --git a/packages/autofmt/src/lib.rs b/packages/autofmt/src/lib.rs index 0c3fe6bb8..e40b873d6 100644 --- a/packages/autofmt/src/lib.rs +++ b/packages/autofmt/src/lib.rs @@ -140,7 +140,9 @@ pub fn write_block_out(body: CallBody) -> Option { } fn write_body(buf: &mut Writer, body: &CallBody) { - if buf.is_short_children(&body.roots).is_some() { + let is_short = buf.is_short_children(&body.roots).is_some(); + let is_empty = buf.is_empty_children(&body.roots); + if (is_short && !buf.out.indent.split_line_attributes()) || is_empty { // write all the indents with spaces and commas between for idx in 0..body.roots.len() - 1 { let ident = &body.roots[idx]; diff --git a/packages/autofmt/tests/wrong.rs b/packages/autofmt/tests/wrong.rs index 06a0f00d1..8f2d08452 100644 --- a/packages/autofmt/tests/wrong.rs +++ b/packages/autofmt/tests/wrong.rs @@ -18,11 +18,11 @@ macro_rules! twoway { }; } -twoway!("comments-4sp" => comments_4sp (IndentOptions::new(IndentType::Spaces, 4))); -twoway!("comments-tab" => comments_tab (IndentOptions::new(IndentType::Tabs, 4))); +twoway!("comments-4sp" => comments_4sp (IndentOptions::new(IndentType::Spaces, 4, false))); +twoway!("comments-tab" => comments_tab (IndentOptions::new(IndentType::Tabs, 4, false))); -twoway!("multi-4sp" => multi_4sp (IndentOptions::new(IndentType::Spaces, 4))); -twoway!("multi-tab" => multi_tab (IndentOptions::new(IndentType::Tabs, 4))); +twoway!("multi-4sp" => multi_4sp (IndentOptions::new(IndentType::Spaces, 4, false))); +twoway!("multi-tab" => multi_tab (IndentOptions::new(IndentType::Tabs, 4, false))); -twoway!("multiexpr-4sp" => multiexpr_4sp (IndentOptions::new(IndentType::Spaces, 4))); -twoway!("multiexpr-tab" => multiexpr_tab (IndentOptions::new(IndentType::Tabs, 4))); +twoway!("multiexpr-4sp" => multiexpr_4sp (IndentOptions::new(IndentType::Spaces, 4, false))); +twoway!("multiexpr-tab" => multiexpr_tab (IndentOptions::new(IndentType::Tabs, 4, false))); diff --git a/packages/cli/src/cli/autoformat.rs b/packages/cli/src/cli/autoformat.rs index 016b5e87d..7909cdb88 100644 --- a/packages/cli/src/cli/autoformat.rs +++ b/packages/cli/src/cli/autoformat.rs @@ -22,23 +22,33 @@ pub struct Autoformat { /// Input file #[clap(short, long)] pub file: Option, + + /// Split attributes in lines or not + #[clap(short, long, default_value = "false")] + pub split_line_attributes: bool, } impl Autoformat { // Todo: autoformat the entire crate pub async fn autoformat(self) -> Result<()> { - let Autoformat { check, raw, file } = self; + let Autoformat { + check, + raw, + file, + split_line_attributes, + .. + } = self; // Default to formatting the project if raw.is_none() && file.is_none() { - if let Err(e) = autoformat_project(check).await { + if let Err(e) = autoformat_project(check, split_line_attributes).await { eprintln!("error formatting project: {}", e); exit(1); } } if let Some(raw) = raw { - let indent = indentation_for(".")?; + let indent = indentation_for(".", self.split_line_attributes)?; if let Some(inner) = dioxus_autofmt::fmt_block(&raw, 0, indent) { println!("{}", inner); } else { @@ -50,15 +60,15 @@ impl Autoformat { // Format single file if let Some(file) = file { - refactor_file(file)?; + refactor_file(file, split_line_attributes)?; } Ok(()) } } -fn refactor_file(file: String) -> Result<(), Error> { - let indent = indentation_for(".")?; +fn refactor_file(file: String, split_line_attributes: bool) -> Result<(), Error> { + let indent = indentation_for(".", split_line_attributes)?; let file_content = if file == "-" { let mut contents = String::new(); std::io::stdin().read_to_string(&mut contents)?; @@ -138,7 +148,7 @@ async fn format_file( /// Runs using Tokio for multithreading, so it should be really really fast /// /// Doesn't do mod-descending, so it will still try to format unreachable files. TODO. -async fn autoformat_project(check: bool) -> Result<()> { +async fn autoformat_project(check: bool, split_line_attributes: bool) -> Result<()> { let crate_config = dioxus_cli_config::CrateConfig::new(None)?; let files_to_format = get_project_files(&crate_config); @@ -147,7 +157,7 @@ async fn autoformat_project(check: bool) -> Result<()> { return Ok(()); } - let indent = indentation_for(&files_to_format[0])?; + let indent = indentation_for(&files_to_format[0], split_line_attributes)?; let counts = files_to_format .into_iter() @@ -181,7 +191,10 @@ async fn autoformat_project(check: bool) -> Result<()> { Ok(()) } -fn indentation_for(file_or_dir: impl AsRef) -> Result { +fn indentation_for( + file_or_dir: impl AsRef, + split_line_attributes: bool, +) -> Result { let out = std::process::Command::new("cargo") .args(["fmt", "--", "--print-config", "current"]) .arg(file_or_dir.as_ref()) @@ -221,6 +234,7 @@ fn indentation_for(file_or_dir: impl AsRef) -> Result { IndentType::Spaces }, tab_spaces, + split_line_attributes, )) } @@ -269,6 +283,7 @@ async fn test_auto_fmt() { check: false, raw: Some(test_rsx), file: None, + split_line_attributes: false, }; fmt.autoformat().await.unwrap(); diff --git a/packages/extension/src/lib.rs b/packages/extension/src/lib.rs index fb9cca8a9..6581482ca 100644 --- a/packages/extension/src/lib.rs +++ b/packages/extension/src/lib.rs @@ -15,6 +15,7 @@ pub fn format_rsx(raw: String, use_tabs: bool, indent_size: usize) -> String { IndentType::Spaces }, indent_size, + false, ), ); block.unwrap() @@ -32,6 +33,7 @@ pub fn format_selection(raw: String, use_tabs: bool, indent_size: usize) -> Stri IndentType::Spaces }, indent_size, + false, ), ); block.unwrap() @@ -67,6 +69,7 @@ pub fn format_file(contents: String, use_tabs: bool, indent_size: usize) -> Form IndentType::Spaces }, indent_size, + false, ), ); let out = dioxus_autofmt::apply_formats(&contents, _edits.clone());