Skip to content

Commit d75577f

Browse files
Merge #3483
3483: Unfold groups with single assists into plain assists r=matklad a=SomeoneToIgnore A follow-up of https://github.com/rust-analyzer/rust-analyzer/pull/3120/files#r378788698 , made to show more detailed label when the assist group contains a single element Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
2 parents 670895a + 0ff8c55 commit d75577f

File tree

3 files changed

+73
-66
lines changed

3 files changed

+73
-66
lines changed

crates/ra_assists/src/assist_ctx.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,11 @@ impl<'a> AssistGroup<'a> {
166166
}
167167

168168
pub(crate) fn finish(self) -> Option<Assist> {
169-
assert!(!self.assists.is_empty());
170-
Some(Assist(self.assists))
169+
if self.assists.is_empty() {
170+
None
171+
} else {
172+
Some(Assist(self.assists))
173+
}
171174
}
172175
}
173176

crates/ra_assists/src/handlers/auto_import.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,7 @@ pub(crate) fn auto_import(ctx: AssistCtx) -> Option<Assist> {
4242
return None;
4343
}
4444

45-
let assist_group_name = if proposed_imports.len() == 1 {
46-
format!("Import `{}`", proposed_imports.iter().next().unwrap())
47-
} else {
48-
auto_import_assets.get_import_group_message()
49-
};
50-
let mut group = ctx.add_assist_group(assist_group_name);
45+
let mut group = ctx.add_assist_group(auto_import_assets.get_import_group_message());
5146
for import in proposed_imports {
5247
group.add_assist(AssistId("auto_import"), format!("Import `{}`", &import), |edit| {
5348
edit.target(auto_import_assets.syntax_under_caret.text_range());

crates/rust-analyzer/src/main_loop/handlers.rs

Lines changed: 67 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
//! `ra_ide` crate.
44
55
use std::{
6-
collections::hash_map::Entry,
76
fmt::Write as _,
87
io::Write as _,
98
process::{self, Stdio},
@@ -13,15 +12,15 @@ use lsp_server::ErrorCode;
1312
use lsp_types::{
1413
CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem,
1514
CallHierarchyOutgoingCall, CallHierarchyOutgoingCallsParams, CallHierarchyPrepareParams,
16-
CodeAction, CodeActionOrCommand, CodeActionResponse, CodeLens, Command, CompletionItem,
17-
Diagnostic, DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange,
18-
FoldingRangeParams, Hover, HoverContents, Location, MarkupContent, MarkupKind, Position,
19-
PrepareRenameResponse, Range, RenameParams, SemanticTokens, SemanticTokensParams,
20-
SemanticTokensRangeParams, SemanticTokensRangeResult, SemanticTokensResult, SymbolInformation,
21-
TextDocumentIdentifier, TextEdit, WorkspaceEdit,
15+
CodeAction, CodeActionResponse, CodeLens, Command, CompletionItem, Diagnostic,
16+
DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange, FoldingRangeParams,
17+
Hover, HoverContents, Location, MarkupContent, MarkupKind, Position, PrepareRenameResponse,
18+
Range, RenameParams, SemanticTokens, SemanticTokensParams, SemanticTokensRangeParams,
19+
SemanticTokensRangeResult, SemanticTokensResult, SymbolInformation, TextDocumentIdentifier,
20+
TextEdit, WorkspaceEdit,
2221
};
2322
use ra_ide::{
24-
AssistId, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind,
23+
Assist, AssistId, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind,
2524
SearchScope,
2625
};
2726
use ra_prof::profile;
@@ -649,6 +648,31 @@ pub fn handle_formatting(
649648
}]))
650649
}
651650

