mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 11:20:54 +00:00
Merge pull request #20054 from Young-Flash/folding_all
feat: support folding multiline arg list & fn body in one folding range
This commit is contained in:
commit
600f573256
@ -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",
|
||||
};
|
||||
@ -329,6 +360,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(
|
||||
@ -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>
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
@ -911,7 +911,8 @@ pub(crate) fn folding_range(
|
||||
| FoldKind::Array
|
||||
| FoldKind::TraitAliases
|
||||
| FoldKind::ExternCrates
|
||||
| FoldKind::MatchArm => None,
|
||||
| FoldKind::MatchArm
|
||||
| FoldKind::Function => None,
|
||||
};
|
||||
|
||||
let range = range(line_index, fold.range);
|
||||
|
Loading…
x
Reference in New Issue
Block a user