tinymist_query/
selection_range.rs1use typst_shim::syntax::LinkedNodeExt;
2
3use crate::{SyntaxRequest, prelude::*};
4
5#[derive(Debug, Clone)]
20pub struct SelectionRangeRequest {
21 pub path: PathBuf,
23 pub positions: Vec<LspPosition>,
25}
26
27impl SyntaxRequest for SelectionRangeRequest {
28 type Response = Vec<SelectionRange>;
29
30 fn request(
31 self,
32 source: &Source,
33 position_encoding: PositionEncoding,
34 ) -> Option<Self::Response> {
35 let mut ranges = Vec::new();
36 for position in self.positions {
37 let typst_offset = to_typst_position(position, position_encoding, source)?;
38 let tree = LinkedNode::new(source.root());
39 let leaf = tree.leaf_at_compat(typst_offset + 1)?;
40 ranges.push(range_for_node(source, position_encoding, &leaf));
41 }
42
43 Some(ranges)
44 }
45}
46
47fn range_for_node(
48 source: &Source,
49 position_encoding: PositionEncoding,
50 node: &LinkedNode,
51) -> SelectionRange {
52 let range = to_lsp_range(node.range(), source, position_encoding);
53 SelectionRange {
54 range,
55 parent: node
56 .parent()
57 .map(|node| Box::new(range_for_node(source, position_encoding, node))),
58 }
59}