Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/folding_ranges.rs')
| -rwxr-xr-x | crates/ide/src/folding_ranges.rs | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/crates/ide/src/folding_ranges.rs b/crates/ide/src/folding_ranges.rs index 9bd8504733..c081796d07 100755 --- a/crates/ide/src/folding_ranges.rs +++ b/crates/ide/src/folding_ranges.rs @@ -23,6 +23,7 @@ pub enum FoldKind { WhereClause, ReturnType, MatchArm, + Function, // region: item runs Modules, Consts, @@ -47,6 +48,7 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> { let mut res = vec![]; let mut visited_comments = FxHashSet::default(); let mut visited_nodes = FxHashSet::default(); + let mut merged_fn_bodies = FxHashSet::default(); // regions can be nested, here is a LIFO buffer let mut region_starts: Vec<TextSize> = vec![]; @@ -59,6 +61,32 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> { NodeOrToken::Token(token) => token.text().contains('\n'), }; if is_multiline { + // for the func with multiline param list + if matches!(element.kind(), FN) { + if let NodeOrToken::Node(node) = &element { + if let Some(fn_node) = ast::Fn::cast(node.clone()) { + if !fn_node + .param_list() + .map(|param_list| param_list.syntax().text().contains_char('\n')) + .unwrap_or(false) + { + continue; + } + + if let Some(body) = fn_node.body() { + res.push(Fold { + range: TextRange::new( + node.text_range().start(), + node.text_range().end(), + ), + kind: FoldKind::Function, + }); + merged_fn_bodies.insert(body.syntax().text_range()); + continue; + } + } + } + } res.push(Fold { range: element.text_range(), kind }); continue; } @@ -152,6 +180,7 @@ fn fold_kind(kind: SyntaxKind) -> Option<FoldKind> { ARG_LIST | PARAM_LIST | GENERIC_ARG_LIST | GENERIC_PARAM_LIST => Some(FoldKind::ArgList), ARRAY_EXPR => Some(FoldKind::Array), RET_TYPE => Some(FoldKind::ReturnType), + FN => Some(FoldKind::Function), WHERE_CLAUSE => Some(FoldKind::WhereClause), ASSOC_ITEM_LIST | RECORD_FIELD_LIST @@ -291,6 +320,7 @@ mod tests { use super::*; + #[track_caller] fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str) { let (ranges, text) = extract_tags(ra_fixture, "fold"); @@ -322,6 +352,7 @@ mod tests { FoldKind::WhereClause => "whereclause", FoldKind::ReturnType => "returntype", FoldKind::MatchArm => "matcharm", + FoldKind::Function => "function", FoldKind::TraitAliases => "traitaliases", FoldKind::ExternCrates => "externcrates", }; @@ -330,6 +361,23 @@ mod tests { } #[test] + fn test_fold_func_with_multiline_param_list() { + check( + r#" +<fold function>fn func<fold arglist>( + a: i32, + b: i32, + c: i32, +)</fold> <fold block>{ + + + +}</fold></fold> +"#, + ); + } + + #[test] fn test_fold_comments() { check( r#" @@ -541,10 +589,10 @@ const _: S = S <fold block>{ fn fold_multiline_params() { check( r#" -fn foo<fold arglist>( +<fold function>fn foo<fold arglist>( x: i32, y: String, -)</fold> {} +)</fold> {}</fold> "#, ) } |