From 9769c5140c9c406a4cc880e698593a6c4bcc6826 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 9 Feb 2020 15:32:53 +0100 Subject: Simplify Assists interface Instead of building a physical tree structure, just "tag" related assists with the same group --- crates/ra_lsp_server/src/main_loop/handlers.rs | 76 ++++++++++++++++---------- 1 file changed, 48 insertions(+), 28 deletions(-) (limited to 'crates/ra_lsp_server/src') diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 282f6e8fc..65e8bc856 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs @@ -2,20 +2,21 @@ //! The majority of requests are fulfilled by calling into the `ra_ide` crate. use std::{ + collections::hash_map::Entry, fmt::Write as _, io::Write as _, process::{self, Stdio}, }; -use either::Either; use lsp_server::ErrorCode; use lsp_types::{ CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem, CallHierarchyOutgoingCall, CallHierarchyOutgoingCallsParams, CallHierarchyPrepareParams, - CodeAction, CodeActionResponse, CodeLens, Command, CompletionItem, Diagnostic, - DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange, FoldingRangeParams, - Hover, HoverContents, Location, MarkupContent, MarkupKind, Position, PrepareRenameResponse, - Range, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit, WorkspaceEdit, + CodeAction, CodeActionOrCommand, CodeActionResponse, CodeLens, Command, CompletionItem, + Diagnostic, DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange, + FoldingRangeParams, Hover, HoverContents, Location, MarkupContent, MarkupKind, Position, + PrepareRenameResponse, Range, RenameParams, SymbolInformation, TextDocumentIdentifier, + TextEdit, WorkspaceEdit, }; use ra_ide::{ AssistId, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind, @@ -685,34 +686,53 @@ pub fn handle_code_action( res.push(fix.action.clone()); } + let mut groups = FxHashMap::default(); for assist in world.analysis().assists(FileRange { file_id, range })?.into_iter() { - let title = assist.label.clone(); + let arg = to_value(assist.source_change.try_conv_with(&world)?)?; + + let (command, title, arg) = match assist.group_label { + None => ("rust-analyzer.applySourceChange", assist.label.clone(), arg), + + // Group all assists with the same `group_label` into a single CodeAction. + Some(group_label) => { + match groups.entry(group_label.clone()) { + Entry::Occupied(entry) => { + let idx: usize = *entry.get(); + match &mut res[idx] { + CodeActionOrCommand::CodeAction(CodeAction { + command: Some(Command { arguments: Some(arguments), .. }), + .. + }) => match arguments.as_mut_slice() { + [serde_json::Value::Array(arguments)] => arguments.push(arg), + _ => panic!("invalid group"), + }, + _ => panic!("invalid group"), + } + continue; + } + Entry::Vacant(entry) => { + entry.insert(res.len()); + } + } + ("rust-analyzer.selectAndApplySourceChange", group_label, to_value(vec![arg])?) + } + }; - let command = match assist.change_data { - Either::Left(change) => Command { - title, - command: "rust-analyzer.applySourceChange".to_string(), - arguments: Some(vec![to_value(change.try_conv_with(&world)?)?]), - }, - Either::Right(changes) => Command { - title, - command: "rust-analyzer.selectAndApplySourceChange".to_string(), - arguments: Some(vec![to_value( - changes - .into_iter() - .map(|change| change.try_conv_with(&world)) - .collect::>>()?, - )?]), - }, + let command = Command { + title: assist.label.clone(), + command: command.to_string(), + arguments: Some(vec![arg]), + }; + + let kind = match assist.id { + AssistId("introduce_variable") => Some("refactor.extract.variable".to_string()), + AssistId("add_custom_impl") => Some("refactor.rewrite.add_custom_impl".to_string()), + _ => None, }; let action = CodeAction { - title: command.title.clone(), - kind: match assist.id { - AssistId("introduce_variable") => Some("refactor.extract.variable".to_string()), - AssistId("add_custom_impl") => Some("refactor.rewrite.add_custom_impl".to_string()), - _ => None, - }, + title, + kind, diagnostics: None, edit: None, command: Some(command), -- cgit v1.2.3