diff --git a/examp/grouped_reorder.toml b/examp/grouped_reorder.toml new file mode 100644 index 0000000..538796c --- /dev/null +++ b/examp/grouped_reorder.toml @@ -0,0 +1,12 @@ +[package] +name = "foobar" +version = "0.1.0" +edition = "2021" + +[dependencies] +a = { workspace = true } +c = { workspace = true } +b = { workspace = true } + +e = { workspace = true } +d = { workspace = true } diff --git a/examp/grouped_reorder_output.toml b/examp/grouped_reorder_output.toml new file mode 100644 index 0000000..84f2e23 --- /dev/null +++ b/examp/grouped_reorder_output.toml @@ -0,0 +1,12 @@ +[package] +name = "foobar" +version = "0.1.0" +edition = "2021" + +[dependencies] +a = { workspace = true } +b = { workspace = true } +c = { workspace = true } + +d = { workspace = true } +e = { workspace = true } diff --git a/src/sort.rs b/src/sort.rs index 7252398..0c1c959 100644 --- a/src/sort.rs +++ b/src/sort.rs @@ -165,6 +165,7 @@ fn sort_by_group(table: &mut Table) { table.clear(); let mut groups = BTreeMap::new(); let mut curr = 0; + for (idx, (k, v)) in table_clone.iter_mut().enumerate() { let blank_lines = k .leaf_decor() @@ -175,9 +176,20 @@ fn sort_by_group(table: &mut Table) { .filter(|l| !l.starts_with('#')) .count(); - let k = Key::new(&*k).with_leaf_decor(k.leaf_decor().clone()); + let mut k = Key::new(&*k).with_leaf_decor(k.leaf_decor().clone()); if blank_lines > 0 { + // remove the newline from the beginning of the new group in case it gets moved to a + // different place in the group + let decor = k.leaf_decor_mut(); + if let Some(prefix) = decor.prefix().and_then(RawString::as_str) { + if prefix.starts_with("\n") { + decor.set_prefix(RawString::from(&prefix[1..])); + } else if prefix.starts_with("\r\n") { + decor.set_prefix(RawString::from(&prefix[2..])); + } + } + groups.entry(idx).or_insert_with(|| vec![(k, v)]); curr = idx; } else { @@ -185,8 +197,20 @@ fn sort_by_group(table: &mut Table) { } } - for (_, mut group) in groups { + for (i, mut group) in groups.into_values().enumerate() { group.sort_by(|a, b| a.0.cmp(&b.0)); + + // for sections after the first, attach a newline to the decor of the first element + if i != 0 { + if let Some((k, _)) = group.first_mut() { + let decor = k.leaf_decor_mut(); + let prefix = + decor.prefix().and_then(RawString::as_str).unwrap_or_default(); + // converting to clrf gets handled later if necessary + decor.set_prefix(RawString::from(format!("\n{prefix}"))); + } + } + for (k, v) in group { table.insert_formatted(&k, v.clone()); } @@ -360,4 +384,13 @@ mod test { ); assert_ne!(input, sorted.to_string()); } + + #[test] + fn grouped_reorder() { + let input = fs::read_to_string("examp/grouped_reorder.toml").unwrap(); + let expected_output = + fs::read_to_string("examp/grouped_reorder_output.toml").unwrap(); + let sorted = super::sort_toml(&input, MATCHER, true, &[]); + assert_eq!(sorted.to_string(), expected_output); + } }