Function: treesit-query-range-by-language

treesit-query-range-by-language is a byte-compiled function defined in treesit.el.gz.

Signature

(treesit-query-range-by-language NODE QUERY LANGUAGE-FN &optional BEG END OFFSET RANGE-FN)

Documentation

Like treesit-query-range, but return multiple ranges by language.

Return an alist of the form ((LANGUAGE . RANGES) ...), containing separate ranges for each language detected in the query.

Query NODE with QUERY, the captured nodes generates ranges. Nodes captured by the @language capture name are converted to language symbols with LANGUAGE-FN. LANGUAGE-FN can return nil, meaning no valid language is detected, in which case the range is skipped.

RANGE-FN, if non-nil, is a function that takes a NODE and OFFSET, and returns the ranges to use for that NODE.

BEG, END, OFFSET are the same as in treesit-query-range.

Source Code

;; Defined in /usr/src/emacs/lisp/treesit.el.gz
(defun treesit-query-range-by-language
    (node query language-fn &optional beg end offset range-fn)
  "Like `treesit-query-range', but return multiple ranges by language.

Return an alist of the form ((LANGUAGE . RANGES) ...), containing
separate ranges for each language detected in the query.

Query NODE with QUERY, the captured nodes generates ranges.  Nodes
captured by the `@language' capture name are converted to language
symbols with LANGUAGE-FN.  LANGUAGE-FN can return nil, meaning no
valid language is detected, in which case the range is skipped.

RANGE-FN, if non-nil, is a function that takes a NODE and OFFSET, and
returns the ranges to use for that NODE.

BEG, END, OFFSET are the same as in `treesit-query-range'."
  (let ((offset-left (or (car offset) 0))
        (offset-right (or (cdr offset) 0))
        (ranges-by-language nil))
    (dolist (match-group (treesit-query-capture node query beg end nil t))
      (let* ((lang-node (alist-get 'language match-group))
             (lang (funcall language-fn lang-node)))
        (when lang
          (dolist (capture match-group)
            (let ((name (car capture))
                  (node (cdr capture)))
              (when (and (not (equal (symbol-name name) "language"))
                         (not (string-prefix-p "_" (symbol-name name))))
                (push (if range-fn
                          (funcall range-fn node offset)
                        (list (cons (+ (treesit-node-start node) offset-left)
                                    (+ (treesit-node-end node) offset-right))))
                      (alist-get lang ranges-by-language))))))))
    (mapcar (lambda (entry)
              (cons (car entry)
                    (apply #'append (nreverse (cdr entry)))))
            ranges-by-language)))