tinymist_query/
document_highlight.rs

1use typst_shim::syntax::LinkedNodeExt;
2
3use crate::{SemanticRequest, analysis::doc_highlight::DocumentHighlightWorker, prelude::*};
4
5/// The [`textDocument/documentHighlight`] request
6///
7/// [`textDocument/documentHighlight`]: https://microsoft.github.io/language-server-protocol/specification#textDocument_documentHighlight
8#[derive(Debug, Clone)]
9pub struct DocumentHighlightRequest {
10    /// The path of the document to request highlight for.
11    pub path: PathBuf,
12    /// The position of the document to request highlight for.
13    pub position: LspPosition,
14}
15
16impl SemanticRequest for DocumentHighlightRequest {
17    type Response = Vec<DocumentHighlight>;
18
19    fn request(self, ctx: &mut LocalContext) -> Option<Self::Response> {
20        let source = ctx.source_by_path(&self.path).ok()?;
21        let cursor = ctx.to_typst_pos(self.position, &source)?;
22
23        let root = LinkedNode::new(source.root());
24        let node = root.leaf_at_compat(cursor)?;
25
26        let mut worker = DocumentHighlightWorker::new(ctx, &source);
27        worker.work(&node)?;
28        (!worker.annotated.is_empty()).then_some(worker.annotated)
29    }
30}
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35    use crate::tests::*;
36
37    #[test]
38    fn test() {
39        snapshot_testing("document_highlight", &|ctx, path| {
40            let source = ctx.source_by_path(&path).unwrap();
41
42            let request = DocumentHighlightRequest {
43                path: path.clone(),
44                position: find_test_position_after(&source),
45            };
46
47            let result = request.request(ctx);
48            assert_snapshot!(JsonRepr::new_redacted(result, &REDACT_LOC));
49        });
50    }
51}