mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
Prepare server capabilities based on client ones.
This commit is contained in:
parent
6ddcdb8b29
commit
594ce72d1e
1 changed files with 74 additions and 38 deletions
|
@ -7,16 +7,18 @@ use lsp_types::{
|
||||||
DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability, HoverProviderCapability,
|
DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability, HoverProviderCapability,
|
||||||
ImplementationProviderCapability, RenameOptions, RenameProviderCapability, SaveOptions,
|
ImplementationProviderCapability, RenameOptions, RenameProviderCapability, SaveOptions,
|
||||||
SelectionRangeProviderCapability, SemanticTokensDocumentProvider, SemanticTokensLegend,
|
SelectionRangeProviderCapability, SemanticTokensDocumentProvider, SemanticTokensLegend,
|
||||||
SemanticTokensOptions, ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability,
|
SemanticTokensOptions, SemanticTokensServerCapabilities, ServerCapabilities,
|
||||||
TextDocumentSyncKind, TextDocumentSyncOptions, TypeDefinitionProviderCapability,
|
SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind,
|
||||||
WorkDoneProgressOptions,
|
TextDocumentSyncOptions, TypeDefinitionProviderCapability, WorkDoneProgressOptions,
|
||||||
};
|
};
|
||||||
use serde_json::json;
|
use serde_json::{json, Value};
|
||||||
|
|
||||||
use crate::semantic_tokens;
|
use crate::semantic_tokens;
|
||||||
|
|
||||||
pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabilities {
|
pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabilities {
|
||||||
let code_action_provider = code_action_capabilities(client_caps);
|
let code_action_provider = code_action_capabilities(client_caps);
|
||||||
|
let semantic_tokens_provider = semantic_tokens_capabilities(client_caps);
|
||||||
|
let experimental = experimental_capabilities(client_caps);
|
||||||
|
|
||||||
ServerCapabilities {
|
ServerCapabilities {
|
||||||
text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
|
text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
|
||||||
|
@ -69,50 +71,84 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
|
||||||
execute_command_provider: None,
|
execute_command_provider: None,
|
||||||
workspace: None,
|
workspace: None,
|
||||||
call_hierarchy_provider: Some(CallHierarchyServerCapability::Simple(true)),
|
call_hierarchy_provider: Some(CallHierarchyServerCapability::Simple(true)),
|
||||||
semantic_tokens_provider: Some(
|
semantic_tokens_provider,
|
||||||
SemanticTokensOptions {
|
experimental,
|
||||||
legend: SemanticTokensLegend {
|
|
||||||
token_types: semantic_tokens::SUPPORTED_TYPES.to_vec(),
|
|
||||||
token_modifiers: semantic_tokens::SUPPORTED_MODIFIERS.to_vec(),
|
|
||||||
},
|
|
||||||
|
|
||||||
document_provider: Some(SemanticTokensDocumentProvider::Bool(true)),
|
|
||||||
range_provider: Some(true),
|
|
||||||
work_done_progress_options: Default::default(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
experimental: Some(json!({
|
|
||||||
"joinLines": true,
|
|
||||||
"ssr": true,
|
|
||||||
"onEnter": true,
|
|
||||||
"parentModule": true,
|
|
||||||
"runnables": {
|
|
||||||
"kinds": [ "cargo" ],
|
|
||||||
},
|
|
||||||
})),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn experimental_capabilities(client_caps: &ClientCapabilities) -> Option<Value> {
|
||||||
|
client_caps.experimental.as_ref().and_then(|it| {
|
||||||
|
it.as_object().map(|map| {
|
||||||
|
let mut obj = json!({});
|
||||||
|
let result = obj.as_object_mut().unwrap();
|
||||||
|
|
||||||
|
if map.contains_key("joinLines") {
|
||||||
|
result.insert("joinLines".into(), true.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
if map.contains_key("ssr") {
|
||||||
|
result.insert("ssr".into(), true.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
if map.contains_key("onEnter") {
|
||||||
|
result.insert("onEnter".into(), true.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
if map.contains_key("parentModule") {
|
||||||
|
result.insert("parentModule".into(), true.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
if map.contains_key("runnables") {
|
||||||
|
result.insert("runnables".into(), json!({ "kinds": [ "cargo" ] }));
|
||||||
|
}
|
||||||
|
|
||||||
|
obj
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn semantic_tokens_capabilities(
|
||||||
|
client_caps: &ClientCapabilities,
|
||||||
|
) -> Option<SemanticTokensServerCapabilities> {
|
||||||
|
client_caps.text_document.as_ref().and_then(|it| it.semantic_tokens.as_ref()).map(|_|
|
||||||
|
// client supports semanticTokens
|
||||||
|
SemanticTokensOptions {
|
||||||
|
legend: SemanticTokensLegend {
|
||||||
|
token_types: semantic_tokens::SUPPORTED_TYPES.to_vec(),
|
||||||
|
token_modifiers: semantic_tokens::SUPPORTED_MODIFIERS.to_vec(),
|
||||||
|
},
|
||||||
|
|
||||||
|
document_provider: Some(SemanticTokensDocumentProvider::Bool(true)),
|
||||||
|
range_provider: Some(true),
|
||||||
|
work_done_progress_options: Default::default(),
|
||||||
|
}
|
||||||
|
.into())
|
||||||
|
}
|
||||||
|
|
||||||
fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProviderCapability {
|
fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProviderCapability {
|
||||||
client_caps
|
client_caps
|
||||||
.text_document
|
.text_document
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|it| it.code_action.as_ref())
|
.and_then(|it| it.code_action.as_ref())
|
||||||
.and_then(|it| it.code_action_literal_support.as_ref())
|
.and_then(|it| it.code_action_literal_support.as_ref())
|
||||||
.map_or(CodeActionProviderCapability::Simple(true), |_| {
|
.map_or(CodeActionProviderCapability::Simple(true), |caps| {
|
||||||
|
let mut action_kinds = vec![
|
||||||
|
CodeActionKind::EMPTY,
|
||||||
|
CodeActionKind::QUICKFIX,
|
||||||
|
CodeActionKind::REFACTOR,
|
||||||
|
CodeActionKind::REFACTOR_EXTRACT,
|
||||||
|
CodeActionKind::REFACTOR_INLINE,
|
||||||
|
CodeActionKind::REFACTOR_REWRITE,
|
||||||
|
];
|
||||||
|
|
||||||
|
// Not all clients can fall back gracefully for unknown values.
|
||||||
|
// Microsoft.VisualStudio.LanguageServer.Protocol.CodeActionKind does not support CodeActionKind::EMPTY
|
||||||
|
// So have to filter out.
|
||||||
|
action_kinds
|
||||||
|
.retain(|it| caps.code_action_kind.value_set.contains(&it.as_str().to_owned()));
|
||||||
|
|
||||||
CodeActionProviderCapability::Options(CodeActionOptions {
|
CodeActionProviderCapability::Options(CodeActionOptions {
|
||||||
// Advertise support for all built-in CodeActionKinds.
|
code_action_kinds: Some(action_kinds),
|
||||||
// Ideally we would base this off of the client capabilities
|
|
||||||
// but the client is supposed to fall back gracefully for unknown values.
|
|
||||||
code_action_kinds: Some(vec![
|
|
||||||
CodeActionKind::EMPTY,
|
|
||||||
CodeActionKind::QUICKFIX,
|
|
||||||
CodeActionKind::REFACTOR,
|
|
||||||
CodeActionKind::REFACTOR_EXTRACT,
|
|
||||||
CodeActionKind::REFACTOR_INLINE,
|
|
||||||
CodeActionKind::REFACTOR_REWRITE,
|
|
||||||
]),
|
|
||||||
work_done_progress_options: Default::default(),
|
work_done_progress_options: Default::default(),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue