From 2075e77ee5784e72396c64c9ca059763508219ff Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 22 May 2020 17:29:55 +0200 Subject: CodeAction groups --- crates/rust-analyzer/src/config.rs | 9 +++- ...tics__to_proto__tests__snap_multi_line_fix.snap | 1 + ...o_proto__tests__snap_rustc_unused_variable.snap | 1 + crates/rust-analyzer/src/diagnostics/to_proto.rs | 1 + crates/rust-analyzer/src/lsp_ext.rs | 10 +--- crates/rust-analyzer/src/main_loop/handlers.rs | 54 +++------------------- crates/rust-analyzer/src/to_proto.rs | 10 +--- 7 files changed, 19 insertions(+), 67 deletions(-) (limited to 'crates') diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index d75c48597..0e4412ade 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -102,6 +102,7 @@ pub struct ClientCapsConfig { pub hierarchical_symbols: bool, pub code_action_literals: bool, pub work_done_progress: bool, + pub code_action_group: bool, } impl Default for Config { @@ -294,9 +295,13 @@ impl Config { self.assist.allow_snippets(false); if let Some(experimental) = &caps.experimental { - let enable = + let snippet_text_edit = experimental.get("snippetTextEdit").and_then(|it| it.as_bool()) == Some(true); - self.assist.allow_snippets(enable); + self.assist.allow_snippets(snippet_text_edit); + + let code_action_group = + experimental.get("codeActionGroup").and_then(|it| it.as_bool()) == Some(true); + self.client_caps.code_action_group = code_action_group } } } diff --git a/crates/rust-analyzer/src/diagnostics/snapshots/rust_analyzer__diagnostics__to_proto__tests__snap_multi_line_fix.snap b/crates/rust-analyzer/src/diagnostics/snapshots/rust_analyzer__diagnostics__to_proto__tests__snap_multi_line_fix.snap index 96466b5c9..c40cfdcdc 100644 --- a/crates/rust-analyzer/src/diagnostics/snapshots/rust_analyzer__diagnostics__to_proto__tests__snap_multi_line_fix.snap +++ b/crates/rust-analyzer/src/diagnostics/snapshots/rust_analyzer__diagnostics__to_proto__tests__snap_multi_line_fix.snap @@ -65,6 +65,7 @@ expression: diag fixes: [ CodeAction { title: "return the expression directly", + group: None, kind: Some( "quickfix", ), diff --git a/crates/rust-analyzer/src/diagnostics/snapshots/rust_analyzer__diagnostics__to_proto__tests__snap_rustc_unused_variable.snap b/crates/rust-analyzer/src/diagnostics/snapshots/rust_analyzer__diagnostics__to_proto__tests__snap_rustc_unused_variable.snap index 8f962277f..6dd3fcb2e 100644 --- a/crates/rust-analyzer/src/diagnostics/snapshots/rust_analyzer__diagnostics__to_proto__tests__snap_rustc_unused_variable.snap +++ b/crates/rust-analyzer/src/diagnostics/snapshots/rust_analyzer__diagnostics__to_proto__tests__snap_rustc_unused_variable.snap @@ -50,6 +50,7 @@ expression: diag fixes: [ CodeAction { title: "consider prefixing with an underscore", + group: None, kind: Some( "quickfix", ), diff --git a/crates/rust-analyzer/src/diagnostics/to_proto.rs b/crates/rust-analyzer/src/diagnostics/to_proto.rs index afea59525..a500d670a 100644 --- a/crates/rust-analyzer/src/diagnostics/to_proto.rs +++ b/crates/rust-analyzer/src/diagnostics/to_proto.rs @@ -145,6 +145,7 @@ fn map_rust_child_diagnostic( } else { MappedRustChildDiagnostic::SuggestedFix(lsp_ext::CodeAction { title: rd.message.clone(), + group: None, kind: Some("quickfix".to_string()), edit: Some(lsp_ext::SnippetWorkspaceEdit { // FIXME: there's no good reason to use edit_map here.... diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs index 0fd60caf4..c25d90a50 100644 --- a/crates/rust-analyzer/src/lsp_ext.rs +++ b/crates/rust-analyzer/src/lsp_ext.rs @@ -133,14 +133,6 @@ pub struct Runnable { pub cwd: Option, } -#[derive(Deserialize, Serialize, Debug)] -#[serde(rename_all = "camelCase")] -pub struct SourceChange { - pub label: String, - pub workspace_edit: SnippetWorkspaceEdit, - pub cursor_position: Option, -} - pub enum InlayHints {} impl Request for InlayHints { @@ -196,6 +188,8 @@ impl Request for CodeActionRequest { pub struct CodeAction { pub title: String, #[serde(skip_serializing_if = "Option::is_none")] + pub group: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub kind: Option, #[serde(skip_serializing_if = "Option::is_none")] pub command: Option, diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index 25e660bd5..89144f743 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs @@ -18,7 +18,7 @@ use lsp_types::{ SemanticTokensResult, SymbolInformation, TextDocumentIdentifier, Url, WorkspaceEdit, }; use ra_ide::{ - Assist, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind, SearchScope, + FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind, SearchScope, TextEdit, }; use ra_prof::profile; @@ -720,6 +720,7 @@ pub fn handle_code_action( let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; let line_index = world.analysis().file_line_index(file_id)?; let range = from_proto::text_range(&line_index, params.range); + let frange = FileRange { file_id, range }; let diagnostics = world.analysis().diagnostics(file_id)?; let mut res: Vec = Vec::new(); @@ -733,7 +734,8 @@ pub fn handle_code_action( for source_edit in fixes_from_diagnostics { let title = source_edit.label.clone(); let edit = to_proto::snippet_workspace_edit(&world, source_edit)?; - let action = lsp_ext::CodeAction { title, kind: None, edit: Some(edit), command: None }; + let action = + lsp_ext::CodeAction { title, group: None, kind: None, edit: Some(edit), command: None }; res.push(action); } @@ -745,53 +747,9 @@ pub fn handle_code_action( res.push(fix.action.clone()); } - let mut grouped_assists: FxHashMap)> = FxHashMap::default(); - for assist in - world.analysis().assists(&world.config.assist, FileRange { file_id, range })?.into_iter() - { - match &assist.group_label { - Some(label) => grouped_assists - .entry(label.to_owned()) - .or_insert_with(|| { - let idx = res.len(); - let dummy = lsp_ext::CodeAction { - title: String::new(), - kind: None, - command: None, - edit: None, - }; - res.push(dummy); - (idx, Vec::new()) - }) - .1 - .push(assist), - None => { - res.push(to_proto::code_action(&world, assist)?.into()); - } - } - } - - for (group_label, (idx, assists)) in grouped_assists { - if assists.len() == 1 { - res[idx] = to_proto::code_action(&world, assists.into_iter().next().unwrap())?.into(); - } else { - let title = group_label; - - let mut arguments = Vec::with_capacity(assists.len()); - for assist in assists { - let source_change = to_proto::source_change(&world, assist.source_change)?; - arguments.push(to_value(source_change)?); - } - - let command = Some(Command { - title: title.clone(), - command: "rust-analyzer.selectAndApplySourceChange".to_string(), - arguments: Some(vec![serde_json::Value::Array(arguments)]), - }); - res[idx] = lsp_ext::CodeAction { title, kind: None, edit: None, command }; - } + for assist in world.analysis().assists(&world.config.assist, frange)?.into_iter() { + res.push(to_proto::code_action(&world, assist)?.into()); } - Ok(Some(res)) } diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index f6f4bb134..461944ada 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -478,15 +478,6 @@ pub(crate) fn resource_op( Ok(res) } -pub(crate) fn source_change( - world: &WorldSnapshot, - source_change: SourceChange, -) -> Result { - let label = source_change.label.clone(); - let workspace_edit = self::snippet_workspace_edit(world, source_change)?; - Ok(lsp_ext::SourceChange { label, workspace_edit, cursor_position: None }) -} - pub(crate) fn snippet_workspace_edit( world: &WorldSnapshot, source_change: SourceChange, @@ -606,6 +597,7 @@ fn main() { pub(crate) fn code_action(world: &WorldSnapshot, assist: Assist) -> Result { let res = lsp_ext::CodeAction { title: assist.label, + group: if world.config.client_caps.code_action_group { assist.group_label } else { None }, kind: Some(String::new()), edit: Some(snippet_workspace_edit(world, assist.source_change)?), command: None, -- cgit v1.2.3