Generalize tree-sitter-query--eval-query
ymarco opened this issue · comments
I wrote this code. A big part of it (tree-sitter-occur--find-patterns
) is a copy-paste of tree-sitter-query--eval-query
but returning the matches instead of highlighting.
Would you accept a PR modifying tree-sitter-query--eval-query
to return a list or maybe accept a lambda in place of tree-sitter-query--highlight-capture
?
I am doing basically the same thing right now for a moldable emacs mold.
(me-register-mold
:key "TreesitterGrep"
:given (:fn (and
(executable-find "tree-grepper")
(eq major-mode 'tree-sitter-query-mode)
;; (bound-and-true-p tree-sitter-language)
))
:then (:fn ;; the :then clause
(let* ((file buffer-file-name)
(language-name ())
(language (with-current-buffer tree-sitter-query--target-buffer
tree-sitter-language))
(language-symbol (with-current-buffer tree-sitter-query--target-buffer
(alist-get major-mode tree-sitter-major-mode-language-alist)))
(contents (save-excursion
(goto-char (point-min))
(eval `',(read (current-buffer)))))) ;; the scope here is in the original buffer you called the mold from
(with-current-buffer buffername ;; `buffername' is available by default
(erase-buffer)
(insert (format "tree-grepper --query %S \"%S\" ." language-symbol contents))
(setq-local self contents)))) ;; always set the `self' variable!
:docs "Run tree-grepper")
and in another version I am wanting to run the query directly as
(defun me-mold-treesitter-query1 ()
"Evaluate query PATTERNS against the target buffer."
(interactive)
(let ((patterns "(pair (string) @foo)"))
(with-current-buffer (current-buffer)
(tsc--without-restriction
(remove-overlays)
(when-let*
((query
(condition-case err
(tsc-make-query tree-sitter-language patterns)
((tsc-query-invalid-node-type
tsc-query-invalid-field
tsc-query-invalid-capture)
(message "%s: %s" (get (car err) 'error-message) (cadr err))
nil)
(tsc-query-invalid
(message "%s" (get (car err) 'error-message))
nil)))
(root-node (tsc-root-node tree-sitter-tree))
(captures (tsc-query-captures query root-node #'tsc--buffer-substring-no-properties)))
(if (= (length captures) 0)
(message "No captures found")
(message "captures found:%S" (mapcar #'me-mold-treesitter-capture-to-plist captures))
(mapc #'tree-sitter-query--highlight-capture captures)))))))
;; derived from tree-sitter-query--highlight-capture
(defun me-mold-treesitter-capture-to-plist (capture)
"Convert CAPTURE to a plist."
(pcase-let* ((`(,capture-symbol . ,captured-node) capture)
(`(,node-start . ,node-end) (tsc-node-position-range captured-node))
(capture-name (symbol-name capture-symbol)))
(list :symbol capture-symbol :name capture-name :start node-start :end node-end)
))
Never mind. I see that most of the stuff I'm copy-pasting is error handling which maybe shouldn't be generalized.
@alanz I don't know what's a mold, I see you're using tree-grepper. My thought process with tree-sitter-occur was basically "We have tree-grepper but adding languages to it is a pain, why can't I do it with the languages already in tree-sitter-langs"
Perhaps a mold is related to this?
There's a molds
directory: https://github.com/ag91/moldable-emacs/tree/master/molds
@sogaiu yes it is. It's a way of quickly stringing together snippets of code to do some kind of analysis. See https://emacsconf.org/2021/talks/mold/ for an overview. It is an emacs version of https://gtoolkit.com/