diff options
-rw-r--r-- | crates/ra_analysis/src/imp.rs | 10 | ||||
-rw-r--r-- | crates/ra_analysis/src/lib.rs | 7 | ||||
-rw-r--r-- | crates/ra_editor/src/symbols.rs | 26 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/caps.rs | 2 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 29 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/mod.rs | 1 |
6 files changed, 71 insertions, 4 deletions
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 819827b95..166f1484f 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs | |||
@@ -364,6 +364,16 @@ impl AnalysisImpl { | |||
364 | ret | 364 | ret |
365 | } | 365 | } |
366 | 366 | ||
367 | pub fn doc_comment_for( | ||
368 | &self, | ||
369 | file_id: FileId, | ||
370 | symbol: FileSymbol, | ||
371 | ) -> Cancelable<Option<String>> { | ||
372 | let file = self.db.file_syntax(file_id); | ||
373 | |||
374 | Ok(symbol.docs(&file)) | ||
375 | } | ||
376 | |||
367 | pub fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> { | 377 | pub fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> { |
368 | let module_tree = self.module_tree(file_id)?; | 378 | let module_tree = self.module_tree(file_id)?; |
369 | let syntax = self.db.file_syntax(file_id); | 379 | let syntax = self.db.file_syntax(file_id); |
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 0ea9ebee7..db4e1ba86 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs | |||
@@ -258,6 +258,13 @@ impl Analysis { | |||
258 | pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> { | 258 | pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> { |
259 | Ok(self.imp.find_all_refs(position)) | 259 | Ok(self.imp.find_all_refs(position)) |
260 | } | 260 | } |
261 | pub fn doc_comment_for( | ||
262 | &self, | ||
263 | file_id: FileId, | ||
264 | symbol: FileSymbol | ||
265 | ) -> Cancelable<Option<String>> { | ||
266 | self.imp.doc_comment_for(file_id, symbol) | ||
267 | } | ||
261 | pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<(FileId, FileSymbol)>> { | 268 | pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<(FileId, FileSymbol)>> { |
262 | self.imp.parent_module(position) | 269 | self.imp.parent_module(position) |
263 | } | 270 | } |
diff --git a/crates/ra_editor/src/symbols.rs b/crates/ra_editor/src/symbols.rs index 4e602d0e3..bf3ac6ff2 100644 --- a/crates/ra_editor/src/symbols.rs +++ b/crates/ra_editor/src/symbols.rs | |||
@@ -2,7 +2,7 @@ use crate::TextRange; | |||
2 | 2 | ||
3 | use ra_syntax::{ | 3 | use ra_syntax::{ |
4 | algo::visit::{visitor, Visitor}, | 4 | algo::visit::{visitor, Visitor}, |
5 | ast::{self, NameOwner}, | 5 | ast::{self, DocCommentsOwner, NameOwner}, |
6 | AstNode, File, SmolStr, SyntaxKind, SyntaxNodeRef, WalkEvent, | 6 | AstNode, File, SmolStr, SyntaxKind, SyntaxNodeRef, WalkEvent, |
7 | }; | 7 | }; |
8 | 8 | ||
@@ -22,6 +22,30 @@ pub struct FileSymbol { | |||
22 | pub kind: SyntaxKind, | 22 | pub kind: SyntaxKind, |
23 | } | 23 | } |
24 | 24 | ||
25 | impl FileSymbol { | ||
26 | pub fn docs(&self, file: &File) -> Option<String> { | ||
27 | file.syntax().descendants() | ||
28 | .filter(|node| node.kind() == self.kind && node.range() == self.node_range) | ||
29 | .filter_map(|node: SyntaxNodeRef| { | ||
30 | fn doc_comments<'a, N: DocCommentsOwner<'a>>(node: N) -> Option<String> { | ||
31 | let comments = node.doc_comment_text(); | ||
32 | if comments.is_empty() { None } else { Some(comments) } | ||
33 | } | ||
34 | |||
35 | visitor() | ||
36 | .visit(doc_comments::<ast::FnDef>) | ||
37 | .visit(doc_comments::<ast::StructDef>) | ||
38 | .visit(doc_comments::<ast::EnumDef>) | ||
39 | .visit(doc_comments::<ast::TraitDef>) | ||
40 | .visit(doc_comments::<ast::Module>) | ||
41 | .visit(doc_comments::<ast::TypeDef>) | ||
42 | .visit(doc_comments::<ast::ConstDef>) | ||
43 | .visit(doc_comments::<ast::StaticDef>) | ||
44 | .accept(node)? | ||
45 | }).nth(0) | ||
46 | } | ||
47 | } | ||
48 | |||
25 | pub fn file_symbols(file: &File) -> Vec<FileSymbol> { | 49 | pub fn file_symbols(file: &File) -> Vec<FileSymbol> { |
26 | file.syntax().descendants().filter_map(to_symbol).collect() | 50 | file.syntax().descendants().filter_map(to_symbol).collect() |
27 | } | 51 | } |
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/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 5314a333e..97ab53f91 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,31 @@ 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 name = symbol.name.to_string(); | ||
491 | let comment = world.analysis.doc_comment_for(file_id, symbol)?; | ||
492 | |||
493 | if comment.is_some() { | ||
494 | let contents = HoverContents::Scalar(MarkedString::String(comment.unwrap())); | ||
495 | |||
496 | return Ok(Some(Hover { | ||
497 | contents, | ||
498 | range: Some(range) | ||
499 | })) | ||
500 | } | ||
501 | } | ||
502 | |||
503 | Ok(None) | ||
504 | } | ||
505 | |||
481 | pub fn handle_prepare_rename( | 506 | pub fn handle_prepare_rename( |
482 | world: ServerWorld, | 507 | world: ServerWorld, |
483 | params: req::TextDocumentPositionParams, | 508 | 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..db878e0aa 100644 --- a/crates/ra_lsp_server/src/main_loop/mod.rs +++ b/crates/ra_lsp_server/src/main_loop/mod.rs | |||
@@ -259,6 +259,7 @@ fn on_request( | |||
259 | .on::<req::CodeActionRequest>(handlers::handle_code_action)? | 259 | .on::<req::CodeActionRequest>(handlers::handle_code_action)? |
260 | .on::<req::FoldingRangeRequest>(handlers::handle_folding_range)? | 260 | .on::<req::FoldingRangeRequest>(handlers::handle_folding_range)? |
261 | .on::<req::SignatureHelpRequest>(handlers::handle_signature_help)? | 261 | .on::<req::SignatureHelpRequest>(handlers::handle_signature_help)? |
262 | .on::<req::HoverRequest>(handlers::handle_hover)? | ||
262 | .on::<req::PrepareRenameRequest>(handlers::handle_prepare_rename)? | 263 | .on::<req::PrepareRenameRequest>(handlers::handle_prepare_rename)? |
263 | .on::<req::Rename>(handlers::handle_rename)? | 264 | .on::<req::Rename>(handlers::handle_rename)? |
264 | .on::<req::References>(handlers::handle_references)? | 265 | .on::<req::References>(handlers::handle_references)? |