mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-14 17:07:26 +00:00
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 <kjeremy@gmail.com>
This commit is contained in:
commit
26079c7f2c
4 changed files with 51 additions and 18 deletions
|
@ -3,13 +3,13 @@
|
|||
use crate::semantic_tokens;
|
||||
|
||||
use lsp_types::{
|
||||
CallHierarchyServerCapability, CodeActionProviderCapability, CodeLensOptions,
|
||||
CompletionOptions, DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability,
|
||||
ImplementationProviderCapability, RenameOptions, RenameProviderCapability, SaveOptions,
|
||||
SelectionRangeProviderCapability, SemanticTokensDocumentProvider, SemanticTokensLegend,
|
||||
SemanticTokensOptions, ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability,
|
||||
TextDocumentSyncKind, TextDocumentSyncOptions, TypeDefinitionProviderCapability,
|
||||
WorkDoneProgressOptions,
|
||||
CallHierarchyServerCapability, CodeActionOptions, CodeActionProviderCapability,
|
||||
CodeLensOptions, CompletionOptions, DocumentOnTypeFormattingOptions,
|
||||
FoldingRangeProviderCapability, ImplementationProviderCapability, RenameOptions,
|
||||
RenameProviderCapability, SaveOptions, SelectionRangeProviderCapability,
|
||||
SemanticTokensDocumentProvider, SemanticTokensLegend, SemanticTokensOptions,
|
||||
ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind,
|
||||
TextDocumentSyncOptions, TypeDefinitionProviderCapability, WorkDoneProgressOptions,
|
||||
};
|
||||
|
||||
pub fn server_capabilities() -> ServerCapabilities {
|
||||
|
@ -40,7 +40,20 @@ pub fn server_capabilities() -> ServerCapabilities {
|
|||
document_highlight_provider: Some(true),
|
||||
document_symbol_provider: Some(true),
|
||||
workspace_symbol_provider: Some(true),
|
||||
code_action_provider: Some(CodeActionProviderCapability::Simple(true)),
|
||||
code_action_provider: Some(CodeActionProviderCapability::Options(CodeActionOptions {
|
||||
// Advertise support for all built-in CodeActionKinds
|
||||
code_action_kinds: Some(vec![
|
||||
String::new(),
|
||||
lsp_types::code_action_kind::QUICKFIX.to_string(),
|
||||
lsp_types::code_action_kind::REFACTOR.to_string(),
|
||||
lsp_types::code_action_kind::REFACTOR_EXTRACT.to_string(),
|
||||
lsp_types::code_action_kind::REFACTOR_INLINE.to_string(),
|
||||
lsp_types::code_action_kind::REFACTOR_REWRITE.to_string(),
|
||||
lsp_types::code_action_kind::SOURCE.to_string(),
|
||||
lsp_types::code_action_kind::SOURCE_ORGANIZE_IMPORTS.to_string(),
|
||||
]),
|
||||
work_done_progress_options: Default::default(),
|
||||
})),
|
||||
code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }),
|
||||
document_formatting_provider: Some(true),
|
||||
document_range_formatting_provider: None,
|
||||
|
|
|
@ -70,6 +70,7 @@ pub struct ClientCapsConfig {
|
|||
pub location_link: bool,
|
||||
pub line_folding_only: bool,
|
||||
pub hierarchical_symbols: bool,
|
||||
pub code_action_literals: bool,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
|
@ -221,6 +222,11 @@ impl Config {
|
|||
{
|
||||
self.client_caps.hierarchical_symbols = value
|
||||
}
|
||||
if let Some(value) =
|
||||
caps.code_action.as_ref().and_then(|it| Some(it.code_action_literal_support.is_some()))
|
||||
{
|
||||
self.client_caps.code_action_literals = value;
|
||||
}
|
||||
self.completion.allow_snippets(false);
|
||||
if let Some(completion) = &caps.completion {
|
||||
if let Some(completion_item) = &completion.completion_item {
|
||||
|
|
|
@ -19,8 +19,7 @@ use lsp_types::{
|
|||
TextEdit, Url, WorkspaceEdit,
|
||||
};
|
||||
use ra_ide::{
|
||||
Assist, AssistId, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind,
|
||||
SearchScope,
|
||||
Assist, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind, SearchScope,
|
||||
};
|
||||
use ra_prof::profile;
|
||||
use ra_syntax::{AstNode, SyntaxKind, TextRange, TextSize};
|
||||
|
@ -702,15 +701,9 @@ fn create_single_code_action(assist: Assist, world: &WorldSnapshot) -> Result<Co
|
|||
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,
|
||||
};
|
||||
|
||||
Ok(CodeAction {
|
||||
title,
|
||||
kind,
|
||||
kind: Some(String::new()),
|
||||
diagnostics: None,
|
||||
edit: None,
|
||||
command: Some(command),
|
||||
|
@ -812,6 +805,23 @@ pub fn handle_code_action(
|
|||
}
|
||||
}
|
||||
|
||||
// If the client only supports commands then filter the list
|
||||
// and remove and actions that depend on edits.
|
||||
if !world.config.client_caps.code_action_literals {
|
||||
// FIXME: use drain_filter once it hits stable.
|
||||
res = res
|
||||
.into_iter()
|
||||
.filter_map(|it| match it {
|
||||
cmd @ lsp_types::CodeActionOrCommand::Command(_) => Some(cmd),
|
||||
lsp_types::CodeActionOrCommand::CodeAction(action) => match action.command {
|
||||
Some(cmd) if action.edit.is_none() => {
|
||||
Some(lsp_types::CodeActionOrCommand::Command(cmd))
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
Ok(Some(res))
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,11 @@ impl<'a> Project<'a> {
|
|||
let roots = self.roots.into_iter().map(|root| tmp_dir.path().join(root)).collect();
|
||||
|
||||
let mut config = Config {
|
||||
client_caps: ClientCapsConfig { location_link: true, ..Default::default() },
|
||||
client_caps: ClientCapsConfig {
|
||||
location_link: true,
|
||||
code_action_literals: true,
|
||||
..Default::default()
|
||||
},
|
||||
with_sysroot: self.with_sysroot,
|
||||
..Config::default()
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue