diff options
Diffstat (limited to 'crates/ide')
-rw-r--r-- | crates/ide/src/folding_ranges.rs | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/crates/ide/src/folding_ranges.rs b/crates/ide/src/folding_ranges.rs index 2b9ed123c..e03ddaa14 100644 --- a/crates/ide/src/folding_ranges.rs +++ b/crates/ide/src/folding_ranges.rs | |||
@@ -20,6 +20,7 @@ pub enum FoldKind { | |||
20 | Consts, | 20 | Consts, |
21 | Statics, | 21 | Statics, |
22 | Array, | 22 | Array, |
23 | WhereClause, | ||
23 | } | 24 | } |
24 | 25 | ||
25 | #[derive(Debug)] | 26 | #[derive(Debug)] |
@@ -35,6 +36,7 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> { | |||
35 | let mut visited_mods = FxHashSet::default(); | 36 | let mut visited_mods = FxHashSet::default(); |
36 | let mut visited_consts = FxHashSet::default(); | 37 | let mut visited_consts = FxHashSet::default(); |
37 | let mut visited_statics = FxHashSet::default(); | 38 | let mut visited_statics = FxHashSet::default(); |
39 | let mut visited_where_clauses = FxHashSet::default(); | ||
38 | // regions can be nested, here is a LIFO buffer | 40 | // regions can be nested, here is a LIFO buffer |
39 | let mut regions_starts: Vec<TextSize> = vec![]; | 41 | let mut regions_starts: Vec<TextSize> = vec![]; |
40 | 42 | ||
@@ -109,6 +111,15 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> { | |||
109 | res.push(Fold { range, kind: FoldKind::Statics }) | 111 | res.push(Fold { range, kind: FoldKind::Statics }) |
110 | } | 112 | } |
111 | } | 113 | } |
114 | |||
115 | // Fold where clause | ||
116 | if node.kind() == WHERE_CLAUSE && !visited_where_clauses.contains(&node) { | ||
117 | if let Some(range) = | ||
118 | contiguous_range_for_where(&node, &mut visited_where_clauses) | ||
119 | { | ||
120 | res.push(Fold { range, kind: FoldKind::WhereClause }) | ||
121 | } | ||
122 | } | ||
112 | } | 123 | } |
113 | } | 124 | } |
114 | } | 125 | } |
@@ -241,6 +252,28 @@ fn contiguous_range_for_comment( | |||
241 | } | 252 | } |
242 | } | 253 | } |
243 | 254 | ||
255 | fn contiguous_range_for_where( | ||
256 | node: &SyntaxNode, | ||
257 | visited: &mut FxHashSet<SyntaxNode>, | ||
258 | ) -> Option<TextRange> { | ||
259 | let first_where_pred = node.first_child(); | ||
260 | let last_where_pred = node.last_child(); | ||
261 | |||
262 | if first_where_pred != last_where_pred { | ||
263 | let mut it = node.descendants_with_tokens(); | ||
264 | if let (Some(_where_clause), Some(where_kw), Some(last_comma)) = | ||
265 | (it.next(), it.next(), it.last()) | ||
266 | { | ||
267 | let start = where_kw.text_range().end(); | ||
268 | let end = last_comma.text_range().end(); | ||
269 | |||
270 | visited.insert(node.clone()); | ||
271 | return Some(TextRange::new(start, end)); | ||
272 | } | ||
273 | } | ||
274 | None | ||
275 | } | ||
276 | |||
244 | #[cfg(test)] | 277 | #[cfg(test)] |
245 | mod tests { | 278 | mod tests { |
246 | use test_utils::extract_tags; | 279 | use test_utils::extract_tags; |
@@ -272,6 +305,7 @@ mod tests { | |||
272 | FoldKind::Consts => "consts", | 305 | FoldKind::Consts => "consts", |
273 | FoldKind::Statics => "statics", | 306 | FoldKind::Statics => "statics", |
274 | FoldKind::Array => "array", | 307 | FoldKind::Array => "array", |
308 | FoldKind::WhereClause => "whereclause", | ||
275 | }; | 309 | }; |
276 | assert_eq!(kind, &attr.unwrap()); | 310 | assert_eq!(kind, &attr.unwrap()); |
277 | } | 311 | } |
@@ -513,4 +547,23 @@ static SECOND_STATIC: &str = "second";</fold> | |||
513 | "#, | 547 | "#, |
514 | ) | 548 | ) |
515 | } | 549 | } |
550 | |||
551 | #[test] | ||
552 | fn fold_where_clause() { | ||
553 | // fold multi-line and don't fold single line. | ||
554 | check( | ||
555 | r#" | ||
556 | fn foo() | ||
557 | where<fold whereclause> | ||
558 | A: Foo, | ||
559 | B: Foo, | ||
560 | C: Foo, | ||
561 | D: Foo,</fold> {} | ||
562 | |||
563 | fn bar() | ||
564 | where | ||
565 | A: Bar, {} | ||
566 | "#, | ||
567 | ) | ||
568 | } | ||
516 | } | 569 | } |