typst_analyzer/hints/
handle.rs1use 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 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 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 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}