Function: treesit--update-ranges-non-local

treesit--update-ranges-non-local is a byte-compiled function defined in treesit.el.gz.

Signature

(treesit--update-ranges-non-local HOST-PARSER QUERY EMBED-LANG MODIFIED-TICK EMBED-LEVEL &optional BEG END OFFSET RANGE-FN)

Documentation

Update range for non-local parsers between BEG and END under HOST-PARSER.

OFFSET is a cons (OFFSET-START . OFFSET-END), the start and end will be added to each captured range as range offset.

Use QUERY to get the ranges, and set ranges for embedded parsers to those ranges. HOST-PARSER and QUERY must match.

EMBED-LANG is either a language symbol or a function that takes a node and returns a language symbol.

When this function touches an overlay, it sets the treesit-parser-ov-timestamp property of the overlay to MODIFIED-TICK. This will help Emacs garbage-collect overlays that aren't in use anymore.

EMBED-LEVEL is the embed level for the local parsers being created or updated. When looking for existing local parsers, only look for parsers of this level; when creating new local parsers, set their level to this level.

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

Return updated parsers as a list.

Source Code

;; Defined in /usr/src/emacs/lisp/treesit.el.gz
(defun treesit--update-ranges-non-local
    ( host-parser query embed-lang modified-tick embed-level
      &optional beg end offset range-fn)
  "Update range for non-local parsers between BEG and END under HOST-PARSER.

OFFSET is a cons (OFFSET-START . OFFSET-END), the start and end will be
added to each captured range as range offset.

Use QUERY to get the ranges, and set ranges for embedded parsers to
those ranges.  HOST-PARSER and QUERY must match.

EMBED-LANG is either a language symbol or a function that takes a node
and returns a language symbol.

When this function touches an overlay, it sets the
`treesit-parser-ov-timestamp' property of the overlay to MODIFIED-TICK.
This will help Emacs garbage-collect overlays that aren't in use
anymore.

EMBED-LEVEL is the embed level for the local parsers being created or
updated.  When looking for existing local parsers, only look for parsers
of this level; when creating new local parsers, set their level to this
level.

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

Return updated parsers as a list."
  (let ((ranges-by-lang
         (if (functionp embed-lang)
             (treesit-query-range-by-language
              host-parser query embed-lang beg end offset range-fn)
           (list (cons embed-lang
                       (treesit-query-range
                        host-parser query beg end offset range-fn)))))
        (touched-parsers nil))
    (dolist (lang-and-ranges ranges-by-lang)
      (let* ((resolved-embed-lang (car lang-and-ranges))
             (new-ranges (cdr lang-and-ranges))
             (embed-parser
              ;; Prefer embed parser with the right level, but if none
              ;; exists, ones that doesn't have a embed level are ok
              ;; too.
              (or (car (treesit--parser-at-level
                        (treesit-parser-list nil resolved-embed-lang)
                        embed-level))
                  (car (treesit--parser-at-level
                        (treesit-parser-list nil resolved-embed-lang)
                        embed-level 'include-null)))))
        (when embed-parser
          ;; Lay an overlay over each range to mark the start & end of
          ;; it for other functions to access (e.g., outline wants to
          ;; know this).  Refer to (ref:local-parser-overlay) for more
          ;; explanation of local parser overlays.
          (dolist (range new-ranges)
            (let ((has-existing-ov nil))
              (setq has-existing-ov
                    (catch 'done
                      (dolist (ov (overlays-in (car range) (cdr range)))
                        (when (eq (overlay-get ov 'treesit-parser)
                                  embed-parser)
                          (move-overlay ov (car range) (cdr range))
                          (overlay-put ov 'treesit-parser-ov-timestamp
                                       modified-tick)
                          (throw 'done t)))))
              (unless has-existing-ov
                (let ((ov (make-overlay (car range) (cdr range))))
                  (overlay-put ov 'treesit-parser embed-parser)
                  (overlay-put ov 'treesit-parser-local-p nil)
                  (overlay-put ov 'treesit-host-parser host-parser)
                  (overlay-put ov 'treesit-parser-ov-timestamp
                               modified-tick)))))
          ;; Set ranges for the embed parser.
          (let* ((old-ranges (treesit-parser-included-ranges
                              embed-parser))
                 (set-ranges (treesit--clip-ranges
                              (treesit--merge-ranges
                               old-ranges new-ranges beg end)
                              (point-min) (point-max))))
            (treesit-parser-set-embed-level
             embed-parser embed-level)
            (treesit-parser-set-included-ranges
             embed-parser (or set-ranges
                              ;; When there's no range for the
                              ;; embedded language, set it's
                              ;; range to a dummy (1 . 1),
                              ;; otherwise it would be set to
                              ;; the whole buffer, which is
                              ;; not what we want.
                              `((,(point-min) . ,(point-min)))))
            (push embed-parser touched-parsers)))))
    touched-parsers))