Skip to content

Hover: Show documentation #196

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions crates/ra_analysis/src/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,16 @@ impl AnalysisImpl {
ret
}

pub fn doc_comment_for(
&self,
file_id: FileId,
symbol: FileSymbol,
) -> Cancelable<Option<String>> {
let file = self.db.file_syntax(file_id);

Ok(symbol.docs(&file))
}

pub fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> {
let module_tree = self.module_tree(file_id)?;
let syntax = self.db.file_syntax(file_id);
Expand Down
7 changes: 7 additions & 0 deletions crates/ra_analysis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,13 @@ impl Analysis {
pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> {
Ok(self.imp.find_all_refs(position))
}
pub fn doc_comment_for(
&self,
file_id: FileId,
symbol: FileSymbol,
) -> Cancelable<Option<String>> {
self.imp.doc_comment_for(file_id, symbol)
}
pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<(FileId, FileSymbol)>> {
self.imp.parent_module(position)
}
Expand Down
32 changes: 31 additions & 1 deletion crates/ra_editor/src/symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::TextRange;

use ra_syntax::{
algo::visit::{visitor, Visitor},
ast::{self, NameOwner},
ast::{self, DocCommentsOwner, NameOwner},
AstNode, File, SmolStr, SyntaxKind, SyntaxNodeRef, WalkEvent,
};

Expand All @@ -22,6 +22,36 @@ pub struct FileSymbol {
pub kind: SyntaxKind,
}

impl FileSymbol {
pub fn docs(&self, file: &File) -> Option<String> {
file.syntax()
.descendants()
.filter(|node| node.kind() == self.kind && node.range() == self.node_range)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels like we probably should move FileSymbols to ra_analysis, and use SyntaxPtr

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like a good idea. I can tackle that in a separate PR.

.filter_map(|node: SyntaxNodeRef| {
fn doc_comments<'a, N: DocCommentsOwner<'a>>(node: N) -> Option<String> {
let comments = node.doc_comment_text();
if comments.is_empty() {
None
} else {
Some(comments)
}
}

visitor()
.visit(doc_comments::<ast::FnDef>)
.visit(doc_comments::<ast::StructDef>)
.visit(doc_comments::<ast::EnumDef>)
.visit(doc_comments::<ast::TraitDef>)
.visit(doc_comments::<ast::Module>)
.visit(doc_comments::<ast::TypeDef>)
.visit(doc_comments::<ast::ConstDef>)
.visit(doc_comments::<ast::StaticDef>)
.accept(node)?
})
.nth(0)
}
}

pub fn file_symbols(file: &File) -> Vec<FileSymbol> {
file.syntax().descendants().filter_map(to_symbol).collect()
}
Expand Down
2 changes: 1 addition & 1 deletion crates/ra_lsp_server/src/caps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub fn server_capabilities() -> ServerCapabilities {
save: None,
},
)),
hover_provider: None,
hover_provider: Some(true),
completion_provider: Some(CompletionOptions {
resolve_provider: None,
trigger_characters: None,
Expand Down
28 changes: 26 additions & 2 deletions crates/ra_lsp_server/src/main_loop/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use gen_lsp_server::ErrorCode;
use languageserver_types::{
CodeActionResponse, Command, CompletionItem, CompletionItemKind, Diagnostic,
DiagnosticSeverity, DocumentSymbol, Documentation, FoldingRange, FoldingRangeKind,
FoldingRangeParams, InsertTextFormat, Location, MarkupContent, MarkupKind, Position,
FoldingRangeParams, InsertTextFormat, Location, MarkupContent, MarkupKind, MarkedString, Position,
PrepareRenameResponse, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit,
WorkspaceEdit, ParameterInformation, SignatureInformation,
WorkspaceEdit, ParameterInformation, SignatureInformation, Hover, HoverContents,
};
use ra_analysis::{FileId, FoldKind, Query, RunnableKind, FilePosition};
use ra_syntax::text_utils::contains_offset_nonstrict;
Expand Down Expand Up @@ -478,6 +478,30 @@ pub fn handle_signature_help(
}
}

pub fn handle_hover(
world: ServerWorld,
params: req::TextDocumentPositionParams,
) -> Result<Option<Hover>> {
let position = params.try_conv_with(&world)?;
let line_index = world.analysis().file_line_index(position.file_id);

for (file_id, symbol) in world.analysis().approximately_resolve_symbol(position)? {
let range = symbol.node_range.conv_with(&line_index);
let comment = world.analysis.doc_comment_for(file_id, symbol)?;

if comment.is_some() {
let contents = HoverContents::Scalar(MarkedString::String(comment.unwrap()));

return Ok(Some(Hover {
contents,
range: Some(range),
}));
}
}

Ok(None)
}

pub fn handle_prepare_rename(
world: ServerWorld,
params: req::TextDocumentPositionParams,
Expand Down
1 change: 1 addition & 0 deletions crates/ra_lsp_server/src/main_loop/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ fn on_request(
.on::<req::CodeActionRequest>(handlers::handle_code_action)?
.on::<req::FoldingRangeRequest>(handlers::handle_folding_range)?
.on::<req::SignatureHelpRequest>(handlers::handle_signature_help)?
.on::<req::HoverRequest>(handlers::handle_hover)?
.on::<req::PrepareRenameRequest>(handlers::handle_prepare_rename)?
.on::<req::Rename>(handlers::handle_rename)?
.on::<req::References>(handlers::handle_references)?
Expand Down
7 changes: 7 additions & 0 deletions crates/ra_syntax/src/ast/generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,7 @@ impl<R: TreeRoot<RaTypes>> ConstDefNode<R> {
impl<'a> ast::NameOwner<'a> for ConstDef<'a> {}
impl<'a> ast::TypeParamsOwner<'a> for ConstDef<'a> {}
impl<'a> ast::AttrsOwner<'a> for ConstDef<'a> {}
impl<'a> ast::DocCommentsOwner<'a> for ConstDef<'a> {}
impl<'a> ConstDef<'a> {}

// ContinueExpr
Expand Down Expand Up @@ -722,6 +723,7 @@ impl<R: TreeRoot<RaTypes>> EnumDefNode<R> {
impl<'a> ast::NameOwner<'a> for EnumDef<'a> {}
impl<'a> ast::TypeParamsOwner<'a> for EnumDef<'a> {}
impl<'a> ast::AttrsOwner<'a> for EnumDef<'a> {}
impl<'a> ast::DocCommentsOwner<'a> for EnumDef<'a> {}
impl<'a> EnumDef<'a> {}

// Expr
Expand Down Expand Up @@ -1886,6 +1888,7 @@ impl<R: TreeRoot<RaTypes>> ModuleNode<R> {

impl<'a> ast::NameOwner<'a> for Module<'a> {}
impl<'a> ast::AttrsOwner<'a> for Module<'a> {}
impl<'a> ast::DocCommentsOwner<'a> for Module<'a> {}
impl<'a> Module<'a> {
pub fn item_list(self) -> Option<ItemList<'a>> {
super::child_opt(self)
Expand Down Expand Up @@ -3205,6 +3208,7 @@ impl<R: TreeRoot<RaTypes>> StaticDefNode<R> {
impl<'a> ast::NameOwner<'a> for StaticDef<'a> {}
impl<'a> ast::TypeParamsOwner<'a> for StaticDef<'a> {}
impl<'a> ast::AttrsOwner<'a> for StaticDef<'a> {}
impl<'a> ast::DocCommentsOwner<'a> for StaticDef<'a> {}
impl<'a> StaticDef<'a> {}

// Stmt
Expand Down Expand Up @@ -3270,6 +3274,7 @@ impl<R: TreeRoot<RaTypes>> StructDefNode<R> {
impl<'a> ast::NameOwner<'a> for StructDef<'a> {}
impl<'a> ast::TypeParamsOwner<'a> for StructDef<'a> {}
impl<'a> ast::AttrsOwner<'a> for StructDef<'a> {}
impl<'a> ast::DocCommentsOwner<'a> for StructDef<'a> {}
impl<'a> StructDef<'a> {
pub fn fields(self) -> impl Iterator<Item = NamedFieldDef<'a>> + 'a {
super::children(self)
Expand Down Expand Up @@ -3424,6 +3429,7 @@ impl<R: TreeRoot<RaTypes>> TraitDefNode<R> {

impl<'a> ast::NameOwner<'a> for TraitDef<'a> {}
impl<'a> ast::AttrsOwner<'a> for TraitDef<'a> {}
impl<'a> ast::DocCommentsOwner<'a> for TraitDef<'a> {}
impl<'a> TraitDef<'a> {}

// TryExpr
Expand Down Expand Up @@ -3649,6 +3655,7 @@ impl<R: TreeRoot<RaTypes>> TypeDefNode<R> {
impl<'a> ast::NameOwner<'a> for TypeDef<'a> {}
impl<'a> ast::TypeParamsOwner<'a> for TypeDef<'a> {}
impl<'a> ast::AttrsOwner<'a> for TypeDef<'a> {}
impl<'a> ast::DocCommentsOwner<'a> for TypeDef<'a> {}
impl<'a> TypeDef<'a> {}

// TypeParam
Expand Down
9 changes: 7 additions & 2 deletions crates/ra_syntax/src/grammar.ron
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ Grammar(
"NameOwner",
"TypeParamsOwner",
"AttrsOwner",
"DocCommentsOwner"
],
collections: [
["fields", "NamedFieldDef"]
Expand All @@ -270,10 +271,11 @@ Grammar(
"NameOwner",
"TypeParamsOwner",
"AttrsOwner",
"DocCommentsOwner"
] ),
"TraitDef": ( traits: ["NameOwner", "AttrsOwner"] ),
"TraitDef": ( traits: ["NameOwner", "AttrsOwner", "DocCommentsOwner"] ),
"Module": (
traits: ["NameOwner", "AttrsOwner" ],
traits: ["NameOwner", "AttrsOwner", "DocCommentsOwner" ],
options: [ "ItemList" ]
),
"ItemList": (
Expand All @@ -283,16 +285,19 @@ Grammar(
"NameOwner",
"TypeParamsOwner",
"AttrsOwner",
"DocCommentsOwner"
] ),
"StaticDef": ( traits: [
"NameOwner",
"TypeParamsOwner",
"AttrsOwner",
"DocCommentsOwner"
] ),
"TypeDef": ( traits: [
"NameOwner",
"TypeParamsOwner",
"AttrsOwner",
"DocCommentsOwner"
] ),
"ImplItem": (),

Expand Down