diff options
Diffstat (limited to 'crates/ra_ide/src')
-rw-r--r-- | crates/ra_ide/src/hover.rs | 102 |
1 files changed, 48 insertions, 54 deletions
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index 1531aca2e..f6854a18d 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs | |||
@@ -1,8 +1,4 @@ | |||
1 | use std::collections::{HashMap, HashSet}; | 1 | use std::iter::once; |
2 | use std::{ | ||
3 | iter::{once, FromIterator}, | ||
4 | sync::Mutex, | ||
5 | }; | ||
6 | 2 | ||
7 | use hir::{ | 3 | use hir::{ |
8 | db::DefDatabase, Adt, AsAssocItem, AsName, AssocItemContainer, AttrDef, Crate, Documentation, | 4 | db::DefDatabase, Adt, AsAssocItem, AsName, AssocItemContainer, AttrDef, Crate, Documentation, |
@@ -10,7 +6,6 @@ use hir::{ | |||
10 | ModuleSource, Semantics, | 6 | ModuleSource, Semantics, |
11 | }; | 7 | }; |
12 | use itertools::Itertools; | 8 | use itertools::Itertools; |
13 | use once_cell::sync::Lazy; | ||
14 | use pulldown_cmark::{CowStr, Event, Options, Parser, Tag}; | 9 | use pulldown_cmark::{CowStr, Event, Options, Parser, Tag}; |
15 | use pulldown_cmark_to_cmark::cmark; | 10 | use pulldown_cmark_to_cmark::cmark; |
16 | use ra_db::SourceDatabase; | 11 | use ra_db::SourceDatabase; |
@@ -402,10 +397,9 @@ fn rewrite_links(db: &RootDatabase, markdown: &str, definition: &Definition) -> | |||
402 | try_resolve_path(db, definition, &target).map(|target| (target, title.to_string())) | 397 | try_resolve_path(db, definition, &target).map(|target| (target, title.to_string())) |
403 | }); | 398 | }); |
404 | 399 | ||
405 | if let Some((target, title)) = resolved { | 400 | match resolved { |
406 | (target, title) | 401 | Some((target, title)) => (target, title), |
407 | } else { | 402 | None => (target.to_string(), title.to_string()), |
408 | (target.to_string(), title.to_string()) | ||
409 | } | 403 | } |
410 | } | 404 | } |
411 | }); | 405 | }); |
@@ -421,65 +415,61 @@ enum Namespace { | |||
421 | Macros, | 415 | Macros, |
422 | } | 416 | } |
423 | 417 | ||
424 | static NS_MAP: Lazy< | 418 | static TYPES: ([&str; 7], [&str; 0]) = |
425 | HashMap<Namespace, (HashSet<&'static &'static str>, HashSet<&'static &'static str>)>, | 419 | (["type", "struct", "enum", "mod", "trait", "union", "module"], []); |
426 | > = Lazy::new(|| { | 420 | static VALUES: ([&str; 8], [&str; 1]) = |
427 | let mut map = HashMap::new(); | 421 | (["value", "function", "fn", "method", "const", "static", "mod", "module"], ["()"]); |
428 | map.insert(Namespace::Types, (HashSet::new(), HashSet::new())); | 422 | static MACROS: ([&str; 1], [&str; 1]) = (["macro"], ["!"]); |
429 | map.insert( | ||
430 | Namespace::Values, | ||
431 | ( | ||
432 | HashSet::from_iter( | ||
433 | ["value", "function", "fn", "method", "const", "static", "mod", "module"].iter(), | ||
434 | ), | ||
435 | HashSet::from_iter(["()"].iter()), | ||
436 | ), | ||
437 | ); | ||
438 | map.insert( | ||
439 | Namespace::Macros, | ||
440 | (HashSet::from_iter(["macro"].iter()), HashSet::from_iter(["!"].iter())), | ||
441 | ); | ||
442 | map | ||
443 | }); | ||
444 | 423 | ||
445 | impl Namespace { | 424 | impl Namespace { |
446 | /// Extract the specified namespace from an intra-doc-link if one exists. | 425 | /// Extract the specified namespace from an intra-doc-link if one exists. |
447 | fn from_intra_spec(s: &str) -> Option<Self> { | 426 | fn from_intra_spec(s: &str) -> Option<Self> { |
448 | NS_MAP | 427 | [ |
449 | .iter() | 428 | (Namespace::Types, (TYPES.0.iter(), TYPES.1.iter())), |
450 | .filter(|(_ns, (prefixes, suffixes))| { | 429 | (Namespace::Values, (VALUES.0.iter(), VALUES.1.iter())), |
451 | prefixes | 430 | (Namespace::Macros, (MACROS.0.iter(), MACROS.1.iter())), |
452 | .iter() | 431 | ] |
453 | .map(|prefix| { | 432 | .iter() |
454 | s.starts_with(*prefix) | 433 | .filter(|(_ns, (prefixes, suffixes))| { |
434 | prefixes | ||
435 | .clone() | ||
436 | .map(|prefix| { | ||
437 | s.starts_with(*prefix) | ||
438 | && s.chars() | ||
439 | .nth(prefix.len() + 1) | ||
440 | .map(|c| c == '@' || c == ' ') | ||
441 | .unwrap_or(false) | ||
442 | }) | ||
443 | .any(|cond| cond) | ||
444 | || suffixes | ||
445 | .clone() | ||
446 | .map(|suffix| { | ||
447 | s.starts_with(*suffix) | ||
455 | && s.chars() | 448 | && s.chars() |
456 | .nth(prefix.len() + 1) | 449 | .nth(suffix.len() + 1) |
457 | .map(|c| c == '@' || c == ' ') | 450 | .map(|c| c == '@' || c == ' ') |
458 | .unwrap_or(false) | 451 | .unwrap_or(false) |
459 | }) | 452 | }) |
460 | .any(|cond| cond) | 453 | .any(|cond| cond) |
461 | || suffixes | 454 | }) |
462 | .iter() | 455 | .map(|(ns, (_, _))| *ns) |
463 | .map(|suffix| { | 456 | .next() |
464 | s.starts_with(*suffix) | ||
465 | && s.chars() | ||
466 | .nth(suffix.len() + 1) | ||
467 | .map(|c| c == '@' || c == ' ') | ||
468 | .unwrap_or(false) | ||
469 | }) | ||
470 | .any(|cond| cond) | ||
471 | }) | ||
472 | .map(|(ns, (_, _))| *ns) | ||
473 | .next() | ||
474 | } | 457 | } |
475 | } | 458 | } |
476 | 459 | ||
477 | // Strip prefixes, suffixes, and inline code marks from the given string. | 460 | // Strip prefixes, suffixes, and inline code marks from the given string. |
478 | fn strip_prefixes_suffixes(mut s: &str) -> &str { | 461 | fn strip_prefixes_suffixes(mut s: &str) -> &str { |
479 | s = s.trim_matches('`'); | 462 | s = s.trim_matches('`'); |
480 | NS_MAP.iter().for_each(|(_, (prefixes, suffixes))| { | 463 | |
481 | prefixes.iter().for_each(|prefix| s = s.trim_start_matches(*prefix)); | 464 | [ |
482 | suffixes.iter().for_each(|suffix| s = s.trim_end_matches(*suffix)); | 465 | (TYPES.0.iter(), TYPES.1.iter()), |
466 | (VALUES.0.iter(), VALUES.1.iter()), | ||
467 | (MACROS.0.iter(), MACROS.1.iter()), | ||
468 | ] | ||
469 | .iter() | ||
470 | .for_each(|(prefixes, suffixes)| { | ||
471 | prefixes.clone().for_each(|prefix| s = s.trim_start_matches(*prefix)); | ||
472 | suffixes.clone().for_each(|suffix| s = s.trim_end_matches(*suffix)); | ||
483 | }); | 473 | }); |
484 | s.trim_start_matches("@").trim() | 474 | s.trim_start_matches("@").trim() |
485 | } | 475 | } |
@@ -493,6 +483,8 @@ fn try_resolve_intra( | |||
493 | link_text: &str, | 483 | link_text: &str, |
494 | link_target: &str, | 484 | link_target: &str, |
495 | ) -> Option<(String, String)> { | 485 | ) -> Option<(String, String)> { |
486 | eprintln!("resolving intra"); | ||
487 | |||
496 | // Set link_target for implied shortlinks | 488 | // Set link_target for implied shortlinks |
497 | let link_target = | 489 | let link_target = |
498 | if link_target.is_empty() { link_text.trim_matches('`') } else { link_target }; | 490 | if link_target.is_empty() { link_text.trim_matches('`') } else { link_target }; |
@@ -551,6 +543,8 @@ fn try_resolve_intra( | |||
551 | 543 | ||
552 | /// Try to resolve path to local documentation via path-based links (i.e. `../gateway/struct.Shard.html`). | 544 | /// Try to resolve path to local documentation via path-based links (i.e. `../gateway/struct.Shard.html`). |
553 | fn try_resolve_path(db: &RootDatabase, definition: &Definition, link: &str) -> Option<String> { | 545 | fn try_resolve_path(db: &RootDatabase, definition: &Definition, link: &str) -> Option<String> { |
546 | eprintln!("resolving path"); | ||
547 | |||
554 | if !link.contains("#") && !link.contains(".html") { | 548 | if !link.contains("#") && !link.contains(".html") { |
555 | return None; | 549 | return None; |
556 | } | 550 | } |