Skip to content

Commit 26079c7

Browse files
bors[bot]kjeremy
andauthored
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]>
2 parents 4d33cdc + 99826da commit 26079c7

File tree

4 files changed

+51
-18
lines changed

4 files changed

+51
-18
lines changed

crates/rust-analyzer/src/caps.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
use crate::semantic_tokens;
44

55
use lsp_types::{
6-
CallHierarchyServerCapability, CodeActionProviderCapability, CodeLensOptions,
7-
CompletionOptions, DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability,
8-
ImplementationProviderCapability, RenameOptions, RenameProviderCapability, SaveOptions,
9-
SelectionRangeProviderCapability, SemanticTokensDocumentProvider, SemanticTokensLegend,
10-
SemanticTokensOptions, ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability,
11-
TextDocumentSyncKind, TextDocumentSyncOptions, TypeDefinitionProviderCapability,
12-
WorkDoneProgressOptions,
6+
CallHierarchyServerCapability, CodeActionOptions, CodeActionProviderCapability,
7+
CodeLensOptions, CompletionOptions, DocumentOnTypeFormattingOptions,
8+
FoldingRangeProviderCapability, ImplementationProviderCapability, RenameOptions,
9+
RenameProviderCapability, SaveOptions, SelectionRangeProviderCapability,
10+
SemanticTokensDocumentProvider, SemanticTokensLegend, SemanticTokensOptions,
11+
ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind,
12+
TextDocumentSyncOptions, TypeDefinitionProviderCapability, WorkDoneProgressOptions,
1313
};
1414

1515
pub fn server_capabilities() -> ServerCapabilities {
@@ -40,7 +40,20 @@ pub fn server_capabilities() -> ServerCapabilities {
4040
document_highlight_provider: Some(true),
4141
document_symbol_provider: Some(true),
4242
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+
})),
4457
code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }),
4558
document_formatting_provider: Some(true),
4659
document_range_formatting_provider: None,

crates/rust-analyzer/src/config.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ pub struct ClientCapsConfig {
7070
pub location_link: bool,
7171
pub line_folding_only: bool,
7272
pub hierarchical_symbols: bool,
73+
pub code_action_literals: bool,
7374
}
7475

7576
impl Default for Config {
@@ -221,6 +222,11 @@ impl Config {
221222
{
222223
self.client_caps.hierarchical_symbols = value
223224
}
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+
}
224230
self.completion.allow_snippets(false);
225231
if let Some(completion) = &caps.completion {
226232
if let Some(completion_item) = &completion.completion_item {

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

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ use lsp_types::{
1919
TextEdit, Url, WorkspaceEdit,
2020
};
2121
use ra_ide::{
22-
Assist, AssistId, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind,
23-
SearchScope,
22+
Assist, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind, SearchScope,
2423
};
2524
use ra_prof::profile;
2625
use ra_syntax::{AstNode, SyntaxKind, TextRange, TextSize};
@@ -702,15 +701,9 @@ fn create_single_code_action(assist: Assist, world: &WorldSnapshot) -> Result<Co
702701
arguments: Some(vec![arg]),
703702
};
704703

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-
711704
Ok(CodeAction {
712705
title,
713-
kind,
706+
kind: Some(String::new()),
714707
diagnostics: None,
715708
edit: None,
716709
command: Some(command),
@@ -812,6 +805,23 @@ pub fn handle_code_action(
812805
}
813806
}
814807

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+
}
815825
Ok(Some(res))
816826
}
817827

crates/rust-analyzer/tests/heavy_tests/support.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,11 @@ impl<'a> Project<'a> {
7777
let roots = self.roots.into_iter().map(|root| tmp_dir.path().join(root)).collect();
7878

7979
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+
},
8185
with_sysroot: self.with_sysroot,
8286
..Config::default()
8387
};

0 commit comments

Comments
 (0)