@@ -45,6 +45,7 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
45
45
let mut visited_mods = FxHashSet :: default ( ) ;
46
46
let mut visited_consts = FxHashSet :: default ( ) ;
47
47
let mut visited_statics = FxHashSet :: default ( ) ;
48
+ let mut merged_fn_bodies = FxHashSet :: default ( ) ;
48
49
49
50
// regions can be nested, here is a LIFO buffer
50
51
let mut region_starts: Vec < TextSize > = vec ! [ ] ;
@@ -57,6 +58,31 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
57
58
NodeOrToken :: Token ( token) => token. text ( ) . contains ( '\n' ) ,
58
59
} ;
59
60
if is_multiline {
61
+ // for the arg list, we need to special handle
62
+ if matches ! ( element. kind( ) , ARG_LIST | PARAM_LIST ) {
63
+ if let NodeOrToken :: Node ( node) = & element {
64
+ if let Some ( fn_node) = node. parent ( ) . and_then ( ast:: Fn :: cast) {
65
+ if let Some ( body) = fn_node. body ( ) {
66
+ // just add a big fold combine the params and body
67
+ res. push ( Fold {
68
+ range : TextRange :: new (
69
+ node. text_range ( ) . start ( ) ,
70
+ body. syntax ( ) . text_range ( ) . end ( ) ,
71
+ ) ,
72
+ kind : FoldKind :: ArgList ,
73
+ } ) ;
74
+ merged_fn_bodies. insert ( body. syntax ( ) . text_range ( ) ) ;
75
+ continue ;
76
+ }
77
+ }
78
+ }
79
+ }
80
+ // skip the merged function body
81
+ if matches ! ( element. kind( ) , BLOCK_EXPR )
82
+ && merged_fn_bodies. contains ( & element. text_range ( ) )
83
+ {
84
+ continue ;
85
+ }
60
86
res. push ( Fold { range : element. text_range ( ) , kind } ) ;
61
87
continue ;
62
88
}
@@ -287,6 +313,7 @@ mod tests {
287
313
288
314
use super :: * ;
289
315
316
+ #[ track_caller]
290
317
fn check ( #[ rust_analyzer:: rust_fixture] ra_fixture : & str ) {
291
318
let ( ranges, text) = extract_tags ( ra_fixture, "fold" ) ;
292
319
@@ -537,7 +564,7 @@ const _: S = S <fold block>{
537
564
fn foo<fold arglist>(
538
565
x: i32,
539
566
y: String,
540
- )</fold> {}
567
+ ) {} </fold>
541
568
"# ,
542
569
)
543
570
}
0 commit comments