bend_language_server/core/
document.rs1use ropey::Rope;
2use tower_lsp::lsp_types as lsp;
3use tree_sitter as ts;
4use tree_sitter_highlight::{self as hg, Highlighter};
5
6use crate::language::{bend, bend_parser};
7use crate::utils::rope::TextProviderRope;
8
9pub struct Document {
11 pub url: lsp::Url,
12 pub text: Rope,
13 pub tree: Option<ts::Tree>,
14 pub parser: ts::Parser,
15 pub highlighter: hg::Highlighter,
16 }
18
19impl Document {
20 pub fn new(url: lsp::Url) -> Self {
22 Self {
23 url,
24 text: Rope::new(),
25 tree: None,
26 parser: bend_parser().unwrap(),
27 highlighter: Highlighter::new(),
28 }
29 }
30
31 pub fn new_with_text(url: lsp::Url, text: &str) -> Self {
33 let mut doc = Self::new(url);
34 doc.update_whole_text(text);
35 doc
36 }
37
38 pub fn update_whole_text(&mut self, text: &str) {
40 self.text = Rope::from_str(text);
41 self.tree = self.parser.parse(text, None);
42 }
43
44 pub fn get_tree(&mut self) -> &ts::Tree {
45 if self.tree.is_none() {
46 self.do_parse();
47 }
48 self.tree.as_ref().expect("tried to get empty tree")
49 }
50
51 pub fn find_one(&self, query: &str) -> Option<ts::Node> {
53 let mut cursor = ts::QueryCursor::new();
54 let query = ts::Query::new(&bend(), query).unwrap();
55 let root = self.tree.as_ref()?.root_node();
56
57 cursor
58 .captures(&query, root, &TextProviderRope(&self.text))
59 .flat_map(|(m, _)| m.captures)
60 .next()
61 .map(|capture| capture.node)
62 }
63
64 fn do_parse(&mut self) -> Option<ts::Tree> {
65 self.parser.parse_with(
66 &mut |start_byte, _| {
67 self.text
68 .byte_slice(start_byte..)
69 .chunks()
70 .next()
71 .unwrap_or("")
72 },
73 self.tree.as_ref(),
74 )
75 }
76}