Function: ansi-color-apply

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

Signature

(ansi-color-apply STRING)

Documentation

Translates SGR control sequences into text properties.

Delete all other control sequences without processing them.

Applies SGR control sequences setting foreground and background colors to STRING using text properties and returns the result. See function ansi-color-apply-sequence for details.

Every call to this function will set and use the buffer-local variable ansi-color-context to save partial escape sequences and current ansi codes. This information will be used for the next call to ansi-color-apply. Set ansi-color-context to nil if you don't want this.

This function can be added to comint-preoutput-filter-functions.

Probably introduced at or before Emacs version 21.1.

Source Code

;; Defined in /usr/src/emacs/lisp/ansi-color.el.gz
(defun ansi-color-apply (string)
  "Translates SGR control sequences into text properties.
Delete all other control sequences without processing them.

Applies SGR control sequences setting foreground and background colors
to STRING using text properties and returns the result.  See function
`ansi-color-apply-sequence' for details.

Every call to this function will set and use the buffer-local variable
`ansi-color-context' to save partial escape sequences and current ansi codes.
This information will be used for the next call to `ansi-color-apply'.
Set `ansi-color-context' to nil if you don't want this.

This function can be added to `comint-preoutput-filter-functions'."
  (let* ((context
          (ansi-color--ensure-context 'ansi-color-context nil))
         (face-vec (car context))
         (start 0)
         end result)
    ;; If context was saved and is a string, prepend it.
    (setq string (concat (cadr context) string))
    (setcar (cdr context) "")
    ;; Find the next escape sequence.
    (while (setq end (string-match ansi-color-control-seq-regexp string start))
      (let ((esc-end (match-end 0)))
        ;; Colorize the old block from start to end using old face.
        (when-let* ((face (ansi-color--face-vec-face face-vec)))
          (put-text-property start end 'font-lock-face
                             face string))
        (push (substring string start end) result)
        (setq start (match-end 0))
        ;; If this is a color escape sequence,
        (when (eq (aref string (1- esc-end)) ?m)
          ;; create a new face from it.
          (let ((cur-pos end))
            (ansi-color--update-face-vec
             face-vec
             (lambda ()
               (when (string-match ansi-color-parameter-regexp
                                   string cur-pos)
                 (setq cur-pos (match-end 0))
                 (when (<= cur-pos esc-end)
                   (string-to-number (match-string 1 string))))))))))
    ;; if the rest of the string should have a face, put it there
    (when-let* ((face (ansi-color--face-vec-face face-vec)))
      (put-text-property start (length string)
                         'font-lock-face face string))
    ;; save context, add the remainder of the string to the result
    (if (string-match
         (concat "\\(?:" ansi-color--control-seq-fragment-regexp "\\)\\'")
         string start)
        (let ((pos (match-beginning 0)))
          (setcar (cdr context) (substring string pos))
          (push (substring string start pos) result))
      (push (substring string start) result))
    (apply 'concat (nreverse result))))