|
2 | 2 |
|
3 | 3 | import weakref
|
4 | 4 | from asyncio import CancelledError, Event, Task, create_task, sleep
|
5 |
| -from contextlib import contextmanager |
6 | 5 | from functools import partial
|
7 |
| -from typing import Callable, ContextManager, NamedTuple |
| 6 | +from typing import Callable, NamedTuple |
8 | 7 |
|
9 | 8 | try:
|
10 |
| - from tree_sitter import Language, Node, Parser, Query, Tree |
| 9 | + from tree_sitter import Language, Parser, Query, Tree |
11 | 10 |
|
12 | 11 | TREE_SITTER = True
|
13 | 12 | except ImportError:
|
|
17 | 16 | from textual.document._document import Document, EditResult, Location, _utf8_encode
|
18 | 17 |
|
19 | 18 |
|
20 |
| -@contextmanager |
21 |
| -def temporary_query_point_range( |
22 |
| - query: Query, |
23 |
| - start_point: tuple[int, int] | None, |
24 |
| - end_point: tuple[int, int] | None, |
25 |
| -) -> ContextManager[None]: |
26 |
| - """Temporarily change the start and/or end point for a tree-sitter Query. |
27 |
| -
|
28 |
| - Args: |
29 |
| - query: The tree-sitter Query. |
30 |
| - start_point: The (row, column byte) to start the query at. |
31 |
| - end_point: The (row, column byte) to end the query at. |
32 |
| - """ |
33 |
| - # Note: Although not documented for the tree-sitter Python API, an |
34 |
| - # end-point of (0, 0) means 'end of document'. |
35 |
| - default_point_range = [(0, 0), (0, 0)] |
36 |
| - |
37 |
| - point_range = list(default_point_range) |
38 |
| - if start_point is not None: |
39 |
| - point_range[0] = start_point |
40 |
| - if end_point is not None: |
41 |
| - point_range[1] = end_point |
42 |
| - query.set_point_range(point_range) |
43 |
| - try: |
44 |
| - yield None |
45 |
| - finally: |
46 |
| - query.set_point_range(default_point_range) |
47 |
| - |
48 |
| - |
49 | 19 | class SyntaxTreeEdit(NamedTuple):
|
50 | 20 | """Details of a tree-sitter syntax tree edit operation."""
|
51 | 21 |
|
@@ -99,14 +69,15 @@ def __init__(
|
99 | 69 | self._background_parser = BackgroundSyntaxParser(self)
|
100 | 70 | self._pending_syntax_edits: list[SyntaxTreeEdit] = []
|
101 | 71 |
|
| 72 | + @property |
| 73 | + def current_syntax_tree(self) -> Tree: |
| 74 | + """The current syntax tree.""" |
| 75 | + return self._syntax_tree |
| 76 | + |
102 | 77 | def clean_up(self) -> None:
|
103 | 78 | """Perform any pre-deletion clean up."""
|
104 | 79 | self._background_parser.stop()
|
105 | 80 |
|
106 |
| - def copy_of_lines(self): |
107 |
| - """Provide a copy of the document's lines.""" |
108 |
| - return list(self._lines) |
109 |
| - |
110 | 81 | def apply_pending_syntax_edits(self) -> bool:
|
111 | 82 | """Apply any pending edits to the syntax tree.
|
112 | 83 |
|
@@ -136,29 +107,6 @@ def prepare_query(self, query: str) -> Query | None:
|
136 | 107 | """
|
137 | 108 | return self.language.query(query)
|
138 | 109 |
|
139 |
| - def query_syntax_tree( |
140 |
| - self, |
141 |
| - query: Query, |
142 |
| - start_point: tuple[int, int] | None = None, |
143 |
| - end_point: tuple[int, int] | None = None, |
144 |
| - ) -> dict[str, list["Node"]]: |
145 |
| - """Query the tree-sitter syntax tree. |
146 |
| -
|
147 |
| - The default implementation always returns an empty list. |
148 |
| -
|
149 |
| - To support querying in a subclass, this must be implemented. |
150 |
| -
|
151 |
| - Args: |
152 |
| - query: The tree-sitter Query to perform. |
153 |
| - start_point: The (row, column byte) to start the query at. |
154 |
| - end_point: The (row, column byte) to end the query at. |
155 |
| -
|
156 |
| - Returns: |
157 |
| - A tuple containing the nodes and text captured by the query. |
158 |
| - """ |
159 |
| - with temporary_query_point_range(query, start_point, end_point): |
160 |
| - return query.captures(self._syntax_tree.root_node) |
161 |
| - |
162 | 110 | def set_syntax_tree_update_callback(
|
163 | 111 | self,
|
164 | 112 | callback: Callable[[], None],
|
@@ -239,10 +187,14 @@ def reparse(self, timeout_us: int, lines: list[str], syntax_tree=None) -> bool:
|
239 | 187 | # The only known cause is a timeout.
|
240 | 188 | return False
|
241 | 189 | else:
|
| 190 | + self._syntax_tree = tree |
242 | 191 | if self._syntax_tree_update_callback is not None:
|
| 192 | + |
| 193 | + def set_new_tree(): |
| 194 | + self._syntax_tree = tree |
| 195 | + |
243 | 196 | changed_ranges = self._syntax_tree.changed_ranges(tree)
|
244 |
| - self._syntax_tree = tree |
245 |
| - self._syntax_tree_update_callback(changed_ranges) |
| 197 | + self._syntax_tree_update_callback(self._syntax_tree, len(lines)) |
246 | 198 | else:
|
247 | 199 | self._syntax_tree = tree
|
248 | 200 | return True
|
|
0 commit comments