diff options
author | Wilfred Hughes <me@wilfred.me.uk> | 2024-07-21 15:34:53 -0700 |
---|---|---|
committer | Wilfred Hughes <me@wilfred.me.uk> | 2024-07-23 17:36:05 -0700 |
commit | 9d957afc028fdaa371a2a5c3a4e87fdd2e1be809 (patch) | |
tree | 6de56947ae4c51250a378373e21118cf7fb0828a | |
parent | 78650c310ad5f4683910a0ff54418efc7520a689 (diff) |
Experiment with an empty delimiter heuristc on changed listsempty_delimiters_heuristic
TODO: only do this change on atoms.
See #587
-rw-r--r-- | a1.py | 5 | ||||
-rw-r--r-- | a2.py | 5 | ||||
-rw-r--r-- | sample_files/compare.expected | 2 | ||||
-rw-r--r-- | src/diff/sliders.rs | 81 |
4 files changed, 89 insertions, 4 deletions
@@ -0,0 +1,5 @@ +def test(a, b): + if a: + print(a) + if b: + print(b) @@ -0,0 +1,5 @@ +def test(a, b): + if a: + print(a) + if b: + print(b) diff --git a/sample_files/compare.expected b/sample_files/compare.expected index abf93c3298..be95950c04 100644 --- a/sample_files/compare.expected +++ b/sample_files/compare.expected @@ -281,7 +281,7 @@ sample_files/typescript_1.ts sample_files/typescript_2.ts fee7ee33d2037ad1941ba6bb5532a1db - sample_files/typing_1.ml sample_files/typing_2.ml -36161bd77a8c86643bc90656ec41c92c - +cbaa5ed3cb2c7ad8174944feb5820670 - sample_files/utf16_1.py sample_files/utf16_2.py 39014a682ed2318f980c7ea4177cf659 - diff --git a/src/diff/sliders.rs b/src/diff/sliders.rs index cd3da98929..fe450246e4 100644 --- a/src/diff/sliders.rs +++ b/src/diff/sliders.rs @@ -32,9 +32,15 @@ use line_numbers::SingleLineSpan; use crate::{ - diff::changes::{insert_deep_novel, insert_deep_unchanged, ChangeKind::*, ChangeMap}, - parse::guess_language, - parse::syntax::Syntax::{self, *}, + diff::changes::{ + insert_deep_novel, insert_deep_unchanged, + ChangeKind::{self, *}, + ChangeMap, + }, + parse::{ + guess_language, + syntax::Syntax::{self, *}, + }, }; pub(crate) fn fix_all_sliders<'a>( @@ -47,6 +53,75 @@ pub(crate) fn fix_all_sliders<'a>( fix_all_sliders_one_step(nodes, change_map); fix_all_nested_sliders(language, nodes, change_map); + + fix_invisible_delims(nodes, change_map); +} + +fn fix_invisible_delims<'a>(nodes: &[&'a Syntax<'a>], change_map: &mut ChangeMap<'a>) { + for node in nodes { + match node { + List { + open_content, + children, + close_content, + .. + } => { + if let Some(change_kind) = change_map.get(node) { + if open_content == "" + && close_content == "" + && matches!(change_kind, ChangeKind::Novel) + { + let mut all_children_unchanged = true; + for child in children { + let Some(child_change) = change_map.get(child) else { + continue; + }; + + if !matches!(child_change, ChangeKind::Unchanged(_)) { + all_children_unchanged = false; + break; + } + } + + if all_children_unchanged { + if let Some(parent) = node.parent() { + let List { + children: siblings, .. + } = parent + else { + unreachable!() + }; + + let child = siblings.first().unwrap(); + change_unchanged_to_novel(child, change_map); + + if siblings.len() > 1 { + change_unchanged_to_novel( + siblings[siblings.len() - 2], + change_map, + ); + } + } + } + } + fix_invisible_delims(children, change_map); + } + } + Atom { .. } => {} + } + } +} + +fn change_unchanged_to_novel<'a>(node: &'a Syntax<'a>, change_map: &mut ChangeMap<'a>) { + let Some(change) = change_map.get(node) else { + return; + }; + let Unchanged(opposite_node) = change else { + return; + }; + + change_map.insert(node, ChangeKind::Novel); + change_map.insert(opposite_node, ChangeKind::Novel); } /// Should nester slider correction prefer the inner or outer |