Browse Source

Merge pull request #1701 from marc2332/feat/inline-attributes-fmt

feat: `--split-line-attributes` parameter for CLI `fmt`
Jonathan Kelley 1 year ago
parent
commit
18a56bf62c

+ 3 - 3
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)?;
         }

+ 5 - 2
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

+ 15 - 9
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
         );
     }

+ 3 - 1
packages/autofmt/src/lib.rs

@@ -140,7 +140,9 @@ pub fn write_block_out(body: CallBody) -> Option<String> {
 }
 
 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];

+ 6 - 6
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)));

+ 24 - 9
packages/cli/src/cli/autoformat.rs

@@ -22,23 +22,33 @@ pub struct Autoformat {
     /// Input file
     #[clap(short, long)]
     pub file: Option<String>,
+
+    /// 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<Path>) -> Result<IndentOptions> {
+fn indentation_for(
+    file_or_dir: impl AsRef<Path>,
+    split_line_attributes: bool,
+) -> Result<IndentOptions> {
     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<Path>) -> Result<IndentOptions> {
             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();

+ 3 - 0
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());