diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-05-01 19:57:55 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-05-01 19:57:55 +0100 |
commit | 26079c7f2cce4cd1a2e833a045fb14377fa737d3 (patch) | |
tree | 07da881c1daeb65ea8e8683c367acc56e23cf322 /crates | |
parent | 4d33cdcfb2e06088c8bccc57565224f8a377d899 (diff) | |
parent | 99826dab153feffc8fe0d80600d9e812824d67b2 (diff) |
Merge #4167
4167: Filter out code actions if unsupported by the client and advertise our capabilities r=matklad a=kjeremy
This PR does three things:
1. If the client does not support `CodeActionKind` this will filter the results and only send `Command[]` back.
2. Correctly advertises to the client that the server supports `CodeActionKind`. This may cause clients to not request code actions if they are checking for the provider to be `true` (or implement LSP < 3.8) in the caps but I will fix that in a followup PR.
3. Marks most CodeActions as <strike>"refactor" so that they show up in the menu in vscode.</strike>`""`.
Part of #144
#4147
#2833
Co-authored-by: kjeremy <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r-- | crates/rust-analyzer/src/caps.rs | 29 | ||||
-rw-r--r-- | crates/rust-analyzer/src/config.rs | 6 | ||||
-rw-r--r-- | crates/rust-analyzer/src/main_loop/handlers.rs | 28 | ||||
-rw-r--r-- | crates/rust-analyzer/tests/heavy_tests/support.rs | 6 |
4 files changed, 51 insertions, 18 deletions
diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs index e22ab8402..c0d320926 100644 --- a/crates/rust-analyzer/src/caps.rs +++ b/crates/rust-analyzer/src/caps.rs | |||
@@ -3,13 +3,13 @@ | |||
3 | use crate::semantic_tokens; | 3 | use crate::semantic_tokens; |
4 | 4 | ||
5 | use lsp_types::{ | 5 | use lsp_types::{ |
6 | CallHierarchyServerCapability, CodeActionProviderCapability, CodeLensOptions, | 6 | CallHierarchyServerCapability, CodeActionOptions, CodeActionProviderCapability, |
7 | CompletionOptions, DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability, | 7 | CodeLensOptions, CompletionOptions, DocumentOnTypeFormattingOptions, |
8 | ImplementationProviderCapability, RenameOptions, RenameProviderCapability, SaveOptions, | 8 | FoldingRangeProviderCapability, ImplementationProviderCapability, RenameOptions, |
9 | SelectionRangeProviderCapability, SemanticTokensDocumentProvider, SemanticTokensLegend, | 9 | RenameProviderCapability, SaveOptions, SelectionRangeProviderCapability, |
10 | SemanticTokensOptions, ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability, | 10 | SemanticTokensDocumentProvider, SemanticTokensLegend, SemanticTokensOptions, |
11 | TextDocumentSyncKind, TextDocumentSyncOptions, TypeDefinitionProviderCapability, | 11 | ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind, |
12 | WorkDoneProgressOptions, | 12 | TextDocumentSyncOptions, TypeDefinitionProviderCapability, WorkDoneProgressOptions, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | pub fn server_capabilities() -> ServerCapabilities { | 15 | pub fn server_capabilities() -> ServerCapabilities { |
@@ -40,7 +40,20 @@ pub fn server_capabilities() -> ServerCapabilities { | |||
40 | document_highlight_provider: Some(true), | 40 | document_highlight_provider: Some(true), |
41 | document_symbol_provider: Some(true), | 41 | document_symbol_provider: Some(true), |
42 | workspace_symbol_provider: Some(true), | 42 | workspace_symbol_provider: Some(true), |
43 | code_action_provider: Some(CodeActionProviderCapability::Simple(true)), | 43 | code_action_provider: Some(CodeActionProviderCapability::Options(CodeActionOptions { |
44 | // Advertise support for all built-in CodeActionKinds | ||
45 | code_action_kinds: Some(vec![ | ||
46 | String::new(), | ||
47 | lsp_types::code_action_kind::QUICKFIX.to_string(), | ||
48 | lsp_types::code_action_kind::REFACTOR.to_string(), | ||
49 | lsp_types::code_action_kind::REFACTOR_EXTRACT.to_string(), | ||
50 | lsp_types::code_action_kind::REFACTOR_INLINE.to_string(), | ||
51 | lsp_types::code_action_kind::REFACTOR_REWRITE.to_string(), | ||
52 | lsp_types::code_action_kind::SOURCE.to_string(), | ||
53 | lsp_types::code_action_kind::SOURCE_ORGANIZE_IMPORTS.to_string(), | ||
54 | ]), | ||
55 | work_done_progress_options: Default::default(), | ||
56 | })), | ||
44 | code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }), | 57 | code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }), |
45 | document_formatting_provider: Some(true), | 58 | document_formatting_provider: Some(true), |
46 | document_range_formatting_provider: None, | 59 | document_range_formatting_provider: None, |
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 74a63e32a..177da94cc 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs | |||
@@ -70,6 +70,7 @@ pub struct ClientCapsConfig { | |||
70 | pub location_link: bool, | 70 | pub location_link: bool, |
71 | pub line_folding_only: bool, | 71 | pub line_folding_only: bool, |
72 | pub hierarchical_symbols: bool, | 72 | pub hierarchical_symbols: bool, |
73 | pub code_action_literals: bool, | ||
73 | } | 74 | } |
74 | 75 | ||
75 | impl Default for Config { | 76 | impl Default for Config { |
@@ -221,6 +222,11 @@ impl Config { | |||
221 | { | 222 | { |
222 | self.client_caps.hierarchical_symbols = value | 223 | self.client_caps.hierarchical_symbols = value |
223 | } | 224 | } |
225 | if let Some(value) = | ||
226 | caps.code_action.as_ref().and_then(|it| Some(it.code_action_literal_support.is_some())) | ||
227 | { | ||
228 | self.client_caps.code_action_literals = value; | ||
229 | } | ||
224 | self.completion.allow_snippets(false); | 230 | self.completion.allow_snippets(false); |
225 | if let Some(completion) = &caps.completion { | 231 | if let Some(completion) = &caps.completion { |
226 | if let Some(completion_item) = &completion.completion_item { | 232 | if let Some(completion_item) = &completion.completion_item { |
diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index 8db2dfa0c..0f623949e 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs | |||
@@ -19,8 +19,7 @@ use lsp_types::{ | |||
19 | TextEdit, Url, WorkspaceEdit, | 19 | TextEdit, Url, WorkspaceEdit, |
20 | }; | 20 | }; |
21 | use ra_ide::{ | 21 | use ra_ide::{ |
22 | Assist, AssistId, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind, | 22 | Assist, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind, SearchScope, |
23 | SearchScope, | ||
24 | }; | 23 | }; |
25 | use ra_prof::profile; | 24 | use ra_prof::profile; |
26 | use ra_syntax::{AstNode, SyntaxKind, TextRange, TextSize}; | 25 | use ra_syntax::{AstNode, SyntaxKind, TextRange, TextSize}; |
@@ -702,15 +701,9 @@ fn create_single_code_action(assist: Assist, world: &WorldSnapshot) -> Result<Co | |||
702 | arguments: Some(vec![arg]), | 701 | arguments: Some(vec![arg]), |
703 | }; | 702 | }; |
704 | 703 | ||
705 | let kind = match assist.id { | ||
706 | AssistId("introduce_variable") => Some("refactor.extract.variable".to_string()), | ||
707 | AssistId("add_custom_impl") => Some("refactor.rewrite.add_custom_impl".to_string()), | ||
708 | _ => None, | ||
709 | }; | ||
710 | |||
711 | Ok(CodeAction { | 704 | Ok(CodeAction { |
712 | title, | 705 | title, |
713 | kind, | 706 | kind: Some(String::new()), |
714 | diagnostics: None, | 707 | diagnostics: None, |
715 | edit: None, | 708 | edit: None, |
716 | command: Some(command), | 709 | command: Some(command), |
@@ -812,6 +805,23 @@ pub fn handle_code_action( | |||
812 | } | 805 | } |
813 | } | 806 | } |
814 | 807 | ||
808 | // If the client only supports commands then filter the list | ||
809 | // and remove and actions that depend on edits. | ||
810 | if !world.config.client_caps.code_action_literals { | ||
811 | // FIXME: use drain_filter once it hits stable. | ||
812 | res = res | ||
813 | .into_iter() | ||
814 | .filter_map(|it| match it { | ||
815 | cmd @ lsp_types::CodeActionOrCommand::Command(_) => Some(cmd), | ||
816 | lsp_types::CodeActionOrCommand::CodeAction(action) => match action.command { | ||
817 | Some(cmd) if action.edit.is_none() => { | ||
818 | Some(lsp_types::CodeActionOrCommand::Command(cmd)) | ||
819 | } | ||
820 | _ => None, | ||
821 | }, | ||
822 | }) | ||
823 | .collect(); | ||
824 | } | ||
815 | Ok(Some(res)) | 825 | Ok(Some(res)) |
816 | } | 826 | } |
817 | 827 | ||
diff --git a/crates/rust-analyzer/tests/heavy_tests/support.rs b/crates/rust-analyzer/tests/heavy_tests/support.rs index e4fe3411a..8d47ee4f6 100644 --- a/crates/rust-analyzer/tests/heavy_tests/support.rs +++ b/crates/rust-analyzer/tests/heavy_tests/support.rs | |||
@@ -77,7 +77,11 @@ impl<'a> Project<'a> { | |||
77 | let roots = self.roots.into_iter().map(|root| tmp_dir.path().join(root)).collect(); | 77 | let roots = self.roots.into_iter().map(|root| tmp_dir.path().join(root)).collect(); |
78 | 78 | ||
79 | let mut config = Config { | 79 | let mut config = Config { |
80 | client_caps: ClientCapsConfig { location_link: true, ..Default::default() }, | 80 | client_caps: ClientCapsConfig { |
81 | location_link: true, | ||
82 | code_action_literals: true, | ||
83 | ..Default::default() | ||
84 | }, | ||
81 | with_sysroot: self.with_sysroot, | 85 | with_sysroot: self.with_sysroot, |
82 | ..Config::default() | 86 | ..Config::default() |
83 | }; | 87 | }; |