Function: ansi-color-apply-on-region

ansi-color-apply-on-region is a byte-compiled function defined in ansi-color.el.gz.

Signature

(ansi-color-apply-on-region BEGIN END &optional PRESERVE-SEQUENCES)

Documentation

Translates SGR control sequences into overlays or extents.

Delete all other control sequences without processing them.

SGR control sequences are applied by calling the function specified by ansi-color-apply-face-function. The default function sets foreground and background colors to the text between BEGIN and END, using overlays. See function ansi-color-apply-sequence for details.

Every call to this function will set and use the buffer-local variable ansi-color-context-region to save position and current ansi codes. This information will be used for the next call to ansi-color-apply-on-region. Specifically, it will override BEGIN, the start of the region and set the face with which to start. Set ansi-color-context-region to nil if you don't want this.

If PRESERVE-SEQUENCES is t, the sequences are hidden instead of being deleted.

Source Code

;; Defined in /usr/src/emacs/lisp/ansi-color.el.gz
(defun ansi-color-apply-on-region (begin end &optional preserve-sequences)
  "Translates SGR control sequences into overlays or extents.
Delete all other control sequences without processing them.

SGR control sequences are applied by calling the function
specified by `ansi-color-apply-face-function'.  The default
function sets foreground and background colors to the text
between BEGIN and END, using overlays.  See function
`ansi-color-apply-sequence' for details.

Every call to this function will set and use the buffer-local
variable `ansi-color-context-region' to save position and current
ansi codes.  This information will be used for the next call to
`ansi-color-apply-on-region'.  Specifically, it will override
BEGIN, the start of the region and set the face with which to
start.  Set `ansi-color-context-region' to nil if you don't want
this.

If PRESERVE-SEQUENCES is t, the sequences are hidden instead of
being deleted."
  (let* ((context (ansi-color--ensure-context
                   'ansi-color-context-region begin))
         (face-vec (car context))
         (start-marker (cadr context))
         (end-marker (copy-marker end)))
    (save-excursion
      (goto-char start-marker)
      ;; Find the next escape sequence.
      (while (re-search-forward ansi-color-control-seq-regexp end-marker t)
        ;; Extract escape sequence.
        (let ((esc-beg (match-beginning 0))
              (esc-end (point)))
          ;; Colorize the old block from start to end using old face.
          (funcall ansi-color-apply-face-function
                   (prog1 (marker-position start-marker)
                     ;; Store new start position.
                     (set-marker start-marker esc-end))
                   esc-beg (ansi-color--face-vec-face face-vec))
          ;; If this is a color sequence,
          (when (eq (char-before esc-end) ?m)
            (goto-char esc-beg)
            (ansi-color--update-face-vec
             face-vec (lambda ()
                        (when (re-search-forward ansi-color-parameter-regexp
                                                 esc-end t)
                          (string-to-number (match-string 1))))))

          (if preserve-sequences
              ;; Make the escape sequence transparent.
              (overlay-put (make-overlay esc-beg esc-end) 'invisible t)
            ;; Otherwise, strip.
            (delete-region esc-beg esc-end))))
      ;; search for the possible start of a new escape sequence
      (while (re-search-forward ansi-color--control-seq-fragment-regexp
                                end-marker t))
      (if (and (/= (point) start-marker)
               (= (point) end-marker))
          (progn
            (goto-char (match-beginning 0))
            (funcall ansi-color-apply-face-function
                     start-marker (point)
                     (ansi-color--face-vec-face face-vec))
            (set-marker start-marker (point)))
        (let ((faces (ansi-color--face-vec-face face-vec)))
          (funcall ansi-color-apply-face-function
                   start-marker end-marker faces)
          ;; Save a restart position when there are codes active. It's
          ;; convenient for man.el's process filter to pass `begin'
          ;; positions that overlap regions previously colored; these
          ;; `codes' should not be applied to that overlap, so we need
          ;; to know where they should really start.
          (set-marker start-marker (when faces end-marker)))))
    ;; Clean up our temporary marker.
    (set-marker end-marker nil)))