aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock4
-rw-r--r--crates/rust-analyzer/src/bin/main.rs17
-rw-r--r--crates/rust-analyzer/src/caps.rs60
3 files changed, 55 insertions, 26 deletions
diff --git a/Cargo.lock b/Cargo.lock
index c06236692..5ce35c5b1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -658,9 +658,9 @@ dependencies = [
658 658
659[[package]] 659[[package]]
660name = "lsp-server" 660name = "lsp-server"
661version = "0.3.1" 661version = "0.3.2"
662source = "registry+https://github.com/rust-lang/crates.io-index" 662source = "registry+https://github.com/rust-lang/crates.io-index"
663checksum = "5383e043329615624bbf45e1ba27bd75c176762b2592855c659bc28ac580a06b" 663checksum = "dccec31bfd027ac0dd288a78e19005fd89624d9099456e284b5241316a6c3072"
664dependencies = [ 664dependencies = [
665 "crossbeam-channel", 665 "crossbeam-channel",
666 "log", 666 "log",
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs
index 09908458d..e82fd57de 100644
--- a/crates/rust-analyzer/src/bin/main.rs
+++ b/crates/rust-analyzer/src/bin/main.rs
@@ -74,12 +74,25 @@ fn run_server() -> Result<()> {
74 log::info!("lifecycle: server started"); 74 log::info!("lifecycle: server started");
75 75
76 let (connection, io_threads) = Connection::stdio(); 76 let (connection, io_threads) = Connection::stdio();
77 let server_capabilities = serde_json::to_value(rust_analyzer::server_capabilities()).unwrap();
78 77
79 let initialize_params = connection.initialize(server_capabilities)?; 78 let (initialize_id, initialize_params) = connection.initialize_start()?;
80 let initialize_params = 79 let initialize_params =
81 from_json::<lsp_types::InitializeParams>("InitializeParams", initialize_params)?; 80 from_json::<lsp_types::InitializeParams>("InitializeParams", initialize_params)?;
82 81
82 let server_capabilities = rust_analyzer::server_capabilities(&initialize_params.capabilities);
83
84 let initialize_result = lsp_types::InitializeResult {
85 capabilities: server_capabilities,
86 server_info: Some(lsp_types::ServerInfo {
87 name: String::from("rust-analyzer"),
88 version: Some(String::from(env!("REV"))),
89 }),
90 };
91
92 let initialize_result = serde_json::to_value(initialize_result).unwrap();
93
94 connection.initialize_finish(initialize_id, initialize_result)?;
95
83 if let Some(client_info) = initialize_params.client_info { 96 if let Some(client_info) = initialize_params.client_info {
84 log::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default()); 97 log::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default());
85 } 98 }
diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs
index 13af75469..780fc9317 100644
--- a/crates/rust-analyzer/src/caps.rs
+++ b/crates/rust-analyzer/src/caps.rs
@@ -2,19 +2,22 @@
2use std::env; 2use std::env;
3 3
4use lsp_types::{ 4use lsp_types::{
5 CallHierarchyServerCapability, CodeActionOptions, CodeActionProviderCapability, 5 CallHierarchyServerCapability, ClientCapabilities, CodeActionOptions,
6 CodeLensOptions, CompletionOptions, DocumentOnTypeFormattingOptions, 6 CodeActionProviderCapability, CodeLensOptions, CompletionOptions,
7 FoldingRangeProviderCapability, ImplementationProviderCapability, RenameOptions, 7 DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability,
8 RenameProviderCapability, SaveOptions, SelectionRangeProviderCapability, 8 ImplementationProviderCapability, RenameOptions, RenameProviderCapability, SaveOptions,
9 SemanticTokensDocumentProvider, SemanticTokensLegend, SemanticTokensOptions, 9 SelectionRangeProviderCapability, SemanticTokensDocumentProvider, SemanticTokensLegend,
10 ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind, 10 SemanticTokensOptions, ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability,
11 TextDocumentSyncOptions, TypeDefinitionProviderCapability, WorkDoneProgressOptions, 11 TextDocumentSyncKind, TextDocumentSyncOptions, TypeDefinitionProviderCapability,
12 WorkDoneProgressOptions,
12}; 13};
13use serde_json::json; 14use serde_json::json;
14 15
15use crate::semantic_tokens; 16use crate::semantic_tokens;
16 17
17pub fn server_capabilities() -> ServerCapabilities { 18pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabilities {
19 let code_action_provider = code_action_capabilities(client_caps);
20
18 ServerCapabilities { 21 ServerCapabilities {
19 text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions { 22 text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
20 open_close: Some(true), 23 open_close: Some(true),
@@ -46,20 +49,7 @@ pub fn server_capabilities() -> ServerCapabilities {
46 document_highlight_provider: Some(true), 49 document_highlight_provider: Some(true),
47 document_symbol_provider: Some(true), 50 document_symbol_provider: Some(true),
48 workspace_symbol_provider: Some(true), 51 workspace_symbol_provider: Some(true),
49 code_action_provider: Some(CodeActionProviderCapability::Options(CodeActionOptions { 52 code_action_provider: Some(code_action_provider),
50 // Advertise support for all built-in CodeActionKinds
51 code_action_kinds: Some(vec![
52 lsp_types::code_action_kind::EMPTY.to_string(),
53 lsp_types::code_action_kind::QUICKFIX.to_string(),
54 lsp_types::code_action_kind::REFACTOR.to_string(),
55 lsp_types::code_action_kind::REFACTOR_EXTRACT.to_string(),
56 lsp_types::code_action_kind::REFACTOR_INLINE.to_string(),
57 lsp_types::code_action_kind::REFACTOR_REWRITE.to_string(),
58 lsp_types::code_action_kind::SOURCE.to_string(),
59 lsp_types::code_action_kind::SOURCE_ORGANIZE_IMPORTS.to_string(),
60 ]),
61 work_done_progress_options: Default::default(),
62 })),
63 code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }), 53 code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }),
64 document_formatting_provider: Some(true), 54 document_formatting_provider: Some(true),
65 document_range_formatting_provider: None, 55 document_range_formatting_provider: None,
@@ -98,3 +88,29 @@ pub fn server_capabilities() -> ServerCapabilities {
98 })), 88 })),
99 } 89 }
100} 90}
91
92fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProviderCapability {
93 client_caps
94 .text_document
95 .as_ref()
96 .and_then(|it| it.code_action.as_ref())
97 .and_then(|it| it.code_action_literal_support.as_ref())
98 .map_or(CodeActionProviderCapability::Simple(true), |_| {
99 CodeActionProviderCapability::Options(CodeActionOptions {
100 // Advertise support for all built-in CodeActionKinds.
101 // Ideally we would base this off of the client capabilities
102 // but the client is supposed to fall back gracefully for unknown values.
103 code_action_kinds: Some(vec![
104 lsp_types::code_action_kind::EMPTY.to_string(),
105 lsp_types::code_action_kind::QUICKFIX.to_string(),
106 lsp_types::code_action_kind::REFACTOR.to_string(),
107 lsp_types::code_action_kind::REFACTOR_EXTRACT.to_string(),
108 lsp_types::code_action_kind::REFACTOR_INLINE.to_string(),
109 lsp_types::code_action_kind::REFACTOR_REWRITE.to_string(),
110 lsp_types::code_action_kind::SOURCE.to_string(),
111 lsp_types::code_action_kind::SOURCE_ORGANIZE_IMPORTS.to_string(),
112 ]),
113 work_done_progress_options: Default::default(),
114 })
115 })
116}