Skip to content

Commit 90aea3b

Browse files
committed
Add target_dir path argument for external_docs and other methods
1 parent 4d1039a commit 90aea3b

File tree

3 files changed

+36
-19
lines changed

3 files changed

+36
-19
lines changed

crates/ide/src/doc_links.rs

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ mod tests;
55

66
mod intra_doc_links;
77

8+
use std::ffi::OsStr;
9+
810
use pulldown_cmark::{BrokenLink, CowStr, Event, InlineStr, LinkType, Options, Parser, Tag};
911
use pulldown_cmark_to_cmark::{cmark_resume_with_options, Options as CMarkOptions};
1012
use stdx::format_to;
@@ -127,7 +129,11 @@ pub(crate) fn remove_links(markdown: &str) -> String {
127129
//
128130
// | VS Code | **rust-analyzer: Open Docs**
129131
// |===
130-
pub(crate) fn external_docs(db: &RootDatabase, position: &FilePosition) -> DocumentationLinks {
132+
pub(crate) fn external_docs(
133+
db: &RootDatabase,
134+
position: &FilePosition,
135+
target_dir: Option<&OsStr>,
136+
) -> DocumentationLinks {
131137
let sema = &Semantics::new(db);
132138
let file = sema.parse(position.file_id).syntax().clone();
133139
let token = pick_best_token(file.token_at_offset(position.offset), |kind| match kind {
@@ -158,7 +164,7 @@ pub(crate) fn external_docs(db: &RootDatabase, position: &FilePosition) -> Docum
158164
}
159165
};
160166

161-
return get_doc_links(db, definition);
167+
return get_doc_links(db, definition, target_dir);
162168
}
163169

164170
/// Extracts all links from a given markdown text returning the definition text range, link-text
@@ -316,10 +322,14 @@ fn broken_link_clone_cb(link: BrokenLink<'_>) -> Option<(CowStr<'_>, CowStr<'_>)
316322
//
317323
// This should cease to be a problem if RFC2988 (Stable Rustdoc URLs) is implemented
318324
// https://github.com/rust-lang/rfcs/pull/2988
319-
fn get_doc_links(db: &RootDatabase, def: Definition) -> DocumentationLinks {
325+
fn get_doc_links(
326+
db: &RootDatabase,
327+
def: Definition,
328+
target_dir: Option<&OsStr>,
329+
) -> DocumentationLinks {
320330
let Some((target, file, frag)) = filename_and_frag_for_def(db, def) else { return Default::default(); };
321331

322-
let (mut web_url, mut local_url) = get_doc_base_urls(db, target);
332+
let (mut web_url, mut local_url) = get_doc_base_urls(db, target, target_dir);
323333

324334
if let Some(path) = mod_path_of_def(db, target) {
325335
web_url = join_url(web_url, &path);
@@ -355,7 +365,7 @@ fn rewrite_intra_doc_link(
355365
let (link, ns) = parse_intra_doc_link(target);
356366

357367
let resolved = resolve_doc_path_for_def(db, def, link, ns)?;
358-
let mut url = get_doc_base_urls(db, resolved).0?;
368+
let mut url = get_doc_base_urls(db, resolved, None).0?;
359369

360370
let (_, file, frag) = filename_and_frag_for_def(db, resolved)?;
361371
if let Some(path) = mod_path_of_def(db, resolved) {
@@ -374,7 +384,7 @@ fn rewrite_url_link(db: &RootDatabase, def: Definition, target: &str) -> Option<
374384
return None;
375385
}
376386

377-
let mut url = get_doc_base_urls(db, def).0?;
387+
let mut url = get_doc_base_urls(db, def, None).0?;
378388
let (def, file, frag) = filename_and_frag_for_def(db, def)?;
379389

380390
if let Some(path) = mod_path_of_def(db, def) {
@@ -450,23 +460,23 @@ fn map_links<'e>(
450460
/// https://doc.rust-lang.org/std/iter/trait.Iterator.html#tymethod.next
451461
/// ^^^^^^^^^^^^^^^^^^^^^^^^^^
452462
/// ```
453-
fn get_doc_base_urls(db: &RootDatabase, def: Definition) -> (Option<Url>, Option<Url>) {
454-
// TODO: get this is from `CargoWorkspace`
455-
// TODO: get `CargoWorkspace` from `db`
456-
let target_path = "file:///project/root/target";
457-
let target_path = Url::parse(target_path).ok();
458-
let local_doc_path = target_path.and_then(|url| url.join("doc").ok());
459-
debug_assert!(local_doc_path.is_some(), "failed to parse local doc path");
460-
463+
fn get_doc_base_urls(
464+
db: &RootDatabase,
465+
def: Definition,
466+
target_dir: Option<&OsStr>,
467+
) -> (Option<Url>, Option<Url>) {
468+
let local_doc_path = target_dir
469+
.and_then(|it| Url::from_directory_path(it).ok())
470+
.and_then(|it| it.join("doc").ok());
461471
// special case base url of `BuiltinType` to core
462472
// https://github.com/rust-lang/rust-analyzer/issues/12250
463473
if let Definition::BuiltinType(..) = def {
464474
let weblink = Url::parse("https://doc.rust-lang.org/nightly/core/").ok();
465475
return (weblink, local_doc_path);
466476
};
467477

468-
let Some(krate) = def.krate(db) else { return Default::default() };
469-
let Some(display_name) = krate.display_name(db) else { return Default::default() };
478+
let Some(krate) = def.krate(db) else { return (None, local_doc_path) };
479+
let Some(display_name) = krate.display_name(db) else { return (None, local_doc_path) };
470480
let crate_data = &db.crate_graph()[krate.into()];
471481
let channel = crate_data.channel.map_or("nightly", ReleaseChannel::as_str);
472482
let (web_base, local_base) = match &crate_data.origin {

crates/ide/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ mod view_mir;
5959
mod view_item_tree;
6060
mod shuffle_crate_graph;
6161

62-
use std::sync::Arc;
62+
use std::{ffi::OsStr, sync::Arc};
6363

6464
use cfg::CfgOptions;
6565
use ide_db::{
@@ -460,8 +460,9 @@ impl Analysis {
460460
pub fn external_docs(
461461
&self,
462462
position: FilePosition,
463+
target_dir: Option<&OsStr>,
463464
) -> Cancellable<doc_links::DocumentationLinks> {
464-
self.with_db(|db| doc_links::external_docs(db, &position))
465+
self.with_db(|db| doc_links::external_docs(db, &position, target_dir))
465466
}
466467

467468
/// Computes parameter information at the given position.

crates/rust-analyzer/src/handlers.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1564,7 +1564,13 @@ pub(crate) fn handle_open_docs(
15641564
let _p = profile::span("handle_open_docs");
15651565
let position = from_proto::file_position(&snap, params)?;
15661566

1567-
let Ok(remote_urls) = snap.analysis.external_docs(position) else { return Ok((None, None)); };
1567+
let cargo = match snap.workspaces.get(0) {
1568+
Some(ProjectWorkspace::Cargo { cargo, .. }) => Some(cargo),
1569+
_ => None,
1570+
};
1571+
let target_dir =
1572+
cargo.and_then(|cargo| Some(cargo.target_directory())).and_then(|p| Some(p.as_os_str()));
1573+
let Ok(remote_urls) = snap.analysis.external_docs(position, target_dir) else { return Ok((None, None)); };
15681574

15691575
let web_url = remote_urls.web_url.and_then(|it| Url::parse(&it).ok());
15701576
let local_url = remote_urls.local_url.and_then(|it| Url::parse(&it).ok());

0 commit comments

Comments
 (0)