Function: treesit--merge-ranges

treesit--merge-ranges is a byte-compiled function defined in treesit.el.gz.

Signature

(treesit--merge-ranges OLD-RANGES NEW-RANGES START END)

Documentation

Merge OLD-RANGES and NEW-RANGES, discarding ranges between START and END.

OLD-RANGES and NEW-RANGES are lists of cons of the form (BEG . END). When merging the two ranges, if a range in OLD-RANGES intersects with another range in NEW-RANGES, discard the one in OLD-RANGES and keep the one in NEW-RANGES. Also discard any range in OLD-RANGES that intersects the region marked by START and END.

Return the merged list of ranges.

Source Code

;; Defined in /usr/src/emacs/lisp/treesit.el.gz
(defun treesit--merge-ranges (old-ranges new-ranges start end)
  "Merge OLD-RANGES and NEW-RANGES, discarding ranges between START and END.
OLD-RANGES and NEW-RANGES are lists of cons of the form (BEG . END).
When merging the two ranges, if a range in OLD-RANGES intersects with
another range in NEW-RANGES, discard the one in OLD-RANGES and
keep the one in NEW-RANGES.  Also discard any range in OLD-RANGES
that intersects the region marked by START and END.

Return the merged list of ranges."
  (let ((result nil))
    (while (and old-ranges new-ranges)
      (let ((new-beg (caar new-ranges))
            (new-end (cdar new-ranges))
            (old-beg (caar old-ranges))
            (old-end (cdar old-ranges)))
        (cond
         ;; Old range intersects with START-END, discard.
         ((and (< start old-end)
               (< old-beg end))
          (setq old-ranges (cdr old-ranges)))
         ;; New range and old range don't intersect, new comes
         ;; before, push new.
         ((<= new-end old-beg)
          (unless (eq new-beg new-end)
            (push (car new-ranges) result))
          (setq new-ranges (cdr new-ranges)))
         ;; New range and old range don't intersect, old comes
         ;; before, push old.
         ((<= old-end new-beg)
          (unless (eq old-beg old-end)
            (push (car old-ranges) result))
          (setq old-ranges (cdr old-ranges)))
         (t ;; New and old range intersect, discard old.
          (setq old-ranges (cdr old-ranges))))))
    ;; At this point, either old-ranges has left-over or new-ranges has
    ;; left-over, but not both.
    (while old-ranges
      ;; For each left-over old range, push to result unless it
      ;; intersects with START-END.
      (let ((old-beg (caar old-ranges))
            (old-end (cdar old-ranges)))
        (unless (or (and (< start old-end)
                         (< old-beg end))
                    (eq old-beg old-end))
          (push (car old-ranges) result)))
      (setq old-ranges (cdr old-ranges)))
    ;; Unconditionally push left-over new ranges to result.
    (while new-ranges
      (unless (eq (caar new-ranges) (cdar new-ranges))
        (push (car new-ranges) result))
      (setq new-ranges (cdr new-ranges)))
    (nreverse result)))