diff options
| author | Po Lu | 2022-10-27 21:30:23 +0800 |
|---|---|---|
| committer | Po Lu | 2022-11-03 19:13:33 +0800 |
| commit | bd8e19e1e2ccfb76c1fccc4dff1f8774185cfea4 (patch) | |
| tree | 0756173e0f224e81d80529be57acf8cf8e168046 | |
| parent | 88d54756d46101b97b7fde97b4bc3b62f7bd6c06 (diff) | |
| download | emacs-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.c | 386 | ||||
| -rw-r--r-- | src/treesit.h | 14 |
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 | |||
| 449 | treesit_find_override_name (Lisp_Object language_symbol, Lisp_Object *name, | 453 | treesit_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 | |||
| 475 | treesit_load_language_push_for_each_suffix (Lisp_Object lib_base_name, | 486 | treesit_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 | ||
| 590 | DEFUN ("treesit-language-available-p", | 608 | DEFUN ("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 |
| 671 | function 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 |
| 672 | should be very fast.) */ | 689 | should be very fast. */ |
| 673 | void | 690 | void |
| 674 | treesit_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte, | 691 | treesit_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 |
| 829 | to, we call this function to parse and update the tree. */ | 845 | to, we call this function to parse and update the tree. */ |
| 830 | static void | 846 | static void |
| 831 | treesit_ensure_parsed (Lisp_Object parser) | 847 | treesit_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. */ | ||
| 919 | Lisp_Object | 936 | Lisp_Object |
| 920 | make_treesit_parser (Lisp_Object buffer, TSParser *parser, | 937 | make_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, | |||
| 942 | Lisp_Object | 961 | Lisp_Object |
| 943 | make_treesit_node (Lisp_Object parser, TSNode node) | 962 | make_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 | |||
| 956 | make_treesit_query (Lisp_Object query, Lisp_Object language) | 977 | make_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 | ||
| 1299 | DEFUN ("treesit-parser-set-included-ranges", | 1333 | DEFUN ("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 | |||
| 1942 | See Info node `(elisp)Pattern Matching' for detailed explanation. */) | 1979 | See 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 | |||
| 1967 | treesit_predicates_for_pattern (TSQuery *query, uint32_t pattern_index) | 2004 | treesit_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 | */ | ||
| 2360 | static TSNode | 2407 | static TSNode |
| 2361 | treesit_traverse_sibling_helper (TSNode node, bool forward, bool named) | 2408 | treesit_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 | ||
| 2671 | DEFUN ("treesit-induce-sparse-tree", | 2718 | DEFUN ("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 | ||
| 172 | void | 172 | extern void treesit_record_change (ptrdiff_t, ptrdiff_t, ptrdiff_t); |
| 173 | treesit_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte, | 173 | extern Lisp_Object make_treesit_parser (Lisp_Object, TSParser *, TSTree *, |
| 174 | ptrdiff_t new_end_byte); | 174 | Lisp_Object); |
| 175 | 175 | extern Lisp_Object make_treesit_node (Lisp_Object, TSNode); | |
| 176 | Lisp_Object | ||
| 177 | make_treesit_parser (Lisp_Object buffer, TSParser *parser, | ||
| 178 | TSTree *tree, Lisp_Object language_symbol); | ||
| 179 | |||
| 180 | Lisp_Object | ||
| 181 | make_treesit_node (Lisp_Object parser, TSNode node); | ||
| 182 | 176 | ||
| 183 | bool treesit_node_uptodate_p (Lisp_Object obj); | 177 | bool treesit_node_uptodate_p (Lisp_Object obj); |
| 184 | 178 | ||