summaryrefslogtreecommitdiff
path: root/support/texlab/crates/texlab/src/features/inlay_hint.rs
blob: 44ed0757a50f1101da9335e602d04620b315cb4b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use base_db::{util::RenderedObject, FeatureParams, Workspace};
use inlay_hints::{InlayHintData, InlayHintParams};

use crate::util::line_index_ext::LineIndexExt;

pub fn find_all(
    workspace: &Workspace,
    uri: &lsp_types::Url,
    range: lsp_types::Range,
) -> Option<Vec<lsp_types::InlayHint>> {
    let document = workspace.lookup(uri)?;
    let line_index = &document.line_index;
    let range = line_index.offset_lsp_range(range)?;

    let feature = FeatureParams::new(workspace, document);
    let params = InlayHintParams { range, feature };
    let hints = inlay_hints::find_all(params)?;
    let hints = hints.into_iter().filter_map(|hint| {
        let position = line_index.line_col_lsp(hint.offset)?;
        Some(match hint.data {
            InlayHintData::LabelDefinition(label) => {
                let number = label.number?;

                let text = match &label.object {
                    RenderedObject::Section { prefix, .. } => {
                        format!("{} {}", prefix, number)
                    }
                    RenderedObject::Float { kind, .. } => {
                        format!("{} {}", kind.as_str(), number)
                    }
                    RenderedObject::Theorem { kind, .. } => {
                        format!("{} {}", kind, number)
                    }
                    RenderedObject::Equation => format!("Equation ({})", number),
                    RenderedObject::EnumItem => format!("Item {}", number),
                };

                lsp_types::InlayHint {
                    position,
                    label: lsp_types::InlayHintLabel::String(format!(" {text} ")),
                    kind: None,
                    text_edits: None,
                    tooltip: None,
                    padding_left: Some(true),
                    padding_right: None,
                    data: None,
                }
            }
            InlayHintData::LabelReference(label) => {
                let text = label.reference();

                lsp_types::InlayHint {
                    position,
                    label: lsp_types::InlayHintLabel::String(format!(" {text} ")),
                    kind: None,
                    text_edits: None,
                    tooltip: None,
                    padding_left: Some(true),
                    padding_right: None,
                    data: None,
                }
            }
        })
    });

    Some(hints.collect())
}