Package: emacs Version: 1:30.2+1-6 Severity: important The tree-sitter patch included in 1:30.2+1-4 fixed building, but the tree-sitter query supported in Emacs 30.2 is incompatible with tree-sitter 0.26+. More details in [1].
I have backported the suggested patch from upstream[2], and adapted to the Debian version. Tested in a docker image that the syntax high-lighting is working now (tried source code in C, C++, Python, and Java). Please find in the attachment. (Note: I'm using important severity to avoid blocking Emacs migration, which may further delay the tree-sitter transition. Please feel free to adjust.) [1] https://github.com/doomemacs/core/issues/8746#issuecomment-4233133006 [2] https://gitlab.archlinux.org/archlinux/packaging/packages/emacs/-/blob/30.2-3/02_all_ts-query-pred.patch?ref_type=tags -- System Information: Debian Release: forky/sid APT prefers unstable APT policy: (500, 'unstable'), (500, 'testing'), (200, 'experimental') Architecture: amd64 (x86_64) Kernel: Linux 7.0.13+deb14-amd64 (SMP w/2 CPU threads; PREEMPT) Locale: LANG=C.UTF-8, LC_CTYPE=C.UTF-8 (charmap=UTF-8), LANGUAGE not set Shell: /bin/sh linked to /usr/bin/dash Init: systemd (via /run/systemd/system) LSM: AppArmor: enabled Versions of packages emacs depends on: ii emacs-gtk 1:30.2+1-6 emacs recommends no packages. emacs suggests no packages. -- no debconf information -- Regards, Xiyue Deng
From 7c7e3af01d57bdb869d469dc102cb957eaf7b322 Mon Sep 17 00:00:00 2001 From: Yuan Fu <[email protected]> Date: Sun, 2 Nov 2025 16:16:50 -0800 Subject: [PATCH] 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. --- src/treesit.c | 101 +++++++++++++++++++++----------------- test/src/treesit-tests.el | 6 +-- 2 files changed, 58 insertions(+), 49 deletions(-) diff --git a/src/treesit.c b/src/treesit.c index f87f4654209..bf212639078 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -431,17 +431,17 @@ #define ts_tree_root_node fn_ts_tree_root_node static Lisp_Object Vtreesit_str_question_mark; static Lisp_Object Vtreesit_str_star; static Lisp_Object Vtreesit_str_plus; -static Lisp_Object Vtreesit_str_pound_equal; -static Lisp_Object Vtreesit_str_pound_match; -static Lisp_Object Vtreesit_str_pound_pred; +static Lisp_Object Vtreesit_str_pound_eq_question_mark; +static Lisp_Object Vtreesit_str_pound_match_question_mark; +static Lisp_Object Vtreesit_str_pound_pred_question_mark; static Lisp_Object Vtreesit_str_open_bracket; static Lisp_Object Vtreesit_str_close_bracket; static Lisp_Object Vtreesit_str_open_paren; static Lisp_Object Vtreesit_str_close_paren; static Lisp_Object Vtreesit_str_space; -static Lisp_Object Vtreesit_str_equal; -static Lisp_Object Vtreesit_str_match; -static Lisp_Object Vtreesit_str_pred; +static Lisp_Object Vtreesit_str_eq_question_mark; +static Lisp_Object Vtreesit_str_match_question_mark; +static Lisp_Object Vtreesit_str_pred_question_mark; static Lisp_Object Vtreesit_str_empty; /* This is the limit on recursion levels for some tree-sitter @@ -2636,12 +2636,12 @@ DEFUN ("treesit-pattern-expand", return Vtreesit_str_star; if (BASE_EQ (pattern, QCplus)) return Vtreesit_str_plus; - if (BASE_EQ (pattern, QCequal)) - return Vtreesit_str_pound_equal; - if (BASE_EQ (pattern, QCmatch)) - return Vtreesit_str_pound_match; - if (BASE_EQ (pattern, QCpred)) - return Vtreesit_str_pound_pred; + if (BASE_EQ (pattern, QCequal) || BASE_EQ (pattern, QCeq_q)) + return Vtreesit_str_pound_eq_question_mark; + if (BASE_EQ (pattern, QCmatch) || BASE_EQ (pattern, QCmatch_q)) + return Vtreesit_str_pound_match_question_mark; + if (BASE_EQ (pattern, QCpred) || BASE_EQ (pattern, QCpred_q)) + return Vtreesit_str_pound_pred_question_mark; Lisp_Object opening_delimeter = VECTORP (pattern) ? Vtreesit_str_open_bracket : Vtreesit_str_open_paren; @@ -2672,7 +2672,9 @@ DEFUN ("treesit-query-expand", :* :+ :equal + :eq? :match + :match? (TYPE PATTERN...) [PATTERN...] FIELD-NAME: @@ -2835,7 +2837,7 @@ treesit_predicate_equal (Lisp_Object args, struct capture_range captures, return !NILP (Fstring_equal (text1, text2)); } -/* Handles predicate (#match "regexp" @node). Return true if "regexp" +/* Handles predicate (#match? "regexp" @node). Return true if "regexp" matches the text spanned by @node; return false otherwise. Matching is case-sensitive. If everything goes fine, don't touch SIGNAL_DATA; if error occurs, set it to a suitable signal data. */ @@ -2845,26 +2847,25 @@ treesit_predicate_match (Lisp_Object args, struct capture_range captures, { if (list_length (args) != 2) { - *signal_data = list2 (build_string ("Predicate `match' requires two " + *signal_data = list2 (build_string ("Predicate `match?' requires two " "arguments but got"), Flength (args)); return false; } - Lisp_Object regexp = XCAR (args); - Lisp_Object capture_name = XCAR (XCDR (args)); - - /* It's probably common to get the argument order backwards. Catch - this mistake early and show helpful explanation, because Emacs - loves you. (We put the regexp first because that's what - string-match does.) */ - if (!STRINGP (regexp)) - xsignal1 (Qtreesit_query_error, - build_string ("The first argument to `match' should " - "be a regexp string, not a capture name")); - if (!SYMBOLP (capture_name)) - xsignal1 (Qtreesit_query_error, - build_string ("The second argument to `match' should " - "be a capture name, not a string")); + Lisp_Object arg1 = XCAR (args); + Lisp_Object arg2 = XCAR (XCDR (args)); + Lisp_Object regexp = SYMBOLP (arg2) ? arg1 : arg2; + Lisp_Object capture_name = SYMBOLP (arg2) ? arg2 : arg1; + + if (!STRINGP (regexp) || !SYMBOLP (capture_name)) + { + *signal_data = list2 (build_string ("Predicate `match?' takes a regexp " + "and a node capture (order doesn't " + "matter), but got"), + Flength (args)); + return false; + } + Lisp_Object node = Qnil; if (!treesit_predicate_capture_name_to_node (capture_name, captures, &node, @@ -2948,11 +2949,11 @@ treesit_eval_predicates (struct capture_range captures, Lisp_Object predicates, Lisp_Object predicate = XCAR (tail); Lisp_Object fn = XCAR (predicate); Lisp_Object args = XCDR (predicate); - if (!NILP (Fstring_equal (fn, Vtreesit_str_equal))) + if (!NILP (Fstring_equal (fn, Vtreesit_str_eq_question_mark))) pass &= treesit_predicate_equal (args, captures, signal_data); - else if (!NILP (Fstring_equal (fn, Vtreesit_str_match))) + else if (!NILP (Fstring_equal (fn, Vtreesit_str_match_question_mark))) pass &= treesit_predicate_match (args, captures, signal_data); - else if (!NILP (Fstring_equal (fn, Vtreesit_str_pred))) + else if (!NILP (Fstring_equal (fn, Vtreesit_str_pred_question_mark))) pass &= treesit_predicate_pred (args, captures, signal_data); else { @@ -4224,8 +4225,16 @@ syms_of_treesit (void) DEFSYM (QCstar, ":*"); DEFSYM (QCplus, ":+"); DEFSYM (QCequal, ":equal"); + DEFSYM (QCeq_q, ":eq?"); DEFSYM (QCmatch, ":match"); + DEFSYM (QCmatch_q, ":match?"); DEFSYM (QCpred, ":pred"); + DEFSYM (QCpred_q, ":pred?"); + DEFSYM (QCline, ":line"); + DEFSYM (QCcol, ":col"); + DEFSYM (QCpos, ":pos"); + DEFSYM (QCbytepos, ":bytepos"); + DEFSYM (Qnot_found, "not-found"); DEFSYM (Qsymbol_error, "symbol-error"); @@ -4355,13 +4364,13 @@ cons (REGEXP . FN), which is a combination of a regexp and a predicate staticpro (&Vtreesit_str_star); Vtreesit_str_star = build_pure_c_string ("*"); staticpro (&Vtreesit_str_plus); - Vtreesit_str_plus = build_pure_c_string ("+"); - staticpro (&Vtreesit_str_pound_equal); - Vtreesit_str_pound_equal = build_pure_c_string ("#equal"); - staticpro (&Vtreesit_str_pound_match); - Vtreesit_str_pound_match = build_pure_c_string ("#match"); - staticpro (&Vtreesit_str_pound_pred); - Vtreesit_str_pound_pred = build_pure_c_string ("#pred"); + Vtreesit_str_plus = build_string ("+"); + staticpro (&Vtreesit_str_pound_eq_question_mark); + Vtreesit_str_pound_eq_question_mark = build_string ("#eq?"); + staticpro (&Vtreesit_str_pound_match_question_mark); + Vtreesit_str_pound_match_question_mark = build_string ("#match?"); + staticpro (&Vtreesit_str_pound_pred_question_mark); + Vtreesit_str_pound_pred_question_mark = build_string ("#pred?"); staticpro (&Vtreesit_str_open_bracket); Vtreesit_str_open_bracket = build_pure_c_string ("["); staticpro (&Vtreesit_str_close_bracket); @@ -4371,13 +4380,13 @@ cons (REGEXP . FN), which is a combination of a regexp and a predicate staticpro (&Vtreesit_str_close_paren); Vtreesit_str_close_paren = build_pure_c_string (")"); staticpro (&Vtreesit_str_space); - Vtreesit_str_space = build_pure_c_string (" "); - staticpro (&Vtreesit_str_equal); - Vtreesit_str_equal = build_pure_c_string ("equal"); - staticpro (&Vtreesit_str_match); - Vtreesit_str_match = build_pure_c_string ("match"); - staticpro (&Vtreesit_str_pred); - Vtreesit_str_pred = build_pure_c_string ("pred"); + Vtreesit_str_space = build_string (" "); + staticpro (&Vtreesit_str_eq_question_mark); + Vtreesit_str_eq_question_mark = build_string ("eq?"); + staticpro (&Vtreesit_str_match_question_mark); + Vtreesit_str_match_question_mark = build_string ("match?"); + staticpro (&Vtreesit_str_pred_question_mark); + Vtreesit_str_pred_question_mark = build_string ("pred?"); staticpro (&Vtreesit_str_empty); Vtreesit_str_empty = build_pure_c_string (""); diff --git a/test/src/treesit-tests.el b/test/src/treesit-tests.el index 7cbe516fc42..8fa8f098113 100644 --- a/test/src/treesit-tests.el +++ b/test/src/treesit-tests.el @@ -434,10 +434,10 @@ treesit-query-api ;; String query. '("(string) @string (pair key: (_) @keyword) -((_) @bob (#match \"\\\\`B.b\\\\'\" @bob)) +((_) @bob (#match? \"\\\\`B.b\\\\'\" @bob)) (number) @number -((number) @n3 (#equal \"3\" @n3)) -((number) @n3p (#pred treesit--ert-pred-last-sibling @n3p))" +((number) @n3 (#eq? \"3\" @n3)) +((number) @n3p (#pred? treesit--ert-pred-last-sibling @n3p))" ;; Sexp query. ((string) @string (pair key: (_) @keyword) -- 2.53.0
signature.asc
Description: PGP signature

