Merge pull request #1701 from marc2332/feat/inline-attributes-fmt
feat: `--split-line-attributes` parameter for CLI `fmt`
This commit is contained in:
7 files changed
+59
-30
No files matched your search
@@ -67,7 +67,7 @@ impl Writer<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// multiline handlers bump everything down
|
// multiline handlers bump everything down
|
||||||
if attr_len > 1000 {
|
if attr_len > 1000 || self.out.indent.split_line_attributes() {
|
||||||
opt_level = ShortOptimization::NoOpt;
|
opt_level = ShortOptimization::NoOpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ impl Writer<'_> {
|
|||||||
|
|
||||||
while let Some(field) = field_iter.next() {
|
while let Some(field) = field_iter.next() {
|
||||||
if !sameline {
|
if !sameline {
|
||||||
self.out.indented_tabbed_line()?;
|
self.out.indented_tabbed_line().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = &field.name;
|
let name = &field.name;
|
||||||
@@ -206,7 +206,7 @@ impl Writer<'_> {
|
|||||||
|
|
||||||
if let Some(exp) = manual_props {
|
if let Some(exp) = manual_props {
|
||||||
if !sameline {
|
if !sameline {
|
||||||
self.out.indented_tabbed_line()?;
|
self.out.indented_tabbed_line().unwrap();
|
||||||
}
|
}
|
||||||
self.write_manual_props(exp)?;
|
self.write_manual_props(exp)?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ impl Writer<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// multiline handlers bump everything down
|
// multiline handlers bump everything down
|
||||||
if attr_len > 1000 {
|
if attr_len > 1000 || self.out.indent.split_line_attributes() {
|
||||||
opt_level = ShortOptimization::NoOpt;
|
opt_level = ShortOptimization::NoOpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,7 +262,6 @@ impl Writer<'_> {
|
|||||||
}
|
}
|
||||||
ElementAttrValue::EventTokens(tokens) => {
|
ElementAttrValue::EventTokens(tokens) => {
|
||||||
let out = self.retrieve_formatted_expr(tokens).to_string();
|
let out = self.retrieve_formatted_expr(tokens).to_string();
|
||||||
|
|
||||||
let mut lines = out.split('\n').peekable();
|
let mut lines = out.split('\n').peekable();
|
||||||
let first = lines.next().unwrap();
|
let first = lines.next().unwrap();
|
||||||
|
|
||||||
@@ -327,6 +326,10 @@ impl Writer<'_> {
|
|||||||
beginning.is_empty()
|
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
|
// 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
|
// 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
|
// returns the total line length if it's short
|
||||||
|
|||||||
@@ -8,10 +8,11 @@ pub enum IndentType {
|
|||||||
pub struct IndentOptions {
|
pub struct IndentOptions {
|
||||||
width: usize,
|
width: usize,
|
||||||
indent_string: String,
|
indent_string: String,
|
||||||
|
split_line_attributes: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IndentOptions {
|
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");
|
assert_ne!(width, 0, "Cannot have an indent width of 0");
|
||||||
Self {
|
Self {
|
||||||
width,
|
width,
|
||||||
@@ -19,6 +20,7 @@ impl IndentOptions {
|
|||||||
IndentType::Tabs => "\t".into(),
|
IndentType::Tabs => "\t".into(),
|
||||||
IndentType::Spaces => " ".repeat(width),
|
IndentType::Spaces => " ".repeat(width),
|
||||||
},
|
},
|
||||||
|
split_line_attributes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,11 +64,15 @@ impl IndentOptions {
|
|||||||
}
|
}
|
||||||
indent
|
indent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn split_line_attributes(&self) -> bool {
|
||||||
|
self.split_line_attributes
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for IndentOptions {
|
impl Default for IndentOptions {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new(IndentType::Spaces, 4)
|
Self::new(IndentType::Spaces, 4, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,31 +83,31 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn count_indents() {
|
fn count_indents() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
IndentOptions::new(IndentType::Spaces, 4).count_indents("no indentation here!"),
|
IndentOptions::new(IndentType::Spaces, 4, false).count_indents("no indentation here!"),
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
IndentOptions::new(IndentType::Spaces, 4).count_indents(" v += 2"),
|
IndentOptions::new(IndentType::Spaces, 4, false).count_indents(" v += 2"),
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
IndentOptions::new(IndentType::Spaces, 4).count_indents(" v += 2"),
|
IndentOptions::new(IndentType::Spaces, 4, false).count_indents(" v += 2"),
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
IndentOptions::new(IndentType::Spaces, 4).count_indents(" v += 2"),
|
IndentOptions::new(IndentType::Spaces, 4, false).count_indents(" v += 2"),
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
IndentOptions::new(IndentType::Spaces, 4).count_indents("\t\tv += 2"),
|
IndentOptions::new(IndentType::Spaces, 4, false).count_indents("\t\tv += 2"),
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
assert_eq!(
|
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
|
2
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
IndentOptions::new(IndentType::Spaces, 2).count_indents(" v += 2"),
|
IndentOptions::new(IndentType::Spaces, 2, false).count_indents(" v += 2"),
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,7 +140,9 @@ pub fn write_block_out(body: CallBody) -> Option<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn write_body(buf: &mut Writer, body: &CallBody) {
|
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
|
// write all the indents with spaces and commas between
|
||||||
for idx in 0..body.roots.len() - 1 {
|
for idx in 0..body.roots.len() - 1 {
|
||||||
let ident = &body.roots[idx];
|
let ident = &body.roots[idx];
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ macro_rules! twoway {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
twoway!("comments-4sp" => comments_4sp (IndentOptions::new(IndentType::Spaces, 4)));
|
twoway!("comments-4sp" => comments_4sp (IndentOptions::new(IndentType::Spaces, 4, false)));
|
||||||
twoway!("comments-tab" => comments_tab (IndentOptions::new(IndentType::Tabs, 4)));
|
twoway!("comments-tab" => comments_tab (IndentOptions::new(IndentType::Tabs, 4, false)));
|
||||||
|
|
||||||
twoway!("multi-4sp" => multi_4sp (IndentOptions::new(IndentType::Spaces, 4)));
|
twoway!("multi-4sp" => multi_4sp (IndentOptions::new(IndentType::Spaces, 4, false)));
|
||||||
twoway!("multi-tab" => multi_tab (IndentOptions::new(IndentType::Tabs, 4)));
|
twoway!("multi-tab" => multi_tab (IndentOptions::new(IndentType::Tabs, 4, false)));
|
||||||
|
|
||||||
twoway!("multiexpr-4sp" => multiexpr_4sp (IndentOptions::new(IndentType::Spaces, 4)));
|
twoway!("multiexpr-4sp" => multiexpr_4sp (IndentOptions::new(IndentType::Spaces, 4, false)));
|
||||||
twoway!("multiexpr-tab" => multiexpr_tab (IndentOptions::new(IndentType::Tabs, 4)));
|
twoway!("multiexpr-tab" => multiexpr_tab (IndentOptions::new(IndentType::Tabs, 4, false)));
|
||||||
@@ -22,23 +22,33 @@ pub struct Autoformat {
|
|||||||
/// Input file
|
/// Input file
|
||||||
#[clap(short, long)]
|
#[clap(short, long)]
|
||||||
pub file: Option<String>,
|
pub file: Option<String>,
|
||||||
|
|
||||||
|
/// Split attributes in lines or not
|
||||||
|
#[clap(short, long, default_value = "false")]
|
||||||
|
pub split_line_attributes: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Autoformat {
|
impl Autoformat {
|
||||||
// Todo: autoformat the entire crate
|
// Todo: autoformat the entire crate
|
||||||
pub async fn autoformat(self) -> Result<()> {
|
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
|
// Default to formatting the project
|
||||||
if raw.is_none() && file.is_none() {
|
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);
|
eprintln!("error formatting project: {}", e);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(raw) = raw {
|
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) {
|
if let Some(inner) = dioxus_autofmt::fmt_block(&raw, 0, indent) {
|
||||||
println!("{}", inner);
|
println!("{}", inner);
|
||||||
} else {
|
} else {
|
||||||
@@ -50,15 +60,15 @@ impl Autoformat {
|
|||||||
|
|
||||||
// Format single file
|
// Format single file
|
||||||
if let Some(file) = file {
|
if let Some(file) = file {
|
||||||
refactor_file(file)?;
|
refactor_file(file, split_line_attributes)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn refactor_file(file: String) -> Result<(), Error> {
|
fn refactor_file(file: String, split_line_attributes: bool) -> Result<(), Error> {
|
||||||
let indent = indentation_for(".")?;
|
let indent = indentation_for(".", split_line_attributes)?;
|
||||||
let file_content = if file == "-" {
|
let file_content = if file == "-" {
|
||||||
let mut contents = String::new();
|
let mut contents = String::new();
|
||||||
std::io::stdin().read_to_string(&mut contents)?;
|
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
|
/// 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.
|
/// 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 crate_config = dioxus_cli_config::CrateConfig::new(None)?;
|
||||||
|
|
||||||
let files_to_format = get_project_files(&crate_config);
|
let files_to_format = get_project_files(&crate_config);
|
||||||
@@ -147,7 +157,7 @@ async fn autoformat_project(check: bool) -> Result<()> {
|
|||||||
return Ok(());
|
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
|
let counts = files_to_format
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@@ -181,7 +191,10 @@ async fn autoformat_project(check: bool) -> Result<()> {
|
|||||||
Ok(())
|
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")
|
let out = std::process::Command::new("cargo")
|
||||||
.args(["fmt", "--", "--print-config", "current"])
|
.args(["fmt", "--", "--print-config", "current"])
|
||||||
.arg(file_or_dir.as_ref())
|
.arg(file_or_dir.as_ref())
|
||||||
@@ -221,6 +234,7 @@ fn indentation_for(file_or_dir: impl AsRef<Path>) -> Result<IndentOptions> {
|
|||||||
IndentType::Spaces
|
IndentType::Spaces
|
||||||
},
|
},
|
||||||
tab_spaces,
|
tab_spaces,
|
||||||
|
split_line_attributes,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,6 +283,7 @@ async fn test_auto_fmt() {
|
|||||||
check: false,
|
check: false,
|
||||||
raw: Some(test_rsx),
|
raw: Some(test_rsx),
|
||||||
file: None,
|
file: None,
|
||||||
|
split_line_attributes: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
fmt.autoformat().await.unwrap();
|
fmt.autoformat().await.unwrap();
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ pub fn format_rsx(raw: String, use_tabs: bool, indent_size: usize) -> String {
|
|||||||
IndentType::Spaces
|
IndentType::Spaces
|
||||||
},
|
},
|
||||||
indent_size,
|
indent_size,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
block.unwrap()
|
block.unwrap()
|
||||||
@@ -32,6 +33,7 @@ pub fn format_selection(raw: String, use_tabs: bool, indent_size: usize) -> Stri
|
|||||||
IndentType::Spaces
|
IndentType::Spaces
|
||||||
},
|
},
|
||||||
indent_size,
|
indent_size,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
block.unwrap()
|
block.unwrap()
|
||||||
@@ -67,6 +69,7 @@ pub fn format_file(contents: String, use_tabs: bool, indent_size: usize) -> Form
|
|||||||
IndentType::Spaces
|
IndentType::Spaces
|
||||||
},
|
},
|
||||||
indent_size,
|
indent_size,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
let out = dioxus_autofmt::apply_formats(&contents, _edits.clone());
|
let out = dioxus_autofmt::apply_formats(&contents, _edits.clone());
|
||||||
|
|||||||
Reference in new issue
Block a user