diff options
-rw-r--r-- | Cargo.lock | 4 | ||||
-rw-r--r-- | crates/rust-analyzer/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/rust-analyzer/src/global_state.rs | 13 | ||||
-rw-r--r-- | crates/rust-analyzer/src/handlers.rs | 22 | ||||
-rw-r--r-- | crates/rust-analyzer/src/main_loop.rs | 67 | ||||
-rw-r--r-- | crates/rust-analyzer/src/to_proto.rs | 7 | ||||
-rw-r--r-- | docs/dev/lsp-extensions.md | 8 | ||||
-rw-r--r-- | docs/user/manual.adoc | 4 |
8 files changed, 87 insertions, 40 deletions
diff --git a/Cargo.lock b/Cargo.lock index 280d97432..af7062815 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -619,9 +619,9 @@ dependencies = [ | |||
619 | 619 | ||
620 | [[package]] | 620 | [[package]] |
621 | name = "lsp-types" | 621 | name = "lsp-types" |
622 | version = "0.77.0" | 622 | version = "0.78.0" |
623 | source = "registry+https://github.com/rust-lang/crates.io-index" | 623 | source = "registry+https://github.com/rust-lang/crates.io-index" |
624 | checksum = "897c6c8930fbf12b67deffc83729287bb379dd5e5a4bd0ae2d81eff8d6503db6" | 624 | checksum = "d2e6cf68e3492cfa2035f0382c1da1b6ab045db0320feca505b86b4f13d66c27" |
625 | dependencies = [ | 625 | dependencies = [ |
626 | "base64", | 626 | "base64", |
627 | "bitflags", | 627 | "bitflags", |
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index 023c104d1..758aa1c5d 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml | |||
@@ -20,7 +20,7 @@ env_logger = { version = "0.7.1", default-features = false } | |||
20 | itertools = "0.9.0" | 20 | itertools = "0.9.0" |
21 | jod-thread = "0.1.0" | 21 | jod-thread = "0.1.0" |
22 | log = "0.4.8" | 22 | log = "0.4.8" |
23 | lsp-types = { version = "0.77.0", features = ["proposed"] } | 23 | lsp-types = { version = "0.78.0", features = ["proposed"] } |
24 | parking_lot = "0.11.0" | 24 | parking_lot = "0.11.0" |
25 | pico-args = "0.3.1" | 25 | pico-args = "0.3.1" |
26 | rand = { version = "0.7.3", features = ["small_rng"] } | 26 | rand = { version = "0.7.3", features = ["small_rng"] } |
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index 94973b90a..80937dbc4 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs | |||
@@ -12,7 +12,7 @@ use parking_lot::RwLock; | |||
12 | use ra_db::{CrateId, VfsPath}; | 12 | use ra_db::{CrateId, VfsPath}; |
13 | use ra_ide::{Analysis, AnalysisChange, AnalysisHost, FileId}; | 13 | use ra_ide::{Analysis, AnalysisChange, AnalysisHost, FileId}; |
14 | use ra_project_model::{CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target}; | 14 | use ra_project_model::{CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target}; |
15 | use rustc_hash::{FxHashMap, FxHashSet}; | 15 | use rustc_hash::FxHashMap; |
16 | 16 | ||
17 | use crate::{ | 17 | use crate::{ |
18 | config::Config, | 18 | config::Config, |
@@ -69,7 +69,7 @@ pub(crate) struct GlobalState { | |||
69 | pub(crate) config: Config, | 69 | pub(crate) config: Config, |
70 | pub(crate) analysis_host: AnalysisHost, | 70 | pub(crate) analysis_host: AnalysisHost, |
71 | pub(crate) diagnostics: DiagnosticCollection, | 71 | pub(crate) diagnostics: DiagnosticCollection, |
72 | pub(crate) mem_docs: FxHashSet<VfsPath>, | 72 | pub(crate) mem_docs: FxHashMap<VfsPath, Option<i64>>, |
73 | pub(crate) vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>, | 73 | pub(crate) vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>, |
74 | pub(crate) status: Status, | 74 | pub(crate) status: Status, |
75 | pub(crate) source_root_config: SourceRootConfig, | 75 | pub(crate) source_root_config: SourceRootConfig, |
@@ -84,6 +84,7 @@ pub(crate) struct GlobalStateSnapshot { | |||
84 | pub(crate) analysis: Analysis, | 84 | pub(crate) analysis: Analysis, |
85 | pub(crate) check_fixes: CheckFixes, | 85 | pub(crate) check_fixes: CheckFixes, |
86 | pub(crate) latest_requests: Arc<RwLock<LatestRequests>>, | 86 | pub(crate) latest_requests: Arc<RwLock<LatestRequests>>, |
87 | mem_docs: FxHashMap<VfsPath, Option<i64>>, | ||
87 | vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>, | 88 | vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>, |
88 | pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>, | 89 | pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>, |
89 | } | 90 | } |
@@ -117,7 +118,7 @@ impl GlobalState { | |||
117 | config, | 118 | config, |
118 | analysis_host, | 119 | analysis_host, |
119 | diagnostics: Default::default(), | 120 | diagnostics: Default::default(), |
120 | mem_docs: FxHashSet::default(), | 121 | mem_docs: FxHashMap::default(), |
121 | vfs: Arc::new(RwLock::new((vfs::Vfs::default(), FxHashMap::default()))), | 122 | vfs: Arc::new(RwLock::new((vfs::Vfs::default(), FxHashMap::default()))), |
122 | status: Status::default(), | 123 | status: Status::default(), |
123 | source_root_config: SourceRootConfig::default(), | 124 | source_root_config: SourceRootConfig::default(), |
@@ -183,6 +184,7 @@ impl GlobalState { | |||
183 | vfs: Arc::clone(&self.vfs), | 184 | vfs: Arc::clone(&self.vfs), |
184 | latest_requests: Arc::clone(&self.latest_requests), | 185 | latest_requests: Arc::clone(&self.latest_requests), |
185 | check_fixes: Arc::clone(&self.diagnostics.check_fixes), | 186 | check_fixes: Arc::clone(&self.diagnostics.check_fixes), |
187 | mem_docs: self.mem_docs.clone(), | ||
186 | } | 188 | } |
187 | } | 189 | } |
188 | 190 | ||
@@ -255,6 +257,11 @@ impl GlobalStateSnapshot { | |||
255 | self.vfs.read().1[&id] | 257 | self.vfs.read().1[&id] |
256 | } | 258 | } |
257 | 259 | ||
260 | pub(crate) fn url_file_version(&self, url: &Url) -> Option<i64> { | ||
261 | let path = from_proto::vfs_path(&url).ok()?; | ||
262 | self.mem_docs.get(&path).copied()? | ||
263 | } | ||
264 | |||
258 | pub(crate) fn anchored_path(&self, file_id: FileId, path: &str) -> Url { | 265 | pub(crate) fn anchored_path(&self, file_id: FileId, path: &str) -> Url { |
259 | let mut base = self.vfs.read().0.file_path(file_id); | 266 | let mut base = self.vfs.read().0.file_path(file_id); |
260 | base.pop(); | 267 | base.pop(); |
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index d880570d2..8d8c9442b 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs | |||
@@ -15,7 +15,7 @@ use lsp_types::{ | |||
15 | DocumentHighlight, DocumentSymbol, FoldingRange, FoldingRangeParams, HoverContents, Location, | 15 | DocumentHighlight, DocumentSymbol, FoldingRange, FoldingRangeParams, HoverContents, Location, |
16 | Position, PrepareRenameResponse, Range, RenameParams, SemanticTokensParams, | 16 | Position, PrepareRenameResponse, Range, RenameParams, SemanticTokensParams, |
17 | SemanticTokensRangeParams, SemanticTokensRangeResult, SemanticTokensResult, SymbolInformation, | 17 | SemanticTokensRangeParams, SemanticTokensRangeResult, SemanticTokensResult, SymbolInformation, |
18 | TextDocumentIdentifier, Url, WorkspaceEdit, | 18 | SymbolTag, TextDocumentIdentifier, Url, WorkspaceEdit, |
19 | }; | 19 | }; |
20 | use ra_ide::{ | 20 | use ra_ide::{ |
21 | FileId, FilePosition, FileRange, HoverAction, HoverGotoTypeData, NavigationTarget, Query, | 21 | FileId, FilePosition, FileRange, HoverAction, HoverGotoTypeData, NavigationTarget, Query, |
@@ -253,10 +253,17 @@ pub(crate) fn handle_document_symbol( | |||
253 | let mut parents: Vec<(DocumentSymbol, Option<usize>)> = Vec::new(); | 253 | let mut parents: Vec<(DocumentSymbol, Option<usize>)> = Vec::new(); |
254 | 254 | ||
255 | for symbol in snap.analysis.file_structure(file_id)? { | 255 | for symbol in snap.analysis.file_structure(file_id)? { |
256 | let mut tags = Vec::new(); | ||
257 | if symbol.deprecated { | ||
258 | tags.push(SymbolTag::Deprecated) | ||
259 | }; | ||
260 | |||
261 | #[allow(deprecated)] | ||
256 | let doc_symbol = DocumentSymbol { | 262 | let doc_symbol = DocumentSymbol { |
257 | name: symbol.label, | 263 | name: symbol.label, |
258 | detail: symbol.detail, | 264 | detail: symbol.detail, |
259 | kind: to_proto::symbol_kind(symbol.kind), | 265 | kind: to_proto::symbol_kind(symbol.kind), |
266 | tags: Some(tags), | ||
260 | deprecated: Some(symbol.deprecated), | 267 | deprecated: Some(symbol.deprecated), |
261 | range: to_proto::range(&line_index, symbol.node_range), | 268 | range: to_proto::range(&line_index, symbol.node_range), |
262 | selection_range: to_proto::range(&line_index, symbol.navigation_range), | 269 | selection_range: to_proto::range(&line_index, symbol.navigation_range), |
@@ -296,9 +303,19 @@ pub(crate) fn handle_document_symbol( | |||
296 | url: &Url, | 303 | url: &Url, |
297 | res: &mut Vec<SymbolInformation>, | 304 | res: &mut Vec<SymbolInformation>, |
298 | ) { | 305 | ) { |
306 | let mut tags = Vec::new(); | ||
307 | |||
308 | #[allow(deprecated)] | ||
309 | match symbol.deprecated { | ||
310 | Some(true) => tags.push(SymbolTag::Deprecated), | ||
311 | _ => {} | ||
312 | } | ||
313 | |||
314 | #[allow(deprecated)] | ||
299 | res.push(SymbolInformation { | 315 | res.push(SymbolInformation { |
300 | name: symbol.name.clone(), | 316 | name: symbol.name.clone(), |
301 | kind: symbol.kind, | 317 | kind: symbol.kind, |
318 | tags: Some(tags), | ||
302 | deprecated: symbol.deprecated, | 319 | deprecated: symbol.deprecated, |
303 | location: Location::new(url.clone(), symbol.range), | 320 | location: Location::new(url.clone(), symbol.range), |
304 | container_name, | 321 | container_name, |
@@ -342,9 +359,12 @@ pub(crate) fn handle_workspace_symbol( | |||
342 | let mut res = Vec::new(); | 359 | let mut res = Vec::new(); |
343 | for nav in snap.analysis.symbol_search(query)? { | 360 | for nav in snap.analysis.symbol_search(query)? { |
344 | let container_name = nav.container_name.as_ref().map(|v| v.to_string()); | 361 | let container_name = nav.container_name.as_ref().map(|v| v.to_string()); |
362 | |||
363 | #[allow(deprecated)] | ||
345 | let info = SymbolInformation { | 364 | let info = SymbolInformation { |
346 | name: nav.name.to_string(), | 365 | name: nav.name.to_string(), |
347 | kind: to_proto::symbol_kind(nav.kind), | 366 | kind: to_proto::symbol_kind(nav.kind), |
367 | tags: None, | ||
348 | location: to_proto::location_from_nav(snap, nav)?, | 368 | location: to_proto::location_from_nav(snap, nav)?, |
349 | container_name, | 369 | container_name, |
350 | deprecated: None, | 370 | deprecated: None, |
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index bb7c4c0c6..ac95e428e 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs | |||
@@ -97,22 +97,6 @@ impl fmt::Debug for Event { | |||
97 | } | 97 | } |
98 | 98 | ||
99 | impl GlobalState { | 99 | impl GlobalState { |
100 | fn next_event(&self, inbox: &Receiver<lsp_server::Message>) -> Option<Event> { | ||
101 | select! { | ||
102 | recv(inbox) -> msg => | ||
103 | msg.ok().map(Event::Lsp), | ||
104 | |||
105 | recv(self.task_pool.receiver) -> task => | ||
106 | Some(Event::Task(task.unwrap())), | ||
107 | |||
108 | recv(self.loader.receiver) -> task => | ||
109 | Some(Event::Vfs(task.unwrap())), | ||
110 | |||
111 | recv(self.flycheck_receiver) -> task => | ||
112 | Some(Event::Flycheck(task.unwrap())), | ||
113 | } | ||
114 | } | ||
115 | |||
116 | fn run(mut self, inbox: Receiver<lsp_server::Message>) -> Result<()> { | 100 | fn run(mut self, inbox: Receiver<lsp_server::Message>) -> Result<()> { |
117 | if self.config.linked_projects.is_empty() && self.config.notifications.cargo_toml_not_found | 101 | if self.config.linked_projects.is_empty() && self.config.notifications.cargo_toml_not_found |
118 | { | 102 | { |
@@ -169,6 +153,22 @@ impl GlobalState { | |||
169 | Err("client exited without proper shutdown sequence")? | 153 | Err("client exited without proper shutdown sequence")? |
170 | } | 154 | } |
171 | 155 | ||
156 | fn next_event(&self, inbox: &Receiver<lsp_server::Message>) -> Option<Event> { | ||
157 | select! { | ||
158 | recv(inbox) -> msg => | ||
159 | msg.ok().map(Event::Lsp), | ||
160 | |||
161 | recv(self.task_pool.receiver) -> task => | ||
162 | Some(Event::Task(task.unwrap())), | ||
163 | |||
164 | recv(self.loader.receiver) -> task => | ||
165 | Some(Event::Vfs(task.unwrap())), | ||
166 | |||
167 | recv(self.flycheck_receiver) -> task => | ||
168 | Some(Event::Flycheck(task.unwrap())), | ||
169 | } | ||
170 | } | ||
171 | |||
172 | fn handle_event(&mut self, event: Event) -> Result<()> { | 172 | fn handle_event(&mut self, event: Event) -> Result<()> { |
173 | let loop_start = Instant::now(); | 173 | let loop_start = Instant::now(); |
174 | // NOTE: don't count blocking select! call as a loop-turn time | 174 | // NOTE: don't count blocking select! call as a loop-turn time |
@@ -210,7 +210,7 @@ impl GlobalState { | |||
210 | let vfs = &mut self.vfs.write().0; | 210 | let vfs = &mut self.vfs.write().0; |
211 | for (path, contents) in files { | 211 | for (path, contents) in files { |
212 | let path = VfsPath::from(path); | 212 | let path = VfsPath::from(path); |
213 | if !self.mem_docs.contains(&path) { | 213 | if !self.mem_docs.contains_key(&path) { |
214 | vfs.set_file_contents(path, contents) | 214 | vfs.set_file_contents(path, contents) |
215 | } | 215 | } |
216 | } | 216 | } |
@@ -299,7 +299,7 @@ impl GlobalState { | |||
299 | if self.status == Status::Ready && (state_changed || prev_status == Status::Loading) { | 299 | if self.status == Status::Ready && (state_changed || prev_status == Status::Loading) { |
300 | let subscriptions = self | 300 | let subscriptions = self |
301 | .mem_docs | 301 | .mem_docs |
302 | .iter() | 302 | .keys() |
303 | .map(|path| self.vfs.read().0.file_id(&path).unwrap()) | 303 | .map(|path| self.vfs.read().0.file_id(&path).unwrap()) |
304 | .collect::<Vec<_>>(); | 304 | .collect::<Vec<_>>(); |
305 | 305 | ||
@@ -310,8 +310,12 @@ impl GlobalState { | |||
310 | for file_id in diagnostic_changes { | 310 | for file_id in diagnostic_changes { |
311 | let url = file_id_to_url(&self.vfs.read().0, file_id); | 311 | let url = file_id_to_url(&self.vfs.read().0, file_id); |
312 | let diagnostics = self.diagnostics.diagnostics_for(file_id).cloned().collect(); | 312 | let diagnostics = self.diagnostics.diagnostics_for(file_id).cloned().collect(); |
313 | let version = from_proto::vfs_path(&url) | ||
314 | .map(|path| self.mem_docs.get(&path).copied().flatten()) | ||
315 | .unwrap_or_default(); | ||
316 | |||
313 | self.send_notification::<lsp_types::notification::PublishDiagnostics>( | 317 | self.send_notification::<lsp_types::notification::PublishDiagnostics>( |
314 | lsp_types::PublishDiagnosticsParams { uri: url, diagnostics, version: None }, | 318 | lsp_types::PublishDiagnosticsParams { uri: url, diagnostics, version }, |
315 | ); | 319 | ); |
316 | } | 320 | } |
317 | } | 321 | } |
@@ -400,7 +404,11 @@ impl GlobalState { | |||
400 | })? | 404 | })? |
401 | .on::<lsp_types::notification::DidOpenTextDocument>(|this, params| { | 405 | .on::<lsp_types::notification::DidOpenTextDocument>(|this, params| { |
402 | if let Ok(path) = from_proto::vfs_path(¶ms.text_document.uri) { | 406 | if let Ok(path) = from_proto::vfs_path(¶ms.text_document.uri) { |
403 | if !this.mem_docs.insert(path.clone()) { | 407 | if this |
408 | .mem_docs | ||
409 | .insert(path.clone(), Some(params.text_document.version)) | ||
410 | .is_some() | ||
411 | { | ||
404 | log::error!("duplicate DidOpenTextDocument: {}", path) | 412 | log::error!("duplicate DidOpenTextDocument: {}", path) |
405 | } | 413 | } |
406 | this.vfs | 414 | this.vfs |
@@ -412,29 +420,38 @@ impl GlobalState { | |||
412 | })? | 420 | })? |
413 | .on::<lsp_types::notification::DidChangeTextDocument>(|this, params| { | 421 | .on::<lsp_types::notification::DidChangeTextDocument>(|this, params| { |
414 | if let Ok(path) = from_proto::vfs_path(¶ms.text_document.uri) { | 422 | if let Ok(path) = from_proto::vfs_path(¶ms.text_document.uri) { |
415 | assert!(this.mem_docs.contains(&path)); | 423 | *this.mem_docs.get_mut(&path).unwrap() = params.text_document.version; |
416 | let vfs = &mut this.vfs.write().0; | 424 | let vfs = &mut this.vfs.write().0; |
417 | let file_id = vfs.file_id(&path).unwrap(); | 425 | let file_id = vfs.file_id(&path).unwrap(); |
418 | let mut text = String::from_utf8(vfs.file_contents(file_id).to_vec()).unwrap(); | 426 | let mut text = String::from_utf8(vfs.file_contents(file_id).to_vec()).unwrap(); |
419 | apply_document_changes(&mut text, params.content_changes); | 427 | apply_document_changes(&mut text, params.content_changes); |
420 | vfs.set_file_contents(path, Some(text.into_bytes())) | 428 | vfs.set_file_contents(path.clone(), Some(text.into_bytes())); |
429 | |||
430 | this.mem_docs.insert(path, params.text_document.version); | ||
421 | } | 431 | } |
422 | Ok(()) | 432 | Ok(()) |
423 | })? | 433 | })? |
424 | .on::<lsp_types::notification::DidCloseTextDocument>(|this, params| { | 434 | .on::<lsp_types::notification::DidCloseTextDocument>(|this, params| { |
435 | let mut version = None; | ||
425 | if let Ok(path) = from_proto::vfs_path(¶ms.text_document.uri) { | 436 | if let Ok(path) = from_proto::vfs_path(¶ms.text_document.uri) { |
426 | if !this.mem_docs.remove(&path) { | 437 | match this.mem_docs.remove(&path) { |
427 | log::error!("orphan DidCloseTextDocument: {}", path) | 438 | Some(entry) => version = entry, |
439 | None => log::error!("orphan DidCloseTextDocument: {}", path), | ||
428 | } | 440 | } |
441 | |||
429 | if let Some(path) = path.as_path() { | 442 | if let Some(path) = path.as_path() { |
430 | this.loader.handle.invalidate(path.to_path_buf()); | 443 | this.loader.handle.invalidate(path.to_path_buf()); |
431 | } | 444 | } |
432 | } | 445 | } |
446 | |||
447 | // Clear the diagnostics for the previously known version of the file. | ||
448 | // This prevents stale "cargo check" diagnostics if the file is | ||
449 | // closed, "cargo check" is run and then the file is reopened. | ||
433 | this.send_notification::<lsp_types::notification::PublishDiagnostics>( | 450 | this.send_notification::<lsp_types::notification::PublishDiagnostics>( |
434 | lsp_types::PublishDiagnosticsParams { | 451 | lsp_types::PublishDiagnosticsParams { |
435 | uri: params.text_document.uri, | 452 | uri: params.text_document.uri, |
436 | diagnostics: Vec::new(), | 453 | diagnostics: Vec::new(), |
437 | version: None, | 454 | version, |
438 | }, | 455 | }, |
439 | ); | 456 | ); |
440 | Ok(()) | 457 | Ok(()) |
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index fc94f28b9..c6935c029 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs | |||
@@ -480,9 +480,10 @@ pub(crate) fn url_from_abs_path(path: &Path) -> lsp_types::Url { | |||
480 | pub(crate) fn versioned_text_document_identifier( | 480 | pub(crate) fn versioned_text_document_identifier( |
481 | snap: &GlobalStateSnapshot, | 481 | snap: &GlobalStateSnapshot, |
482 | file_id: FileId, | 482 | file_id: FileId, |
483 | version: Option<i64>, | ||
484 | ) -> lsp_types::VersionedTextDocumentIdentifier { | 483 | ) -> lsp_types::VersionedTextDocumentIdentifier { |
485 | lsp_types::VersionedTextDocumentIdentifier { uri: url(snap, file_id), version } | 484 | let url = url(snap, file_id); |
485 | let version = snap.url_file_version(&url); | ||
486 | lsp_types::VersionedTextDocumentIdentifier { uri: url, version } | ||
486 | } | 487 | } |
487 | 488 | ||
488 | pub(crate) fn location( | 489 | pub(crate) fn location( |
@@ -571,7 +572,7 @@ pub(crate) fn snippet_text_document_edit( | |||
571 | is_snippet: bool, | 572 | is_snippet: bool, |
572 | source_file_edit: SourceFileEdit, | 573 | source_file_edit: SourceFileEdit, |
573 | ) -> Result<lsp_ext::SnippetTextDocumentEdit> { | 574 | ) -> Result<lsp_ext::SnippetTextDocumentEdit> { |
574 | let text_document = versioned_text_document_identifier(snap, source_file_edit.file_id, None); | 575 | let text_document = versioned_text_document_identifier(snap, source_file_edit.file_id); |
575 | let line_index = snap.analysis.file_line_index(source_file_edit.file_id)?; | 576 | let line_index = snap.analysis.file_line_index(source_file_edit.file_id)?; |
576 | let line_endings = snap.file_line_endings(source_file_edit.file_id); | 577 | let line_endings = snap.file_line_endings(source_file_edit.file_id); |
577 | let edits = source_file_edit | 578 | let edits = source_file_edit |
diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md index 6d6bbac7c..98d14450b 100644 --- a/docs/dev/lsp-extensions.md +++ b/docs/dev/lsp-extensions.md | |||
@@ -11,11 +11,13 @@ If you want to be notified about the changes to this document, subscribe to [#46 | |||
11 | 11 | ||
12 | ## `initializationOptions` | 12 | ## `initializationOptions` |
13 | 13 | ||
14 | As `initializationOptions`, `rust-analyzer` expects `"rust-analyzer"` section of the configuration. | 14 | For `initializationOptions`, `rust-analyzer` expects `"rust-analyzer"` section of the configuration. |
15 | That is, `rust-analyzer` usually sends `"workspace/configuration"` request with `{ "items": ["rust-analyzer"] }` payload. | 15 | That is, `rust-analyzer` usually sends `"workspace/configuration"` request with `{ "items": ["rust-analyzer"] }` payload. |
16 | `initializationOptions` should contain the same data that would be in the first item of the result. | 16 | `initializationOptions` should contain the same data that would be in the first item of the result. |
17 | It's OK to not send anything, then all the settings would take their default values. | 17 | If a language client does not know about `rust-analyzer`'s configuration options it can get sensible defaults by doing any of the following: |
18 | However, some settings can not be changed after startup at the moment. | 18 | * Not sending `initializationOptions` |
19 | * Send `"initializationOptions": null` | ||
20 | * Send `"initializationOptions": {}` | ||
19 | 21 | ||
20 | ## Snippet `TextEdit` | 22 | ## Snippet `TextEdit` |
21 | 23 | ||
diff --git a/docs/user/manual.adoc b/docs/user/manual.adoc index 978b463d5..57251b851 100644 --- a/docs/user/manual.adoc +++ b/docs/user/manual.adoc | |||
@@ -110,8 +110,8 @@ Here are some useful self-diagnostic commands: | |||
110 | * **Rust Analyzer: Show RA Version** shows the version of `rust-analyzer` binary | 110 | * **Rust Analyzer: Show RA Version** shows the version of `rust-analyzer` binary |
111 | * **Rust Analyzer: Status** prints some statistics about the server, like the few latest LSP requests | 111 | * **Rust Analyzer: Status** prints some statistics about the server, like the few latest LSP requests |
112 | * To enable server-side logging, run with `env RA_LOG=info` and see `Output > Rust Analyzer Language Server` in VS Code's panel. | 112 | * To enable server-side logging, run with `env RA_LOG=info` and see `Output > Rust Analyzer Language Server` in VS Code's panel. |
113 | * To log all LSP requests, add `"rust-analyzer.trace.server": "verbose"` to the settings and look for `Server Trace` in the panel. | 113 | * To log all LSP requests, add `"rust-analyzer.trace.server": "verbose"` to the settings and look for `Rust Analyzer Language Server Trace` in the panel. |
114 | * To enable client-side logging, add `"rust-analyzer.trace.extension": true` to the settings and open the `Console` tab of VS Code developer tools. | 114 | * To enable client-side logging, add `"rust-analyzer.trace.extension": true` to the settings and open `Output > Rust Analyzer Client` in the panel. |
115 | 115 | ||
116 | === rust-analyzer Language Server Binary | 116 | === rust-analyzer Language Server Binary |
117 | 117 | ||