typst_analyzer/hints/
handle.rs

1use regex::Regex;
2use tower_lsp::lsp_types::*;
3
4use crate::backend::Backend;
5
6pub trait TypstInlayHints {
7    fn calculate_inlay_hints(&self, doc: &str) -> Vec<InlayHint>;
8}
9
10impl TypstInlayHints for Backend {
11    fn calculate_inlay_hints(&self, doc: &str) -> Vec<InlayHint> {
12        let mut hints: Vec<InlayHint> = Vec::new();
13
14        // Regex to match any word within angle brackets and @word
15        let angle_brackets_re: Regex = Regex::new(r"<(\w+)>").unwrap();
16        let at_word_re: Regex = Regex::new(r"@(\w+)").unwrap();
17
18        doc.lines().enumerate().for_each(|(line_idx, line)| {
19            // Match words within angle brackets
20            angle_brackets_re.captures_iter(line).for_each(|cap| {
21                if let Some(matched_word) = cap.get(1) {
22                    let start = cap.get(0).unwrap().start();
23                    hints.push(InlayHint {
24                        position: Position {
25                            line: line_idx as u32,
26                            character: start as u32 + 1,
27                        },
28                        label: InlayHintLabel::String("label".to_owned()),
29                        kind: Some(InlayHintKind::TYPE),
30                        text_edits: None,
31                        tooltip: Some(InlayHintTooltip::String(format!(
32                            "Suggested label for <{}>",
33                            matched_word.as_str()
34                        ))),
35                        padding_left: Some(true),
36                        padding_right: Some(true),
37                        data: None,
38                    });
39                }
40            });
41
42            // Match @word patterns
43            at_word_re.captures_iter(line).for_each(|cap| {
44                if let Some(matched_word) = cap.get(1) {
45                    let start = cap.get(0).unwrap().start();
46                    hints.push(InlayHint {
47                        position: Position {
48                            line: line_idx as u32,
49                            character: start as u32 + 1,
50                        },
51                        label: InlayHintLabel::String("reference".to_owned()),
52                        kind: Some(InlayHintKind::TYPE),
53                        text_edits: None,
54                        tooltip: Some(InlayHintTooltip::String(format!(
55                            "Reference for @{}",
56                            matched_word.as_str()
57                        ))),
58                        padding_left: Some(true),
59                        padding_right: Some(true),
60                        data: None,
61                    });
62                }
63            });
64        });
65        hints
66    }
67}