Repository: atomontage/xterm-color
Branch: master
Commit: 86fab1d247eb
Files: 7
Total size: 66.5 KB
Directory structure:
gitextract_76wscj12/
├── .gitignore
├── LICENSE
├── NEWS.org
├── README.org
├── tests/
│ ├── 256colors2.pl
│ └── xterm-colortest
└── xterm-color.el
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
*.elc
================================================
FILE: LICENSE
================================================
Copyright (c) 2010-2020 xristos@sdf.org
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: NEWS.org
================================================
* Changes
** 2.0 (2020-05-10)
+ Added truecolor (24-bit) and overlay support. Overlays may optionally
be used only when colorizing entire buffers. Thanks to Dan Davison
for initial implementation.
+ Better parsing and malformed input detection. Errors are no longer
signaled to avoid desynchronizing the state machine. Unsupported SGR
sequences that happen to overlap with supported ones are skipped.
+ Added `xterm-color-render' (default: t) that can be used to filter out
ANSI control sequences without applying them to the text.
+ Minor documentation fixes and style updates.
================================================
FILE: README.org
================================================
[[https://opensource.org/licenses/BSD-2-Clause][https://img.shields.io/badge/license-BSD-blue.svg]]
[[https://melpa.org/#/xterm-color][https://melpa.org/packages/xterm-color-badge.svg]]
[[http://stable.melpa.org/#/xterm-color][https://stable.melpa.org/packages/xterm-color-badge.svg]]
xterm-color.el is an ANSI control sequence to text-property translator.
Translation takes place through state machine emulation which provides
a far more accurate, comprehensive result than ansi-color.el that is
built-into Emacs, without compromising on performance.
* Features
+ Regular ANSI color support
+ XTERM 256 color support
+ Truecolor (24-bit) support
+ AIXTERM bright foreground color
+ AIXTERM bright background color (since 1.8)
+ Use bold instead of bright (since 1.8)
+ When colorizing entire buffers, optional overlay support (since 2.0)
+ Optionally, filter out ANSI control sequences (since 2.0)
+ Works with compilation-mode
+ Works with eshell
* Install
Simple and most flexible method:
#+BEGIN_SRC emacs-lisp
;; Clone this repository, ensure directory of xterm-color.el is in your
;; load-path and add the following to your init file:
(require 'xterm-color)
;; You should byte-compile xterm-color.el for maximum performance.
#+END_SRC
Alternatively, you can install through [[https://melpa.org/][MELPA]] or some other Emacs package
manager.
* Usage
Interactively or from Emacs Lisp, call ~xterm-color-colorize-buffer~ to
colorize an entire buffer.
You may customize ~xterm-color-debug~ (default nil, if non-nil you will get warnings
in *Messages* when unsupported escape sequences are encountered),
~xterm-color-use-bold-for-bright~ (default nil), ~xterm-color-names~,
~xterm-color-names-bright~. Additionally, you may set ~xterm-color-preserve-properties~
to t (default nil, should be set to t only if using xterm-color with eshell, see below).
If you want to filter out all ANSI control sequences, without applying them to the text,
set ~xterm-color-render~ to nil.
A buffer-local face attribute cache is used since 1.8 to improve performance.
This means that if changes are made to ~xterm-color-names~ or ~xterm-color-names-bright~ or
~xterm-color-use-bold-for-bright~ at runtime, ~xterm-color-clear-cache~ should be called
in a buffer with activated xterm-color for changes to take effect in that buffer.
** Comint
You can replace ansi-color.el with xterm-color for all comint buffers,
but you should take into account modes that propertize strings and pass them
through ~comint-preoutput-filter-functions~ since ~xterm-color-filter~ will
strip all text properties (this is done to get maximum performance). The
recommended configuration that avoids issues is to remove ~ansi-color-process-output~
from the buffer-local ~comint-output-filter-functions~ and add ~xterm-color-filter~ as
the *first* hook in the buffer-local ~comint-preoutput-filter-functions~ for any
comint-based mode that you would like it to affect (e.g. shell-mode).
Additionally, it is recommended to disable font-locking for shell-mode buffers
[[https://github.com/atomontage/xterm-color/issues/28][since it interacts badly with comint and drastically affects performance]].
Font locking in shell-mode buffers is superfluous since xterm-color.el will
handle faces fine by itself.
Example configuration for shell-mode (M-x shell):
#+BEGIN_SRC emacs-lisp
(add-hook 'shell-mode-hook
(lambda ()
;; Disable font-locking in this buffer to improve performance
(font-lock-mode -1)
;; Prevent font-locking from being re-enabled in this buffer
(make-local-variable 'font-lock-function)
(setq font-lock-function (lambda (_) nil))
;; Replace ansi-color-process-output with xterm-color-filter
(make-local-variable 'comint-output-filter-functions)
(remove-hook 'comint-output-filter-functions 'ansi-color-process-output t)
(add-hook 'comint-preoutput-filter-functions 'xterm-color-filter nil t)))
;; Also set TERM accordingly (xterm-256color) in the shell itself.
#+END_SRC
Using ~compilation-shell-minor-mode~ (NOTE: not the same as compilation-mode)
with shell-mode buffers that have xterm-color enabled is NOT recommended,
as ~compilation-shell-minor-mode~ depends on font-locking and causes severe
performance degradation. Omit the statements that disable font-locking in the
shell-mode example configuration if you need it.
** Eshell
An example configuration for eshell:
#+BEGIN_SRC emacs-lisp
(require 'eshell) ; or use with-eval-after-load
(add-hook 'eshell-before-prompt-hook
(lambda ()
(setq xterm-color-preserve-properties t)))
(add-to-list 'eshell-preoutput-filter-functions 'xterm-color-filter)
(setq eshell-output-filter-functions (remove 'eshell-handle-ansi-color eshell-output-filter-functions))
(setenv "TERM" "xterm-256color")
#+END_SRC
** Compilation buffers
For standalone compilation buffers use the following configuration:
#+BEGIN_SRC emacs-lisp
(setq compilation-environment '("TERM=xterm-256color"))
(define-advice compilation-filter (:around (f proc string) xterm-color)
(funcall f proc (xterm-color-filter string)))
#+END_SRC
*NOTE*: This compilation-mode configuration will break
[[https://github.com/Wilfred/ag.el][ag.el]] and [[https://github.com/dajva/rg.el][rg.el]],
since these packages expect ANSI control sequences to be part of
compilation output so that they can be used for matching. Suggestions
for these packages to improve the way they perform matching
[[https://github.com/dajva/rg.el/issues/65][already]] [[https://github.com/atomontage/xterm-color/issues/37][exist]].
** Other
For programmatic usage from Emacs Lisp, call ~xterm-color-filter~ to propertize
strings that you can then insert into a buffer. All state is kept in
buffer-local variables which means that control sequences can span
~xterm-color-filter~ calls (state machine processing).
Example:
#+BEGIN_SRC emacs-lisp
(let ((buffer (generate-new-buffer "*xterm-color-test*")))
(with-current-buffer buffer
(insert (xterm-color-filter "\x1b[0;1;3;4"))
(insert (xterm-color-filter ";35"))
(insert (xterm-color-filter ";51mThis is only a test"))
(insert (xterm-color-filter "\x1b[0m")))
(switch-to-buffer buffer))
#+END_SRC
* Test
#+BEGIN_SRC emacs-lisp
M-x xterm-color-test
For comint or eshell:
M-x shell || M-x eshell
perl tests/xterm-colortest && perl tests/256colors2.pl
printf "\x1b[0;1;3;4;35;51mThis is only a test\x1b[0m\n"
Comparison with ansi-color.el:
M-x xterm-color-test-raw then M-x xterm-color-colorize-buffer
and contrast with
M-x xterm-color-test-raw then M-: (ansi-color-apply-on-region (point-min) (point-max))
#+END_SRC
[[file:img/xterm-color.png][file:img/xterm-color-thumb.png]] [[file:img/godwars2.png][file:img/godwars2-thumb.png]] [[file:img/wttr.png][file:img/wttr-thumb.png]]
* License
The code comes with a BSD-style license so you can basically do with it
whatever you want.
* Author
xristos (AT) sdf (DOT) org
================================================
FILE: tests/256colors2.pl
================================================
#!/usr/bin/perl
# Author: Todd Larason <jtl@molehill.org>
# $XFree86: xc/programs/xterm/vttests/256colors2.pl,v 1.2 2002/03/26 01:46:43 dickey Exp $
# use the resources for colors 0-15 - usually more-or-less a
# reproduction of the standard ANSI colors, but possibly more
# pleasing shades
# first the system ones:
print "System colors:\n";
for ($color = 0; $color < 8; $color++) {
print "\x1b[48;5;${color}m ";
}
print "\x1b[0m\n";
for ($color = 8; $color < 16; $color++) {
print "\x1b[48;5;${color}m ";
}
print "\x1b[0m\n\n";
# now the color cube
print "Color cube, 6x6x6:\n";
for ($green = 0; $green < 6; $green++) {
for ($red = 0; $red < 6; $red++) {
for ($blue = 0; $blue < 6; $blue++) {
$color = 16 + ($red * 36) + ($green * 6) + $blue;
print "\x1b[48;5;${color}m \x1b[0m";
}
print "\x1b[0m ";
}
print "\n";
}
# now the grayscale ramp
print "Grayscale ramp:\n";
for ($color = 232; $color < 256; $color++) {
print "\x1b[48;5;${color}m ";
}
print "\x1b[0m\n";
================================================
FILE: tests/xterm-colortest
================================================
#!/usr/bin/perl
# by entheon, do whatever the hell you want with this file
print "\n";
print "**************************\n";
print "*XTERM 256Color Test Chart\n";
print "**************************\n";
print "* 16 = black\n";
print "* 255 = white\n";
print "*\n";
print "* Usage:\n";
print "* colortest -w\n";
print "* wide display\n";
print "*\n";
print "* colortest -w -r\n";
print "* wide display reversed\n";
print "*\n";
print "* colortest -w -s\n";
print "* extra spaces padding\n";
print "*\n";
print "* colortest -w -r -s\n";
print "* available combination\n";
print "*\n";
print "**************************\n";
if( $ARGV[0] eq "-w" || $ARGV[1] eq "-w" || $ARGV[2] eq "-w" ) {
push(@arr, [( "[38;5;16m 16: 00/00/00", "[38;5;17m 17: 00/00/5f", "[38;5;18m 18: 00/00/87", "[38;5;19m 19: 00/00/af", "[38;5;20m 20: 00/00/d7", "[38;5;21m 21: 00/00/ff")] );
push(@arr, [( "[38;5;22m 22: 00/5f/00", "[38;5;23m 23: 00/5f/5f", "[38;5;24m 24: 00/5f/87", "[38;5;25m 25: 00/5f/af", "[38;5;26m 26: 00/5f/d7", "[38;5;27m 27: 00/5f/ff")] );
push(@arr, [( "[38;5;28m 28: 00/87/00", "[38;5;29m 29: 00/87/5f", "[38;5;30m 30: 00/87/87", "[38;5;31m 31: 00/87/af", "[38;5;32m 32: 00/87/d7", "[38;5;33m 33: 00/87/ff")] );
push(@arr, [( "[38;5;34m 34: 00/af/00", "[38;5;35m 35: 00/af/5f", "[38;5;36m 36: 00/af/87", "[38;5;37m 37: 00/af/af", "[38;5;38m 38: 00/af/d7", "[38;5;39m 39: 00/af/ff")] );
push(@arr, [( "[38;5;40m 40: 00/d7/00", "[38;5;41m 41: 00/d7/5f", "[38;5;42m 42: 00/d7/87", "[38;5;43m 43: 00/d7/af", "[38;5;44m 44: 00/d7/d7", "[38;5;45m 45: 00/d7/ff")] );
push(@arr, [( "[38;5;46m 46: 00/ff/00", "[38;5;47m 47: 00/ff/5f", "[38;5;48m 48: 00/ff/87", "[38;5;49m 49: 00/ff/af", "[38;5;50m 50: 00/ff/d7", "[38;5;51m 51: 00/ff/ff")] );
push(@arr, [( "[38;5;52m 52: 5f/00/00", "[38;5;53m 53: 5f/00/5f", "[38;5;54m 54: 5f/00/87", "[38;5;55m 55: 5f/00/af", "[38;5;56m 56: 5f/00/d7", "[38;5;57m 57: 5f/00/ff")] );
push(@arr, [( "[38;5;58m 58: 5f/5f/00", "[38;5;59m 59: 5f/5f/5f", "[38;5;60m 60: 5f/5f/87", "[38;5;61m 61: 5f/5f/af", "[38;5;62m 62: 5f/5f/d7", "[38;5;63m 63: 5f/5f/ff")] );
push(@arr, [( "[38;5;64m 64: 5f/87/00", "[38;5;65m 65: 5f/87/5f", "[38;5;66m 66: 5f/87/87", "[38;5;67m 67: 5f/87/af", "[38;5;68m 68: 5f/87/d7", "[38;5;69m 69: 5f/87/ff")] );
push(@arr, [( "[38;5;70m 70: 5f/af/00", "[38;5;71m 71: 5f/af/5f", "[38;5;72m 72: 5f/af/87", "[38;5;73m 73: 5f/af/af", "[38;5;74m 74: 5f/af/d7", "[38;5;75m 75: 5f/af/ff")] );
push(@arr, [( "[38;5;76m 76: 5f/d7/00", "[38;5;77m 77: 5f/d7/5f", "[38;5;78m 78: 5f/d7/87", "[38;5;79m 79: 5f/d7/af", "[38;5;80m 80: 5f/d7/d7", "[38;5;81m 81: 5f/d7/ff")] );
push(@arr, [( "[38;5;82m 82: 5f/ff/00", "[38;5;83m 83: 5f/ff/5f", "[38;5;84m 84: 5f/ff/87", "[38;5;85m 85: 5f/ff/af", "[38;5;86m 86: 5f/ff/d7", "[38;5;87m 87: 5f/ff/ff")] );
push(@arr, [( "[38;5;88m 88: 87/00/00", "[38;5;89m 89: 87/00/5f", "[38;5;90m 90: 87/00/87", "[38;5;91m 91: 87/00/af", "[38;5;92m 92: 87/00/d7", "[38;5;93m 93: 87/00/ff")] );
push(@arr, [( "[38;5;94m 94: 87/5f/00", "[38;5;95m 95: 87/5f/5f", "[38;5;96m 96: 87/5f/87", "[38;5;97m 97: 87/5f/af", "[38;5;98m 98: 87/5f/d7", "[38;5;99m 99: 87/5f/ff")] );
push(@arr, [( "[38;5;100m 100: 87/87/00", "[38;5;101m 101: 87/87/5f", "[38;5;102m 102: 87/87/87", "[38;5;103m 103: 87/87/af", "[38;5;104m 104: 87/87/d7", "[38;5;105m 105: 87/87/ff")] );
push(@arr, [( "[38;5;106m 106: 87/af/00", "[38;5;107m 107: 87/af/5f", "[38;5;108m 108: 87/af/87", "[38;5;109m 109: 87/af/af", "[38;5;110m 110: 87/af/d7", "[38;5;111m 111: 87/af/ff")] );
push(@arr, [( "[38;5;112m 112: 87/d7/00", "[38;5;113m 113: 87/d7/5f", "[38;5;114m 114: 87/d7/87", "[38;5;115m 115: 87/d7/af", "[38;5;116m 116: 87/d7/d7", "[38;5;117m 117: 87/d7/ff")] );
push(@arr, [( "[38;5;118m 118: 87/ff/00", "[38;5;119m 119: 87/ff/5f", "[38;5;120m 120: 87/ff/87", "[38;5;121m 121: 87/ff/af", "[38;5;122m 122: 87/ff/d7", "[38;5;123m 123: 87/ff/ff")] );
push(@arr, [( "[38;5;124m 124: af/00/00", "[38;5;125m 125: af/00/5f", "[38;5;126m 126: af/00/87", "[38;5;127m 127: af/00/af", "[38;5;128m 128: af/00/d7", "[38;5;129m 129: af/00/ff")] );
push(@arr, [( "[38;5;130m 130: af/5f/00", "[38;5;131m 131: af/5f/5f", "[38;5;132m 132: af/5f/87", "[38;5;133m 133: af/5f/af", "[38;5;134m 134: af/5f/d7", "[38;5;135m 135: af/5f/ff")] );
push(@arr, [( "[38;5;136m 136: af/87/00", "[38;5;137m 137: af/87/5f", "[38;5;138m 138: af/87/87", "[38;5;139m 139: af/87/af", "[38;5;140m 140: af/87/d7", "[38;5;141m 141: af/87/ff")] );
push(@arr, [( "[38;5;142m 142: af/af/00", "[38;5;143m 143: af/af/5f", "[38;5;144m 144: af/af/87", "[38;5;145m 145: af/af/af", "[38;5;146m 146: af/af/d7", "[38;5;147m 147: af/af/ff")] );
push(@arr, [( "[38;5;148m 148: af/d7/00", "[38;5;149m 149: af/d7/5f", "[38;5;150m 150: af/d7/87", "[38;5;151m 151: af/d7/af", "[38;5;152m 152: af/d7/d7", "[38;5;153m 153: af/d7/ff")] );
push(@arr, [( "[38;5;154m 154: af/ff/00", "[38;5;155m 155: af/ff/5f", "[38;5;156m 156: af/ff/87", "[38;5;157m 157: af/ff/af", "[38;5;158m 158: af/ff/d7", "[38;5;159m 159: af/ff/ff")] );
push(@arr, [( "[38;5;160m 160: d7/00/00", "[38;5;161m 161: d7/00/5f", "[38;5;162m 162: d7/00/87", "[38;5;163m 163: d7/00/af", "[38;5;164m 164: d7/00/d7", "[38;5;165m 165: d7/00/ff")] );
push(@arr, [( "[38;5;166m 166: d7/5f/00", "[38;5;167m 167: d7/5f/5f", "[38;5;168m 168: d7/5f/87", "[38;5;169m 169: d7/5f/af", "[38;5;170m 170: d7/5f/d7", "[38;5;171m 171: d7/5f/ff")] );
push(@arr, [( "[38;5;172m 172: d7/87/00", "[38;5;173m 173: d7/87/5f", "[38;5;174m 174: d7/87/87", "[38;5;175m 175: d7/87/af", "[38;5;176m 176: d7/87/d7", "[38;5;177m 177: d7/87/ff")] );
push(@arr, [( "[38;5;178m 178: d7/af/00", "[38;5;179m 179: d7/af/5f", "[38;5;180m 180: d7/af/87", "[38;5;181m 181: d7/af/af", "[38;5;182m 182: d7/af/d7", "[38;5;183m 183: d7/af/ff")] );
push(@arr, [( "[38;5;184m 184: d7/d7/00", "[38;5;185m 185: d7/d7/5f", "[38;5;186m 186: d7/d7/87", "[38;5;187m 187: d7/d7/af", "[38;5;188m 188: d7/d7/d7", "[38;5;189m 189: d7/d7/ff")] );
push(@arr, [( "[38;5;190m 190: d7/ff/00", "[38;5;191m 191: d7/ff/5f", "[38;5;192m 192: d7/ff/87", "[38;5;193m 193: d7/ff/af", "[38;5;194m 194: d7/ff/d7", "[38;5;195m 195: d7/ff/ff")] );
push(@arr, [( "[38;5;196m 196: ff/00/00", "[38;5;197m 197: ff/00/5f", "[38;5;198m 198: ff/00/87", "[38;5;199m 199: ff/00/af", "[38;5;200m 200: ff/00/d7", "[38;5;201m 201: ff/00/ff")] );
push(@arr, [( "[38;5;202m 202: ff/5f/00", "[38;5;203m 203: ff/5f/5f", "[38;5;204m 204: ff/5f/87", "[38;5;205m 205: ff/5f/af", "[38;5;206m 206: ff/5f/d7", "[38;5;207m 207: ff/5f/ff")] );
push(@arr, [( "[38;5;208m 208: ff/87/00", "[38;5;209m 209: ff/87/5f", "[38;5;210m 210: ff/87/87", "[38;5;211m 211: ff/87/af", "[38;5;212m 212: ff/87/d7", "[38;5;213m 213: ff/87/ff")] );
push(@arr, [( "[38;5;214m 214: ff/af/00", "[38;5;215m 215: ff/af/5f", "[38;5;216m 216: ff/af/87", "[38;5;217m 217: ff/af/af", "[38;5;218m 218: ff/af/d7", "[38;5;219m 219: ff/af/ff")] );
push(@arr, [( "[38;5;220m 220: ff/d7/00", "[38;5;221m 221: ff/d7/5f", "[38;5;222m 222: ff/d7/87", "[38;5;223m 223: ff/d7/af", "[38;5;224m 224: ff/d7/d7", "[38;5;225m 225: ff/d7/ff")] );
push(@arr, [( "[38;5;226m 226: ff/ff/00", "[38;5;227m 227: ff/ff/5f", "[38;5;228m 228: ff/ff/87", "[38;5;229m 229: ff/ff/af", "[38;5;230m 230: ff/ff/d7", "[38;5;231m 231: ff/ff/ff")] );
push(@arr, [( "[38;5;232m 232: 08/08/08", "[38;5;233m 233: 12/12/12", "[38;5;234m 234: 1c/1c/1c", "[38;5;235m 235: 26/26/26", "[38;5;236m 236: 30/30/30", "[38;5;237m 237: 3a/3a/3a")] );
push(@arr, [( "[38;5;238m 238: 44/44/44", "[38;5;239m 239: 4e/4e/4e", "[38;5;240m 240: 58/58/58", "[38;5;241m 241: 62/62/62", "[38;5;242m 242: 6c/6c/6c", "[38;5;243m 243: 76/76/76")] );
push(@arr, [( "[38;5;244m 244: 80/80/80", "[38;5;245m 245: 8a/8a/8a", "[38;5;246m 246: 94/94/94", "[38;5;247m 247: 9e/9e/9e", "[38;5;248m 248: a8/a8/a8", "[38;5;249m 249: b2/b2/b2")] );
push(@arr, [( "[38;5;250m 250: bc/bc/bc", "[38;5;251m 251: c6/c6/c6", "[38;5;252m 252: d0/d0/d0", "[38;5;253m 253: da/da/da", "[38;5;254m 254: e4/e4/e4", "[38;5;255m 255: ee/ee/ee")] );
if( $ARGV[0] eq "-s" || $ARGV[1] eq "-s" || $ARGV[2] eq "-s" ){
$padding = " ";
}
else {
}
# display in reverse order
if( $ARGV[0] eq "-r" || $ARGV[1] eq "-r" || $ARGV[2] eq "-r" ){
for( $dimone = 0; $dimone < scalar @arr; $dimone++ ) {
$seed = ($dimone % 6) * -1;
for( $dimtwo = 0; $dimtwo < 6; $dimtwo++ ) {
$movone = $seed;
$movtwo = $seed * -1;
print $arr[$dimone][$dimtwo] . $padding;
$seed = $seed+1;
}
print "\n";
}
}
else {
for( $dimone = 0; $dimone < scalar @arr; $dimone++ ) {
$seed = ($dimone % 6) * -1;
for( $dimtwo = 0; $dimtwo < 6; $dimtwo++ ) {
$movone = $seed;
$movtwo = $seed * -1;
$newone = $dimone+$movone;
$newtwo = $dimtwo+$movtwo;
if( $newone < scalar @arr ){
print $arr[$newone][$newtwo] . $padding;
}
$seed = $seed+1;
}
print "\n";
}
}
print "\n";
print "\n";
}
else {
print "[38;5;16m 16: 00/00/00\n";
print "[38;5;17m 17: 00/00/5f\n";
print "[38;5;18m 18: 00/00/87\n";
print "[38;5;19m 19: 00/00/af\n";
print "[38;5;20m 20: 00/00/d7\n";
print "[38;5;21m 21: 00/00/ff\n";
print "[38;5;22m 22: 00/5f/00\n";
print "[38;5;23m 23: 00/5f/5f\n";
print "[38;5;24m 24: 00/5f/87\n";
print "[38;5;25m 25: 00/5f/af\n";
print "[38;5;26m 26: 00/5f/d7\n";
print "[38;5;27m 27: 00/5f/ff\n";
print "[38;5;28m 28: 00/87/00\n";
print "[38;5;29m 29: 00/87/5f\n";
print "[38;5;30m 30: 00/87/87\n";
print "[38;5;31m 31: 00/87/af\n";
print "[38;5;32m 32: 00/87/d7\n";
print "[38;5;33m 33: 00/87/ff\n";
print "[38;5;34m 34: 00/af/00\n";
print "[38;5;35m 35: 00/af/5f\n";
print "[38;5;36m 36: 00/af/87\n";
print "[38;5;37m 37: 00/af/af\n";
print "[38;5;38m 38: 00/af/d7\n";
print "[38;5;39m 39: 00/af/ff\n";
print "[38;5;40m 40: 00/d7/00\n";
print "[38;5;41m 41: 00/d7/5f\n";
print "[38;5;42m 42: 00/d7/87\n";
print "[38;5;43m 43: 00/d7/af\n";
print "[38;5;44m 44: 00/d7/d7\n";
print "[38;5;45m 45: 00/d7/ff\n";
print "[38;5;46m 46: 00/ff/00\n";
print "[38;5;47m 47: 00/ff/5f\n";
print "[38;5;48m 48: 00/ff/87\n";
print "[38;5;49m 49: 00/ff/af\n";
print "[38;5;50m 50: 00/ff/d7\n";
print "[38;5;51m 51: 00/ff/ff\n";
print "[38;5;52m 52: 5f/00/00\n";
print "[38;5;53m 53: 5f/00/5f\n";
print "[38;5;54m 54: 5f/00/87\n";
print "[38;5;55m 55: 5f/00/af\n";
print "[38;5;56m 56: 5f/00/d7\n";
print "[38;5;57m 57: 5f/00/ff\n";
print "[38;5;58m 58: 5f/5f/00\n";
print "[38;5;59m 59: 5f/5f/5f\n";
print "[38;5;60m 60: 5f/5f/87\n";
print "[38;5;61m 61: 5f/5f/af\n";
print "[38;5;62m 62: 5f/5f/d7\n";
print "[38;5;63m 63: 5f/5f/ff\n";
print "[38;5;64m 64: 5f/87/00\n";
print "[38;5;65m 65: 5f/87/5f\n";
print "[38;5;66m 66: 5f/87/87\n";
print "[38;5;67m 67: 5f/87/af\n";
print "[38;5;68m 68: 5f/87/d7\n";
print "[38;5;69m 69: 5f/87/ff\n";
print "[38;5;70m 70: 5f/af/00\n";
print "[38;5;71m 71: 5f/af/5f\n";
print "[38;5;72m 72: 5f/af/87\n";
print "[38;5;73m 73: 5f/af/af\n";
print "[38;5;74m 74: 5f/af/d7\n";
print "[38;5;75m 75: 5f/af/ff\n";
print "[38;5;76m 76: 5f/d7/00\n";
print "[38;5;77m 77: 5f/d7/5f\n";
print "[38;5;78m 78: 5f/d7/87\n";
print "[38;5;79m 79: 5f/d7/af\n";
print "[38;5;80m 80: 5f/d7/d7\n";
print "[38;5;81m 81: 5f/d7/ff\n";
print "[38;5;82m 82: 5f/ff/00\n";
print "[38;5;83m 83: 5f/ff/5f\n";
print "[38;5;84m 84: 5f/ff/87\n";
print "[38;5;85m 85: 5f/ff/af\n";
print "[38;5;86m 86: 5f/ff/d7\n";
print "[38;5;87m 87: 5f/ff/ff\n";
print "[38;5;88m 88: 87/00/00\n";
print "[38;5;89m 89: 87/00/5f\n";
print "[38;5;90m 90: 87/00/87\n";
print "[38;5;91m 91: 87/00/af\n";
print "[38;5;92m 92: 87/00/d7\n";
print "[38;5;93m 93: 87/00/ff\n";
print "[38;5;94m 94: 87/5f/00\n";
print "[38;5;95m 95: 87/5f/5f\n";
print "[38;5;96m 96: 87/5f/87\n";
print "[38;5;97m 97: 87/5f/af\n";
print "[38;5;98m 98: 87/5f/d7\n";
print "[38;5;99m 99: 87/5f/ff\n";
print "[38;5;100m 100 :87/87/00\n";
print "[38;5;101m 101 :87/87/5f\n";
print "[38;5;102m 102 :87/87/87\n";
print "[38;5;103m 103 :87/87/af\n";
print "[38;5;104m 104 :87/87/d7\n";
print "[38;5;105m 105 :87/87/ff\n";
print "[38;5;106m 106 :87/af/00\n";
print "[38;5;107m 107 :87/af/5f\n";
print "[38;5;108m 108 :87/af/87\n";
print "[38;5;109m 109 :87/af/af\n";
print "[38;5;110m 110 :87/af/d7\n";
print "[38;5;111m 111 :87/af/ff\n";
print "[38;5;112m 112 :87/d7/00\n";
print "[38;5;113m 113 :87/d7/5f\n";
print "[38;5;114m 114 :87/d7/87\n";
print "[38;5;115m 115 :87/d7/af\n";
print "[38;5;116m 116 :87/d7/d7\n";
print "[38;5;117m 117 :87/d7/ff\n";
print "[38;5;118m 118 :87/ff/00\n";
print "[38;5;119m 119 :87/ff/5f\n";
print "[38;5;120m 120 :87/ff/87\n";
print "[38;5;121m 121 :87/ff/af\n";
print "[38;5;122m 122 :87/ff/d7\n";
print "[38;5;123m 123 :87/ff/ff\n";
print "[38;5;124m 124 :af/00/00\n";
print "[38;5;125m 125 :af/00/5f\n";
print "[38;5;126m 126 :af/00/87\n";
print "[38;5;127m 127 :af/00/af\n";
print "[38;5;128m 128 :af/00/d7\n";
print "[38;5;129m 129 :af/00/ff\n";
print "[38;5;130m 130 :af/5f/00\n";
print "[38;5;131m 131 :af/5f/5f\n";
print "[38;5;132m 132 :af/5f/87\n";
print "[38;5;133m 133 :af/5f/af\n";
print "[38;5;134m 134 :af/5f/d7\n";
print "[38;5;135m 135 :af/5f/ff\n";
print "[38;5;136m 136 :af/87/00\n";
print "[38;5;137m 137 :af/87/5f\n";
print "[38;5;138m 138 :af/87/87\n";
print "[38;5;139m 139 :af/87/af\n";
print "[38;5;140m 140 :af/87/d7\n";
print "[38;5;141m 141 :af/87/ff\n";
print "[38;5;142m 142 :af/af/00\n";
print "[38;5;143m 143 :af/af/5f\n";
print "[38;5;144m 144 :af/af/87\n";
print "[38;5;145m 145 :af/af/af\n";
print "[38;5;146m 146 :af/af/d7\n";
print "[38;5;147m 147 :af/af/ff\n";
print "[38;5;148m 148 :af/d7/00\n";
print "[38;5;149m 149 :af/d7/5f\n";
print "[38;5;150m 150 :af/d7/87\n";
print "[38;5;151m 151 :af/d7/af\n";
print "[38;5;152m 152 :af/d7/d7\n";
print "[38;5;153m 153 :af/d7/ff\n";
print "[38;5;154m 154 :af/ff/00\n";
print "[38;5;155m 155 :af/ff/5f\n";
print "[38;5;156m 156 :af/ff/87\n";
print "[38;5;157m 157 :af/ff/af\n";
print "[38;5;158m 158 :af/ff/d7\n";
print "[38;5;159m 159 :af/ff/ff\n";
print "[38;5;160m 160 :d7/00/00\n";
print "[38;5;161m 161 :d7/00/5f\n";
print "[38;5;162m 162 :d7/00/87\n";
print "[38;5;163m 163 :d7/00/af\n";
print "[38;5;164m 164 :d7/00/d7\n";
print "[38;5;165m 165 :d7/00/ff\n";
print "[38;5;166m 166 :d7/5f/00\n";
print "[38;5;167m 167 :d7/5f/5f\n";
print "[38;5;168m 168 :d7/5f/87\n";
print "[38;5;169m 169 :d7/5f/af\n";
print "[38;5;170m 170 :d7/5f/d7\n";
print "[38;5;171m 171 :d7/5f/ff\n";
print "[38;5;172m 172 :d7/87/00\n";
print "[38;5;173m 173 :d7/87/5f\n";
print "[38;5;174m 174 :d7/87/87\n";
print "[38;5;175m 175 :d7/87/af\n";
print "[38;5;176m 176 :d7/87/d7\n";
print "[38;5;177m 177 :d7/87/ff\n";
print "[38;5;178m 178 :d7/af/00\n";
print "[38;5;179m 179 :d7/af/5f\n";
print "[38;5;180m 180 :d7/af/87\n";
print "[38;5;181m 181 :d7/af/af\n";
print "[38;5;182m 182 :d7/af/d7\n";
print "[38;5;183m 183 :d7/af/ff\n";
print "[38;5;184m 184 :d7/d7/00\n";
print "[38;5;185m 185 :d7/d7/5f\n";
print "[38;5;186m 186 :d7/d7/87\n";
print "[38;5;187m 187 :d7/d7/af\n";
print "[38;5;188m 188 :d7/d7/d7\n";
print "[38;5;189m 189 :d7/d7/ff\n";
print "[38;5;190m 190 :d7/ff/00\n";
print "[38;5;191m 191 :d7/ff/5f\n";
print "[38;5;192m 192 :d7/ff/87\n";
print "[38;5;193m 193 :d7/ff/af\n";
print "[38;5;194m 194 :d7/ff/d7\n";
print "[38;5;195m 195 :d7/ff/ff\n";
print "[38;5;196m 196 :ff/00/00\n";
print "[38;5;197m 197 :ff/00/5f\n";
print "[38;5;198m 198 :ff/00/87\n";
print "[38;5;199m 199 :ff/00/af\n";
print "[38;5;200m 200 :ff/00/d7\n";
print "[38;5;201m 201 :ff/00/ff\n";
print "[38;5;202m 202 :ff/5f/00\n";
print "[38;5;203m 203 :ff/5f/5f\n";
print "[38;5;204m 204 :ff/5f/87\n";
print "[38;5;205m 205 :ff/5f/af\n";
print "[38;5;206m 206 :ff/5f/d7\n";
print "[38;5;207m 207 :ff/5f/ff\n";
print "[38;5;208m 208 :ff/87/00\n";
print "[38;5;209m 209 :ff/87/5f\n";
print "[38;5;210m 210 :ff/87/87\n";
print "[38;5;211m 211 :ff/87/af\n";
print "[38;5;212m 212 :ff/87/d7\n";
print "[38;5;213m 213 :ff/87/ff\n";
print "[38;5;214m 214 :ff/af/00\n";
print "[38;5;215m 215 :ff/af/5f\n";
print "[38;5;216m 216 :ff/af/87\n";
print "[38;5;217m 217 :ff/af/af\n";
print "[38;5;218m 218 :ff/af/d7\n";
print "[38;5;219m 219 :ff/af/ff\n";
print "[38;5;220m 220 :ff/d7/00\n";
print "[38;5;221m 221 :ff/d7/5f\n";
print "[38;5;222m 222 :ff/d7/87\n";
print "[38;5;223m 223 :ff/d7/af\n";
print "[38;5;224m 224 :ff/d7/d7\n";
print "[38;5;225m 225 :ff/d7/ff\n";
print "[38;5;226m 226 :ff/ff/00\n";
print "[38;5;227m 227 :ff/ff/5f\n";
print "[38;5;228m 228 :ff/ff/87\n";
print "[38;5;229m 229 :ff/ff/af\n";
print "[38;5;230m 230 :ff/ff/d7\n";
print "[38;5;231m 231 :ff/ff/ff\n";
print "[38;5;232m 232 :08/08/08\n";
print "[38;5;233m 233 :12/12/12\n";
print "[38;5;234m 234 :1c/1c/1c\n";
print "[38;5;235m 235 :26/26/26\n";
print "[38;5;236m 236 :30/30/30\n";
print "[38;5;237m 237 :3a/3a/3a\n";
print "[38;5;238m 238 :44/44/44\n";
print "[38;5;239m 239 :4e/4e/4e\n";
print "[38;5;240m 240 :58/58/58\n";
print "[38;5;241m 241 :62/62/62\n";
print "[38;5;242m 242 :6c/6c/6c\n";
print "[38;5;243m 243 :76/76/76\n";
print "[38;5;244m 244 :80/80/80\n";
print "[38;5;245m 245 :8a/8a/8a\n";
print "[38;5;246m 246 :94/94/94\n";
print "[38;5;247m 247 :9e/9e/9e\n";
print "[38;5;248m 248 :a8/a8/a8\n";
print "[38;5;249m 249 :b2/b2/b2\n";
print "[38;5;250m 250 :bc/bc/bc\n";
print "[38;5;251m 251 :c6/c6/c6\n";
print "[38;5;252m 252 :d0/d0/d0\n";
print "[38;5;253m 253 :da/da/da\n";
print "[38;5;254m 254 :e4/e4/e4\n";
print "[38;5;255m 255 :ee/ee/ee\n";
print "\n";
print "\n";
}
print "[0m";
exit;
================================================
FILE: xterm-color.el
================================================
;;; xterm-color.el --- ANSI, XTERM 256 and Truecolor support -*- lexical-binding: t -*-
;; Copyright (C) 2010-2020 xristos@sdf.org
;; All rights reserved
;; Modified: 2020-05-10
;; Version: 2.0
;; Author: xristos <xristos@sdf.org>
;; URL: https://github.com/atomontage/xterm-color
;; Package-Requires: ((emacs "24.4"))
;; Keywords: faces
;; Redistribution and use in source and binary forms, with or without
;; modification, are permitted provided that the following conditions
;; are met:
;;
;; * Redistributions of source code must retain the above copyright
;; notice, this list of conditions and the following disclaimer.
;;
;; * Redistributions in binary form must reproduce the above
;; copyright notice, this list of conditions and the following
;; disclaimer in the documentation and/or other materials
;; provided with the distribution.
;;
;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
;; POSSIBILITY OF SUCH DAMAGE.
;;; Commentary:
;;
;; Translate ANSI control sequences into text properties through state machine
;; emulation. This provides a far more accurate, comprehensive result than
;; `ansi-color.el' that is built-into Emacs, without compromising on performance.
;;
;; Please see README.org for documentation including example configurations.
;;
;;; Notes:
;;
;; Unsupported SGR attributes: 5 (slow blink), 6 (rapid blink), 8 (conceal),
;; 10 (primary font), 11-19 (alternative font), 20 (fraktur), 21 (double underline),
;; 25 (blink off), 29 (reveal), 52 (encircled), 60-65 (ideogram)
;;
;; Most of these can not be mapped to Emacs face properties. The rest may be
;; supported in a future release.
;;
;; Supported SGR attributes: Look at `xterm-color--dispatch-SGR'.
;; SGR attribute 1 is rendered as bright unless `xterm-color-use-bold-for-bright'
;; is non-nil which will, if current font has a bold variant, switch to bold.
;; SGR attributes 38 and 48 are supported in both their 256 color and truecolor
;; (24-bit) variants.
;;; Test:
;;
;; M-x xterm-color-test
;;
;; In shell or eshell:
;;
;; perl tests/xterm-colortest && perl tests/256colors2.pl
;;
;; printf "\x1b[0;1;3;4;35;51mThis is only a test\x1b[0m\n"
;;
;; Comparison with ansi-color.el:
;;
;; M-x xterm-color-test-raw then M-x xterm-color-colorize-buffer
;;
;; and contrast with
;;
;; M-x xterm-color-test-raw then M-: (ansi-color-apply-on-region (point-min) (point-max))
;;
;; Use `xterm-color--bench' for benchmarks during development.
;;; Code:
(require 'subr-x)
(require 'cl-lib)
(defgroup xterm-color nil
"Translate ANSI control sequences to text properties."
:prefix "xterm-color-"
:group 'processes)
;;;
;;; CUSTOM
;;;
(defcustom xterm-color-debug nil
"If non-nil, print ANSI state machine debug information in *Messages*."
:type 'boolean
:group 'xterm-color)
(defcustom xterm-color-use-bold-for-bright nil
"If non-nil, render bright foreground attribute as bold."
:type 'boolean
:group 'xterm-color)
(defcustom xterm-color-names
["#192033" ; black
"#A93F43" ; red
"#59963A" ; green
"#BE8A2D" ; yellow
"#4068A3" ; blue
"#7F60A7" ; magenta
"#4E9B9B" ; cyan
"#7E8A90"] ; white
"Default colors to use as regular ANSI colors."
:type '(vector string string string string string string string string)
:group 'xterm-color)
(defcustom xterm-color-names-bright
["#666666" ; black
"#EC6261" ; red
"#ADCF44" ; green
"#F0C649" ; yellow
"#63B4F6" ; blue
"#CB77F9" ; magenta
"#86D7DB" ; cyan
"#D3D2D1"] ; white
"Default colors to use as bright ANSI colors."
:type '(vector string string string string string string string string)
:group 'xterm-color)
;;;
;;; Buffer locals, used by state machine
;;;
(defvar-local xterm-color-preserve-properties nil
"If non-nil, preserve existing text properties on input about to be filtered.
Effectively this skips ANSI control sequence processing for input parts
that have text properties applied. This should be nil most of the time.
It is really meant for and works ok with eshell.")
(defvar-local xterm-color-render t
"If non-nil, render SGR attributes. Otherwise, discard them.
The latter enables processing and filtering out ANSI control sequences,
without applying them to the text.")
(defvar-local xterm-color--current-fg nil)
(defvar-local xterm-color--current-bg nil)
(defvar-local xterm-color--char-list nil
"List of characters that the current ANSI color applies to.
All characters are stored in reverse, LIFO, order.")
(defvar-local xterm-color--CSI-list nil
"List of current ANSI CSI sequence bytes (characters).
All characters are stored in reverse, LIFO, order.")
(defvar-local xterm-color--state :char
"Current state of ANSI state machine.
Can be one of :char, :set-char, :ansi-esc, :ansi-csi, :ansi-osc,
:ansi-osc-esc.")
(defvar-local xterm-color--attributes 0
"Bitvector that keeps track of state machine attributes.
These are: bright, italic, underline, strike-through, inverse-color,
frame, overline.")
(defvar-local xterm-color--face-cache nil
"Cache for auto-generated face attributes.")
(defvar-local xterm-color--truecolor-face-cache nil
"Cache for auto-generated face attributes.")
;;;
;;; Constants
;;;
(defconst +xterm-color--table-256+ [0 #x5f #x87 #xaf #xd7 #xff])
;;;
;;; Internal API
;;;
;; The face caching scheme requires an integer width of at least 56 bits
;; to cache faces derived from truecolor (24-bit) ANSI sequences. Truecolor
;; support is therefore disabled on e.g. machines with 32-bit integers.
(defvar xterm-color--support-truecolor (>= (1+ (floor (log most-positive-fixnum 2)))
59))
(cl-defun xterm-color--string-properties (string)
"Split STRING into substrings according to text properties.
Returns a list of (POS PROPERTIES SUBSTRING) elements."
(cl-loop
with pos = 0 and result
for next-pos = (next-property-change pos string)
while next-pos do
(push (list pos
(text-properties-at pos string)
(substring string pos next-pos))
result)
(setq pos next-pos)
finally
(push (list pos
(text-properties-at pos string)
(substring string pos))
result)
(cl-return-from xterm-color--string-properties
(nreverse result))))
(defun xterm-color--convert-text-properties-to-overlays (beg end)
"Transform face text properties between BEG and END, to equivalent overlays."
(save-excursion
(goto-char beg)
(let ((face-prop (if (or (get-text-property (point) 'font-lock-face)
(next-single-property-change (point) 'font-lock-face))
'font-lock-face 'face)))
(while (< (point) end)
(let* ((pos (point))
(current-value (get-text-property pos face-prop))
(next-change (next-single-property-change pos face-prop nil end)))
(when current-value
(let ((ov (make-overlay pos next-change)))
(overlay-put ov face-prop current-value)
(overlay-put ov 'xterm-color t)
(overlay-put ov 'evaporate t)))
(goto-char next-change)))
(remove-text-properties beg end (list 'xterm-color nil face-prop nil)))))
(defun xterm-color--message (format-string &rest args)
"Call `message' with FORMAT-STRING and ARGS.
Also see `xterm-color-debug'."
(when xterm-color-debug
(let ((message-truncate-lines t))
(message "xterm-color: %s" (apply #'format format-string args))
(message nil))))
;;;
;;; SGR state machine
;;;
(cl-defmacro xterm-color--with-SGR-constants (&body body)
(declare (indent defun))
`(cl-symbol-macrolet
((+bright+ 1)
(+italic+ 2)
(+underline+ 4)
(+strike-through+ 8)
(+negative+ 16)
(+frame+ 32)
(+overline+ 64))
,@body))
(cl-defmacro xterm-color--create-SGR-table ((attrib SGR-list) &body body)
"Create an iteration/dispatch table based on provided rules that
match SGR attributes.
For each attribute in SGR-LIST, check to see if it matches a rule in BODY and
evaluate the rule body if that is the case.
ATTRIB must be a symbol that is bound to SGR-LIST attributes in BODY.
SGR-LIST must be a list of SGR attributes (integers) in LIFO order.
BODY must contain rules with each rule being a list of form:
(:match (condition &key (skip 1)) rule-body-form..)
CONDITION must be a Lisp form which is evaluated as part of a COND
condition clause. If it is an atom, it is rewritten to (eq CONDITION ATTRIB).
Otherwise it is used as is. As per COND statement, if CONDITION evaluates
to non-nil, rule body forms are evaluated as part of the body of the COND
clause.
SKIP, if given, must be an integer specifying the number of elements that
should be skipped before the next iteration. The default is 1,
going down SGR-LIST one element at a time."
(declare (indent defun))
`(xterm-color--with-SGR-constants
(cl-macrolet
;; The following macros should be used in rule bodies
((set-a! (attr) `(setq xterm-color--attributes
(logior xterm-color--attributes ,attr)))
(unset-a! (attr) `(setq xterm-color--attributes
(logand xterm-color--attributes
(logand #xff (lognot ,attr)))))
(set-f! (fg-color) `(setq xterm-color--current-fg ,fg-color))
(set-b! (bg-color) `(setq xterm-color--current-bg ,bg-color))
(set-truecolor! (r g b current-color)
;; A single integer must be able to
;; hold and distinguish between:
;;
;; - 24bit truecolor values
;; - ANSI colors
;; - XTerm 256 colors
;;
;; The following packing scheme achieves that.
`(setq ,current-color
(logior (ash r 25) (ash g 17) (ash b 9)
#x100)))
(reset! () `(setq xterm-color--current-fg nil
xterm-color--current-bg nil
xterm-color--attributes 0)))
(cl-loop
for ,attrib = (cl-first ,SGR-list)
while ,SGR-list do
(cond
,@(cl-loop
for skip = 1
for (tag (c . rest) . rule-body) in body
when (not (eq tag :match)) do
(error "Rule (%s (%s..)..) does not start with :match" tag c)
when rest do
(setq skip (plist-get rest :skip))
(when (or (null skip) (cddr rest))
(error "Rule (%s (%s..)..) has malformed arguments: %s" tag c rest))
;; Condition part of COND
collect `(,(if (atom c) `(eq ,c ,attrib) c)
;; Body of COND
,@rule-body
(setq ,SGR-list
,(if (> skip 1)
`(nthcdr ,skip ,SGR-list)
`(cdr ,SGR-list)))))
(t (xterm-color--message "Not implemented SGR attribute %s" ,attrib)
(setq ,SGR-list (cdr ,SGR-list))))))))
(defsubst xterm-color--dispatch-SGR (SGR-list)
"Update state machine based on SGR-LIST (list of SGR attributes /integers)."
(xterm-color--create-SGR-table (elem SGR-list)
(:match (0) (reset!)) ; RESET everything
(:match ((<= 30 elem 37)) (set-f! (- elem 30))) ; ANSI FG color
(:match ((<= 40 elem 47)) (set-b! (- elem 40))) ; ANSI BG color
(:match (39) (set-f! nil)) ; RESET FG color (switch to default)
(:match (49) (set-b! nil)) ; RESET BG color (switch to default)
(:match (1) (set-a! +bright+))
(:match (2) (unset-a! +bright+))
(:match (22) (unset-a! +bright+))
(:match ((and (eq 38 (cl-first SGR-list))
(eq 2 (cl-second SGR-list))) ; Truecolor (24-bit) FG color
:skip 5)
(when xterm-color--support-truecolor
(if-let ((r (cl-third SGR-list))
(g (cl-fourth SGR-list))
(b (cl-fifth SGR-list)))
(if (or (> r 255) (> g 255) (> b 255))
(xterm-color--message "SGR 38;2;%s;%s;%s exceeds range"
r g b)
(set-truecolor! r g b xterm-color--current-fg))
(xterm-color--message "SGR 38;2;%s;%s;%s error, expected 38;2;R;G;B"
r g b))))
(:match ((and (eq 38 (cl-first SGR-list))
(eq 5 (cl-second SGR-list)))
:skip 3) ; XTERM 256 FG color
(if-let ((color (cl-third SGR-list)))
(if (> color 255)
(xterm-color--message "SGR 38;5;%s exceeds range" color)
(set-f! color))
(xterm-color--message "SGR 38;5;%s error, expected 38;5;COLOR"
color)))
(:match ((and (eq 48 (cl-first SGR-list))
(eq 2 (cl-second SGR-list))) ; Truecolor (24-bit) BG color
:skip 5)
(when xterm-color--support-truecolor
(if-let ((r (cl-third SGR-list))
(g (cl-fourth SGR-list))
(b (cl-fifth SGR-list)))
(if (or (> r 255) (> g 255) (> b 255))
(xterm-color--message "SGR 48;2;%s;%s;%s exceeds range"
r g b)
(set-truecolor! r g b xterm-color--current-bg))
(xterm-color--message "SGR 48;2;%s;%s;%s error, expected 48;2;R;G;B"
r g b))))
(:match ((and (eq 48 (cl-first SGR-list))
(eq 5 (cl-second SGR-list)))
:skip 3) ; XTERM 256 BG color
(if-let ((color (cl-third SGR-list)))
(if (> color 255)
(xterm-color--message "SGR 48;5;%s exceeds range" color)
(set-b! color))
(xterm-color--message "SGR 48;5;%s error, expected 48;5;COLOR"
color)))
(:match ((<= 90 elem 97)) ; AIXTERM hi-intensity FG
;; Rather than setting bright, which would be wrong,
;; rescale color to fall within 8-15 so that it gets
;; mapped to xterm-color-names-bright by xterm-color-256
(set-f! (- elem 82)))
;; Same for BG, rescale to 8-15
(:match ((<= 100 elem 107)) (set-b! (- elem 92))) ; AIXTERM hi-intensity BG
(:match (51) (set-a! +frame+))
(:match (53) (set-a! +overline+))
(:match (54) (unset-a! +frame+))
(:match (55) (unset-a! +overline+))
(:match (4) (set-a! +underline+))
(:match (24) (unset-a! +underline+))
(:match (3) (set-a! +italic+))
(:match (23) (unset-a! +italic+))
(:match (9) (set-a! +strike-through+))
(:match (29) (unset-a! +strike-through+))
(:match (7) (set-a! +negative+))
(:match (27) (unset-a! +negative+))))
(defsubst xterm-color--SGR-attributes (list)
"Convert LIFO list of SGR characters to FIFO list of SGR attributes (integers).
Returns FIFO list of SGR attributes or nil on errors.
Characters must be in the ASCII set 0-9 (decimal 48 to 57) and are converted
to integer digits by subtracting 48 from each character. E.g. Character 48
is converted to integer digit 0, character 49 to integer digit1..
Character 59 (;) is not converted but signifies that all accumulated integer
digits should be reversed and combined into a single integer (SGR attribute).
Examples:
Given (48) return (0)
Given (59) return (0 0)
Given (48 49 50) return (210)
Given (48 49 50 59 50 50 59 48 49) return (10 22 210)"
(cl-loop
with mul = 1 and n = 0 and ret
for c in list do
(if (/= 59 c)
(let ((e (- c 48)))
(unless (<= 0 e 9)
(xterm-color--message "Invalid SGR attribute %s" c)
(cl-return))
(cl-incf n (* mul e))
(setq mul (* mul 10)))
(push n ret)
(setq n 0 mul 1))
finally return (push n ret)))
;;;
;;; CSI state machine
;;;
(defsubst xterm-color--dispatch-CSI ()
"Update state machine based on CSI parameters collected so far.
Parameters are taken from `xterm-color--CSI-list' which stores them
in LIFO order."
(let* ((csi xterm-color--CSI-list)
(term (car csi)) ; final parameter, terminator
(params (cdr csi))) ; rest of parameters, LIFO order
(setq xterm-color--CSI-list nil)
(cond ((eq ?m term)
;; SGR
(let ((SGR-list (if (null params) '(0)
(xterm-color--SGR-attributes params))))
(when SGR-list
(xterm-color--dispatch-SGR SGR-list))))
(t
(xterm-color--message "%s CSI not implemented" csi)))))
(defmacro xterm-color--with-ANSI-macro-helpers (&rest body)
(declare (indent defun))
`(xterm-color--with-SGR-constants
(cl-symbol-macrolet ((fg xterm-color--current-fg)
(bg xterm-color--current-bg)
(attrs xterm-color--attributes)
(bold-bright xterm-color-use-bold-for-bright))
(cl-macrolet
((out! (x) `(push ,x result))
(push-char! (c) `(push ,c xterm-color--char-list))
(push-csi! (c) `(push ,c xterm-color--CSI-list))
(state! (s) `(setq state ,s))
(graphics? () `(or fg bg (/= attrs 0)))
(has? (attr) `(/= (logand ,attr attrs) 0))
(fmt-24bit (color) `(format "#%06x" ,color))
(fmt-256 (color) `(xterm-color-256 ,color))
;; Unpacks a packed truecolor value (as stored in
;; `xterm-color--current-fg' and `xterm-color--current-fg'.
(unpack (color) `(ash ,color -9))
;; To avoid hash collisions, a different packing scheme is used
;; for hash table keys. It can encode two colors (foreground
;; and background) that can either be truecolor 24bit or XTerm 256
;; color 8bit. XTerm 256 color values subsume ANSI colors, a
;; separate encoding scheme is not needed.
;;
;; The scheme used also accounts for the combination of a truecolor
;; with an XTerm 256 color as part of the same hashed entry. Since
;; two different hash tables are used to work around 32bit Emacs
;; limited integer range, two packing schemes are needed:
;;
;; High< 25 bits >Low
;; ATTR[7 bits]BG[9 bits]FG[9 bits] where BG and FG are each
;; encoded as the 8bit color value shifted left by 1 and combined
;; with a flag bit which is set when the color is present.
;;
;; High< 59 bits >Low
;; ATTR[7 bits]BG[26 bits]FG[26 bits] where BG and FG are each
;; encoded as the 24bit (RGB) or 8bit color value shifted left by
;; 2 and combined with 2 flag bits that are set when the value
;; is 24bit (high bit) and when the color is present (low bit).
(pack-256 (color) `(if ,color (logior (ash ,color 1) 1) 0))
(pack-24bit (color) `(if ,color
(if (> ,color 255)
(logior (ash (unpack ,color) 2) 3)
(logior (ash ,color 2) 1))
0))
;; If at least one of foreground / background color is a 24bit
;; truecolor value: Second packing scheme with
;; `xterm-color--truecolor-face-cache' is used.
;;
;; Every other case, including when no colors are present:
;; First packing scheme with `xterm-color--face-cache' is used.
(pack-key-into (k) `(cond ((or (and fg (> fg 255))
(and bg (> bg 255)))
;; At least one truecolor 24bit value
(setq ,k (logior (ash attrs 52)
(ash (pack-24bit bg) 26)
(pack-24bit fg)))
xterm-color--truecolor-face-cache)
(t ;; No truecolor 24bit value
(setq ,k (logior (ash attrs 18)
(ash (pack-256 bg) 9)
(pack-256 fg)))
xterm-color--face-cache)))
(face! (k v) `(setq plistf (plist-put plistf ,k ,v)))
(make-color-fg () `(if (and bold-bright
(< fg 256)
(or (has? +bright+) (<= 8 fg 15)))
(progn (face! :weight 'bold)
(face! :foreground
(fmt-256 (if (<= 8 fg) (- fg 8) fg))))
(face! :foreground
(if (> fg 255)
(fmt-24bit (unpack fg))
(fmt-256 (if (and (<= fg 7) (has? +bright+))
(+ fg 8)
fg))))))
(make-color-bg () `(face! :background (cond ((> bg 255) (fmt-24bit (unpack bg)))
(t (fmt-256 bg)))))
(make-face () `(let* (k
(table (pack-key-into k)))
(or (gethash k table)
(let (plistf)
(when (has? +italic+) (face! :slant 'italic))
(when (has? +underline+) (face! :underline t))
(when (has? +strike-through+) (face! :strike-through t))
(when (has? +negative+) (face! :inverse-video t))
(when (has? +overline+) (face! :overline t))
(when (has? +frame+) (face! :box t))
(cond (fg (make-color-fg))
(t (when (and bold-bright (has? +bright+))
(face! :weight 'bold))))
(when bg (make-color-bg))
(puthash k plistf table)))))
(maybe-fontify () '(when xterm-color--char-list
(let ((s (concat (nreverse xterm-color--char-list))))
(when (and xterm-color-render (graphics?))
(add-text-properties
0 (length s)
(list 'xterm-color t
(if font-lock-mode 'font-lock-face 'face) (make-face))
s))
(out! s))
(setq xterm-color--char-list nil))))
,@body))))
;;;
;;; Exports
;;;
;;;###autoload
(defun xterm-color-filter-strip (string)
"Translate ANSI color sequences in STRING into text properties.
Returns new STRING with text properties applied.
In order to get maximum performance, this function strips text properties
if they are present in STRING."
(unless xterm-color--face-cache
(setq xterm-color--face-cache
(make-hash-table :weakness 'value)))
(unless xterm-color--truecolor-face-cache
(setq xterm-color--truecolor-face-cache
(make-hash-table :weakness 'value)))
(xterm-color--with-ANSI-macro-helpers
(cl-loop
with state = xterm-color--state and result
for char across string do
(cond
((eq state :char)
(cond
((eq char 27) ; ESC
(maybe-fontify)
(state! :ansi-esc))
(t
(if (graphics?)
(push-char! char)
(out! (list char))))))
((eq state :ansi-esc)
(cond ((eq char ?\[)
(state! :ansi-csi))
((eq char ?\])
(state! :ansi-osc))
((or (eq char ?\()
(eq char ?\)))
(state! :set-char))
(t
(push-char! char)
(state! :char))))
((eq state :ansi-csi)
(push-csi! char)
(when (and (>= char #x40)
(<= char #x7e))
(xterm-color--dispatch-CSI)
(state! :char)))
((eq state :ansi-osc)
;; OSC sequences are skipped
(cond ((eq char 7)
(state! :char))
((eq char 27)
;; ESC
(state! :ansi-osc-esc))))
((eq state :ansi-osc-esc)
(cond ((eq char ?\\)
(state! :char))
(t (state! :ansi-osc))))
((eq state :set-char)
(xterm-color--message "%s SET-CHAR not implemented" char)
(state! :char)))
finally return
(progn (when (eq state :char) (maybe-fontify))
(setq xterm-color--state state)
(apply 'concat (nreverse result))))))
;;;###autoload
(defun xterm-color-filter (string)
"Translate ANSI color sequences in STRING into text properties.
Returns new STRING with text properties applied.
This function checks if `xterm-color-preserve-properties' is non-nil
and only calls `xterm-color-filter-strip' on substrings that do not
have text properties applied (passing through the rest unmodified).
Preserving properties in this fashion is not very robust as there may
be situations where text properties are applied on ANSI data, which
will desync the state machine.
Preserving properties works ok with and is really meant for eshell.
This can be inserted into `comint-preoutput-filter-functions'."
(if (not xterm-color-preserve-properties)
(xterm-color-filter-strip string)
(cl-loop
with result
for (_ props substring) in (xterm-color--string-properties string) do
(push (if props substring (xterm-color-filter-strip substring))
result)
finally return (apply 'concat (nreverse result)))))
;;;###autoload
(defun xterm-color-256 (color)
(cond ((and (>= color 232)
(<= color 255))
;; Grayscale
(let ((val (+ 8 (* (- color 232) 10))))
(format "#%02x%02x%02x" val val val)))
((<= color 7)
;; Normal ANSI color
(aref xterm-color-names color))
((and (>= color 8)
(<= color 15))
;; Bright ANSI color
(aref xterm-color-names-bright (- color 8)))
(t (let* ((color (- color 16))
(red (/ color 36))
(color (mod color 36))
(green (/ color 6))
(color (mod color 6))
(blue color))
;; XTERM 256 color
(format "#%02x%02x%02x"
(aref +xterm-color--table-256+ red)
(aref +xterm-color--table-256+ green)
(aref +xterm-color--table-256+ blue))))))
;;;
;;; Interactive
;;;
;;;###autoload
(cl-defun xterm-color-colorize-buffer (&optional use-overlays)
"Apply `xterm-color-filter' to current buffer, and replace its contents.
Colors are applied using \\='face, unless font-lock-mode is active, in
which case \\='font-lock-face is used. Operation with font-lock mode active
is not recommended.
If USE-OVERLAYS is non-nil, colors are applied to the buffer using overlays
instead of text properties. A C-u prefix arg causes overlays to be used."
(interactive "P")
(let ((read-only-p buffer-read-only))
(when read-only-p
(unless (y-or-n-p "Buffer is read only, continue colorizing? ")
(cl-return-from xterm-color-colorize-buffer))
(read-only-mode -1))
(insert (xterm-color-filter (delete-and-extract-region (point-min) (point-max))))
(when (and xterm-color-render use-overlays)
(xterm-color--convert-text-properties-to-overlays (point-min) (point-max)))
(goto-char (point-min))
(when read-only-p (read-only-mode 1))))
;;;###autoload
(defun xterm-color-clear-cache ()
"Clear xterm color face attribute cache.
You may want to call this if you change `xterm-color-names' or
`xterm-color-names-bright' at runtime and you want to see the changes
take place in a pre-existing buffer that has had xterm-color initialized.
Since the cache is buffer-local and created on-demand when needed, this has no
effect when called from a buffer that does not have a cache."
(interactive)
(and xterm-color--face-cache
(clrhash xterm-color--face-cache)
(xterm-color--message "Cleared face attribute cache"))
(and xterm-color--truecolor-face-cache
(clrhash xterm-color--truecolor-face-cache)
(xterm-color--message "Cleared truecolor face attribute cache")))
;;;
;;; Tests
;;;
(defmacro xterm-color--bench (path &optional repetitions)
`(benchmark-run-compiled ,repetitions
(with-temp-buffer
(insert-file-contents-literally ,path)
(xterm-color-colorize-buffer))))
(defvar xterm-color--test-do-filter t)
(cl-defmacro xterm-color--with-tests (&body body)
`(cl-labels ((ansi-filter (msg &rest args)
(insert
(if xterm-color--test-do-filter
(xterm-color-filter
(apply #'format msg args))
(apply #'format msg args))))
(test (name &rest attribs)
(ansi-filter "\x1b[0;%smThis is only a test!\x1b[0m\t --[ %s\n"
(mapconcat #'identity attribs ";")
name)))
,@body))
(defun xterm-color--test-ansi ()
(xterm-color--with-tests
(let ((test-attributes
'(("1" . "bright")
("51" . "frame")
("3" . "italic")
("4" . "underline")
("7" . "negative")
("9" . "strike through")
("53" . "overline")
("1;51" . "bright + frame")
("1;3" . "bright + italic")
("1;4" . "bright + underline")
("1;7" . "bright + negative")
("1;9" . "bright + strike through")
("1;53" . "bright + overline"))))
;; Attributes (no color)
(insert "* ANSI attributes (default colors)\n")
(if xterm-color-use-bold-for-bright
(insert " Expect: Bold instead of bright")
(insert " Expect: Bright not to be rendered since no foreground color is set"))
(insert "\n\n")
(cl-loop for (attrib . name) in test-attributes
do (test name attrib)
finally (insert "\n"))
(insert "* ANSI attributes (blue foreground)\n")
(if xterm-color-use-bold-for-bright
(insert " Expect: Bold instead of bright")
(insert " Expect: Bright rendered as bright color"))
(insert "\n\n")
(cl-loop for (attrib . name) in test-attributes
do (test name "34" attrib)
finally (insert "\n"))
(insert "* ANSI attributes (blue background)\n")
(if xterm-color-use-bold-for-bright
(insert " Expect: Bold instead of bright")
(insert " Expect: Bright not to be rendered since no foreground color is set"))
(insert "\n\n")
(cl-loop for (attrib . name) in test-attributes
do (test name "44" attrib)
finally (insert "\n"))
(insert "* ANSI attributes (AIXTERM blue foreground)\n")
(if xterm-color-use-bold-for-bright
(insert " Expect: Bold instead of bright")
(insert " Expect: Bright color everywhere due to AIXTERM"))
(insert "\n\n")
(cl-loop for (attrib . name) in test-attributes
do (test name "94" attrib)
finally (insert "\n"))
(insert "* ANSI attributes (AIXTERM red background)\n")
(insert " Expect: Bright background color due to AIXTERM\n")
(if xterm-color-use-bold-for-bright
(insert " Expect: Bold instead of bright for foreground\n\n")
(insert "\n"))
(cl-loop for (attrib . name) in test-attributes
do (test name "101" attrib)
finally (insert "\n"))
(insert "* Misc\n")
(if xterm-color-use-bold-for-bright
(progn
(insert " Expect: Bold instead of bright\n")
(insert " Otherwise bright rendered as normal intensity\n\n"))
(insert "\n"))
(insert "; Resetting FG color should not affect other SGR bits\n")
(ansi-filter "Default \x1b[34;1mBright blue\x1b[39m Reset-fg-color \x1b[34mBlue (bright)\x1b[0m\n\n")
(insert "; AIXTERM bright color should not set bright SGR bit\n")
(ansi-filter "Default \x1b[94mBright blue\x1b[34m Switch-to-blue (normal)\x1b[0m\n")
(insert "\n"))))
(defun xterm-color--test-xterm ()
(xterm-color--with-tests
;; System colors
(cl-loop for color from 40 to 47
do (ansi-filter "\x1b[0;%sm " color)
finally (ansi-filter "\x1b[0m * ANSI system colors\n"))
;; Normal ANSI colors mapped to XTERM
(cl-loop for color from 0 to 7
do (ansi-filter "\x1b[48;5;%sm " color)
finally (ansi-filter "\x1b[0m * ANSI colors mapped to XTERM\n"))
;; Bright ANSI colors mapped to XTERM
(cl-loop for color from 8 to 15
do (ansi-filter "\x1b[48;5;%sm " color)
finally (ansi-filter "\x1b[0m * ANSI bright colors mapped to XTERM\n\n"))
;; XTERM 256 color cubes
(insert "* XTERM 256 color cubes\n\n")
(cl-loop for green from 0 to 5 do
(cl-loop for red from 0 to 5 do
(cl-loop for blue from 0 to 5
for color = (+ 16 (* 36 red) (* green 6) blue)
do (ansi-filter "\x1b[48;5;%sm \x1b[0m" color))
(ansi-filter "\x1b[0m "))
(insert "\n"))
;; Truecolor color ramps
(insert "\n")
(insert "* Truecolor\n\n")
(cond (xterm-color--support-truecolor
;; Adapted from: https://gist.github.com/XVilka/8346728
(cl-loop
with steps = 77
for c from 0 below steps
for r = (- 255 (* c (/ 255 steps)))
for g = (* c (/ 510 steps))
for b = (* c (/ 255 steps)) do
(when (> g 255) (setq g (- 510 g)))
(ansi-filter "\x1b[48;2;%s;%s;%sm \x1b[m" r g b)))
(t
(insert "Truecolor is not supported on Emacs 32bit")))
(insert "\n\n")
(insert "* XTERM color grayscale ramp\n\n")
(cl-loop for color from 232 to 255
do (ansi-filter "\x1b[48;5;%sm " color)
finally (ansi-filter "\x1b[0m\n\n"))))
;;;###autoload
(defun xterm-color-test ()
"Create, display and render a new buffer containing ANSI control sequences."
(interactive)
(let* ((name (generate-new-buffer-name "*xterm-color-test*"))
(buf (get-buffer-create name)))
(switch-to-buffer buf))
(xterm-color--test-xterm)
(let ((xterm-color-use-bold-for-bright nil))
(xterm-color--test-ansi))
(xterm-color-clear-cache)
(insert "; Temporarily setting `xterm-color-use-bold-for-bright' to T\n")
(insert "; Current font needs to have a bold variant for following tests\n\n")
(let ((xterm-color-use-bold-for-bright t))
(xterm-color--test-ansi))
(setq buffer-read-only t)
(goto-char (point-min)))
;;;###autoload
(defun xterm-color-test-raw ()
"Create and display a new buffer containing ANSI SGR control sequences.
ANSI sequences are not processed. One can use a different Emacs package,
such as ansi-color.el to do so. This is really meant to be used for easy
comparisons/benchmarks with libraries that offer similar functionality."
(interactive)
(let* ((name (generate-new-buffer-name "*xterm-color-test-raw*"))
(buf (get-buffer-create name)))
(switch-to-buffer buf))
(let (xterm-color--test-do-filter)
(xterm-color--test-xterm)
(xterm-color--test-ansi))
(goto-char (point-min)))
(provide 'xterm-color)
;;; xterm-color.el ends here
gitextract_76wscj12/ ├── .gitignore ├── LICENSE ├── NEWS.org ├── README.org ├── tests/ │ ├── 256colors2.pl │ └── xterm-colortest └── xterm-color.el
Condensed preview — 7 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (74K chars).
[
{
"path": ".gitignore",
"chars": 5,
"preview": "*.elc"
},
{
"path": "LICENSE",
"chars": 1301,
"preview": "Copyright (c) 2010-2020 xristos@sdf.org\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or"
},
{
"path": "NEWS.org",
"chars": 594,
"preview": "* Changes\n\n** 2.0 (2020-05-10)\n\n+ Added truecolor (24-bit) and overlay support. Overlays may optionally\n be used only w"
},
{
"path": "README.org",
"chars": 7014,
"preview": "[[https://opensource.org/licenses/BSD-2-Clause][https://img.shields.io/badge/license-BSD-blue.svg]]\n[[https://melpa.org/"
},
{
"path": "tests/256colors2.pl",
"chars": 1021,
"preview": "#!/usr/bin/perl\n# Author: Todd Larason <jtl@molehill.org>\n# $XFree86: xc/programs/xterm/vttests/256colors2.pl,v 1.2 2002"
},
{
"path": "tests/xterm-colortest",
"chars": 20173,
"preview": "#!/usr/bin/perl\n\n# by entheon, do whatever the hell you want with this file\n\nprint \"\\n\";\nprint \"************************"
},
{
"path": "xterm-color.el",
"chars": 38010,
"preview": ";;; xterm-color.el --- ANSI, XTERM 256 and Truecolor support -*- lexical-binding: t -*-\n\n;; Copyright (C) 2010-2020 xris"
}
]
About this extraction
This page contains the full source code of the atomontage/xterm-color GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 7 files (66.5 KB), approximately 23.4k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.