@@ -47,6 +47,7 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
47
47
let mut res = vec ! [ ] ;
48
48
let mut visited_comments = FxHashSet :: default ( ) ;
49
49
let mut visited_nodes = FxHashSet :: default ( ) ;
50
+ let mut merged_fn_bodies = FxHashSet :: default ( ) ;
50
51
51
52
// regions can be nested, here is a LIFO buffer
52
53
let mut region_starts: Vec < TextSize > = vec ! [ ] ;
@@ -59,6 +60,31 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
59
60
NodeOrToken :: Token ( token) => token. text ( ) . contains ( '\n' ) ,
60
61
} ;
61
62
if is_multiline {
63
+ // for the arg list, we need to special handle
64
+ if matches ! ( element. kind( ) , ARG_LIST | PARAM_LIST ) {
65
+ if let NodeOrToken :: Node ( node) = & element {
66
+ if let Some ( fn_node) = node. parent ( ) . and_then ( ast:: Fn :: cast) {
67
+ if let Some ( body) = fn_node. body ( ) {
68
+ // just add a big fold combine the params and body
69
+ res. push ( Fold {
70
+ range : TextRange :: new (
71
+ node. text_range ( ) . start ( ) ,
72
+ body. syntax ( ) . text_range ( ) . end ( ) ,
73
+ ) ,
74
+ kind : FoldKind :: ArgList ,
75
+ } ) ;
76
+ merged_fn_bodies. insert ( body. syntax ( ) . text_range ( ) ) ;
77
+ continue ;
78
+ }
79
+ }
80
+ }
81
+ }
82
+ // skip the merged function body
83
+ if matches ! ( element. kind( ) , BLOCK_EXPR )
84
+ && merged_fn_bodies. contains ( & element. text_range ( ) )
85
+ {
86
+ continue ;
87
+ }
62
88
res. push ( Fold { range : element. text_range ( ) , kind } ) ;
63
89
continue ;
64
90
}
@@ -291,6 +317,7 @@ mod tests {
291
317
292
318
use super :: * ;
293
319
320
+ #[ track_caller]
294
321
fn check ( #[ rust_analyzer:: rust_fixture] ra_fixture : & str ) {
295
322
let ( ranges, text) = extract_tags ( ra_fixture, "fold" ) ;
296
323
@@ -544,7 +571,7 @@ const _: S = S <fold block>{
544
571
fn foo<fold arglist>(
545
572
x: i32,
546
573
y: String,
547
- )</fold> {}
574
+ ) {} </fold>
548
575
"# ,
549
576
)
550
577
}
0 commit comments