@@ -23,6 +23,7 @@ pub enum FoldKind {
23
23
WhereClause ,
24
24
ReturnType ,
25
25
MatchArm ,
26
+ Function ,
26
27
// region: item runs
27
28
Modules ,
28
29
Consts ,
@@ -47,6 +48,7 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
47
48
let mut res = vec ! [ ] ;
48
49
let mut visited_comments = FxHashSet :: default ( ) ;
49
50
let mut visited_nodes = FxHashSet :: default ( ) ;
51
+ let mut merged_fn_bodies = FxHashSet :: default ( ) ;
50
52
51
53
// regions can be nested, here is a LIFO buffer
52
54
let mut region_starts: Vec < TextSize > = vec ! [ ] ;
@@ -59,6 +61,32 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
59
61
NodeOrToken :: Token ( token) => token. text ( ) . contains ( '\n' ) ,
60
62
} ;
61
63
if is_multiline {
64
+ // for the func with multiline param list
65
+ if matches ! ( element. kind( ) , FN ) {
66
+ if let NodeOrToken :: Node ( node) = & element {
67
+ if let Some ( fn_node) = ast:: Fn :: cast ( node. clone ( ) ) {
68
+ if !fn_node
69
+ . param_list ( )
70
+ . map ( |param_list| param_list. syntax ( ) . text ( ) . contains_char ( '\n' ) )
71
+ . unwrap_or ( false )
72
+ {
73
+ continue ;
74
+ }
75
+
76
+ if let Some ( body) = fn_node. body ( ) {
77
+ res. push ( Fold {
78
+ range : TextRange :: new (
79
+ node. text_range ( ) . start ( ) ,
80
+ node. text_range ( ) . end ( ) ,
81
+ ) ,
82
+ kind : FoldKind :: Function ,
83
+ } ) ;
84
+ merged_fn_bodies. insert ( body. syntax ( ) . text_range ( ) ) ;
85
+ continue ;
86
+ }
87
+ }
88
+ }
89
+ }
62
90
res. push ( Fold { range : element. text_range ( ) , kind } ) ;
63
91
continue ;
64
92
}
@@ -152,6 +180,7 @@ fn fold_kind(kind: SyntaxKind) -> Option<FoldKind> {
152
180
ARG_LIST | PARAM_LIST | GENERIC_ARG_LIST | GENERIC_PARAM_LIST => Some ( FoldKind :: ArgList ) ,
153
181
ARRAY_EXPR => Some ( FoldKind :: Array ) ,
154
182
RET_TYPE => Some ( FoldKind :: ReturnType ) ,
183
+ FN => Some ( FoldKind :: Function ) ,
155
184
WHERE_CLAUSE => Some ( FoldKind :: WhereClause ) ,
156
185
ASSOC_ITEM_LIST
157
186
| RECORD_FIELD_LIST
@@ -291,6 +320,7 @@ mod tests {
291
320
292
321
use super :: * ;
293
322
323
+ #[ track_caller]
294
324
fn check ( #[ rust_analyzer:: rust_fixture] ra_fixture : & str ) {
295
325
let ( ranges, text) = extract_tags ( ra_fixture, "fold" ) ;
296
326
@@ -322,13 +352,31 @@ mod tests {
322
352
FoldKind :: WhereClause => "whereclause" ,
323
353
FoldKind :: ReturnType => "returntype" ,
324
354
FoldKind :: MatchArm => "matcharm" ,
355
+ FoldKind :: Function => "function" ,
325
356
FoldKind :: TraitAliases => "traitaliases" ,
326
357
FoldKind :: ExternCrates => "externcrates" ,
327
358
} ;
328
359
assert_eq ! ( kind, & attr. unwrap( ) ) ;
329
360
}
330
361
}
331
362
363
+ #[ test]
364
+ fn test_fold_func_with_multiline_param_list ( ) {
365
+ check (
366
+ r#"
367
+ <fold function>fn func<fold arglist>(
368
+ a: i32,
369
+ b: i32,
370
+ c: i32,
371
+ )</fold> <fold block>{
372
+
373
+
374
+
375
+ }</fold></fold>
376
+ "# ,
377
+ ) ;
378
+ }
379
+
332
380
#[ test]
333
381
fn test_fold_comments ( ) {
334
382
check (
@@ -541,10 +589,10 @@ const _: S = S <fold block>{
541
589
fn fold_multiline_params ( ) {
542
590
check (
543
591
r#"
544
- fn foo<fold arglist>(
592
+ <fold function> fn foo<fold arglist>(
545
593
x: i32,
546
594
y: String,
547
- )</fold> {}
595
+ )</fold> {}</fold>
548
596
"# ,
549
597
)
550
598
}
0 commit comments