]> git.eshelyaron.com Git - emacs.git/commitdiff
Add treesit-query-first-valid
authorYuan Fu <casouri@gmail.com>
Wed, 15 Jan 2025 07:32:48 +0000 (23:32 -0800)
committerEshel Yaron <me@eshelyaron.com>
Sat, 18 Jan 2025 22:01:38 +0000 (23:01 +0100)
This should help major modes to support grammar versions.

* doc/lispref/parsing.texi (Pattern Matching): Mention new function.
* lisp/treesit.el (treesit-query-first-valid): New function.
(treesit-query-valid-p): New function.

(cherry picked from commit 814b45775ffcfa91c03fb54b78611eb97973c387)

doc/lispref/parsing.texi
lisp/treesit.el

index ba7fbca2de968e2e37ebd3b2fd4534aace94e5a9..f69dbfece6a77c33ad83b6c48ed280bfc570f70a 100644 (file)
@@ -1539,22 +1539,35 @@ the specific error.  You can use @code{treesit-query-validate} to
 validate and debug the query.
 @end defun
 
-@defun treesit-query-language query
-This function returns the language of @var{query}.
-@end defun
+@findex treesit-query-language
+@findex treesit-query-expand
+@findex treesit-pattern-expand
+@findex treesit-query-valid-p
+There are some additional functions for queries:
+@code{treesit-query-language} returns the language of a query;
+@code{treesit-query-valid-p} checks whether a query is valid;
+@code{treesit-query-expand} converts a s-expression query into the
+string format; and @code{treesit-pattern-expand} converts a pattern.
+
+@findex treesit-query-first-valid
+Tree-sitter grammars change overtime. To support multiple possible
+versions of a grammar, a Lisp program can use
+@code{treesit-query-first-valid} to pick the right query to use.  For
+example, if a grammar has a @code{(defun)} node in one version, and
+later renamed it to @code{(function_definition)}, a Lisp program can use
 
-@defun treesit-query-expand query
-This function converts the s-expression @var{query} into the string
-format.
-@end defun
+@example
+@group
+(treesit-query-first-valid 'lang
+  '((defun) @defun)
+  '((function_definition) @defun))
+@end group
+@end example
 
-@defun treesit-pattern-expand pattern
-This function converts the s-expression @var{pattern} into the string
-format.
-@end defun
+to support both versions of the grammar.
 
-For more details, read the tree-sitter project's documentation about
-pattern-matching, which can be found at
+For more details, consider reading the tree-sitter project's
+documentation about pattern-matching. The documentation can be found at
 @uref{https://tree-sitter.github.io/tree-sitter/using-parsers#pattern-matching-with-queries}.
 
 @node User-defined Things
index 6c0f119dc5d81236f23f41c7133e7116a3d02fff..ff5fa6317ffe6d84cd46d8659ce26a69bdb7262f 100644 (file)
@@ -505,6 +505,23 @@ that starts with an underscore are ignored."
              collect (cons (+ (treesit-node-start node) offset-left)
                            (+ (treesit-node-end node) offset-right)))))
 
+(defun treesit-query-valid-p (language query)
+  "Return non-nil if QUERY is valid in LANGUAGE, nil otherwise."
+  (ignore-errors
+    (treesit-query-compile language query t)
+    t))
+
+(defun treesit-query-first-valid (language &rest queries)
+  "Return the first query in QUERIES that is valid in LANGUAGE.
+If none are valid, return nil."
+  (declare (indent 1))
+  (let (query)
+    (catch 'valid
+      (while (setq query (pop queries))
+        (ignore-errors
+          (treesit-query-compile language query t)
+          (throw 'valid query))))))
+
 ;;; Range API supplement
 
 (defvar-local treesit-range-settings nil
@@ -4627,6 +4644,8 @@ If anything goes wrong, this function signals an `treesit-error'."
   (treesit-query-language
    :no-eval (treesit-query-language compiled-query)
    :eg-result c)
+  (treesit-query-valid-p)
+  (treesit-query-first-valid)
   (treesit-query-expand
    :eval (treesit-query-expand '((identifier) @id "return" @ret)))
   (treesit-pattern-expand