Add support for 256-color and 24bit ANSI colors in ansi-color
* lisp/ansi-color.el (ansi-color--code-as-hex): New function to convert from 256-color and 24-bit ANSI codes. (ansi-color--face-vec-face): Add support for ANSI color codes greater than 16 (ansi-color--update-face-vec): Add support for ANSI codes 38 and 48 which can specify 256-color and 24bit ANSI colors. * test/lisp/ansi-color-tests.el (ansi-color-tests--strings): Add tests for ANSI codes 38 and 34
This commit is contained in:
parent
21dcb9830a
commit
0fa2279b90
3 changed files with 74 additions and 15 deletions
7
etc/NEWS
7
etc/NEWS
|
@ -82,6 +82,13 @@ mode (instead of at load time).
|
|||
+++
|
||||
*** New macro 'with-memoization' provides a very primitive form of memoization
|
||||
|
||||
** ansi-color.el
|
||||
|
||||
---
|
||||
*** Support for ANSI 256-color and 24-bit colors.
|
||||
256-color and 24-bit color codes are now handled by ANSI color
|
||||
filters and displayed with the specified color.
|
||||
|
||||
|
||||
* New Modes and Packages in Emacs 29.1
|
||||
|
||||
|
|
|
@ -594,22 +594,24 @@ code. It is usually stored as the car of the variable
|
|||
(when-let ((fg (car colors)))
|
||||
(push
|
||||
`(:foreground
|
||||
,(face-foreground
|
||||
(aref (if (or bright (>= fg 8))
|
||||
ansi-color-bright-colors-vector
|
||||
ansi-color-normal-colors-vector)
|
||||
(mod fg 8))
|
||||
nil 'default))
|
||||
,(or (ansi-color--code-as-hex fg)
|
||||
(face-foreground
|
||||
(aref (if (or bright (>= fg 8))
|
||||
ansi-color-bright-colors-vector
|
||||
ansi-color-normal-colors-vector)
|
||||
(mod fg 8))
|
||||
nil 'default)))
|
||||
faces))
|
||||
(when-let ((bg (cadr colors)))
|
||||
(push
|
||||
`(:background
|
||||
,(face-background
|
||||
(aref (if (or bright (>= bg 8))
|
||||
ansi-color-bright-colors-vector
|
||||
ansi-color-normal-colors-vector)
|
||||
(mod bg 8))
|
||||
nil 'default))
|
||||
,(or (ansi-color--code-as-hex bg)
|
||||
(face-background
|
||||
(aref (if (or bright (>= bg 8))
|
||||
ansi-color-bright-colors-vector
|
||||
ansi-color-normal-colors-vector)
|
||||
(mod bg 8))
|
||||
nil 'default)))
|
||||
faces))
|
||||
|
||||
(let ((i 8))
|
||||
|
@ -622,6 +624,32 @@ code. It is usually stored as the car of the variable
|
|||
faces
|
||||
(car faces))))
|
||||
|
||||
(defun ansi-color--code-as-hex (color)
|
||||
"Convert COLOR to hexadecimal string representation.
|
||||
COLOR is an ANSI color code. If it is between 16 and 255
|
||||
inclusive, it corresponds to a color from an 8-bit color cube.
|
||||
If it is greater or equal than 256, it is subtracted by 256 to
|
||||
directly specify a 24-bit color.
|
||||
|
||||
Return a hexadecimal string, specifying the color, or nil, if
|
||||
COLOR is less than 16."
|
||||
(cond
|
||||
((< color 16) nil)
|
||||
((>= color 256) (format "#%06X" (- color 256)))
|
||||
((>= color 232) ;; Grayscale
|
||||
(format "#%06X" (* #x010101 (+ 8 (* 10 (- color 232))))))
|
||||
(t ;; 6x6x6 color cube
|
||||
(setq color (- color 16))
|
||||
(let ((res 0)
|
||||
(frac (* 6 6)))
|
||||
(while (<= 1 frac) ; Repeat 3 times
|
||||
(setq res (* res #x000100))
|
||||
(let ((color-num (mod (/ color frac) 6)))
|
||||
(unless (zerop color-num)
|
||||
(setq res (+ res #x37 (* #x28 color-num)))))
|
||||
(setq frac (/ frac 6)))
|
||||
(format "#%06X" res)))))
|
||||
|
||||
;; Working with regions
|
||||
|
||||
(defvar-local ansi-color-context-region nil
|
||||
|
@ -907,7 +935,23 @@ unset all properties and colors."
|
|||
(let ((r (mod new 10))
|
||||
(cell (if (memq q '(3 9)) colors (cdr colors))))
|
||||
(pcase r
|
||||
(8 (setq do-clear t))
|
||||
(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)))
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
|
||||
(defvar ansi-color-tests--strings
|
||||
(let ((bright-yellow (face-foreground 'ansi-color-bright-yellow nil 'default))
|
||||
(yellow (face-foreground 'ansi-color-yellow nil 'default)))
|
||||
(yellow (face-foreground 'ansi-color-yellow nil 'default))
|
||||
(custom-color "#87FFFF"))
|
||||
`(("Hello World" "Hello World")
|
||||
("\e[33mHello World\e[0m" "Hello World"
|
||||
(:foreground ,yellow))
|
||||
|
@ -51,7 +52,14 @@
|
|||
(ansi-color-bold (:foreground ,bright-yellow)))
|
||||
("\e[1m\e[3m\e[5mbold italics blink\e[0m" "bold italics blink"
|
||||
(ansi-color-bold ansi-color-italic ansi-color-slow-blink))
|
||||
("\e[10munrecognized\e[0m" "unrecognized"))))
|
||||
("\e[10munrecognized\e[0m" "unrecognized")
|
||||
("\e[38;5;3;1mHello World\e[0m" "Hello World"
|
||||
(ansi-color-bold (:foreground ,yellow))
|
||||
(ansi-color-bold (:foreground ,bright-yellow)))
|
||||
("\e[48;5;123;1mHello World\e[0m" "Hello World"
|
||||
(ansi-color-bold (:background ,custom-color)))
|
||||
("\e[48;2;135;255;255;1mHello World\e[0m" "Hello World"
|
||||
(ansi-color-bold (:background ,custom-color))))))
|
||||
|
||||
(ert-deftest ansi-color-apply-on-region-test ()
|
||||
(pcase-dolist (`(,input ,text ,face) ansi-color-tests--strings)
|
||||
|
|
Loading…
Add table
Reference in a new issue