@@ -47,6 +47,7 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
4747 let mut res = vec ! [ ] ;
4848 let mut visited_comments = FxHashSet :: default ( ) ;
4949 let mut visited_nodes = FxHashSet :: default ( ) ;
50+ let mut merged_fn_bodies = FxHashSet :: default ( ) ;
5051
5152 // regions can be nested, here is a LIFO buffer
5253 let mut region_starts: Vec < TextSize > = vec ! [ ] ;
@@ -59,6 +60,31 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
5960 NodeOrToken :: Token ( token) => token. text ( ) . contains ( '\n' ) ,
6061 } ;
6162 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+ }
6288 res. push ( Fold { range : element. text_range ( ) , kind } ) ;
6389 continue ;
6490 }
@@ -291,6 +317,7 @@ mod tests {
291317
292318 use super :: * ;
293319
320+ #[ track_caller]
294321 fn check ( #[ rust_analyzer:: rust_fixture] ra_fixture : & str ) {
295322 let ( ranges, text) = extract_tags ( ra_fixture, "fold" ) ;
296323
@@ -544,7 +571,7 @@ const _: S = S <fold block>{
544571fn foo<fold arglist>(
545572 x: i32,
546573 y: String,
547- )</fold> {}
574+ ) {} </fold>
548575"# ,
549576 )
550577 }
0 commit comments