diff --git a/src/diff/changes.rs b/src/diff/changes.rs index dd60280799..eac05dc8c3 100644 --- a/src/diff/changes.rs +++ b/src/diff/changes.rs @@ -47,6 +47,7 @@ pub(crate) fn insert_deep_unchanged<'a>( }, ) => { for (child, opposite_child) in node_children.iter().zip(opposite_children) { + // TODO: one side may now be CanIgnore insert_deep_unchanged(child, opposite_child, change_map); } } diff --git a/src/display/json.rs b/src/display/json.rs index f0a10498c8..1612b79165 100644 --- a/src/display/json.rs +++ b/src/display/json.rs @@ -267,6 +267,7 @@ impl Highlight { AtomKind::Comment => Highlight::Comment, AtomKind::Type => Highlight::Type, AtomKind::Normal => Highlight::Normal, + AtomKind::CanIgnore => Highlight::Normal, AtomKind::TreeSitterError => Highlight::TreeSitterError, }, } diff --git a/src/display/style.rs b/src/display/style.rs index 8f31db145d..4167b4cabb 100644 --- a/src/display/style.rs +++ b/src/display/style.rs @@ -359,7 +359,7 @@ pub(crate) fn color_positions( style = style.bold(); } AtomKind::TreeSitterError => style = style.purple(), - AtomKind::Normal => {} + AtomKind::Normal | AtomKind::CanIgnore => {} } } } diff --git a/src/parse/syntax.rs b/src/parse/syntax.rs index ab2cafcc6a..eaa154ef4b 100644 --- a/src/parse/syntax.rs +++ b/src/parse/syntax.rs @@ -392,8 +392,14 @@ fn set_content_id(nodes: &[&Syntax], existing: &mut DftHashMap) // Recurse first, so children all have their content_id set. set_content_id(children, existing); - let children_content_ids: Vec<_> = - children.iter().map(|c| c.info().content_id.get()).collect(); + let children_content_ids: Vec<_> = children + .iter() + .filter(|c| match c { + List { .. } => true, + Atom { kind, .. } => *kind != AtomKind::CanIgnore, + }) + .map(|c| c.info().content_id.get()) + .collect(); ( Some(open_content.clone()), @@ -579,6 +585,11 @@ pub(crate) enum AtomKind { Comment, Keyword, TreeSitterError, + /// Trailing commas can be ignored in some positions, such as the + /// last comma in `[1, 2,]` in JS. However, it's not obligatory, + /// and it's useful when diffing `[1,]` against `[1, 2]` to be + /// able to match up the commas. + CanIgnore, } /// Unlike atoms, tokens can be delimiters like `{`. diff --git a/src/parse/tree_sitter_parser.rs b/src/parse/tree_sitter_parser.rs index 5ae72535cd..6245338a7f 100644 --- a/src/parse/tree_sitter_parser.rs +++ b/src/parse/tree_sitter_parser.rs @@ -1875,15 +1875,12 @@ fn list_from_cursor<'a>( if should_ignore_last_child(config, &root_node, &between_delim) { if let Some(last_child) = between_delim.pop() { if let Syntax::Atom { - position, - content, - kind, - .. + position, content, .. } = last_child { let position = position.clone(); - // TODO: New unused kind for atoms. - let new_last_child = Syntax::new_atom(arena, position, content, *kind); + let new_last_child = + Syntax::new_atom(arena, position, content, AtomKind::CanIgnore); between_delim.push(new_last_child); } }