summaryrefslogtreecommitdiff
path: root/src/treesit.c
diff options
context:
space:
mode:
authorStefan Kangas <stefankangas@gmail.com>2022-12-28 21:40:59 +0100
committerStefan Kangas <stefankangas@gmail.com>2022-12-28 21:40:59 +0100
commitdce6791e9934d029ffae45793a5d05096346be0c (patch)
tree387d999b6d6af1d72dfc3416e49d445329139ed9 /src/treesit.c
parent7e98b8a0fa67f51784024fac3199d774dfa77192 (diff)
parentdb96b1282f90ee40560f81e8b715fe785badbb6e (diff)
downloademacs-dce6791e9934d029ffae45793a5d05096346be0c.tar.gz
emacs-dce6791e9934d029ffae45793a5d05096346be0c.tar.bz2
emacs-dce6791e9934d029ffae45793a5d05096346be0c.zip
Merge from origin/emacs-29
db96b1282f9 * lisp/help.el: Use 'C-h C-q' to toggle 'help-quick' wind... 489865c21e4 ; Improve markup of long key sequences d42c2668cf3 ; * etc/NEWS: Fix wording of a recently edited entry. 7a0eaee1980 * lisp/isearch.el: Small fixes. b69bffeec05 * lisp/vc/diff-mode.el (diff-minor-mode-prefix): Replace ... 9263847ab76 ; * etc/NEWS: Move the paragraph with 'C-u RET' closer to... 62fb2dc37da * doc/emacs/display.texi (Text Scale): Improve section ab... 70480d3b6b7 * lisp/repeat.el (repeat-echo-function): Suggest 'add-fun... fd48201ffe7 * lisp/tab-line.el (tab-line-cache-key-default): More cac... b1646602602 * etc/package-keyring.gpg: Update with new key c0be51389eb ; Yet another declare-function to avoid treesit-related w... 8676bec51de ; * lisp/treesit.el (treesit--simple-imenu-1): Doc fix; w... 2ddc480f441 Warn of absent networks module in ERC 19d00fab9aa Avoid "already compiled" warning in erc-compat 2d8f7b66bcc ; Fix one more treesit byte-compilation warning. 2d0a9214863 ; Avoid treesit-related byte-compiler warnings 8503b370be1 (python--treesit-settings): Remove duplicate matcher b464e6c490b Make last change of w32 GUI dialogs conditional and rever... eedc9d79aed Fix tree-sitter typos 248c13dcfe1 Update tree-sitter major modes to use the new Imenu facility b39dc7ab27a Add tree-sitter helper functions for Imenu ba1ddea9dab Fix treesit--things-around (bug#60355) 7512b9025a1 ; * lisp/treesit.el (treesit-traverse-parent): Remove alias. 5326b041982 Improve treesit-node-top-level and treesit-parent-until 637f5b164f2 ; Add "src" to the heuristic sub-directory heuristic 8ab6df0c9fd ; * lisp/epa-ks.el (epa-ks-do-key-to-fetch): Fix 'when' u... 2b55a48d3e3 * src/w32menu.c (simple_dialog_show): Use MB_YESNOCANCEL ... 8b8b7915679 ; Improve documentation of TAB/SPC indentation 624e3822110 ; Improve doc strings of some new faces 41f12e1019b ; * lisp/elide-head.el (elide-head): Doc fix to silence c... e3b4cd0ac1d ; * lisp/htmlfontify.el (hfy-text-p): Fix whitespace. 1b4dc4691c1 Fix htmlfontify.el command injection vulnerability. 1fe4b98b4d5 Improve support for Scheme R6RS and R7RS libraries (bug#5... 2347f37f677 ; * test/src/treesit-tests.el: remove dead store (bytecom... a6d961ae2fd Add a new tree-sitter query predicate 'pred' 835a80dcc48 ; Fix tree-sitter defun tests a14821d6151 Improve gnutls-min-prime-bits docstring b14bbd108e4 Improve handling of tab-bar height. 669160d47b2 ; * nt/INSTALL.W64: More fixes and updates. 26b2ec7cb8c Simplify last change (bug#60311) 082fc6e3088 Fix 'json-available-p' on MS-Windows 6c86faec29e loaddefs-gen: Group results by absolute file name d90d7d15f2f ; Fix vindexes in parsing.texi eb268728376 Fix imenu for c-ts-mode (bug#60296) 8f68b6497ee Clean up python-ts-mode font-lock features 28f26b11a1e Add comment indent and filling to other tree-sitter major... c6b02826450 ; Remove unused function in c-ts-mode 6e52a9fcadc ; * doc/lispref/modes.texi (Parser-based Font Lock): Mino... 2bcd1e9a99d ; * doc/lispref/parsing.texi (Retrieving Nodes): Add notice. 7c7950fe006 Add maintainer stub for tree-sitter files cf327766226 ; * doc/lispref/parsing.texi (Using Parser): Remove delet... # Conflicts: # etc/NEWS # lisp/progmodes/c-ts-mode.el # lisp/progmodes/typescript-ts-mode.el # lisp/treesit.el
Diffstat (limited to 'src/treesit.c')
-rw-r--r--src/treesit.c59
1 files changed, 47 insertions, 12 deletions
diff --git a/src/treesit.c b/src/treesit.c
index ce8a2804439..813d4222f98 100644
--- a/src/treesit.c
+++ b/src/treesit.c
@@ -2,6 +2,8 @@
Copyright (C) 2021-2022 Free Software Foundation, Inc.
+Maintainer: Yuan Fu <casouri@gmail.com>
+
This file is part of GNU Emacs.
GNU Emacs is free software: you can redistribute it and/or modify
@@ -2168,6 +2170,8 @@ See Info node `(elisp)Pattern Matching' for detailed explanation. */)
return build_pure_c_string ("#equal");
if (EQ (pattern, QCmatch))
return build_pure_c_string ("#match");
+ if (EQ (pattern, QCpred))
+ return build_pure_c_string ("#pred");
Lisp_Object opening_delimeter
= build_pure_c_string (VECTORP (pattern) ? "[" : "(");
Lisp_Object closing_delimiter
@@ -2267,10 +2271,10 @@ treesit_predicates_for_pattern (TSQuery *query, uint32_t pattern_index)
return Fnreverse (result);
}
-/* Translate a capture NAME (symbol) to the text of the captured node.
+/* Translate a capture NAME (symbol) to a node.
Signals treesit-query-error if such node is not captured. */
static Lisp_Object
-treesit_predicate_capture_name_to_text (Lisp_Object name,
+treesit_predicate_capture_name_to_node (Lisp_Object name,
struct capture_range captures)
{
Lisp_Object node = Qnil;
@@ -2290,6 +2294,16 @@ treesit_predicate_capture_name_to_text (Lisp_Object name,
name, build_pure_c_string ("A predicate can only refer"
" to captured nodes in the "
"same pattern"));
+ return node;
+}
+
+/* Translate a capture NAME (symbol) to the text of the captured node.
+ Signals treesit-query-error if such node is not captured. */
+static Lisp_Object
+treesit_predicate_capture_name_to_text (Lisp_Object name,
+ struct capture_range captures)
+{
+ Lisp_Object node = treesit_predicate_capture_name_to_node (name, captures);
struct buffer *old_buffer = current_buffer;
set_buffer_internal (XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer));
@@ -2363,13 +2377,30 @@ treesit_predicate_match (Lisp_Object args, struct capture_range captures)
return false;
}
-/* About predicates: I decide to hard-code predicates in C instead of
- implementing an extensible system where predicates are translated
- to Lisp functions, and new predicates can be added by extending a
- list of functions, because I really couldn't imagine any useful
- predicates besides equal and match. If we later found out that
- such system is indeed useful and necessary, it can be easily
- added. */
+/* Handles predicate (#pred FN ARG...). Return true if FN returns
+ non-nil; return false otherwise. The arity of FN must match the
+ number of ARGs */
+static bool
+treesit_predicate_pred (Lisp_Object args, struct capture_range captures)
+{
+ if (XFIXNUM (Flength (args)) < 2)
+ xsignal2 (Qtreesit_query_error,
+ build_pure_c_string ("Predicate `pred' requires "
+ "at least two arguments, "
+ "but was only given"),
+ Flength (args));
+
+ Lisp_Object fn = Fintern (XCAR (args), Qnil);
+ Lisp_Object nodes = Qnil;
+ Lisp_Object tail = XCDR (args);
+ FOR_EACH_TAIL (tail)
+ nodes = Fcons (treesit_predicate_capture_name_to_node (XCAR (tail),
+ captures),
+ nodes);
+ nodes = Fnreverse (nodes);
+
+ return !NILP (CALLN (Fapply, fn, nodes));
+}
/* If all predicates in PREDICATES passes, return true; otherwise
return false. */
@@ -2385,14 +2416,17 @@ treesit_eval_predicates (struct capture_range captures, Lisp_Object predicates)
Lisp_Object fn = XCAR (predicate);
Lisp_Object args = XCDR (predicate);
if (!NILP (Fstring_equal (fn, build_pure_c_string ("equal"))))
- pass = treesit_predicate_equal (args, captures);
+ pass &= treesit_predicate_equal (args, captures);
else if (!NILP (Fstring_equal (fn, build_pure_c_string ("match"))))
- pass = treesit_predicate_match (args, captures);
+ pass &= treesit_predicate_match (args, captures);
+ else if (!NILP (Fstring_equal (fn, build_pure_c_string ("pred"))))
+ pass &= treesit_predicate_pred (args, captures);
else
xsignal3 (Qtreesit_query_error,
build_pure_c_string ("Invalid predicate"),
fn, build_pure_c_string ("Currently Emacs only supports"
- " equal and match predicate"));
+ " equal, match, and pred"
+ " predicate"));
}
/* If all predicates passed, add captures to result list. */
return pass;
@@ -3215,6 +3249,7 @@ syms_of_treesit (void)
DEFSYM (QCanchor, ":anchor");
DEFSYM (QCequal, ":equal");
DEFSYM (QCmatch, ":match");
+ DEFSYM (QCpred, ":pred");
DEFSYM (Qnot_found, "not-found");
DEFSYM (Qsymbol_error, "symbol-error");