Function: ansi-color--update-face-vec

ansi-color--update-face-vec is a byte-compiled function defined in ansi-color.el.gz.

Signature

(ansi-color--update-face-vec FACE-VEC ITERATOR)

Documentation

Apply escape sequences to FACE-VEC.

Destructively modify FACE-VEC, which should be a list containing face information. It is described in ansi-color-context-region. ITERATOR is a function which is called repeatedly with zero arguments and should return either the next ANSI code in the current sequence as a number or nil if there are no more ANSI codes left.

For each new code, the following happens: if it is 1-7, set the corresponding properties; if it is 21-25 or 27, unset appropriate properties; if it is 30-37 (or 90-97) or resp. 39, set the foreground color or resp. unset it; if it is 40-47 (or 100-107) resp. 49, set the background color or resp. unset it; if it is 38 or 48, the following codes are used to set the foreground or background color and the correct color mode; any other code will unset all properties and colors.

Source Code

;; Defined in /usr/src/emacs/lisp/ansi-color.el.gz
(defun ansi-color--update-face-vec (face-vec iterator)
  "Apply escape sequences to FACE-VEC.

Destructively modify FACE-VEC, which should be a list containing
face information.  It is described in
`ansi-color-context-region'.  ITERATOR is a function which is
called repeatedly with zero arguments and should return either
the next ANSI code in the current sequence as a number or nil if
there are no more ANSI codes left.

For each new code, the following happens: if it is 1-7, set the
corresponding properties; if it is 21-25 or 27, unset appropriate
properties; if it is 30-37 (or 90-97) or resp. 39, set the
foreground color or resp. unset it; if it is 40-47 (or 100-107)
resp. 49, set the background color or resp. unset it; if it is 38
or 48, the following codes are used to set the foreground or
background color and the correct color mode; any other code will
unset all properties and colors."
  (let ((basic-faces (car face-vec))
        (colors (cdr face-vec))
        new q do-clear)
    (while (setq new (funcall iterator))
      (setq q (/ new 10))
      (pcase q
        (0 (if (memq new '(0 8 9))
               (setq do-clear t)
             (aset basic-faces new t)))
        (2 (if (memq new '(20 26 28 29))
               (setq do-clear t)
             ;; The standard says `21 doubly underlined' while
             ;; https://en.wikipedia.org/wiki/ANSI_escape_code claims
             ;; `21 Bright/Bold: off or Underline: Double'.
             (aset basic-faces (- new 20) nil)
             (aset basic-faces (pcase new (22 1) (25 6) (_ 0)) nil)))
        ((or 3 4 9 10)
         (let ((r (mod new 10))
               (cell (if (memq q '(3 9)) colors (cdr colors))))
           (pcase r
             (8
              (pcase (funcall iterator)
                (5 (setq new (setcar cell (funcall iterator)))
                   (setq do-clear (or (null new) (>= new 256))))
                (2
                 (let ((red (funcall iterator))
                       (green (funcall iterator))
                       (blue (funcall iterator)))
                   (if (and red green blue
                            (progn
                              (setq new (+ (* #x010000 red)
                                           (* #x000100 green)
                                           (* #x000001 blue)))
                              (<= new #xFFFFFF)))
                       (setcar cell (+ 256 new))
                     (setq do-clear t))))
                (_ (setq do-clear t))))
             (9 (setcar cell nil))
             (_ (setcar cell (+ (if (memq q '(3 4)) 0 8) r))))))
        (_ (setq do-clear t)))

      (when do-clear
        (setq do-clear nil)
        ;; Zero out our bool vector without any allocation.
        (bool-vector-intersection basic-faces #&8"\0" basic-faces)
        (setcar colors nil)
        (setcar (cdr colors) nil)))))