Skip to content

Commit efea07f

Browse files
committed
Add nested region folding test
1 parent 658514d commit efea07f

File tree

1 file changed

+32
-27
lines changed

1 file changed

+32
-27
lines changed

crates/ide/src/folding_ranges.rs

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ use syntax::{
77
SyntaxNode, TextRange, TextSize,
88
};
99

10+
const REGION_START: &str = "// region:";
11+
const REGION_END: &str = "// endregion";
12+
1013
#[derive(Debug, PartialEq, Eq)]
1114
pub enum FoldKind {
1215
Comment,
@@ -30,17 +33,18 @@ pub struct Fold {
3033

3134
// Feature: Folding
3235
//
33-
// Defines folding regions for curly braced blocks, runs of consecutive import
34-
// statements, and `region` / `endregion` comment markers.
36+
// Defines folding regions for curly braced blocks, runs of consecutive use, mod, const or static
37+
// items, and `region` / `endregion` comment markers.
3538
pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
3639
let mut res = vec![];
3740
let mut visited_comments = FxHashSet::default();
3841
let mut visited_imports = FxHashSet::default();
3942
let mut visited_mods = FxHashSet::default();
4043
let mut visited_consts = FxHashSet::default();
4144
let mut visited_statics = FxHashSet::default();
45+
4246
// regions can be nested, here is a LIFO buffer
43-
let mut regions_starts: Vec<TextSize> = vec![];
47+
let mut region_starts: Vec<TextSize> = vec![];
4448

4549
for element in file.syntax().descendants_with_tokens() {
4650
// Fold items that span multiple lines
@@ -59,27 +63,23 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
5963
NodeOrToken::Token(token) => {
6064
// Fold groups of comments
6165
if let Some(comment) = ast::Comment::cast(token) {
62-
if !visited_comments.contains(&comment) {
63-
// regions are not real comments
64-
if comment.text().trim().starts_with("// region:") {
65-
regions_starts.push(comment.syntax().text_range().start());
66-
} else if comment.text().trim().starts_with("// endregion") {
67-
if let Some(region) = regions_starts.pop() {
68-
res.push(Fold {
69-
range: TextRange::new(
70-
region,
71-
comment.syntax().text_range().end(),
72-
),
73-
kind: FoldKind::Region,
74-
})
75-
}
76-
} else {
77-
if let Some(range) =
78-
contiguous_range_for_comment(comment, &mut visited_comments)
79-
{
80-
res.push(Fold { range, kind: FoldKind::Comment })
81-
}
66+
if visited_comments.contains(&comment) {
67+
continue;
68+
}
69+
let text = comment.text().trim_start();
70+
if text.starts_with(REGION_START) {
71+
region_starts.push(comment.syntax().text_range().start());
72+
} else if text.starts_with(REGION_END) {
73+
if let Some(region) = region_starts.pop() {
74+
res.push(Fold {
75+
range: TextRange::new(region, comment.syntax().text_range().end()),
76+
kind: FoldKind::Region,
77+
})
8278
}
79+
} else if let Some(range) =
80+
contiguous_range_for_comment(comment, &mut visited_comments)
81+
{
82+
res.push(Fold { range, kind: FoldKind::Comment })
8383
}
8484
}
8585
}
@@ -286,16 +286,18 @@ mod tests {
286286
let (ranges, text) = extract_tags(ra_fixture, "fold");
287287

288288
let parse = SourceFile::parse(&text);
289-
let folds = folding_ranges(&parse.tree());
289+
let mut folds = folding_ranges(&parse.tree());
290+
folds.sort_by_key(|fold| (fold.range.start(), fold.range.end()));
291+
290292
assert_eq!(
291293
folds.len(),
292294
ranges.len(),
293295
"The amount of folds is different than the expected amount"
294296
);
295297

296298
for (fold, (range, attr)) in folds.iter().zip(ranges.into_iter()) {
297-
assert_eq!(fold.range.start(), range.start());
298-
assert_eq!(fold.range.end(), range.end());
299+
assert_eq!(fold.range.start(), range.start(), "mismatched start of folding ranges");
300+
assert_eq!(fold.range.end(), range.end(), "mismatched end of folding ranges");
299301

300302
let kind = match fold.kind {
301303
FoldKind::Comment => "comment",
@@ -525,7 +527,10 @@ const FOO: [usize; 4] = <fold array>[
525527
// 1. some normal comment
526528
<fold region>// region: test
527529
// 2. some normal comment
528-
calling_function(x,y);
530+
<fold region>// region: inner
531+
fn f() {}
532+
// endregion</fold>
533+
fn f2() {}
529534
// endregion: test</fold>
530535
"#,
531536
)

0 commit comments

Comments
 (0)