mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 21:05:02 +00:00
Add target_dir
path argument for external_docs
and other methods
This commit is contained in:
parent
f2d933ecaf
commit
c47a34fddc
3 changed files with 36 additions and 19 deletions
|
@ -5,6 +5,8 @@ mod tests;
|
||||||
|
|
||||||
mod intra_doc_links;
|
mod intra_doc_links;
|
||||||
|
|
||||||
|
use std::ffi::OsStr;
|
||||||
|
|
||||||
use pulldown_cmark::{BrokenLink, CowStr, Event, InlineStr, LinkType, Options, Parser, Tag};
|
use pulldown_cmark::{BrokenLink, CowStr, Event, InlineStr, LinkType, Options, Parser, Tag};
|
||||||
use pulldown_cmark_to_cmark::{cmark_resume_with_options, Options as CMarkOptions};
|
use pulldown_cmark_to_cmark::{cmark_resume_with_options, Options as CMarkOptions};
|
||||||
use stdx::format_to;
|
use stdx::format_to;
|
||||||
|
@ -127,7 +129,11 @@ pub(crate) fn remove_links(markdown: &str) -> String {
|
||||||
//
|
//
|
||||||
// | VS Code | **rust-analyzer: Open Docs**
|
// | VS Code | **rust-analyzer: Open Docs**
|
||||||
// |===
|
// |===
|
||||||
pub(crate) fn external_docs(db: &RootDatabase, position: &FilePosition) -> DocumentationLinks {
|
pub(crate) fn external_docs(
|
||||||
|
db: &RootDatabase,
|
||||||
|
position: &FilePosition,
|
||||||
|
target_dir: Option<&OsStr>,
|
||||||
|
) -> DocumentationLinks {
|
||||||
let sema = &Semantics::new(db);
|
let sema = &Semantics::new(db);
|
||||||
let file = sema.parse(position.file_id).syntax().clone();
|
let file = sema.parse(position.file_id).syntax().clone();
|
||||||
let token = pick_best_token(file.token_at_offset(position.offset), |kind| match kind {
|
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
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return get_doc_links(db, definition);
|
return get_doc_links(db, definition, target_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extracts all links from a given markdown text returning the definition text range, link-text
|
/// 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<'_>)
|
||||||
//
|
//
|
||||||
// This should cease to be a problem if RFC2988 (Stable Rustdoc URLs) is implemented
|
// This should cease to be a problem if RFC2988 (Stable Rustdoc URLs) is implemented
|
||||||
// https://github.com/rust-lang/rfcs/pull/2988
|
// https://github.com/rust-lang/rfcs/pull/2988
|
||||||
fn get_doc_links(db: &RootDatabase, def: Definition) -> DocumentationLinks {
|
fn get_doc_links(
|
||||||
|
db: &RootDatabase,
|
||||||
|
def: Definition,
|
||||||
|
target_dir: Option<&OsStr>,
|
||||||
|
) -> DocumentationLinks {
|
||||||
let Some((target, file, frag)) = filename_and_frag_for_def(db, def) else { return Default::default(); };
|
let Some((target, file, frag)) = filename_and_frag_for_def(db, def) else { return Default::default(); };
|
||||||
|
|
||||||
let (mut web_url, mut local_url) = get_doc_base_urls(db, target);
|
let (mut web_url, mut local_url) = get_doc_base_urls(db, target, target_dir);
|
||||||
|
|
||||||
if let Some(path) = mod_path_of_def(db, target) {
|
if let Some(path) = mod_path_of_def(db, target) {
|
||||||
web_url = join_url(web_url, &path);
|
web_url = join_url(web_url, &path);
|
||||||
|
@ -355,7 +365,7 @@ fn rewrite_intra_doc_link(
|
||||||
let (link, ns) = parse_intra_doc_link(target);
|
let (link, ns) = parse_intra_doc_link(target);
|
||||||
|
|
||||||
let resolved = resolve_doc_path_for_def(db, def, link, ns)?;
|
let resolved = resolve_doc_path_for_def(db, def, link, ns)?;
|
||||||
let mut url = get_doc_base_urls(db, resolved).0?;
|
let mut url = get_doc_base_urls(db, resolved, None).0?;
|
||||||
|
|
||||||
let (_, file, frag) = filename_and_frag_for_def(db, resolved)?;
|
let (_, file, frag) = filename_and_frag_for_def(db, resolved)?;
|
||||||
if let Some(path) = mod_path_of_def(db, resolved) {
|
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<
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut url = get_doc_base_urls(db, def).0?;
|
let mut url = get_doc_base_urls(db, def, None).0?;
|
||||||
let (def, file, frag) = filename_and_frag_for_def(db, def)?;
|
let (def, file, frag) = filename_and_frag_for_def(db, def)?;
|
||||||
|
|
||||||
if let Some(path) = mod_path_of_def(db, def) {
|
if let Some(path) = mod_path_of_def(db, def) {
|
||||||
|
@ -450,14 +460,14 @@ fn map_links<'e>(
|
||||||
/// https://doc.rust-lang.org/std/iter/trait.Iterator.html#tymethod.next
|
/// https://doc.rust-lang.org/std/iter/trait.Iterator.html#tymethod.next
|
||||||
/// ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
/// ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
/// ```
|
/// ```
|
||||||
fn get_doc_base_urls(db: &RootDatabase, def: Definition) -> (Option<Url>, Option<Url>) {
|
fn get_doc_base_urls(
|
||||||
// TODO: get this is from `CargoWorkspace`
|
db: &RootDatabase,
|
||||||
// TODO: get `CargoWorkspace` from `db`
|
def: Definition,
|
||||||
let target_path = "file:///project/root/target";
|
target_dir: Option<&OsStr>,
|
||||||
let target_path = Url::parse(target_path).ok();
|
) -> (Option<Url>, Option<Url>) {
|
||||||
let local_doc_path = target_path.and_then(|url| url.join("doc").ok());
|
let local_doc_path = target_dir
|
||||||
debug_assert!(local_doc_path.is_some(), "failed to parse local doc path");
|
.and_then(|it| Url::from_directory_path(it).ok())
|
||||||
|
.and_then(|it| it.join("doc").ok());
|
||||||
// special case base url of `BuiltinType` to core
|
// special case base url of `BuiltinType` to core
|
||||||
// https://github.com/rust-lang/rust-analyzer/issues/12250
|
// https://github.com/rust-lang/rust-analyzer/issues/12250
|
||||||
if let Definition::BuiltinType(..) = def {
|
if let Definition::BuiltinType(..) = def {
|
||||||
|
@ -465,8 +475,8 @@ fn get_doc_base_urls(db: &RootDatabase, def: Definition) -> (Option<Url>, Option
|
||||||
return (weblink, local_doc_path);
|
return (weblink, local_doc_path);
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(krate) = def.krate(db) else { return Default::default() };
|
let Some(krate) = def.krate(db) else { return (None, local_doc_path) };
|
||||||
let Some(display_name) = krate.display_name(db) else { return Default::default() };
|
let Some(display_name) = krate.display_name(db) else { return (None, local_doc_path) };
|
||||||
let crate_data = &db.crate_graph()[krate.into()];
|
let crate_data = &db.crate_graph()[krate.into()];
|
||||||
let channel = crate_data.channel.map_or("nightly", ReleaseChannel::as_str);
|
let channel = crate_data.channel.map_or("nightly", ReleaseChannel::as_str);
|
||||||
let (web_base, local_base) = match &crate_data.origin {
|
let (web_base, local_base) = match &crate_data.origin {
|
||||||
|
|
|
@ -61,7 +61,7 @@ mod view_item_tree;
|
||||||
mod shuffle_crate_graph;
|
mod shuffle_crate_graph;
|
||||||
mod fetch_crates;
|
mod fetch_crates;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::{ffi::OsStr, sync::Arc};
|
||||||
|
|
||||||
use cfg::CfgOptions;
|
use cfg::CfgOptions;
|
||||||
use fetch_crates::CrateInfo;
|
use fetch_crates::CrateInfo;
|
||||||
|
@ -471,8 +471,9 @@ impl Analysis {
|
||||||
pub fn external_docs(
|
pub fn external_docs(
|
||||||
&self,
|
&self,
|
||||||
position: FilePosition,
|
position: FilePosition,
|
||||||
|
target_dir: Option<&OsStr>,
|
||||||
) -> Cancellable<doc_links::DocumentationLinks> {
|
) -> Cancellable<doc_links::DocumentationLinks> {
|
||||||
self.with_db(|db| doc_links::external_docs(db, &position))
|
self.with_db(|db| doc_links::external_docs(db, &position, target_dir))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes parameter information at the given position.
|
/// Computes parameter information at the given position.
|
||||||
|
|
|
@ -1539,7 +1539,13 @@ pub(crate) fn handle_open_docs(
|
||||||
let _p = profile::span("handle_open_docs");
|
let _p = profile::span("handle_open_docs");
|
||||||
let position = from_proto::file_position(&snap, params)?;
|
let position = from_proto::file_position(&snap, params)?;
|
||||||
|
|
||||||
let Ok(remote_urls) = snap.analysis.external_docs(position) else { return Ok((None, None)); };
|
let cargo = match snap.workspaces.get(0) {
|
||||||
|
Some(ProjectWorkspace::Cargo { cargo, .. }) => Some(cargo),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
let target_dir =
|
||||||
|
cargo.and_then(|cargo| Some(cargo.target_directory())).and_then(|p| Some(p.as_os_str()));
|
||||||
|
let Ok(remote_urls) = snap.analysis.external_docs(position, target_dir) else { return Ok((None, None)); };
|
||||||
|
|
||||||
let web_url = remote_urls.web_url.and_then(|it| Url::parse(&it).ok());
|
let web_url = remote_urls.web_url.and_then(|it| Url::parse(&it).ok());
|
||||||
let local_url = remote_urls.local_url.and_then(|it| Url::parse(&it).ok());
|
let local_url = remote_urls.local_url.and_then(|it| Url::parse(&it).ok());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue