diff --git a/crates/diffr-core/src/parse/fold_tests.rs b/crates/diffr-core/src/parse/fold_tests.rs index 03d5c6f74..62b47f23d 100644 --- a/crates/diffr-core/src/parse/fold_tests.rs +++ b/crates/diffr-core/src/parse/fold_tests.rs @@ -325,7 +325,8 @@ mod folds { // A function whose body is one `match`: the block the shared query // folds and the `match` the context query folds cover the same // lines, so they are one fold. It is the `match`'s, the innermost - // node whose extent that region is, and it carries both tags. + // node whose extent that region is, and it carries both tags and + // the block's braces, since the `match` has no opener of its own. let src = "fn f(x: u32) -> u32 {\n match x {\n 1 => 2,\n _ => 3,\n }\n}\n"; let params = crate::config::Config::from_toml("") @@ -349,6 +350,11 @@ mod folds { "{:?}", same_lines[0].tags ); + let syntax = same_lines[0].syntax.expect("the block's opener and closer"); + assert_eq!( + text(src, &syntax), + "\n match x {\n 1 => 2,\n _ => 3,\n }\n" + ); } #[test] diff --git a/crates/diffr-core/src/parse/folds.rs b/crates/diffr-core/src/parse/folds.rs index 8e6a48c99..d422566fc 100644 --- a/crates/diffr-core/src/parse/folds.rs +++ b/crates/diffr-core/src/parse/folds.rs @@ -232,7 +232,10 @@ fn depth(node: tree_sitter::Node<'_>) -> usize { /// Merge folds of different nodes that cover the same whole lines, such as a /// Rust `Self { … }` tail expression and the `{ … }` field list inside it. /// The merged fold keeps the innermost node's range, indent and syntax (the -/// deepest among equal ranges), plus every fold's tags and relations. +/// deepest among equal ranges), plus every fold's tags and relations. When +/// the innermost node has no opener, as a lone statement in a block has none, +/// the fold keeps the opener and closer of the node it merged: they delimit +/// the same lines, so frontends still find the brackets and the rail. /// A fold with no whole line merges with nothing. fn merge_by_lines( mut folds: Vec<(usize, usize, FoldMetadata)>, @@ -275,6 +278,7 @@ fn merge_by_lines( } else { (owner, held, metadata) }; + kept.syntax = kept.syntax.or(lost.syntax); kept.tags.extend(lost.tags); kept.tags.sort(); kept.tags.dedup();