aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_analysis/src/imp.rs10
-rw-r--r--crates/ra_analysis/src/lib.rs7
-rw-r--r--crates/ra_editor/src/symbols.rs26
-rw-r--r--crates/ra_lsp_server/src/caps.rs2
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs29
-rw-r--r--crates/ra_lsp_server/src/main_loop/mod.rs1
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
3use ra_syntax::{ 3use 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
25impl 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
25pub fn file_symbols(file: &File) -> Vec<FileSymbol> { 49pub 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;
4use languageserver_types::{ 4use 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};
11use ra_analysis::{FileId, FoldKind, Query, RunnableKind, FilePosition}; 11use ra_analysis::{FileId, FoldKind, Query, RunnableKind, FilePosition};
12use ra_syntax::text_utils::contains_offset_nonstrict; 12use ra_syntax::text_utils::contains_offset_nonstrict;
@@ -478,6 +478,31 @@ pub fn handle_signature_help(
478 } 478 }
479} 479}
480 480
481pub 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
481pub fn handle_prepare_rename( 506pub 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)?