1
use crate::handlers::sync_event::position_to_byte;
2
use crate::server::Backend;
3
use conjure_cp_essence_parser::util::get_documentation;
4
use tower_lsp::{jsonrpc::Error, lsp_types::*};
5

            
6
impl Backend {
7
    pub async fn handle_hovering(&self, params: HoverParams) -> Result<Option<Hover>, Error> {
8
        self.client.log_message(MessageType::INFO, "hovering").await;
9

            
10
        let uri = params
11
            .text_document_position_params
12
            .text_document
13
            .uri
14
            .clone();
15
        let position = params.text_document_position_params.position;
16

            
17
        let lsp_cache = &self.lsp_cache;
18

            
19
        let cache_conts = match lsp_cache.get(&uri).await {
20
            Some(conts) => conts,
21
            None => {
22
                self.client
23
                    .log_message(MessageType::WARNING, "Document not found in cache")
24
                    .await;
25
                return Ok(None);
26
            }
27
        };
28

            
29
        let source_map = match &cache_conts.sourcemap {
30
            Some(map) => map,
31
            None => {
32
                self.client
33
                    .log_message(MessageType::WARNING, "No source map found in cache")
34
                    .await;
35
                return Ok(None);
36
            }
37
        };
38

            
39
        let hover_byte = position_to_byte(&cache_conts.contents, position);
40

            
41
        let mut info = match source_map.hover_info_at_byte(hover_byte) {
42
            Some(info) => info.clone(),
43
            None => {
44
                return Ok(None);
45
            }
46
        };
47
        if let Some(doc_key) = info.doc_key.clone() {
48
            let description = tokio::task::spawn_blocking(move || get_documentation(&doc_key))
49
                .await
50
                .ok()
51
                .flatten();
52
            let Some(description) = description else {
53
                return Ok(None);
54
            };
55
            info.description = description;
56
        }
57
        self.client
58
            .log_message(MessageType::INFO, info.description.clone())
59
            .await;
60
        Ok(Some(Hover {
61
            contents: HoverContents::Array(vec![
62
                MarkedString::String(info.description),
63
                MarkedString::String(info.ty.unwrap_or_default()),
64
            ]),
65
            range: None,
66
        }))
67
    }
68
}