aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/rust-analyzer/src/bin/main.rs84
-rw-r--r--crates/rust-analyzer/src/caps.rs12
-rw-r--r--crates/rust-analyzer/src/config.rs2
3 files changed, 47 insertions, 51 deletions
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs
index 6c883dd58..2b842d393 100644
--- a/crates/rust-analyzer/src/bin/main.rs
+++ b/crates/rust-analyzer/src/bin/main.rs
@@ -158,7 +158,24 @@ fn run_server() -> Result<()> {
158 let initialize_params = 158 let initialize_params =
159 from_json::<lsp_types::InitializeParams>("InitializeParams", initialize_params)?; 159 from_json::<lsp_types::InitializeParams>("InitializeParams", initialize_params)?;
160 160
161 let server_capabilities = rust_analyzer::server_capabilities(&initialize_params.capabilities); 161 let root_path = match initialize_params
162 .root_uri
163 .and_then(|it| it.to_file_path().ok())
164 .and_then(|it| AbsPathBuf::try_from(it).ok())
165 {
166 Some(it) => it,
167 None => {
168 let cwd = env::current_dir()?;
169 AbsPathBuf::assert(cwd)
170 }
171 };
172
173 let mut config = Config::new(root_path, initialize_params.capabilities);
174 if let Some(json) = initialize_params.initialization_options {
175 config.update(json);
176 }
177
178 let server_capabilities = rust_analyzer::server_capabilities(&config);
162 179
163 let initialize_result = lsp_types::InitializeResult { 180 let initialize_result = lsp_types::InitializeResult {
164 capabilities: server_capabilities, 181 capabilities: server_capabilities,
@@ -166,11 +183,7 @@ fn run_server() -> Result<()> {
166 name: String::from("rust-analyzer"), 183 name: String::from("rust-analyzer"),
167 version: Some(String::from(env!("REV"))), 184 version: Some(String::from(env!("REV"))),
168 }), 185 }),
169 offset_encoding: if supports_utf8(&initialize_params.capabilities) { 186 offset_encoding: if supports_utf8(&config.caps) { Some("utf-8".to_string()) } else { None },
170 Some("utf-8".to_string())
171 } else {
172 None
173 },
174 }; 187 };
175 188
176 let initialize_result = serde_json::to_value(initialize_result).unwrap(); 189 let initialize_result = serde_json::to_value(initialize_result).unwrap();
@@ -181,47 +194,26 @@ fn run_server() -> Result<()> {
181 log::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default()); 194 log::info!("Client '{}' {}", client_info.name, client_info.version.unwrap_or_default());
182 } 195 }
183 196
184 let config = { 197 if config.linked_projects().is_empty() && config.detached_files().is_empty() {
185 let root_path = match initialize_params 198 let workspace_roots = initialize_params
186 .root_uri 199 .workspace_folders
187 .and_then(|it| it.to_file_path().ok()) 200 .map(|workspaces| {
188 .and_then(|it| AbsPathBuf::try_from(it).ok()) 201 workspaces
189 { 202 .into_iter()
190 Some(it) => it, 203 .filter_map(|it| it.uri.to_file_path().ok())
191 None => { 204 .filter_map(|it| AbsPathBuf::try_from(it).ok())
192 let cwd = env::current_dir()?; 205 .collect::<Vec<_>>()
193 AbsPathBuf::assert(cwd) 206 })
194 } 207 .filter(|workspaces| !workspaces.is_empty())
195 }; 208 .unwrap_or_else(|| vec![config.root_path.clone()]);
196 209
197 let mut config = Config::new(root_path, initialize_params.capabilities); 210 let discovered = ProjectManifest::discover_all(&workspace_roots);
198 if let Some(json) = initialize_params.initialization_options { 211 log::info!("discovered projects: {:?}", discovered);
199 config.update(json); 212 if discovered.is_empty() {
200 } 213 log::error!("failed to find any projects in {:?}", workspace_roots);
201
202 if config.linked_projects().is_empty() && config.detached_files().is_empty() {
203 let workspace_roots = initialize_params
204 .workspace_folders
205 .map(|workspaces| {
206 workspaces
207 .into_iter()
208 .filter_map(|it| it.uri.to_file_path().ok())
209 .filter_map(|it| AbsPathBuf::try_from(it).ok())
210 .collect::<Vec<_>>()
211 })
212 .filter(|workspaces| !workspaces.is_empty())
213 .unwrap_or_else(|| vec![config.root_path.clone()]);
214
215 let discovered = ProjectManifest::discover_all(&workspace_roots);
216 log::info!("discovered projects: {:?}", discovered);
217 if discovered.is_empty() {
218 log::error!("failed to find any projects in {:?}", workspace_roots);
219 }
220 config.discovered_projects = Some(discovered);
221 } 214 }
222 215 config.discovered_projects = Some(discovered);
223 config 216 }
224 };
225 217
226 rust_analyzer::main_loop(config, connection)?; 218 rust_analyzer::main_loop(config, connection)?;
227 219
diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs
index 4d88932ca..6b9753521 100644
--- a/crates/rust-analyzer/src/caps.rs
+++ b/crates/rust-analyzer/src/caps.rs
@@ -15,9 +15,10 @@ use lsp_types::{
15}; 15};
16use serde_json::json; 16use serde_json::json;
17 17
18use crate::config::{Config, RustfmtConfig};
18use crate::semantic_tokens; 19use crate::semantic_tokens;
19 20
20pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabilities { 21pub fn server_capabilities(config: &Config) -> ServerCapabilities {
21 ServerCapabilities { 22 ServerCapabilities {
22 text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions { 23 text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
23 open_close: Some(true), 24 open_close: Some(true),
@@ -32,7 +33,7 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
32 })), 33 })),
33 hover_provider: Some(HoverProviderCapability::Simple(true)), 34 hover_provider: Some(HoverProviderCapability::Simple(true)),
34 completion_provider: Some(CompletionOptions { 35 completion_provider: Some(CompletionOptions {
35 resolve_provider: completions_resolve_provider(client_caps), 36 resolve_provider: completions_resolve_provider(&config.caps),
36 trigger_characters: Some(vec![":".to_string(), ".".to_string(), "'".to_string()]), 37 trigger_characters: Some(vec![":".to_string(), ".".to_string(), "'".to_string()]),
37 all_commit_characters: None, 38 all_commit_characters: None,
38 completion_item: None, 39 completion_item: None,
@@ -51,10 +52,13 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
51 document_highlight_provider: Some(OneOf::Left(true)), 52 document_highlight_provider: Some(OneOf::Left(true)),
52 document_symbol_provider: Some(OneOf::Left(true)), 53 document_symbol_provider: Some(OneOf::Left(true)),
53 workspace_symbol_provider: Some(OneOf::Left(true)), 54 workspace_symbol_provider: Some(OneOf::Left(true)),
54 code_action_provider: Some(code_action_capabilities(client_caps)), 55 code_action_provider: Some(code_action_capabilities(&config.caps)),
55 code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }), 56 code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }),
56 document_formatting_provider: Some(OneOf::Left(true)), 57 document_formatting_provider: Some(OneOf::Left(true)),
57 document_range_formatting_provider: Some(OneOf::Left(true)), 58 document_range_formatting_provider: match config.rustfmt() {
59 RustfmtConfig::Rustfmt { enable_range_formatting: true, .. } => Some(OneOf::Left(true)),
60 _ => Some(OneOf::Left(false)),
61 },
58 document_on_type_formatting_provider: Some(DocumentOnTypeFormattingOptions { 62 document_on_type_formatting_provider: Some(DocumentOnTypeFormattingOptions {
59 first_trigger_character: "=".to_string(), 63 first_trigger_character: "=".to_string(),
60 more_trigger_character: Some(vec![".".to_string(), ">".to_string(), "{".to_string()]), 64 more_trigger_character: Some(vec![".".to_string(), ">".to_string(), "{".to_string()]),
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 7620a2fe1..b6a1124a5 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -238,7 +238,7 @@ impl Default for ConfigData {
238 238
239#[derive(Debug, Clone)] 239#[derive(Debug, Clone)]
240pub struct Config { 240pub struct Config {
241 caps: lsp_types::ClientCapabilities, 241 pub caps: lsp_types::ClientCapabilities,
242 data: ConfigData, 242 data: ConfigData,
243 detached_files: Vec<AbsPathBuf>, 243 detached_files: Vec<AbsPathBuf>,
244 pub discovered_projects: Option<Vec<ProjectManifest>>, 244 pub discovered_projects: Option<Vec<ProjectManifest>>,