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
         ;; Filter out functions like `markdown' using `commandp'.
         (if (and (functionp embed-lang) (not (commandp 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)))))
        (if (null embed-parser)
            (when treesit--range-verbose
              (message "Couldn't find an embed parser for an embedded code block, language=%s, embed level=%s" resolved-embed-lang embed-level))
          ;; 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.  Each RANGE can be
          ;; either a simple (START . END) or a ((START . END)...).
          (dolist (range new-ranges)
            (let ((has-existing-ov nil)
                  (r-start (treesit--range-start range))
                  (r-end (treesit--range-end range)))
              (setq has-existing-ov
                    (catch 'done
                      (dolist (ov (overlays-in r-start r-end))
                        (when (eq (overlay-get ov 'treesit-parser)
                                  embed-parser)
                          (move-overlay ov r-start r-end)
                          (overlay-put ov 'treesit-parser-ov-timestamp
                                       modified-tick)
                          (throw 'done t)))))
              (unless has-existing-ov
                (let ((ov (make-overlay r-start r-end)))
                  (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* ((new-ranges
                  (treesit--flatten-ranges new-ranges))
                 (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--set-embed-ranges
             set-ranges embed-parser host-parser)
            (push embed-parser touched-parsers)))))
    touched-parsers))