aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2022-10-27 21:30:23 +0800
committerPo Lu2022-11-03 19:13:33 +0800
commitbd8e19e1e2ccfb76c1fccc4dff1f8774185cfea4 (patch)
tree0756173e0f224e81d80529be57acf8cf8e168046
parent88d54756d46101b97b7fde97b4bc3b62f7bd6c06 (diff)
downloademacs-bd8e19e1e2ccfb76c1fccc4dff1f8774185cfea4.tar.gz
emacs-bd8e19e1e2ccfb76c1fccc4dff1f8774185cfea4.zip
Stylistic changes to tree-sitter code
* src/treesit.c (treesit_find_override_name) (treesit_load_language_push_for_each_suffix, treesit_load_language) (Ftreesit_langauge_available_p, treesit_record_change) (make_treesit_parser, make_treesit_node, make_treesit_query) (Ftreesit_parser_create, Ftreesit_parser_delete, Ftreesit_parser_list) (treesit_check_range_argument, Ftreesit_parser_included_ranges) (Ftreesit_node_start, Ftreesit_node_end, Ftreesit_node_check) (Ftreesit_node_child_by_field_name, Ftreesit_pattern_expand) (Ftreesit_query_expand, treesit_predicates_for_pattern) (treesit_predicate_capture_name_to_text, treesit_predicate_equal) (treesit_predicate_match, treesit_eval_predicates) (Ftreesit_query_capture, treesit_search_dfs, treesit_build_sparse_tree) (syms_of_treesit): Use FOR_EACH_TAIL (or FOR_EACH_TAIL_SAFE where not obviously safe), and check list heads and tails correctly; fix coding style of various constructs, especially: variable = mumble (frob (bar), (foo () + bar ()) + (baz () + quux ())) which should actually be variable = mumble (frob (bar), (foo () + bar ()) + (baz () + quux ())) and foo = mumble (frob (bar), 0) + (foo () + bar ()) + (baz () + quux ()) which should actually be foo = (mumble (frob (bar), 0) + (foo () + bar ()) + (baz () + quux ())) * src/treesit.h: Make declaration coding style consistent.
-rw-r--r--src/treesit.c386
-rw-r--r--src/treesit.h14
2 files changed, 221 insertions, 179 deletions
diff --git a/src/treesit.c b/src/treesit.c
index 08740591f4f..2d26f69aab5 100644
--- a/src/treesit.c
+++ b/src/treesit.c
@@ -280,13 +280,15 @@ init_treesit_functions (void)
280 The Emacs wrapper of tree-sitter does not expose everything the C 280 The Emacs wrapper of tree-sitter does not expose everything the C
281 API provides, most notably: 281 API provides, most notably:
282 282
283 - It doesn't expose a syntax tree. We put the syntax tree in the 283 - It doesn't expose a syntax tree. The syntax tree is placed in
284 parser object, and updating the tree is handled on the C level. 284 the parser object, and updating the tree is handled at the C
285 level.
285 286
286 - We don't expose tree cursor either. I think Lisp is slow enough 287 - The tree cursor is not exposed either. I think Lisp is slow
287 to nullify any performance advantage of using a cursor, though I 288 enough to nullify any performance advantage of using a cursor,
288 don't have evidence. Also I want to minimize the number of new 289 though I don't have evidence. Also I want to minimize the number
289 types we introduce. Currently we only add parser and node type. 290 of new types we introduce. Currently we only add parser and node
291 type.
290 292
291 - Because updating the change is handled on the C level as each 293 - Because updating the change is handled on the C level as each
292 change is made in the buffer, there is no way for Lisp to update 294 change is made in the buffer, there is no way for Lisp to update
@@ -295,36 +297,38 @@ init_treesit_functions (void)
295 297
296 - I didn't expose setting timeout and cancellation flag for a 298 - I didn't expose setting timeout and cancellation flag for a
297 parser, mainly because I don't think they are really necessary 299 parser, mainly because I don't think they are really necessary
298 in Emacs' use cases. 300 in Emacs's use cases.
299 301
300 - Many tree-sitter functions asks for a TSPoint, basically a (row, 302 - Many tree-sitter functions take a TSPoint, which is basically a
301 column) location. Emacs uses a gap buffer and keeps no 303 row and column. Emacs uses a gap buffer and does not keep
302 information about row and column position. According to the 304 information about the row and column position of a buffer.
303 author of tree-sitter, tree-sitter only asks for (row, column) 305 According to the author of tree-sitter, those functions only take
304 position to carry it around and return back to the user later; 306 a TSPoint so that it can be moved alongside the byte position and
305 and the real position used is the byte position. He also said 307 returned to the caller afterwards, and the position actually used
306 that he _think_ that it will work to use byte position only. 308 is the specified byte position. He also said that he _thinks_
307 That's why whenever a TSPoint is asked, we pass a dummy one to 309 that just passing a byte position will also work. As a result, a
308 it. Judging by the nature of parsing algorithms, I think it is 310 dummy value is used in place of each TSPoint. Judging by the
309 safe to use only byte position, and I don't think this will 311 nature of parsing algorithms, I think it is safe to use only the
310 change in the future. 312 byte position, and I don't think this will change in the future.
311 313
312 REF: https://github.com/tree-sitter/tree-sitter/issues/445 314 See: https://github.com/tree-sitter/tree-sitter/issues/445
313 315
314 treesit.h has some commentary on the two main data structure 316 treesit.h has some commentary on the two main data structure for
315 for the parser and node. treesit_ensure_position_synced has some 317 the parser and node. treesit_ensure_position_synced has some
316 commentary on how do we make tree-sitter play well with narrowing 318 commentary on how we make tree-sitter play well with narrowing (the
317 (tree-sitter parser only sees the visible region, so we need to 319 tree-sitter parser only sees the visible region, so we need to
318 translate positions back and forth). Most action happens in 320 translate positions back and forth). Most action happens in
319 treesit_ensure_parsed, treesit_read_buffer and treesit_record_change. 321 treesit_ensure_parsed, treesit_read_buffer and
322 treesit_record_change.
320 323
321 A complete correspondence list between tree-sitter functions and 324 A complete correspondence list between tree-sitter functions and
322 exposed Lisp functions can be found in the manual (elisp)API 325 exposed Lisp functions can be found in the manual node (elisp)API
323 Correspondence. 326 Correspondence.
324 327
325 Placement of CHECK_xxx functions: call CHECK_xxx before using any 328 Placement of CHECK_xxx functions: call CHECK_xxx before using any
326 unchecked Lisp values; these include argument of Lisp functions, 329 unchecked Lisp values; these include arguments of Lisp functions,
327 return value of Fsymbol_value, car of a cons. 330 the return value of Fsymbol_value, and that of Fcar or Fcdr on
331 user-specified conses.
328 332
329 Initializing tree-sitter: there are two entry points to tree-sitter 333 Initializing tree-sitter: there are two entry points to tree-sitter
330 functions: 'treesit-parser-create' and 334 functions: 'treesit-parser-create' and
@@ -378,8 +382,8 @@ init_treesit_functions (void)
378 up and the query doesn't EQ to the cache anymore, the performance 382 up and the query doesn't EQ to the cache anymore, the performance
379 mysteriously drops. 3) what if a user uses so many stuff that the 383 mysteriously drops. 3) what if a user uses so many stuff that the
380 default cache size (20) is not enough and we end up thrashing? 384 default cache size (20) is not enough and we end up thrashing?
381 These are all imagined scenarios but they are not impossible :-) 385 These are all imaginary scenarios but they are not impossible
382 */ 386 :-) */
383 387
384 388
385/*** Initialization */ 389/*** Initialization */
@@ -449,21 +453,28 @@ static bool
449treesit_find_override_name (Lisp_Object language_symbol, Lisp_Object *name, 453treesit_find_override_name (Lisp_Object language_symbol, Lisp_Object *name,
450 Lisp_Object *c_symbol) 454 Lisp_Object *c_symbol)
451{ 455{
456 Lisp_Object tem;
457
452 CHECK_LIST (Vtreesit_load_name_override_list); 458 CHECK_LIST (Vtreesit_load_name_override_list);
453 for (Lisp_Object list = Vtreesit_load_name_override_list; 459
454 !NILP (list); list = XCDR (list)) 460 FOR_EACH_TAIL (tem)
455 { 461 {
456 Lisp_Object lang = XCAR (XCAR (list)); 462 Lisp_Object lang = XCAR (XCAR (tem));
457 CHECK_SYMBOL (lang); 463 CHECK_SYMBOL (lang);
464
458 if (EQ (lang, language_symbol)) 465 if (EQ (lang, language_symbol))
459 { 466 {
460 *name = Fnth (make_fixnum (1), XCAR (list)); 467 *name = Fnth (make_fixnum (1), XCAR (tem));
461 CHECK_STRING (*name); 468 CHECK_STRING (*name);
462 *c_symbol = Fnth (make_fixnum (2), XCAR (list)); 469 *c_symbol = Fnth (make_fixnum (2), XCAR (tem));
463 CHECK_STRING (*c_symbol); 470 CHECK_STRING (*c_symbol);
471
464 return true; 472 return true;
465 } 473 }
466 } 474 }
475
476 CHECK_LIST_END (tem, Vtreesit_load_name_override_list);
477
467 return false; 478 return false;
468} 479}
469 480
@@ -475,12 +486,13 @@ static void
475treesit_load_language_push_for_each_suffix (Lisp_Object lib_base_name, 486treesit_load_language_push_for_each_suffix (Lisp_Object lib_base_name,
476 Lisp_Object *path_candidates) 487 Lisp_Object *path_candidates)
477{ 488{
478 for (Lisp_Object suffixes = Vdynamic_library_suffixes; 489 Lisp_Object suffixes;
479 !NILP (suffixes); suffixes = XCDR (suffixes)) 490
480 { 491 suffixes = Vdynamic_library_suffixes;
481 *path_candidates = Fcons (concat2 (lib_base_name, XCAR (suffixes)), 492
482 *path_candidates); 493 FOR_EACH_TAIL (suffixes)
483 } 494 *path_candidates = Fcons (concat2 (lib_base_name, XCAR (suffixes)),
495 *path_candidates);
484} 496}
485 497
486/* Load the dynamic library of LANGUAGE_SYMBOL and return the pointer 498/* Load the dynamic library of LANGUAGE_SYMBOL and return the pointer
@@ -497,10 +509,10 @@ treesit_load_language (Lisp_Object language_symbol,
497 CHECK_LIST (Vtreesit_extra_load_path); 509 CHECK_LIST (Vtreesit_extra_load_path);
498 510
499 /* Figure out the library name and C name. */ 511 /* Figure out the library name and C name. */
500 Lisp_Object lib_base_name = 512 Lisp_Object lib_base_name
501 concat2 (build_pure_c_string ("libtree-sitter-"), symbol_name); 513 = concat2 (build_pure_c_string ("libtree-sitter-"), symbol_name);
502 Lisp_Object base_name = 514 Lisp_Object base_name
503 concat2 (build_pure_c_string ("tree-sitter-"), symbol_name); 515 = concat2 (build_pure_c_string ("tree-sitter-"), symbol_name);
504 516
505 /* Override the library name and C name, if appropriate. */ 517 /* Override the library name and C name, if appropriate. */
506 Lisp_Object override_name; 518 Lisp_Object override_name;
@@ -509,7 +521,7 @@ treesit_load_language (Lisp_Object language_symbol,
509 &override_name, 521 &override_name,
510 &override_c_name); 522 &override_c_name);
511 if (found_override) 523 if (found_override)
512 lib_base_name = override_name; 524 lib_base_name = override_name;
513 525
514 /* Now we generate a list of possible library paths. */ 526 /* Now we generate a list of possible library paths. */
515 Lisp_Object path_candidates = Qnil; 527 Lisp_Object path_candidates = Qnil;
@@ -519,13 +531,16 @@ treesit_load_language (Lisp_Object language_symbol,
519 /* This is used for reporting errors (i.e., just filenames). */ 531 /* This is used for reporting errors (i.e., just filenames). */
520 Lisp_Object base_candidates = path_candidates; 532 Lisp_Object base_candidates = path_candidates;
521 /* Then push ~/.emacs.d/tree-sitter paths. */ 533 /* Then push ~/.emacs.d/tree-sitter paths. */
522 Lisp_Object lib_name = 534 Lisp_Object lib_name
523 Fexpand_file_name (concat2 (build_string ("tree-sitter/"), lib_base_name), 535 = Fexpand_file_name (concat2 (build_string ("tree-sitter/"), lib_base_name),
524 Fsymbol_value (Quser_emacs_directory)); 536 Fsymbol_value (Quser_emacs_directory));
525 treesit_load_language_push_for_each_suffix (lib_name, &path_candidates); 537 treesit_load_language_push_for_each_suffix (lib_name, &path_candidates);
526 /* Then push paths from treesit-extra-load-path. */ 538 /* Then push paths from treesit-extra-load-path. */
527 for (Lisp_Object tail = Freverse (Vtreesit_extra_load_path); 539 Lisp_Object tail;
528 !NILP (tail); tail = XCDR (tail)) 540
541 tail = Freverse (Vtreesit_extra_load_path);
542
543 FOR_EACH_TAIL (tail)
529 { 544 {
530 Lisp_Object expanded_lib = Fexpand_file_name (lib_base_name, XCAR (tail)); 545 Lisp_Object expanded_lib = Fexpand_file_name (lib_base_name, XCAR (tail));
531 treesit_load_language_push_for_each_suffix (expanded_lib, 546 treesit_load_language_push_for_each_suffix (expanded_lib,
@@ -537,8 +552,10 @@ treesit_load_language (Lisp_Object language_symbol,
537 fail. */ 552 fail. */
538 dynlib_handle_ptr handle; 553 dynlib_handle_ptr handle;
539 char const *error; 554 char const *error;
540 for (Lisp_Object tail = path_candidates; 555
541 !NILP (tail); tail = XCDR (tail)) 556 tail = path_candidates;
557
558 FOR_EACH_TAIL (tail)
542 { 559 {
543 char *library_name = SSDATA (XCAR (tail)); 560 char *library_name = SSDATA (XCAR (tail));
544 dynlib_error (); 561 dynlib_error ();
@@ -547,6 +564,7 @@ treesit_load_language (Lisp_Object language_symbol,
547 if (error == NULL) 564 if (error == NULL)
548 break; 565 break;
549 } 566 }
567
550 if (error != NULL) 568 if (error != NULL)
551 { 569 {
552 *signal_symbol = Qtreesit_load_language_error; 570 *signal_symbol = Qtreesit_load_language_error;
@@ -587,8 +605,7 @@ treesit_load_language (Lisp_Object language_symbol,
587 return lang; 605 return lang;
588} 606}
589 607
590DEFUN ("treesit-language-available-p", 608DEFUN ("treesit-language-available-p", Ftreesit_langauge_available_p,
591 Ftreesit_langauge_available_p,
592 Streesit_language_available_p, 609 Streesit_language_available_p,
593 1, 2, 0, 610 1, 2, 0,
594 doc: /* Return non-nil if LANGUAGE exists and is loadable. 611 doc: /* Return non-nil if LANGUAGE exists and is loadable.
@@ -668,15 +685,17 @@ treesit_tree_edit_1 (TSTree *tree, ptrdiff_t start_byte,
668} 685}
669 686
670/* Update each parser's tree after the user made an edit. This 687/* Update each parser's tree after the user made an edit. This
671function does not parse the buffer and only updates the tree. (So it 688 function does not parse the buffer and only updates the tree, so it
672should be very fast.) */ 689 should be very fast. */
673void 690void
674treesit_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte, 691treesit_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte,
675 ptrdiff_t new_end_byte) 692 ptrdiff_t new_end_byte)
676{ 693{
677 for (Lisp_Object parser_list = BVAR (current_buffer, ts_parser_list); 694 Lisp_Object parser_list;
678 !NILP (parser_list); 695
679 parser_list = XCDR (parser_list)) 696 parser_list = BVAR (current_buffer, ts_parser_list);
697
698 FOR_EACH_TAIL_SAFE (parser_list)
680 { 699 {
681 CHECK_CONS (parser_list); 700 CHECK_CONS (parser_list);
682 Lisp_Object lisp_parser = XCAR (parser_list); 701 Lisp_Object lisp_parser = XCAR (parser_list);
@@ -699,15 +718,15 @@ treesit_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte,
699 VISIBLE_BEG. min(visi_end, max(visi_beg, value)) clips 718 VISIBLE_BEG. min(visi_end, max(visi_beg, value)) clips
700 value into [visi_beg, visi_end], and subtracting visi_beg 719 value into [visi_beg, visi_end], and subtracting visi_beg
701 gives the offset from visi_beg. */ 720 gives the offset from visi_beg. */
702 ptrdiff_t start_offset = 721 ptrdiff_t start_offset = (min (visible_end,
703 min (visible_end, 722 max (visible_beg, start_byte))
704 max (visible_beg, start_byte)) - visible_beg; 723 - visible_beg);
705 ptrdiff_t old_end_offset = 724 ptrdiff_t old_end_offset = (min (visible_end,
706 min (visible_end, 725 max (visible_beg, old_end_byte))
707 max (visible_beg, old_end_byte)) - visible_beg; 726 - visible_beg);
708 ptrdiff_t new_end_offset = 727 ptrdiff_t new_end_offset = (min (visible_end,
709 min (visible_end, 728 max (visible_beg, new_end_byte))
710 max (visible_beg, new_end_byte)) - visible_beg; 729 - visible_beg);
711 eassert (start_offset <= old_end_offset); 730 eassert (start_offset <= old_end_offset);
712 eassert (start_offset <= new_end_offset); 731 eassert (start_offset <= new_end_offset);
713 732
@@ -721,21 +740,18 @@ treesit_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte,
721 view changes. */ 740 view changes. */
722 ptrdiff_t visi_beg_delta; 741 ptrdiff_t visi_beg_delta;
723 if (old_end_byte > new_end_byte) 742 if (old_end_byte > new_end_byte)
724 { 743 /* Move backward. */
725 /* Move backward. */ 744 visi_beg_delta = (min (visible_beg, new_end_byte)
726 visi_beg_delta = 745 - min (visible_beg, old_end_byte));
727 min (visible_beg, new_end_byte)
728 - min (visible_beg, old_end_byte);
729 }
730 else 746 else
731 { 747 /* Move forward. */
732 /* Move forward. */ 748 visi_beg_delta = (old_end_byte < visible_beg
733 visi_beg_delta = 749 ? new_end_byte - old_end_byte : 0);
734 old_end_byte < visible_beg ? new_end_byte - old_end_byte : 0;
735 }
736 XTS_PARSER (lisp_parser)->visible_beg = visible_beg + visi_beg_delta; 750 XTS_PARSER (lisp_parser)->visible_beg = visible_beg + visi_beg_delta;
737 XTS_PARSER (lisp_parser)->visible_end 751 XTS_PARSER (lisp_parser)->visible_end = (visible_end
738 = visible_end + visi_beg_delta + (new_end_offset - old_end_offset); 752 + visi_beg_delta
753 + (new_end_offset
754 - old_end_offset));
739 eassert (XTS_PARSER (lisp_parser)->visible_beg >= 0); 755 eassert (XTS_PARSER (lisp_parser)->visible_beg >= 0);
740 eassert (XTS_PARSER (lisp_parser)->visible_beg 756 eassert (XTS_PARSER (lisp_parser)->visible_beg
741 <= XTS_PARSER (lisp_parser)->visible_end); 757 <= XTS_PARSER (lisp_parser)->visible_end);
@@ -826,7 +842,7 @@ treesit_check_buffer_size (struct buffer *buffer)
826} 842}
827 843
828/* Parse the buffer. We don't parse until we have to. When we have 844/* Parse the buffer. We don't parse until we have to. When we have
829to, we call this function to parse and update the tree. */ 845 to, we call this function to parse and update the tree. */
830static void 846static void
831treesit_ensure_parsed (Lisp_Object parser) 847treesit_ensure_parsed (Lisp_Object parser)
832{ 848{
@@ -913,15 +929,18 @@ treesit_read_buffer (void *parser, uint32_t byte_index,
913 return beg; 929 return beg;
914} 930}
915 931
916/*** Functions for parser and node object*/ 932/*** Functions for parser and node object */
917 933
918/* Wrap the parser in a Lisp_Object to be used in the Lisp machine. */ 934/* Wrap the parser in a Lisp_Object to be used in the Lisp
935 machine. */
919Lisp_Object 936Lisp_Object
920make_treesit_parser (Lisp_Object buffer, TSParser *parser, 937make_treesit_parser (Lisp_Object buffer, TSParser *parser,
921 TSTree *tree, Lisp_Object language_symbol) 938 TSTree *tree, Lisp_Object language_symbol)
922{ 939{
923 struct Lisp_TS_Parser *lisp_parser = 940 struct Lisp_TS_Parser *lisp_parser;
924 ALLOCATE_PSEUDOVECTOR (struct Lisp_TS_Parser, buffer, PVEC_TS_PARSER); 941
942 lisp_parser = ALLOCATE_PSEUDOVECTOR (struct Lisp_TS_Parser,
943 buffer, PVEC_TS_PARSER);
925 944
926 lisp_parser->language_symbol = language_symbol; 945 lisp_parser->language_symbol = language_symbol;
927 lisp_parser->buffer = buffer; 946 lisp_parser->buffer = buffer;
@@ -942,8 +961,10 @@ make_treesit_parser (Lisp_Object buffer, TSParser *parser,
942Lisp_Object 961Lisp_Object
943make_treesit_node (Lisp_Object parser, TSNode node) 962make_treesit_node (Lisp_Object parser, TSNode node)
944{ 963{
945 struct Lisp_TS_Node *lisp_node = 964 struct Lisp_TS_Node *lisp_node;
946 ALLOCATE_PSEUDOVECTOR (struct Lisp_TS_Node, parser, PVEC_TS_NODE); 965
966 lisp_node = ALLOCATE_PSEUDOVECTOR (struct Lisp_TS_Node,
967 parser, PVEC_TS_NODE);
947 lisp_node->parser = parser; 968 lisp_node->parser = parser;
948 lisp_node->node = node; 969 lisp_node->node = node;
949 lisp_node->timestamp = XTS_PARSER (parser)->timestamp; 970 lisp_node->timestamp = XTS_PARSER (parser)->timestamp;
@@ -956,9 +977,10 @@ static Lisp_Object
956make_treesit_query (Lisp_Object query, Lisp_Object language) 977make_treesit_query (Lisp_Object query, Lisp_Object language)
957{ 978{
958 TSQueryCursor *treesit_cursor = ts_query_cursor_new (); 979 TSQueryCursor *treesit_cursor = ts_query_cursor_new ();
959 struct Lisp_TS_Query *lisp_query = 980 struct Lisp_TS_Query *lisp_query;
960 ALLOCATE_PSEUDOVECTOR (struct Lisp_TS_Query, source, 981
961 PVEC_TS_COMPILED_QUERY); 982 lisp_query = ALLOCATE_PSEUDOVECTOR (struct Lisp_TS_Query,
983 source, PVEC_TS_COMPILED_QUERY);
962 984
963 lisp_query->language = language; 985 lisp_query->language = language;
964 lisp_query->source = query; 986 lisp_query->source = query;
@@ -1178,8 +1200,9 @@ create a new parser. */)
1178 ts_parser_set_language (parser, lang); 1200 ts_parser_set_language (parser, lang);
1179 1201
1180 /* Create parser. */ 1202 /* Create parser. */
1181 Lisp_Object lisp_parser 1203 Lisp_Object lisp_parser = make_treesit_parser (Fcurrent_buffer (),
1182 = make_treesit_parser (Fcurrent_buffer (), parser, NULL, language); 1204 parser, NULL,
1205 language);
1183 1206
1184 /* Update parser-list. */ 1207 /* Update parser-list. */
1185 BVAR (buf, ts_parser_list) = Fcons (lisp_parser, BVAR (buf, ts_parser_list)); 1208 BVAR (buf, ts_parser_list) = Fcons (lisp_parser, BVAR (buf, ts_parser_list));
@@ -1198,7 +1221,9 @@ See `treesit-parser-list' for the buffer's parser list. */)
1198 1221
1199 Lisp_Object buffer = XTS_PARSER (parser)->buffer; 1222 Lisp_Object buffer = XTS_PARSER (parser)->buffer;
1200 struct buffer *buf = XBUFFER (buffer); 1223 struct buffer *buf = XBUFFER (buffer);
1201 BVAR (buf, ts_parser_list) = Fdelete (parser, BVAR (buf, ts_parser_list)); 1224
1225 BVAR (buf, ts_parser_list)
1226 = Fdelete (parser, BVAR (buf, ts_parser_list));
1202 1227
1203 XTS_PARSER (parser)->deleted = true; 1228 XTS_PARSER (parser)->deleted = true;
1204 return Qnil; 1229 return Qnil;
@@ -1222,12 +1247,13 @@ BUFFER defaults to the current buffer. */)
1222 /* Return a fresh list so messing with that list doesn't affect our 1247 /* Return a fresh list so messing with that list doesn't affect our
1223 internal data. */ 1248 internal data. */
1224 Lisp_Object return_list = Qnil; 1249 Lisp_Object return_list = Qnil;
1225 for (Lisp_Object tail = BVAR (buf, ts_parser_list); 1250 Lisp_Object tail;
1226 !NILP (tail); 1251
1227 tail = XCDR (tail)) 1252 tail = BVAR (buf, ts_parser_list);
1228 { 1253
1229 return_list = Fcons (XCAR (tail), return_list); 1254 FOR_EACH_TAIL (tail)
1230 } 1255 return_list = Fcons (XCAR (tail), return_list);
1256
1231 return Freverse (return_list); 1257 return Freverse (return_list);
1232} 1258}
1233 1259
@@ -1278,8 +1304,13 @@ treesit_check_range_argument (Lisp_Object ranges)
1278 ptrdiff_t point_min = BUF_BEGV (buffer); 1304 ptrdiff_t point_min = BUF_BEGV (buffer);
1279 ptrdiff_t point_max = BUF_ZV (buffer); 1305 ptrdiff_t point_max = BUF_ZV (buffer);
1280 EMACS_INT last_point = point_min; 1306 EMACS_INT last_point = point_min;
1307 Lisp_Object tail;
1308
1309 tail = ranges;
1281 1310
1282 for (Lisp_Object tail = ranges; !NILP (tail); tail = XCDR (tail)) 1311 CHECK_LIST (tail);
1312
1313 FOR_EACH_TAIL (tail)
1283 { 1314 {
1284 CHECK_CONS (tail); 1315 CHECK_CONS (tail);
1285 Lisp_Object range = XCAR (tail); 1316 Lisp_Object range = XCAR (tail);
@@ -1290,10 +1321,13 @@ treesit_check_range_argument (Lisp_Object ranges)
1290 EMACS_INT end = XFIXNUM (XCDR (range)); 1321 EMACS_INT end = XFIXNUM (XCDR (range));
1291 if (!(last_point <= beg && beg <= end && end <= point_max)) 1322 if (!(last_point <= beg && beg <= end && end <= point_max))
1292 xsignal2 (Qtreesit_range_invalid, 1323 xsignal2 (Qtreesit_range_invalid,
1293 build_pure_c_string ("RANGE is either overlapping or out-of-order or out-of-range"), 1324 build_pure_c_string ("RANGE is either overlapping,"
1325 " out-of-order or out-of-range"),
1294 ranges); 1326 ranges);
1295 last_point = end; 1327 last_point = end;
1296 } 1328 }
1329
1330 CHECK_LIST_END (tail, ranges);
1297} 1331}
1298 1332
1299DEFUN ("treesit-parser-set-included-ranges", 1333DEFUN ("treesit-parser-set-included-ranges",
@@ -1385,8 +1419,8 @@ return nil. */)
1385 treesit_check_parser (parser); 1419 treesit_check_parser (parser);
1386 treesit_initialize (); 1420 treesit_initialize ();
1387 uint32_t len; 1421 uint32_t len;
1388 const TSRange *ranges = 1422 const TSRange *ranges
1389 ts_parser_included_ranges (XTS_PARSER (parser)->parser, &len); 1423 = ts_parser_included_ranges (XTS_PARSER (parser)->parser, &len);
1390 if (len == 0) 1424 if (len == 0)
1391 return Qnil; 1425 return Qnil;
1392 1426
@@ -1407,9 +1441,9 @@ return nil. */)
1407 eassert (beg_byte <= end_byte); 1441 eassert (beg_byte <= end_byte);
1408 eassert (end_byte <= BUF_ZV_BYTE (buffer)); 1442 eassert (end_byte <= BUF_ZV_BYTE (buffer));
1409 1443
1410 Lisp_Object lisp_range = 1444 Lisp_Object lisp_range
1411 Fcons (make_fixnum (buf_bytepos_to_charpos (buffer, beg_byte)) , 1445 = Fcons (make_fixnum (buf_bytepos_to_charpos (buffer, beg_byte)),
1412 make_fixnum (buf_bytepos_to_charpos (buffer, end_byte))); 1446 make_fixnum (buf_bytepos_to_charpos (buffer, end_byte)));
1413 list = Fcons (lisp_range, list); 1447 list = Fcons (lisp_range, list);
1414 } 1448 }
1415 return Fnreverse (list); 1449 return Fnreverse (list);
@@ -1469,10 +1503,11 @@ If NODE is nil, return nil. */)
1469 TSNode treesit_node = XTS_NODE (node)->node; 1503 TSNode treesit_node = XTS_NODE (node)->node;
1470 ptrdiff_t visible_beg = XTS_PARSER (XTS_NODE (node)->parser)->visible_beg; 1504 ptrdiff_t visible_beg = XTS_PARSER (XTS_NODE (node)->parser)->visible_beg;
1471 uint32_t start_byte_offset = ts_node_start_byte (treesit_node); 1505 uint32_t start_byte_offset = ts_node_start_byte (treesit_node);
1472 struct buffer *buffer = 1506 struct buffer *buffer
1473 XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer); 1507 = XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer);
1474 ptrdiff_t start_pos = 1508 ptrdiff_t start_pos
1475 buf_bytepos_to_charpos (buffer, start_byte_offset + visible_beg); 1509 = buf_bytepos_to_charpos (buffer,
1510 start_byte_offset + visible_beg);
1476 return make_fixnum (start_pos); 1511 return make_fixnum (start_pos);
1477} 1512}
1478 1513
@@ -1489,10 +1524,10 @@ If NODE is nil, return nil. */)
1489 TSNode treesit_node = XTS_NODE (node)->node; 1524 TSNode treesit_node = XTS_NODE (node)->node;
1490 ptrdiff_t visible_beg = XTS_PARSER (XTS_NODE (node)->parser)->visible_beg; 1525 ptrdiff_t visible_beg = XTS_PARSER (XTS_NODE (node)->parser)->visible_beg;
1491 uint32_t end_byte_offset = ts_node_end_byte (treesit_node); 1526 uint32_t end_byte_offset = ts_node_end_byte (treesit_node);
1492 struct buffer *buffer = 1527 struct buffer *buffer
1493 XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer); 1528 = XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer);
1494 ptrdiff_t end_pos = 1529 ptrdiff_t end_pos
1495 buf_bytepos_to_charpos (buffer, end_byte_offset + visible_beg); 1530 = buf_bytepos_to_charpos (buffer, end_byte_offset + visible_beg);
1496 return make_fixnum (end_pos); 1531 return make_fixnum (end_pos);
1497} 1532}
1498 1533
@@ -1616,7 +1651,8 @@ errors. */)
1616 else if (EQ (property, Qhas_changes)) 1651 else if (EQ (property, Qhas_changes))
1617 result = ts_node_has_changes (treesit_node); 1652 result = ts_node_has_changes (treesit_node);
1618 else 1653 else
1619 signal_error ("Expecting `named', `missing', `extra', `has-changes' or `has-error', but got", 1654 signal_error ("Expecting `named', `missing', `extra', "
1655 "`has-changes' or `has-error', but got",
1620 property); 1656 property);
1621 return result ? Qt : Qnil; 1657 return result ? Qt : Qnil;
1622} 1658}
@@ -1699,7 +1735,8 @@ Return nil if there is no such child. If NODE is nil, return nil. */)
1699 char *name_str = SSDATA (field_name); 1735 char *name_str = SSDATA (field_name);
1700 TSNode treesit_node = XTS_NODE (node)->node; 1736 TSNode treesit_node = XTS_NODE (node)->node;
1701 TSNode child 1737 TSNode child
1702 = ts_node_child_by_field_name (treesit_node, name_str, strlen (name_str)); 1738 = ts_node_child_by_field_name (treesit_node, name_str,
1739 strlen (name_str));
1703 1740
1704 if (ts_node_is_null (child)) 1741 if (ts_node_is_null (child))
1705 return Qnil; 1742 return Qnil;
@@ -1905,10 +1942,10 @@ See Info node `(elisp)Pattern Matching' for detailed explanation. */)
1905 return build_pure_c_string ("#equal"); 1942 return build_pure_c_string ("#equal");
1906 if (EQ (pattern, intern_c_string (":match"))) 1943 if (EQ (pattern, intern_c_string (":match")))
1907 return build_pure_c_string ("#match"); 1944 return build_pure_c_string ("#match");
1908 Lisp_Object opening_delimeter = 1945 Lisp_Object opening_delimeter
1909 build_pure_c_string (VECTORP (pattern) ? "[" : "("); 1946 = build_pure_c_string (VECTORP (pattern) ? "[" : "(");
1910 Lisp_Object closing_delimiter = 1947 Lisp_Object closing_delimiter
1911 build_pure_c_string (VECTORP (pattern) ? "]" : ")"); 1948 = build_pure_c_string (VECTORP (pattern) ? "]" : ")");
1912 if (VECTORP (pattern) || CONSP (pattern)) 1949 if (VECTORP (pattern) || CONSP (pattern))
1913 return concat3 (opening_delimeter, 1950 return concat3 (opening_delimeter,
1914 Fmapconcat (intern_c_string ("treesit-pattern-expand"), 1951 Fmapconcat (intern_c_string ("treesit-pattern-expand"),
@@ -1942,8 +1979,8 @@ A PATTERN in QUERY can be
1942See Info node `(elisp)Pattern Matching' for detailed explanation. */) 1979See Info node `(elisp)Pattern Matching' for detailed explanation. */)
1943 (Lisp_Object query) 1980 (Lisp_Object query)
1944{ 1981{
1945 return Fmapconcat (intern_c_string ("treesit-pattern-expand"), 1982 return Fmapconcat (Qtreesit_pattern_expand,
1946 query, build_pure_c_string (" ")); 1983 query, empty_unibyte_string);
1947} 1984}
1948 1985
1949/* This struct is used for passing captures to be check against 1986/* This struct is used for passing captures to be check against
@@ -1967,8 +2004,8 @@ static Lisp_Object
1967treesit_predicates_for_pattern (TSQuery *query, uint32_t pattern_index) 2004treesit_predicates_for_pattern (TSQuery *query, uint32_t pattern_index)
1968{ 2005{
1969 uint32_t len; 2006 uint32_t len;
1970 const TSQueryPredicateStep *predicate_list = 2007 const TSQueryPredicateStep *predicate_list
1971 ts_query_predicates_for_pattern (query, pattern_index, &len); 2008 = ts_query_predicates_for_pattern (query, pattern_index, &len);
1972 Lisp_Object result = Qnil; 2009 Lisp_Object result = Qnil;
1973 Lisp_Object predicate = Qnil; 2010 Lisp_Object predicate = Qnil;
1974 for (int idx = 0; idx < len; idx++) 2011 for (int idx = 0; idx < len; idx++)
@@ -2024,7 +2061,9 @@ treesit_predicate_capture_name_to_text (Lisp_Object name,
2024 if (NILP (node)) 2061 if (NILP (node))
2025 xsignal3 (Qtreesit_query_error, 2062 xsignal3 (Qtreesit_query_error,
2026 build_pure_c_string ("Cannot find captured node"), 2063 build_pure_c_string ("Cannot find captured node"),
2027 name, build_pure_c_string ("A predicate can only refer to captured nodes in the same pattern")); 2064 name, build_pure_c_string ("A predicate can only refer"
2065 " to captured nodes in the "
2066 "same pattern"));
2028 2067
2029 struct buffer *old_buffer = current_buffer; 2068 struct buffer *old_buffer = current_buffer;
2030 set_buffer_internal (XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer)); 2069 set_buffer_internal (XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer));
@@ -2043,17 +2082,20 @@ treesit_predicate_equal (Lisp_Object args, struct capture_range captures)
2043{ 2082{
2044 if (XFIXNUM (Flength (args)) != 2) 2083 if (XFIXNUM (Flength (args)) != 2)
2045 xsignal2 (Qtreesit_query_error, 2084 xsignal2 (Qtreesit_query_error,
2046 build_pure_c_string ("Predicate `equal' requires two arguments but only given"), 2085 build_pure_c_string ("Predicate `equal' requires "
2086 "two arguments but only given"),
2047 Flength (args)); 2087 Flength (args));
2048 2088
2049 Lisp_Object arg1 = XCAR (args); 2089 Lisp_Object arg1 = XCAR (args);
2050 Lisp_Object arg2 = XCAR (XCDR (args)); 2090 Lisp_Object arg2 = XCAR (XCDR (args));
2051 Lisp_Object text1 = 2091 Lisp_Object text1 = (STRINGP (arg1)
2052 STRINGP (arg1) ? arg1 : treesit_predicate_capture_name_to_text (arg1, 2092 ? arg1
2053 captures); 2093 : treesit_predicate_capture_name_to_text (arg1,
2054 Lisp_Object text2 = 2094 captures));
2055 STRINGP (arg2) ? arg2 : treesit_predicate_capture_name_to_text (arg2, 2095 Lisp_Object text2 = (STRINGP (arg2)
2056 captures); 2096 ? arg2
2097 : treesit_predicate_capture_name_to_text (arg2,
2098 captures));
2057 2099
2058 return !NILP (Fstring_equal (text1, text2)); 2100 return !NILP (Fstring_equal (text1, text2));
2059} 2101}
@@ -2066,7 +2108,8 @@ treesit_predicate_match (Lisp_Object args, struct capture_range captures)
2066{ 2108{
2067 if (XFIXNUM (Flength (args)) != 2) 2109 if (XFIXNUM (Flength (args)) != 2)
2068 xsignal2 (Qtreesit_query_error, 2110 xsignal2 (Qtreesit_query_error,
2069 build_pure_c_string ("Predicate `equal' requires two arguments but only given"), 2111 build_pure_c_string ("Predicate `equal' requires two "
2112 "arguments but only given"),
2070 Flength (args)); 2113 Flength (args));
2071 2114
2072 Lisp_Object regexp = XCAR (args); 2115 Lisp_Object regexp = XCAR (args);
@@ -2080,10 +2123,12 @@ treesit_predicate_match (Lisp_Object args, struct capture_range captures)
2080 string-match does.) */ 2123 string-match does.) */
2081 if (!STRINGP (regexp)) 2124 if (!STRINGP (regexp))
2082 xsignal1 (Qtreesit_query_error, 2125 xsignal1 (Qtreesit_query_error,
2083 build_pure_c_string ("The first argument to `match' should be a regexp string, not a capture name")); 2126 build_pure_c_string ("The first argument to `match' should "
2127 "be a regexp string, not a capture name"));
2084 if (!SYMBOLP (capture_name)) 2128 if (!SYMBOLP (capture_name))
2085 xsignal1 (Qtreesit_query_error, 2129 xsignal1 (Qtreesit_query_error,
2086 build_pure_c_string ("The second argument to `match' should be a capture name, not a string")); 2130 build_pure_c_string ("The second argument to `match' should "
2131 "be a capture name, not a string"));
2087 2132
2088 if (fast_string_match (regexp, text) >= 0) 2133 if (fast_string_match (regexp, text) >= 0)
2089 return true; 2134 return true;
@@ -2119,7 +2164,8 @@ treesit_eval_predicates (struct capture_range captures, Lisp_Object predicates)
2119 else 2164 else
2120 xsignal3 (Qtreesit_query_error, 2165 xsignal3 (Qtreesit_query_error,
2121 build_pure_c_string ("Invalid predicate"), 2166 build_pure_c_string ("Invalid predicate"),
2122 fn, build_pure_c_string ("Currently Emacs only supports equal and match predicate")); 2167 fn, build_pure_c_string ("Currently Emacs only supports"
2168 " equal and match predicate"));
2123 } 2169 }
2124 /* If all predicates passed, add captures to result list. */ 2170 /* If all predicates passed, add captures to result list. */
2125 return pass; 2171 return pass;
@@ -2231,12 +2277,14 @@ the query. */)
2231 treesit_initialize (); 2277 treesit_initialize ();
2232 2278
2233 /* Extract C values from Lisp objects. */ 2279 /* Extract C values from Lisp objects. */
2234 TSNode treesit_node = XTS_NODE (lisp_node)->node; 2280 TSNode treesit_node
2235 Lisp_Object lisp_parser = XTS_NODE (lisp_node)->parser; 2281 = XTS_NODE (lisp_node)->node;
2236 ptrdiff_t visible_beg = 2282 Lisp_Object lisp_parser
2237 XTS_PARSER (XTS_NODE (lisp_node)->parser)->visible_beg; 2283 = XTS_NODE (lisp_node)->parser;
2238 const TSLanguage *lang = 2284 ptrdiff_t visible_beg
2239 ts_parser_language (XTS_PARSER (lisp_parser)->parser); 2285 = XTS_PARSER (XTS_NODE (lisp_node)->parser)->visible_beg;
2286 const TSLanguage *lang
2287 = ts_parser_language (XTS_PARSER (lisp_parser)->parser);
2240 2288
2241 /* Initialize query objects. At the end of this block, we should 2289 /* Initialize query objects. At the end of this block, we should
2242 have a working TSQuery and a TSQueryCursor. */ 2290 have a working TSQuery and a TSQueryCursor. */
@@ -2266,10 +2314,11 @@ the query. */)
2266 uint32_t error_offset; 2314 uint32_t error_offset;
2267 TSQueryError error_type; 2315 TSQueryError error_type;
2268 treesit_query = ts_query_new (lang, query_string, strlen (query_string), 2316 treesit_query = ts_query_new (lang, query_string, strlen (query_string),
2269 &error_offset, &error_type); 2317 &error_offset, &error_type);
2270 if (treesit_query == NULL) 2318 if (treesit_query == NULL)
2271 xsignal (Qtreesit_query_error, 2319 xsignal (Qtreesit_query_error,
2272 treesit_compose_query_signal_data (error_offset, error_type)); 2320 treesit_compose_query_signal_data (error_offset,
2321 error_type));
2273 cursor = ts_query_cursor_new (); 2322 cursor = ts_query_cursor_new ();
2274 needs_to_free_query_and_cursor = true; 2323 needs_to_free_query_and_cursor = true;
2275 } 2324 }
@@ -2321,9 +2370,9 @@ the query. */)
2321 Lisp_Object cap; 2370 Lisp_Object cap;
2322 if (NILP (node_only)) 2371 if (NILP (node_only))
2323 { 2372 {
2324 const char *capture_name = 2373 const char *capture_name
2325 ts_query_capture_name_for_id (treesit_query, capture.index, 2374 = ts_query_capture_name_for_id (treesit_query, capture.index,
2326 &capture_name_len); 2375 &capture_name_len);
2327 cap = Fcons (intern_c_string_1 (capture_name, capture_name_len), 2376 cap = Fcons (intern_c_string_1 (capture_name, capture_name_len),
2328 captured_node); 2377 captured_node);
2329 } 2378 }
@@ -2333,16 +2382,15 @@ the query. */)
2333 result = Fcons (cap, result); 2382 result = Fcons (cap, result);
2334 } 2383 }
2335 /* Get predicates. */ 2384 /* Get predicates. */
2336 Lisp_Object predicates = 2385 Lisp_Object predicates
2337 treesit_predicates_for_pattern (treesit_query, match.pattern_index); 2386 = treesit_predicates_for_pattern (treesit_query,
2387 match.pattern_index);
2338 2388
2339 /* captures_lisp = Fnreverse (captures_lisp); */ 2389 /* captures_lisp = Fnreverse (captures_lisp); */
2340 struct capture_range captures_range = { result, prev_result }; 2390 struct capture_range captures_range = { result, prev_result };
2341 if (!treesit_eval_predicates (captures_range, predicates)) 2391 if (!treesit_eval_predicates (captures_range, predicates))
2342 { 2392 /* Predicates didn't pass, roll back. */
2343 /* Predicates didn't pass, roll back. */ 2393 result = prev_result;
2344 result = prev_result;
2345 }
2346 } 2394 }
2347 if (needs_to_free_query_and_cursor) 2395 if (needs_to_free_query_and_cursor)
2348 { 2396 {
@@ -2355,8 +2403,7 @@ the query. */)
2355/*** Navigation */ 2403/*** Navigation */
2356 2404
2357/* Return the next/previous named/unnamed sibling of NODE. FORWARD 2405/* Return the next/previous named/unnamed sibling of NODE. FORWARD
2358 controls the direction and NAMED controls the nameness. 2406 controls the direction and NAMED controls the nameness. */
2359 */
2360static TSNode 2407static TSNode
2361treesit_traverse_sibling_helper (TSNode node, bool forward, bool named) 2408treesit_traverse_sibling_helper (TSNode node, bool forward, bool named)
2362{ 2409{
@@ -2457,13 +2504,15 @@ treesit_search_dfs (TSNode *root, Lisp_Object pred, Lisp_Object parser,
2457 return false; 2504 return false;
2458 else 2505 else
2459 { 2506 {
2460 int count = 2507 int count = (named
2461 named ? ts_node_named_child_count (node) : ts_node_child_count (node); 2508 ? ts_node_named_child_count (node)
2509 : ts_node_child_count (node));
2462 for (int offset = 0; offset < count; offset++) 2510 for (int offset = 0; offset < count; offset++)
2463 { 2511 {
2464 uint32_t idx = forward ? offset : count - offset - 1; 2512 uint32_t idx = forward ? offset : count - offset - 1;
2465 TSNode child = 2513 TSNode child = (named
2466 named ? ts_node_named_child (node, idx) : ts_node_child (node, idx); 2514 ? ts_node_named_child (node, idx)
2515 : ts_node_child (node, idx));
2467 2516
2468 if (!ts_node_is_null (child) 2517 if (!ts_node_is_null (child)
2469 && treesit_search_dfs (&child, pred, parser, named, 2518 && treesit_search_dfs (&child, pred, parser, named,
@@ -2661,11 +2710,9 @@ treesit_build_sparse_tree (TSTreeCursor *cursor, Lisp_Object parent,
2661 } 2710 }
2662 /* Before we go, reverse children in the sparse tree. */ 2711 /* Before we go, reverse children in the sparse tree. */
2663 if (match) 2712 if (match)
2664 { 2713 /* When match == true, "parent" is actually the node we added in
2665 /* When match == true, "parent" is actually the node we added in 2714 this layer (parent = this). */
2666 this layer (parent = this). */ 2715 Fsetcdr (parent, Fnreverse (Fcdr (parent)));
2667 Fsetcdr (parent, Fnreverse (Fcdr (parent)));
2668 }
2669} 2716}
2670 2717
2671DEFUN ("treesit-induce-sparse-tree", 2718DEFUN ("treesit-induce-sparse-tree",
@@ -2789,6 +2836,7 @@ syms_of_treesit (void)
2789 DEFSYM (Quser_emacs_directory, 2836 DEFSYM (Quser_emacs_directory,
2790 "user-emacs-directory"); 2837 "user-emacs-directory");
2791 DEFSYM (Qtreesit_parser_deleted, "treesit-parser-deleted"); 2838 DEFSYM (Qtreesit_parser_deleted, "treesit-parser-deleted");
2839 DEFSYM (Qtreesit_pattern_expand, "treesit-pattern-expand");
2792 2840
2793 DEFSYM (Qor, "or"); 2841 DEFSYM (Qor, "or");
2794 2842
@@ -2893,6 +2941,6 @@ then in the system default locations for dynamic libraries, in that order. */);
2893 defsubr (&Streesit_search_subtree); 2941 defsubr (&Streesit_search_subtree);
2894 defsubr (&Streesit_search_forward); 2942 defsubr (&Streesit_search_forward);
2895 defsubr (&Streesit_induce_sparse_tree); 2943 defsubr (&Streesit_induce_sparse_tree);
2896#endif /* HAVE_TREE_SITTER */ 2944#endif /* HAVE_TREE_SITTER */
2897 defsubr (&Streesit_available_p); 2945 defsubr (&Streesit_available_p);
2898} 2946}
diff --git a/src/treesit.h b/src/treesit.h
index bb8ca20e196..7e1425fc9e1 100644
--- a/src/treesit.h
+++ b/src/treesit.h
@@ -169,16 +169,10 @@ CHECK_TS_COMPILED_QUERY (Lisp_Object query)
169 Qtreesit_compiled_query_p, query); 169 Qtreesit_compiled_query_p, query);
170} 170}
171 171
172void 172extern void treesit_record_change (ptrdiff_t, ptrdiff_t, ptrdiff_t);
173treesit_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte, 173extern Lisp_Object make_treesit_parser (Lisp_Object, TSParser *, TSTree *,
174 ptrdiff_t new_end_byte); 174 Lisp_Object);
175 175extern Lisp_Object make_treesit_node (Lisp_Object, TSNode);
176Lisp_Object
177make_treesit_parser (Lisp_Object buffer, TSParser *parser,
178 TSTree *tree, Lisp_Object language_symbol);
179
180Lisp_Object
181make_treesit_node (Lisp_Object parser, TSNode node);
182 176
183bool treesit_node_uptodate_p (Lisp_Object obj); 177bool treesit_node_uptodate_p (Lisp_Object obj);
184 178