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 ((codes (car ansi-color-context-region))
        (start-marker (or (cadr ansi-color-context-region)
                          (copy-marker begin)))
        (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-seq (buffer-substring
                        (match-beginning 0) (point))))
          (if preserve-sequences
              ;; Make the escape sequence transparent.
              (overlay-put (make-overlay (match-beginning 0) (point))
                           'invisible t)
            ;; Otherwise, strip.
            (delete-region (match-beginning 0) (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 (point)))
                   (match-beginning 0) (ansi-color--find-face codes))
          ;; If this is a color sequence,
          (when (eq (aref esc-seq (1- (length esc-seq))) ?m)
            ;; update the list of ansi codes.
            (setq codes (ansi-color-apply-sequence esc-seq codes)))))
      ;; search for the possible start of a new escape sequence
      (if (re-search-forward "\033" end-marker t)
	  (progn
	    ;; if the rest of the region should have a face, put it there
	    (funcall ansi-color-apply-face-function
		     start-marker (point) (ansi-color--find-face codes))
	    ;; save codes and point
	    (setq ansi-color-context-region
		  (list codes (copy-marker (match-beginning 0)))))
	;; if the rest of the region should have a face, put it there
	(funcall ansi-color-apply-face-function
		 start-marker end-marker (ansi-color--find-face codes))
        ;; 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.
	(setq ansi-color-context-region
              (if codes (list codes (copy-marker (point)))))))
    ;; Clean up our temporary markers.
    (unless (eq start-marker (cadr ansi-color-context-region))
      (set-marker start-marker nil))
    (unless (eq end-marker (cadr ansi-color-context-region))
      (set-marker end-marker nil))))