Skip to content

Commit c1cf45a

Browse files
authored
Merge pull request #20054 from Young-Flash/folding_all
feat: support folding multiline arg list & fn body in one folding range
2 parents 649ec27 + 594252f commit c1cf45a

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

src/tools/rust-analyzer/crates/ide/src/folding_ranges.rs

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub enum FoldKind {
2323
WhereClause,
2424
ReturnType,
2525
MatchArm,
26+
Function,
2627
// region: item runs
2728
Modules,
2829
Consts,
@@ -47,6 +48,7 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
4748
let mut res = vec![];
4849
let mut visited_comments = FxHashSet::default();
4950
let mut visited_nodes = FxHashSet::default();
51+
let mut merged_fn_bodies = FxHashSet::default();
5052

5153
// regions can be nested, here is a LIFO buffer
5254
let mut region_starts: Vec<TextSize> = vec![];
@@ -59,6 +61,32 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
5961
NodeOrToken::Token(token) => token.text().contains('\n'),
6062
};
6163
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+
}
6290
res.push(Fold { range: element.text_range(), kind });
6391
continue;
6492
}
@@ -152,6 +180,7 @@ fn fold_kind(kind: SyntaxKind) -> Option<FoldKind> {
152180
ARG_LIST | PARAM_LIST | GENERIC_ARG_LIST | GENERIC_PARAM_LIST => Some(FoldKind::ArgList),
153181
ARRAY_EXPR => Some(FoldKind::Array),
154182
RET_TYPE => Some(FoldKind::ReturnType),
183+
FN => Some(FoldKind::Function),
155184
WHERE_CLAUSE => Some(FoldKind::WhereClause),
156185
ASSOC_ITEM_LIST
157186
| RECORD_FIELD_LIST
@@ -291,6 +320,7 @@ mod tests {
291320

292321
use super::*;
293322

323+
#[track_caller]
294324
fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
295325
let (ranges, text) = extract_tags(ra_fixture, "fold");
296326

@@ -322,13 +352,31 @@ mod tests {
322352
FoldKind::WhereClause => "whereclause",
323353
FoldKind::ReturnType => "returntype",
324354
FoldKind::MatchArm => "matcharm",
355+
FoldKind::Function => "function",
325356
FoldKind::TraitAliases => "traitaliases",
326357
FoldKind::ExternCrates => "externcrates",
327358
};
328359
assert_eq!(kind, &attr.unwrap());
329360
}
330361
}
331362

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+
332380
#[test]
333381
fn test_fold_comments() {
334382
check(
@@ -541,10 +589,10 @@ const _: S = S <fold block>{
541589
fn fold_multiline_params() {
542590
check(
543591
r#"
544-
fn foo<fold arglist>(
592+
<fold function>fn foo<fold arglist>(
545593
x: i32,
546594
y: String,
547-
)</fold> {}
595+
)</fold> {}</fold>
548596
"#,
549597
)
550598
}

src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -911,7 +911,8 @@ pub(crate) fn folding_range(
911911
| FoldKind::Array
912912
| FoldKind::TraitAliases
913913
| FoldKind::ExternCrates
914-
| FoldKind::MatchArm => None,
914+
| FoldKind::MatchArm
915+
| FoldKind::Function => None,
915916
};
916917

917918
let range = range(line_index, fold.range);

0 commit comments

Comments
 (0)