aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYuan Fu2025-11-02 16:16:50 -0800
committerYuan Fu2025-11-02 17:11:55 -0800
commitb01435306a36e4e75671fbe7bacea351f89947d5 (patch)
tree702393061f1a049f87c892637365a0582170b136 /src
parent68290e1a03ba4f264eab5d25960cf907b0c903fe (diff)
downloademacs-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.c92
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;
490static Lisp_Object Vtreesit_str_question_mark; 490static Lisp_Object Vtreesit_str_question_mark;
491static Lisp_Object Vtreesit_str_star; 491static Lisp_Object Vtreesit_str_star;
492static Lisp_Object Vtreesit_str_plus; 492static Lisp_Object Vtreesit_str_plus;
493static Lisp_Object Vtreesit_str_pound_equal; 493static Lisp_Object Vtreesit_str_pound_eq_question_mark;
494static Lisp_Object Vtreesit_str_pound_match; 494static Lisp_Object Vtreesit_str_pound_match_question_mark;
495static Lisp_Object Vtreesit_str_pound_pred; 495static Lisp_Object Vtreesit_str_pound_pred_question_mark;
496static Lisp_Object Vtreesit_str_open_bracket; 496static Lisp_Object Vtreesit_str_open_bracket;
497static Lisp_Object Vtreesit_str_close_bracket; 497static Lisp_Object Vtreesit_str_close_bracket;
498static Lisp_Object Vtreesit_str_open_paren; 498static Lisp_Object Vtreesit_str_open_paren;
499static Lisp_Object Vtreesit_str_close_paren; 499static Lisp_Object Vtreesit_str_close_paren;
500static Lisp_Object Vtreesit_str_space; 500static Lisp_Object Vtreesit_str_space;
501static Lisp_Object Vtreesit_str_equal; 501static Lisp_Object Vtreesit_str_eq_question_mark;
502static Lisp_Object Vtreesit_str_match; 502static Lisp_Object Vtreesit_str_match_question_mark;
503static Lisp_Object Vtreesit_str_pred; 503static Lisp_Object Vtreesit_str_pred_question_mark;
504static Lisp_Object Vtreesit_str_empty; 504static 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