1616from pygments .lexers import guess_lexer_for_filename
1717from pygments .token import Token
1818from tqdm import tqdm
19+ from tree_sitter import Query
1920
2021from aider .dump import dump
2122from aider .special import filter_important_files
@@ -262,6 +263,19 @@ def get_tags(self, fname, rel_fname):
262263
263264 return data
264265
266+ def _run_captures (self , query : Query , node ):
267+ # tree-sitter 0.23.2's python bindings had captures directly on the Query object
268+ # but 0.24.0 moved it to a separate QueryCursor class. Support both.
269+ if hasattr (query , "captures" ):
270+ # Old API
271+ return query .captures (node )
272+
273+ # New API
274+ from tree_sitter import QueryCursor
275+
276+ cursor = QueryCursor (query )
277+ return cursor .captures (node )
278+
265279 def get_tags_raw (self , fname , rel_fname ):
266280 lang = filename_to_lang (fname )
267281 if not lang :
@@ -285,17 +299,22 @@ def get_tags_raw(self, fname, rel_fname):
285299 tree = parser .parse (bytes (code , "utf-8" ))
286300
287301 # Run the tags queries
288- query = language .query (query_scm )
289- captures = query .captures (tree .root_node )
302+ captures = self ._run_captures (Query (language , query_scm ), tree .root_node )
303+
304+ captures_by_tag = defaultdict (list )
305+ matches = []
306+ for tag , nodes in captures .items ():
307+ for node in nodes :
308+ captures_by_tag [tag ].append (node )
309+ captures_by_tag [tag ].append (node )
310+ matches .append ((node , tag ))
290311
291- saw = set ()
292312 if USING_TSL_PACK :
293- all_nodes = []
294- for tag , nodes in captures .items ():
295- all_nodes += [(node , tag ) for node in nodes ]
313+ all_nodes = [(node , tag ) for tag , nodes in captures_by_tag .items () for node in nodes ]
296314 else :
297- all_nodes = list ( captures )
315+ all_nodes = matches
298316
317+ saw = set ()
299318 for node , tag in all_nodes :
300319 if tag .startswith ("name.definition." ):
301320 kind = "def"
0 commit comments