651+
fn create_single_code_action(assist: Assist, world: &WorldSnapshot) -> Result<CodeAction> {
652+
let arg = to_value(assist.source_change.try_conv_with(world)?)?;
653+
let title = assist.label;
654+
let command = Command {
655+
title: title.clone(),
656+
command: "rust-analyzer.applySourceChange".to_string(),
657+
arguments: Some(vec![arg]),
658+
};
659+
660+
let kind = match assist.id {
661+
AssistId("introduce_variable") => Some("refactor.extract.variable".to_string()),
662+
AssistId("add_custom_impl") => Some("refactor.rewrite.add_custom_impl".to_string()),
663+
_ => None,
664+
};
665+
666+
Ok(CodeAction {
667+
title,
668+
kind,
669+
diagnostics: None,
670+
edit: None,
671+
command: Some(command),
672+
is_preferred: None,
673+
})
674+
}
675+
652676
pub fn handle_code_action(
653677
world: WorldSnapshot,
654678
params: req::CodeActionParams,
@@ -695,59 +719,44 @@ pub fn handle_code_action(
695719
res.push(fix.action.clone());
696720
}
697721

698-
let mut groups = FxHashMap::default();
722+
let mut grouped_assists: FxHashMap<String, Vec<Assist>> = FxHashMap::default();
699723
for assist in world.analysis().assists(FileRange { file_id, range })?.into_iter() {
700-
let arg = to_value(assist.source_change.try_conv_with(&world)?)?;
701-
702-
let (command, title, arg) = match assist.group_label {
703-
None => ("rust-analyzer.applySourceChange", assist.label.clone(), arg),
704-
705-
// Group all assists with the same `group_label` into a single CodeAction.
706-
Some(group_label) => {
707-
match groups.entry(group_label.clone()) {
708-
Entry::Occupied(entry) => {
709-
let idx: usize = *entry.get();
710-
match &mut res[idx] {
711-
CodeActionOrCommand::CodeAction(CodeAction {
712-
command: Some(Command { arguments: Some(arguments), .. }),
713-
..
714-
}) => match arguments.as_mut_slice() {
715-
[serde_json::Value::Array(arguments)] => arguments.push(arg),
716-
_ => panic!("invalid group"),
717-
},
718-
_ => panic!("invalid group"),
719-
}
720-
continue;
721-
}
722-
Entry::Vacant(entry) => {
723-
entry.insert(res.len());
724-
}
725-
}
726-
("rust-analyzer.selectAndApplySourceChange", group_label, to_value(vec![arg])?)
727-
}
728-
};
729-
730-
let command = Command {
731-
title: assist.label.clone(),
732-
command: command.to_string(),
733-
arguments: Some(vec![arg]),
734-
};
724+
match &assist.group_label {
725+
Some(label) => grouped_assists.entry(label.to_owned()).or_default().push(assist),
726+
None => res.push(create_single_code_action(assist, &world)?.into()),
727+
}
728+
}
735729

736-
let kind = match assist.id {
737-
AssistId("introduce_variable") => Some("refactor.extract.variable".to_string()),
738-
AssistId("add_custom_impl") => Some("refactor.rewrite.add_custom_impl".to_string()),
739-
_ => None,
740-
};
730+
for (group_label, assists) in grouped_assists {
731+
if assists.len() == 1 {
732+
res.push(
733+
create_single_code_action(assists.into_iter().next().unwrap(), &world)?.into(),
734+
);
735+
} else {
736+
let title = group_label;
737+
738+
let mut arguments = Vec::with_capacity(assists.len());
739+
for assist in assists {
740+
arguments.push(to_value(assist.source_change.try_conv_with(&world)?)?);
741+
}
741742

742-
let action = CodeAction {
743-
title,
744-
kind,
745-
diagnostics: None,
746-
edit: None,
747-
command: Some(command),
748-
is_preferred: None,
749-
};
750-
res.push(action.into());
743+
let command = Some(Command {
744+
title: title.clone(),
745+
command: "rust-analyzer.selectAndApplySourceChange".to_string(),
746+
arguments: Some(vec![serde_json::Value::Array(arguments)]),
747+
});
748+
res.push(
749+
CodeAction {
750+
title,
751+
kind: None,
752+
diagnostics: None,
753+
edit: None,
754+
command,
755+
is_preferred: None,
756+
}
757+
.into(),
758+
);
759+
}
751760
}
752761

753762
Ok(Some(res))

0 commit comments

Comments
 (0)