diff options
Diffstat (limited to 'crates/ra_lsp_server/src')
-rw-r--r-- | crates/ra_lsp_server/src/caps.rs | 2 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/conv.rs | 23 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main.rs | 41 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 28 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/mod.rs | 24 |
5 files changed, 96 insertions, 22 deletions
diff --git a/crates/ra_lsp_server/src/caps.rs b/crates/ra_lsp_server/src/caps.rs index 0d02c8073..bcf857fce 100644 --- a/crates/ra_lsp_server/src/caps.rs +++ b/crates/ra_lsp_server/src/caps.rs | |||
@@ -16,7 +16,7 @@ pub fn server_capabilities() -> ServerCapabilities { | |||
16 | save: None, | 16 | save: None, |
17 | }, | 17 | }, |
18 | )), | 18 | )), |
19 | hover_provider: None, | 19 | hover_provider: Some(true), |
20 | completion_provider: Some(CompletionOptions { | 20 | completion_provider: Some(CompletionOptions { |
21 | resolve_provider: None, | 21 | resolve_provider: None, |
22 | trigger_characters: None, | 22 | trigger_characters: None, |
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index fa04f4b00..5d5a0c55e 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs | |||
@@ -2,7 +2,7 @@ use languageserver_types::{ | |||
2 | Location, Position, Range, SymbolKind, TextDocumentEdit, TextDocumentIdentifier, | 2 | Location, Position, Range, SymbolKind, TextDocumentEdit, TextDocumentIdentifier, |
3 | TextDocumentItem, TextDocumentPositionParams, TextEdit, Url, VersionedTextDocumentIdentifier, | 3 | TextDocumentItem, TextDocumentPositionParams, TextEdit, Url, VersionedTextDocumentIdentifier, |
4 | }; | 4 | }; |
5 | use ra_analysis::{FileId, FileSystemEdit, SourceChange, SourceFileEdit, FilePosition}; | 5 | use ra_analysis::{FileId, FileSystemEdit, SourceChange, SourceFileNodeEdit, FilePosition}; |
6 | use ra_editor::{AtomEdit, Edit, LineCol, LineIndex}; | 6 | use ra_editor::{AtomEdit, Edit, LineCol, LineIndex}; |
7 | use ra_syntax::{SyntaxKind, TextRange, TextUnit}; | 7 | use ra_syntax::{SyntaxKind, TextRange, TextUnit}; |
8 | 8 | ||
@@ -49,10 +49,9 @@ impl ConvWith for Position { | |||
49 | type Output = TextUnit; | 49 | type Output = TextUnit; |
50 | 50 | ||
51 | fn conv_with(self, line_index: &LineIndex) -> TextUnit { | 51 | fn conv_with(self, line_index: &LineIndex) -> TextUnit { |
52 | // TODO: UTF-16 | ||
53 | let line_col = LineCol { | 52 | let line_col = LineCol { |
54 | line: self.line as u32, | 53 | line: self.line as u32, |
55 | col: (self.character as u32).into(), | 54 | col_utf16: self.character as u32, |
56 | }; | 55 | }; |
57 | line_index.offset(line_col) | 56 | line_index.offset(line_col) |
58 | } | 57 | } |
@@ -64,8 +63,10 @@ impl ConvWith for TextUnit { | |||
64 | 63 | ||
65 | fn conv_with(self, line_index: &LineIndex) -> Position { | 64 | fn conv_with(self, line_index: &LineIndex) -> Position { |
66 | let line_col = line_index.line_col(self); | 65 | let line_col = line_index.line_col(self); |
67 | // TODO: UTF-16 | 66 | Position::new( |
68 | Position::new(u64::from(line_col.line), u64::from(u32::from(line_col.col))) | 67 | u64::from(line_col.line), |
68 | u64::from(u32::from(line_col.col_utf16)), | ||
69 | ) | ||
69 | } | 70 | } |
70 | } | 71 | } |
71 | 72 | ||
@@ -203,8 +204,10 @@ impl TryConvWith for SourceChange { | |||
203 | .map(|it| it.edits.as_slice()) | 204 | .map(|it| it.edits.as_slice()) |
204 | .unwrap_or(&[]); | 205 | .unwrap_or(&[]); |
205 | let line_col = translate_offset_with_edit(&*line_index, pos.offset, edits); | 206 | let line_col = translate_offset_with_edit(&*line_index, pos.offset, edits); |
206 | let position = | 207 | let position = Position::new( |
207 | Position::new(u64::from(line_col.line), u64::from(u32::from(line_col.col))); | 208 | u64::from(line_col.line), |
209 | u64::from(u32::from(line_col.col_utf16)), | ||
210 | ); | ||
208 | Some(TextDocumentPositionParams { | 211 | Some(TextDocumentPositionParams { |
209 | text_document: TextDocumentIdentifier::new(pos.file_id.try_conv_with(world)?), | 212 | text_document: TextDocumentIdentifier::new(pos.file_id.try_conv_with(world)?), |
210 | position, | 213 | position, |
@@ -247,17 +250,17 @@ fn translate_offset_with_edit( | |||
247 | if in_edit_line_col.line == 0 { | 250 | if in_edit_line_col.line == 0 { |
248 | LineCol { | 251 | LineCol { |
249 | line: edit_line_col.line, | 252 | line: edit_line_col.line, |
250 | col: edit_line_col.col + in_edit_line_col.col, | 253 | col_utf16: edit_line_col.col_utf16 + in_edit_line_col.col_utf16, |
251 | } | 254 | } |
252 | } else { | 255 | } else { |
253 | LineCol { | 256 | LineCol { |
254 | line: edit_line_col.line + in_edit_line_col.line, | 257 | line: edit_line_col.line + in_edit_line_col.line, |
255 | col: in_edit_line_col.col, | 258 | col_utf16: in_edit_line_col.col_utf16, |
256 | } | 259 | } |
257 | } | 260 | } |
258 | } | 261 | } |
259 | 262 | ||
260 | impl TryConvWith for SourceFileEdit { | 263 | impl TryConvWith for SourceFileNodeEdit { |
261 | type Ctx = ServerWorld; | 264 | type Ctx = ServerWorld; |
262 | type Output = TextDocumentEdit; | 265 | type Output = TextDocumentEdit; |
263 | fn try_conv_with(self, world: &ServerWorld) -> Result<TextDocumentEdit> { | 266 | fn try_conv_with(self, world: &ServerWorld) -> Result<TextDocumentEdit> { |
diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs index c07eb0140..26bcddd8e 100644 --- a/crates/ra_lsp_server/src/main.rs +++ b/crates/ra_lsp_server/src/main.rs | |||
@@ -2,10 +2,14 @@ | |||
2 | extern crate log; | 2 | extern crate log; |
3 | #[macro_use] | 3 | #[macro_use] |
4 | extern crate failure; | 4 | extern crate failure; |
5 | #[macro_use] | ||
6 | extern crate serde_derive; | ||
7 | extern crate serde; | ||
5 | extern crate flexi_logger; | 8 | extern crate flexi_logger; |
6 | extern crate gen_lsp_server; | 9 | extern crate gen_lsp_server; |
7 | extern crate ra_lsp_server; | 10 | extern crate ra_lsp_server; |
8 | 11 | ||
12 | use serde::Deserialize; | ||
9 | use flexi_logger::{Duplicate, Logger}; | 13 | use flexi_logger::{Duplicate, Logger}; |
10 | use gen_lsp_server::{run_server, stdio_transport}; | 14 | use gen_lsp_server::{run_server, stdio_transport}; |
11 | use ra_lsp_server::Result; | 15 | use ra_lsp_server::Result; |
@@ -30,6 +34,12 @@ fn main() -> Result<()> { | |||
30 | } | 34 | } |
31 | } | 35 | } |
32 | 36 | ||
37 | #[derive(Deserialize)] | ||
38 | #[serde(rename_all = "camelCase")] | ||
39 | struct InitializationOptions { | ||
40 | publish_decorations: bool, | ||
41 | } | ||
42 | |||
33 | fn main_inner() -> Result<()> { | 43 | fn main_inner() -> Result<()> { |
34 | let (receiver, sender, threads) = stdio_transport(); | 44 | let (receiver, sender, threads) = stdio_transport(); |
35 | let cwd = ::std::env::current_dir()?; | 45 | let cwd = ::std::env::current_dir()?; |
@@ -42,7 +52,12 @@ fn main_inner() -> Result<()> { | |||
42 | .root_uri | 52 | .root_uri |
43 | .and_then(|it| it.to_file_path().ok()) | 53 | .and_then(|it| it.to_file_path().ok()) |
44 | .unwrap_or(cwd); | 54 | .unwrap_or(cwd); |
45 | ra_lsp_server::main_loop(false, root, r, s) | 55 | let publish_decorations = params |
56 | .initialization_options | ||
57 | .and_then(|v| InitializationOptions::deserialize(v).ok()) | ||
58 | .map(|it| it.publish_decorations) | ||
59 | == Some(true); | ||
60 | ra_lsp_server::main_loop(false, root, publish_decorations, r, s) | ||
46 | }, | 61 | }, |
47 | )?; | 62 | )?; |
48 | info!("shutting down IO..."); | 63 | info!("shutting down IO..."); |
@@ -50,3 +65,27 @@ fn main_inner() -> Result<()> { | |||
50 | info!("... IO is down"); | 65 | info!("... IO is down"); |
51 | Ok(()) | 66 | Ok(()) |
52 | } | 67 | } |
68 | |||
69 | /* | ||
70 | (let ((backend (eglot-xref-backend))) | ||
71 | (mapcar | ||
72 | (lambda (xref) | ||
73 | (let ((loc (xref-item-location xref))) | ||
74 | (propertize | ||
75 | (concat | ||
76 | (when (xref-file-location-p loc) | ||
77 | (with-slots (file line column) loc | ||
78 | (format "%s:%s:%s:" | ||
79 | (propertize (file-relative-name file) | ||
80 | 'face 'compilation-info) | ||
81 | (propertize (format "%s" line) | ||
82 | 'face 'compilation-line | ||
83 | ) | ||
84 | column))) | ||
85 | (xref-item-summary xref)) | ||
86 | 'xref xref))) | ||
87 | (xref-backend-apropos backend "Analysis")) | ||
88 | ) | ||
89 | |||
90 | |||
91 | */ | ||
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 5314a333e..c872b0dc4 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -4,9 +4,9 @@ use gen_lsp_server::ErrorCode; | |||
4 | use languageserver_types::{ | 4 | use languageserver_types::{ |
5 | CodeActionResponse, Command, CompletionItem, CompletionItemKind, Diagnostic, | 5 | CodeActionResponse, Command, CompletionItem, CompletionItemKind, Diagnostic, |
6 | DiagnosticSeverity, DocumentSymbol, Documentation, FoldingRange, FoldingRangeKind, | 6 | DiagnosticSeverity, DocumentSymbol, Documentation, FoldingRange, FoldingRangeKind, |
7 | FoldingRangeParams, InsertTextFormat, Location, MarkupContent, MarkupKind, Position, | 7 | FoldingRangeParams, InsertTextFormat, Location, MarkupContent, MarkupKind, MarkedString, Position, |
8 | PrepareRenameResponse, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit, | 8 | PrepareRenameResponse, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit, |
9 | WorkspaceEdit, ParameterInformation, SignatureInformation, | 9 | WorkspaceEdit, ParameterInformation, SignatureInformation, Hover, HoverContents, |
10 | }; | 10 | }; |
11 | use ra_analysis::{FileId, FoldKind, Query, RunnableKind, FilePosition}; | 11 | use ra_analysis::{FileId, FoldKind, Query, RunnableKind, FilePosition}; |
12 | use ra_syntax::text_utils::contains_offset_nonstrict; | 12 | use ra_syntax::text_utils::contains_offset_nonstrict; |
@@ -478,6 +478,30 @@ pub fn handle_signature_help( | |||
478 | } | 478 | } |
479 | } | 479 | } |
480 | 480 | ||
481 | pub fn handle_hover( | ||
482 | world: ServerWorld, | ||
483 | params: req::TextDocumentPositionParams, | ||
484 | ) -> Result<Option<Hover>> { | ||
485 | let position = params.try_conv_with(&world)?; | ||
486 | let line_index = world.analysis().file_line_index(position.file_id); | ||
487 | |||
488 | for (file_id, symbol) in world.analysis().approximately_resolve_symbol(position)? { | ||
489 | let range = symbol.node_range.conv_with(&line_index); | ||
490 | let comment = world.analysis.doc_comment_for(file_id, symbol)?; | ||
491 | |||
492 | if comment.is_some() { | ||
493 | let contents = HoverContents::Scalar(MarkedString::String(comment.unwrap())); | ||
494 | |||
495 | return Ok(Some(Hover { | ||
496 | contents, | ||
497 | range: Some(range), | ||
498 | })); | ||
499 | } | ||
500 | } | ||
501 | |||
502 | Ok(None) | ||
503 | } | ||
504 | |||
481 | pub fn handle_prepare_rename( | 505 | pub fn handle_prepare_rename( |
482 | world: ServerWorld, | 506 | world: ServerWorld, |
483 | params: req::TextDocumentPositionParams, | 507 | params: req::TextDocumentPositionParams, |
diff --git a/crates/ra_lsp_server/src/main_loop/mod.rs b/crates/ra_lsp_server/src/main_loop/mod.rs index 229d1b0f7..78d93741a 100644 --- a/crates/ra_lsp_server/src/main_loop/mod.rs +++ b/crates/ra_lsp_server/src/main_loop/mod.rs | |||
@@ -48,6 +48,7 @@ enum Task { | |||
48 | pub fn main_loop( | 48 | pub fn main_loop( |
49 | internal_mode: bool, | 49 | internal_mode: bool, |
50 | root: PathBuf, | 50 | root: PathBuf, |
51 | publish_decorations: bool, | ||
51 | msg_receiver: &Receiver<RawMessage>, | 52 | msg_receiver: &Receiver<RawMessage>, |
52 | msg_sender: &Sender<RawMessage>, | 53 | msg_sender: &Sender<RawMessage>, |
53 | ) -> Result<()> { | 54 | ) -> Result<()> { |
@@ -67,6 +68,7 @@ pub fn main_loop( | |||
67 | let mut subs = Subscriptions::new(); | 68 | let mut subs = Subscriptions::new(); |
68 | let main_res = main_loop_inner( | 69 | let main_res = main_loop_inner( |
69 | internal_mode, | 70 | internal_mode, |
71 | publish_decorations, | ||
70 | root, | 72 | root, |
71 | &pool, | 73 | &pool, |
72 | msg_sender, | 74 | msg_sender, |
@@ -99,6 +101,7 @@ pub fn main_loop( | |||
99 | 101 | ||
100 | fn main_loop_inner( | 102 | fn main_loop_inner( |
101 | internal_mode: bool, | 103 | internal_mode: bool, |
104 | publish_decorations: bool, | ||
102 | ws_root: PathBuf, | 105 | ws_root: PathBuf, |
103 | pool: &ThreadPool, | 106 | pool: &ThreadPool, |
104 | msg_sender: &Sender<RawMessage>, | 107 | msg_sender: &Sender<RawMessage>, |
@@ -210,6 +213,7 @@ fn main_loop_inner( | |||
210 | update_file_notifications_on_threadpool( | 213 | update_file_notifications_on_threadpool( |
211 | pool, | 214 | pool, |
212 | state.snapshot(), | 215 | state.snapshot(), |
216 | publish_decorations, | ||
213 | task_sender.clone(), | 217 | task_sender.clone(), |
214 | subs.subscriptions(), | 218 | subs.subscriptions(), |
215 | ) | 219 | ) |
@@ -259,6 +263,7 @@ fn on_request( | |||
259 | .on::<req::CodeActionRequest>(handlers::handle_code_action)? | 263 | .on::<req::CodeActionRequest>(handlers::handle_code_action)? |
260 | .on::<req::FoldingRangeRequest>(handlers::handle_folding_range)? | 264 | .on::<req::FoldingRangeRequest>(handlers::handle_folding_range)? |
261 | .on::<req::SignatureHelpRequest>(handlers::handle_signature_help)? | 265 | .on::<req::SignatureHelpRequest>(handlers::handle_signature_help)? |
266 | .on::<req::HoverRequest>(handlers::handle_hover)? | ||
262 | .on::<req::PrepareRenameRequest>(handlers::handle_prepare_rename)? | 267 | .on::<req::PrepareRenameRequest>(handlers::handle_prepare_rename)? |
263 | .on::<req::Rename>(handlers::handle_rename)? | 268 | .on::<req::Rename>(handlers::handle_rename)? |
264 | .on::<req::References>(handlers::handle_references)? | 269 | .on::<req::References>(handlers::handle_references)? |
@@ -415,6 +420,7 @@ impl<'a> PoolDispatcher<'a> { | |||
415 | fn update_file_notifications_on_threadpool( | 420 | fn update_file_notifications_on_threadpool( |
416 | pool: &ThreadPool, | 421 | pool: &ThreadPool, |
417 | world: ServerWorld, | 422 | world: ServerWorld, |
423 | publish_decorations: bool, | ||
418 | sender: Sender<Task>, | 424 | sender: Sender<Task>, |
419 | subscriptions: Vec<FileId>, | 425 | subscriptions: Vec<FileId>, |
420 | ) { | 426 | ) { |
@@ -431,15 +437,17 @@ fn update_file_notifications_on_threadpool( | |||
431 | sender.send(Task::Notify(not)); | 437 | sender.send(Task::Notify(not)); |
432 | } | 438 | } |
433 | } | 439 | } |
434 | match handlers::publish_decorations(&world, file_id) { | 440 | if publish_decorations { |
435 | Err(e) => { | 441 | match handlers::publish_decorations(&world, file_id) { |
436 | if !is_canceled(&e) { | 442 | Err(e) => { |
437 | error!("failed to compute decorations: {:?}", e); | 443 | if !is_canceled(&e) { |
444 | error!("failed to compute decorations: {:?}", e); | ||
445 | } | ||
446 | } | ||
447 | Ok(params) => { | ||
448 | let not = RawNotification::new::<req::PublishDecorations>(¶ms); | ||
449 | sender.send(Task::Notify(not)) | ||
438 | } | 450 | } |
439 | } | ||
440 | Ok(params) => { | ||
441 | let not = RawNotification::new::<req::PublishDecorations>(¶ms); | ||
442 | sender.send(Task::Notify(not)) | ||
443 | } | 451 | } |
444 | } | 452 | } |
445 | } | 453 | } |