diff options
-rw-r--r-- | crates/ra_ide/src/hover.rs | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index 185139250..8c972bb41 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs | |||
@@ -19,7 +19,7 @@ use ra_ide_db::{ | |||
19 | use ra_syntax::{ | 19 | use ra_syntax::{ |
20 | ast, ast::Path, match_ast, AstNode, SyntaxKind::*, SyntaxNode, SyntaxToken, TokenAtOffset, | 20 | ast, ast::Path, match_ast, AstNode, SyntaxKind::*, SyntaxNode, SyntaxToken, TokenAtOffset, |
21 | }; | 21 | }; |
22 | use ra_tt::{Ident, Leaf, Literal, Punct, TokenTree}; | 22 | use ra_tt::{Ident, Leaf, Literal, TokenTree}; |
23 | use url::Url; | 23 | use url::Url; |
24 | 24 | ||
25 | use crate::{ | 25 | use crate::{ |
@@ -410,6 +410,8 @@ fn map_links<'e>( | |||
410 | } | 410 | } |
411 | Event::Text(s) if in_link => { | 411 | Event::Text(s) if in_link => { |
412 | link_text = s.clone(); | 412 | link_text = s.clone(); |
413 | // TODO: This can unintentionally strip words from path-based links. | ||
414 | // See std::box::Box -> std::box link as an example. | ||
413 | Event::Text(CowStr::Boxed(strip_prefixes_suffixes(&s).into())) | 415 | Event::Text(CowStr::Boxed(strip_prefixes_suffixes(&s).into())) |
414 | } | 416 | } |
415 | Event::Code(s) if in_link => { | 417 | Event::Code(s) if in_link => { |
@@ -603,29 +605,33 @@ fn try_resolve_path(db: &RootDatabase, definition: &Definition, link: &str) -> O | |||
603 | } | 605 | } |
604 | 606 | ||
605 | /// Try to get the root URL of the documentation of a crate. | 607 | /// Try to get the root URL of the documentation of a crate. |
606 | // FIXME: Special case standard, core, alloc libraries | ||
607 | fn get_doc_url(db: &RootDatabase, krate: &Crate) -> Option<Url> { | 608 | fn get_doc_url(db: &RootDatabase, krate: &Crate) -> Option<Url> { |
608 | // Look for #![doc(html_root_url = "...")] | 609 | // Look for #![doc(html_root_url = "...")] |
609 | let attrs = db.attrs(AttrDef::from(krate.root_module(db)?).into()); | 610 | let attrs = db.attrs(AttrDef::from(krate.root_module(db)?).into()); |
610 | let doc_attr_q = attrs.by_key("doc"); | 611 | let doc_attr_q = attrs.by_key("doc"); |
612 | |||
613 | // TODO: Tests for this parsing | ||
611 | let doc_url = if doc_attr_q.exists() { | 614 | let doc_url = if doc_attr_q.exists() { |
612 | doc_attr_q.tt_values().filter_map(|tt| match tt.token_trees.as_slice() { | 615 | doc_attr_q.tt_values().map(|tt| { |
613 | &[ | 616 | let name = tt.token_trees.iter() |
614 | TokenTree::Leaf(Leaf::Ident(Ident{text: ref ident_text, ..})), | 617 | .skip_while(|tt| !matches!(tt, TokenTree::Leaf(Leaf::Ident(Ident{text: ref ident, ..})) if ident == "html_root_url")) |
615 | TokenTree::Leaf(Leaf::Punct(Punct{r#char: '=', ..})), | 618 | .skip(2) |
616 | TokenTree::Leaf(Leaf::Literal(Literal{ref text, ..})) | 619 | .next(); |
617 | ] if ident_text == "html_root_url" => Some(text.to_string()), | 620 | |
618 | _ => { | 621 | match name { |
619 | None | 622 | Some(TokenTree::Leaf(Leaf::Literal(Literal{ref text, ..}))) => Some(text), |
620 | } | 623 | _ => None |
621 | }).next() | 624 | } |
625 | }).flat_map(|t| t).next().map(|s| s.to_string()) | ||
622 | } else { | 626 | } else { |
623 | // Fallback to docs.rs | 627 | // Fallback to docs.rs |
624 | // FIXME: Specify an exact version here (from Cargo.lock) | 628 | // FIXME: Specify an exact version here (from Cargo.lock) |
625 | Some(format!("https://docs.rs/{}/*", krate.display_name(db)?)) | 629 | Some(format!("https://docs.rs/{}/*", krate.display_name(db)?)) |
626 | }; | 630 | }; |
627 | 631 | ||
628 | doc_url.map(|s| s.trim_matches('"').to_owned() + "/").and_then(|s| Url::parse(&s).ok()) | 632 | doc_url |
633 | .map(|s| s.trim_matches('"').trim_end_matches("/").to_owned() + "/") | ||
634 | .and_then(|s| Url::parse(&s).ok()) | ||
629 | } | 635 | } |
630 | 636 | ||
631 | /// Get the filename and extension generated for a symbol by rustdoc. | 637 | /// Get the filename and extension generated for a symbol by rustdoc. |