Skip to main content

only_semantic/
hover.rs

1use smol_str::SmolStr;
2use text_size::{TextRange, TextSize};
3
4use crate::SemanticSnapshot;
5
6/// Kind of hover result produced for editor consumers.
7///
8/// Args:
9/// None.
10///
11/// Returns:
12/// Stable hover categories for namespace and task items.
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum HoverKind {
15    Namespace,
16    Task,
17}
18
19/// Hover payload for one source location.
20///
21/// Args:
22/// None.
23///
24/// Returns:
25/// Name, signature, docs and selected range for the hovered item.
26#[derive(Debug, Clone, PartialEq, Eq)]
27pub struct HoverInfo {
28    pub kind: HoverKind,
29    pub name: SmolStr,
30    pub signature: SmolStr,
31    pub docs: Option<SmolStr>,
32    pub range: TextRange,
33    pub container_name: Option<SmolStr>,
34}
35
36/// Resolves hover information at one source offset.
37///
38/// Args:
39/// snapshot: Immutable semantic snapshot for one document version.
40/// offset: Source offset queried by the editor host.
41///
42/// Returns:
43/// Hover information for the matching namespace or task item.
44pub fn hover_at(snapshot: &SemanticSnapshot, offset: TextSize) -> Option<HoverInfo> {
45    for namespace in &snapshot.document.namespaces {
46        if namespace.range.contains(offset) {
47            return Some(HoverInfo {
48                kind: HoverKind::Namespace,
49                name: namespace.name.clone(),
50                signature: SmolStr::from(format!("[{}]", namespace.name)),
51                docs: namespace.doc.clone(),
52                range: namespace.range,
53                container_name: None,
54            });
55        }
56    }
57
58    for task in &snapshot.document.tasks {
59        if task.range.contains(offset) {
60            return Some(HoverInfo {
61                kind: HoverKind::Task,
62                name: task.name.clone(),
63                signature: task.signature(),
64                docs: task.doc.clone(),
65                range: task.range,
66                container_name: task.namespace.clone(),
67            });
68        }
69    }
70
71    None
72}