diff options
| author | Yuan Fu | 2025-11-02 16:16:50 -0800 |
|---|---|---|
| committer | Yuan Fu | 2025-11-02 17:11:55 -0800 |
| commit | b01435306a36e4e75671fbe7bacea351f89947d5 (patch) | |
| tree | 702393061f1a049f87c892637365a0582170b136 /src | |
| parent | 68290e1a03ba4f264eab5d25960cf907b0c903fe (diff) | |
| download | emacs-b01435306a36e4e75671fbe7bacea351f89947d5.tar.gz emacs-b01435306a36e4e75671fbe7bacea351f89947d5.zip | |
Change tree-sitter query predicate names (bug#79687)
Latest tree-sitter library throws a syntax error if the
predicate names in a query don't end with question mark. So we
made the following change:
:equal changed to :eq?
:match changed to :match?
:pred changed to :pred?
Old names are transparently converted to new names when
expanding patterns.
:match predicate can now take the regexp and the node in any
order: it'll figure out which is which automatically. This way
it works with current Emacs convention (regexp first), as well
as tree-sitter's match convention (regexp second).
* doc/lispref/parsing.texi (Pattern Matching): Update manuel to
use new predicate names.
* src/treesit.c:
(Ftreesit_pattern_expand):
(Ftreesit_query_expand):
(treesit_predicate_match):
(treesit_eval_predicates):
(syms_of_treesit): Use new predicate names.
* test/src/treesit-tests.el (treesit-query-api): Update test.
Diffstat (limited to 'src')
| -rw-r--r-- | src/treesit.c | 92 |
1 files changed, 48 insertions, 44 deletions
diff --git a/src/treesit.c b/src/treesit.c index 69751b5ea10..3230d0a50a1 100644 --- a/src/treesit.c +++ b/src/treesit.c | |||
| @@ -490,17 +490,17 @@ static Lisp_Object Vtreesit_str_dot; | |||
| 490 | static Lisp_Object Vtreesit_str_question_mark; | 490 | static Lisp_Object Vtreesit_str_question_mark; |
| 491 | static Lisp_Object Vtreesit_str_star; | 491 | static Lisp_Object Vtreesit_str_star; |
| 492 | static Lisp_Object Vtreesit_str_plus; | 492 | static Lisp_Object Vtreesit_str_plus; |
| 493 | static Lisp_Object Vtreesit_str_pound_equal; | 493 | static Lisp_Object Vtreesit_str_pound_eq_question_mark; |
| 494 | static Lisp_Object Vtreesit_str_pound_match; | 494 | static Lisp_Object Vtreesit_str_pound_match_question_mark; |
| 495 | static Lisp_Object Vtreesit_str_pound_pred; | 495 | static Lisp_Object Vtreesit_str_pound_pred_question_mark; |
| 496 | static Lisp_Object Vtreesit_str_open_bracket; | 496 | static Lisp_Object Vtreesit_str_open_bracket; |
| 497 | static Lisp_Object Vtreesit_str_close_bracket; | 497 | static Lisp_Object Vtreesit_str_close_bracket; |
| 498 | static Lisp_Object Vtreesit_str_open_paren; | 498 | static Lisp_Object Vtreesit_str_open_paren; |
| 499 | static Lisp_Object Vtreesit_str_close_paren; | 499 | static Lisp_Object Vtreesit_str_close_paren; |
| 500 | static Lisp_Object Vtreesit_str_space; | 500 | static Lisp_Object Vtreesit_str_space; |
| 501 | static Lisp_Object Vtreesit_str_equal; | 501 | static Lisp_Object Vtreesit_str_eq_question_mark; |
| 502 | static Lisp_Object Vtreesit_str_match; | 502 | static Lisp_Object Vtreesit_str_match_question_mark; |
| 503 | static Lisp_Object Vtreesit_str_pred; | 503 | static Lisp_Object Vtreesit_str_pred_question_mark; |
| 504 | static Lisp_Object Vtreesit_str_empty; | 504 | static Lisp_Object Vtreesit_str_empty; |
| 505 | 505 | ||
| 506 | /* This is the limit on recursion levels for some tree-sitter | 506 | /* This is the limit on recursion levels for some tree-sitter |
| @@ -3471,12 +3471,12 @@ See Info node `(elisp)Pattern Matching' for detailed explanation. */) | |||
| 3471 | return Vtreesit_str_star; | 3471 | return Vtreesit_str_star; |
| 3472 | if (BASE_EQ (pattern, QCplus)) | 3472 | if (BASE_EQ (pattern, QCplus)) |
| 3473 | return Vtreesit_str_plus; | 3473 | return Vtreesit_str_plus; |
| 3474 | if (BASE_EQ (pattern, QCequal)) | 3474 | if (BASE_EQ (pattern, QCequal) || BASE_EQ (pattern, QCeq_q)) |
| 3475 | return Vtreesit_str_pound_equal; | 3475 | return Vtreesit_str_pound_eq_question_mark; |
| 3476 | if (BASE_EQ (pattern, QCmatch)) | 3476 | if (BASE_EQ (pattern, QCmatch) || BASE_EQ (pattern, QCmatch_q)) |
| 3477 | return Vtreesit_str_pound_match; | 3477 | return Vtreesit_str_pound_match_question_mark; |
| 3478 | if (BASE_EQ (pattern, QCpred)) | 3478 | if (BASE_EQ (pattern, QCpred) || BASE_EQ (pattern, QCpred_q)) |
| 3479 | return Vtreesit_str_pound_pred; | 3479 | return Vtreesit_str_pound_pred_question_mark; |
| 3480 | Lisp_Object opening_delimeter | 3480 | Lisp_Object opening_delimeter |
| 3481 | = VECTORP (pattern) | 3481 | = VECTORP (pattern) |
| 3482 | ? Vtreesit_str_open_bracket : Vtreesit_str_open_paren; | 3482 | ? Vtreesit_str_open_bracket : Vtreesit_str_open_paren; |
| @@ -3507,7 +3507,9 @@ A PATTERN in QUERY can be | |||
| 3507 | :* | 3507 | :* |
| 3508 | :+ | 3508 | :+ |
| 3509 | :equal | 3509 | :equal |
| 3510 | :eq? | ||
| 3510 | :match | 3511 | :match |
| 3512 | :match? | ||
| 3511 | (TYPE PATTERN...) | 3513 | (TYPE PATTERN...) |
| 3512 | [PATTERN...] | 3514 | [PATTERN...] |
| 3513 | FIELD-NAME: | 3515 | FIELD-NAME: |
| @@ -3670,7 +3672,7 @@ treesit_predicate_equal (Lisp_Object args, struct capture_range captures, | |||
| 3670 | return !NILP (Fstring_equal (text1, text2)); | 3672 | return !NILP (Fstring_equal (text1, text2)); |
| 3671 | } | 3673 | } |
| 3672 | 3674 | ||
| 3673 | /* Handles predicate (#match "regexp" @node). Return true if "regexp" | 3675 | /* Handles predicate (#match? "regexp" @node). Return true if "regexp" |
| 3674 | matches the text spanned by @node; return false otherwise. | 3676 | matches the text spanned by @node; return false otherwise. |
| 3675 | Matching is case-sensitive. If everything goes fine, don't touch | 3677 | Matching is case-sensitive. If everything goes fine, don't touch |
| 3676 | SIGNAL_DATA; if error occurs, set it to a suitable signal data. */ | 3678 | SIGNAL_DATA; if error occurs, set it to a suitable signal data. */ |
| @@ -3680,26 +3682,25 @@ treesit_predicate_match (Lisp_Object args, struct capture_range captures, | |||
| 3680 | { | 3682 | { |
| 3681 | if (list_length (args) != 2) | 3683 | if (list_length (args) != 2) |
| 3682 | { | 3684 | { |
| 3683 | *signal_data = list2 (build_string ("Predicate `match' requires two " | 3685 | *signal_data = list2 (build_string ("Predicate `match?' requires two " |
| 3684 | "arguments but got"), | 3686 | "arguments but got"), |
| 3685 | Flength (args)); | 3687 | Flength (args)); |
| 3686 | return false; | 3688 | return false; |
| 3687 | } | 3689 | } |
| 3688 | Lisp_Object regexp = XCAR (args); | 3690 | Lisp_Object arg1 = XCAR (args); |
| 3689 | Lisp_Object capture_name = XCAR (XCDR (args)); | 3691 | Lisp_Object arg2 = XCAR (XCDR (args)); |
| 3690 | 3692 | Lisp_Object regexp = SYMBOLP (arg2) ? arg1 : arg2; | |
| 3691 | /* It's probably common to get the argument order backwards. Catch | 3693 | Lisp_Object capture_name = SYMBOLP (arg2) ? arg2 : arg1; |
| 3692 | this mistake early and show helpful explanation, because Emacs | 3694 | |
| 3693 | loves you. (We put the regexp first because that's what | 3695 | if (!STRINGP (regexp) || !SYMBOLP (capture_name)) |
| 3694 | string-match does.) */ | 3696 | { |
| 3695 | if (!STRINGP (regexp)) | 3697 | *signal_data = list2 (build_string ("Predicate `match?' takes a regexp " |
| 3696 | xsignal1 (Qtreesit_query_error, | 3698 | "and a node capture (order doesn't " |
| 3697 | build_string ("The first argument to `match' should " | 3699 | "matter), but got"), |
| 3698 | "be a regexp string, not a capture name")); | 3700 | Flength (args)); |
| 3699 | if (!SYMBOLP (capture_name)) | 3701 | return false; |
| 3700 | xsignal1 (Qtreesit_query_error, | 3702 | } |
| 3701 | build_string ("The second argument to `match' should " | 3703 | |
| 3702 | "be a capture name, not a string")); | ||
| 3703 | 3704 | ||
| 3704 | Lisp_Object node = Qnil; | 3705 | Lisp_Object node = Qnil; |
| 3705 | if (!treesit_predicate_capture_name_to_node (capture_name, captures, &node, | 3706 | if (!treesit_predicate_capture_name_to_node (capture_name, captures, &node, |
| @@ -3783,11 +3784,11 @@ treesit_eval_predicates (struct capture_range captures, Lisp_Object predicates, | |||
| 3783 | Lisp_Object predicate = XCAR (tail); | 3784 | Lisp_Object predicate = XCAR (tail); |
| 3784 | Lisp_Object fn = XCAR (predicate); | 3785 | Lisp_Object fn = XCAR (predicate); |
| 3785 | Lisp_Object args = XCDR (predicate); | 3786 | Lisp_Object args = XCDR (predicate); |
| 3786 | if (!NILP (Fstring_equal (fn, Vtreesit_str_equal))) | 3787 | if (!NILP (Fstring_equal (fn, Vtreesit_str_eq_question_mark))) |
| 3787 | pass &= treesit_predicate_equal (args, captures, signal_data); | 3788 | pass &= treesit_predicate_equal (args, captures, signal_data); |
| 3788 | else if (!NILP (Fstring_equal (fn, Vtreesit_str_match))) | 3789 | else if (!NILP (Fstring_equal (fn, Vtreesit_str_match_question_mark))) |
| 3789 | pass &= treesit_predicate_match (args, captures, signal_data); | 3790 | pass &= treesit_predicate_match (args, captures, signal_data); |
| 3790 | else if (!NILP (Fstring_equal (fn, Vtreesit_str_pred))) | 3791 | else if (!NILP (Fstring_equal (fn, Vtreesit_str_pred_question_mark))) |
| 3791 | pass &= treesit_predicate_pred (args, captures, signal_data); | 3792 | pass &= treesit_predicate_pred (args, captures, signal_data); |
| 3792 | else | 3793 | else |
| 3793 | { | 3794 | { |
| @@ -5175,8 +5176,11 @@ syms_of_treesit (void) | |||
| 5175 | DEFSYM (QCstar, ":*"); | 5176 | DEFSYM (QCstar, ":*"); |
| 5176 | DEFSYM (QCplus, ":+"); | 5177 | DEFSYM (QCplus, ":+"); |
| 5177 | DEFSYM (QCequal, ":equal"); | 5178 | DEFSYM (QCequal, ":equal"); |
| 5179 | DEFSYM (QCeq_q, ":eq?"); | ||
| 5178 | DEFSYM (QCmatch, ":match"); | 5180 | DEFSYM (QCmatch, ":match"); |
| 5181 | DEFSYM (QCmatch_q, ":match?"); | ||
| 5179 | DEFSYM (QCpred, ":pred"); | 5182 | DEFSYM (QCpred, ":pred"); |
| 5183 | DEFSYM (QCpred_q, ":pred?"); | ||
| 5180 | DEFSYM (QCline, ":line"); | 5184 | DEFSYM (QCline, ":line"); |
| 5181 | DEFSYM (QCcol, ":col"); | 5185 | DEFSYM (QCcol, ":col"); |
| 5182 | DEFSYM (QCpos, ":pos"); | 5186 | DEFSYM (QCpos, ":pos"); |
| @@ -5357,12 +5361,12 @@ depending on customization of `treesit-enabled-modes'. */); | |||
| 5357 | Vtreesit_str_star = build_string ("*"); | 5361 | Vtreesit_str_star = build_string ("*"); |
| 5358 | staticpro (&Vtreesit_str_plus); | 5362 | staticpro (&Vtreesit_str_plus); |
| 5359 | Vtreesit_str_plus = build_string ("+"); | 5363 | Vtreesit_str_plus = build_string ("+"); |
| 5360 | staticpro (&Vtreesit_str_pound_equal); | 5364 | staticpro (&Vtreesit_str_pound_eq_question_mark); |
| 5361 | Vtreesit_str_pound_equal = build_string ("#equal"); | 5365 | Vtreesit_str_pound_eq_question_mark = build_string ("#eq?"); |
| 5362 | staticpro (&Vtreesit_str_pound_match); | 5366 | staticpro (&Vtreesit_str_pound_match_question_mark); |
| 5363 | Vtreesit_str_pound_match = build_string ("#match"); | 5367 | Vtreesit_str_pound_match_question_mark = build_string ("#match?"); |
| 5364 | staticpro (&Vtreesit_str_pound_pred); | 5368 | staticpro (&Vtreesit_str_pound_pred_question_mark); |
| 5365 | Vtreesit_str_pound_pred = build_string ("#pred"); | 5369 | Vtreesit_str_pound_pred_question_mark = build_string ("#pred?"); |
| 5366 | staticpro (&Vtreesit_str_open_bracket); | 5370 | staticpro (&Vtreesit_str_open_bracket); |
| 5367 | Vtreesit_str_open_bracket = build_string ("["); | 5371 | Vtreesit_str_open_bracket = build_string ("["); |
| 5368 | staticpro (&Vtreesit_str_close_bracket); | 5372 | staticpro (&Vtreesit_str_close_bracket); |
| @@ -5373,12 +5377,12 @@ depending on customization of `treesit-enabled-modes'. */); | |||
| 5373 | Vtreesit_str_close_paren = build_string (")"); | 5377 | Vtreesit_str_close_paren = build_string (")"); |
| 5374 | staticpro (&Vtreesit_str_space); | 5378 | staticpro (&Vtreesit_str_space); |
| 5375 | Vtreesit_str_space = build_string (" "); | 5379 | Vtreesit_str_space = build_string (" "); |
| 5376 | staticpro (&Vtreesit_str_equal); | 5380 | staticpro (&Vtreesit_str_eq_question_mark); |
| 5377 | Vtreesit_str_equal = build_string ("equal"); | 5381 | Vtreesit_str_eq_question_mark = build_string ("eq?"); |
| 5378 | staticpro (&Vtreesit_str_match); | 5382 | staticpro (&Vtreesit_str_match_question_mark); |
| 5379 | Vtreesit_str_match = build_string ("match"); | 5383 | Vtreesit_str_match_question_mark = build_string ("match?"); |
| 5380 | staticpro (&Vtreesit_str_pred); | 5384 | staticpro (&Vtreesit_str_pred_question_mark); |
| 5381 | Vtreesit_str_pred = build_string ("pred"); | 5385 | Vtreesit_str_pred_question_mark = build_string ("pred?"); |
| 5382 | staticpro (&Vtreesit_str_empty); | 5386 | staticpro (&Vtreesit_str_empty); |
| 5383 | Vtreesit_str_empty = build_string (""); | 5387 | Vtreesit_str_empty = build_string (""); |
| 5384 | 5388 | ||