auto_lsp_core/
regex.rs

1/*
2This file is part of auto-lsp.
3Copyright (C) 2025 CLAUZEL Adrien
4
5auto-lsp is free software: you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation, either version 3 of the License, or
8(at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program.  If not, see <http://www.gnu.org/licenses/>
17*/
18
19use crate::document::Document;
20use regex::{Match, Regex};
21use streaming_iterator::StreamingIterator;
22
23/// Find matches in the document with the provided regex
24///
25/// This function identifies comments in the [`tree_sitter::Tree`] of the [`Document`] and then
26/// runs a regex search on the comment lines.
27///
28/// ### Returns
29/// A vector of tuples containing the [`Match`] and the line number
30pub fn find_all_with_regex<'a>(
31    query: &tree_sitter::Query,
32    document: &'a Document,
33    regex: &Regex,
34) -> Vec<(Match<'a>, usize)> {
35    let root_node = document.tree.root_node();
36    let source = document.as_str();
37
38    let mut query_cursor = tree_sitter::QueryCursor::new();
39    let mut captures = query_cursor.captures(query, root_node, source.as_bytes());
40
41    let mut results = vec![];
42
43    while let Some((m, capture_index)) = captures.next() {
44        let capture = m.captures[*capture_index];
45        let range = capture.node.range();
46
47        // Comment is maybe multiline
48        let start_line = range.start_point.row;
49        let end_line = range.end_point.row;
50        let comment_lines = start_line..=end_line;
51
52        for line in comment_lines {
53            let text = document.texter.get_row(line).unwrap();
54            for m in regex.find_iter(text) {
55                results.push((m, line));
56            }
57        }
58    }
59    results
60}