diff options
| -rw-r--r-- | lisp/ChangeLog | 21 | ||||
| -rw-r--r-- | lisp/ansi-color.el | 439 |
2 files changed, 361 insertions, 99 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 42df38b4ba1..315958d693e 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -2,6 +2,27 @@ | |||
| 2 | 2 | ||
| 3 | * indent.el (indent-for-tab-command): Doc fix. | 3 | * indent.el (indent-for-tab-command): Doc fix. |
| 4 | 4 | ||
| 5 | 2000-09-14 Alex Schroeder <alex@gnu.org> | ||
| 6 | |||
| 7 | * ansi-color.el (ansi-colors): Doc change. | ||
| 8 | (ansi-color-get-face): Simplified regexp. | ||
| 9 | (ansi-color-faces-vector): Added more faces, doc change. | ||
| 10 | (ansi-color-names-vector): Doc change. | ||
| 11 | (ansi-color-regexp): Simplified regexp. | ||
| 12 | (ansi-color-parameter-regexp): New regexp. | ||
| 13 | (ansi-color-filter-apply): Doc change. | ||
| 14 | (ansi-color-filter-region): Doc change. | ||
| 15 | (ansi-color-apply): Use ansi-color-regexp and ansi-color-get-face, | ||
| 16 | deal with zero length parameters. | ||
| 17 | (ansi-color-apply-on-region): Doc change. | ||
| 18 | (ansi-color-map): Doc change. | ||
| 19 | (ansi-color-map-update): Removed debugging message. | ||
| 20 | (ansi-color-get-face-1): Added condition-case to trap | ||
| 21 | args-out-of-range errors. | ||
| 22 | (ansi-color-get-face): Doc change. | ||
| 23 | (ansi-color-make-face): Removed. | ||
| 24 | (ansi-color-for-shell-mode): New option. | ||
| 25 | |||
| 5 | 2000-09-13 Kenichi Handa <handa@etl.go.jp> | 26 | 2000-09-13 Kenichi Handa <handa@etl.go.jp> |
| 6 | 27 | ||
| 7 | * international/quail.el (quail-start-translation): Translate KEY | 28 | * international/quail.el (quail-start-translation): Translate KEY |
diff --git a/lisp/ansi-color.el b/lisp/ansi-color.el index 746038e32dc..ca07b0f8ea5 100644 --- a/lisp/ansi-color.el +++ b/lisp/ansi-color.el | |||
| @@ -1,10 +1,10 @@ | |||
| 1 | ;;; ansi-color.el -- translate ANSI into text-properties | 1 | ;;; ansi-color.el --- translate ANSI into text-properties |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1999 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1999, 2000 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: Alex Schroeder <alex@gnu.org> | 5 | ;; Author: Alex Schroeder <alex@gnu.org> |
| 6 | ;; Maintainer: Alex Schroeder <alex@gnu.org> | 6 | ;; Maintainer: Alex Schroeder <alex@gnu.org> |
| 7 | ;; Version: 2.1.2 | 7 | ;; Version: 2.4.0 |
| 8 | ;; Keywords: comm processes | 8 | ;; Keywords: comm processes |
| 9 | 9 | ||
| 10 | ;; This file is part of GNU Emacs. | 10 | ;; This file is part of GNU Emacs. |
| @@ -26,53 +26,49 @@ | |||
| 26 | 26 | ||
| 27 | ;;; Commentary: | 27 | ;;; Commentary: |
| 28 | 28 | ||
| 29 | ;; You can get the latest version of this file from my homepage | 29 | ;; This file provides a function that takes a string containing Select |
| 30 | ;; <URL:http://www.geocities.com/TimesSquare/6120/emacs.html>. | 30 | ;; Graphic Rendition (SGR) control sequences (formerly known as ANSI |
| 31 | ;; escape sequences) and tries to replace these with text-properties. | ||
| 31 | ;; | 32 | ;; |
| 32 | ;; This file provides a function that takes a string containing ANSI | 33 | ;; This allows you to run ls --color=yes in shell-mode: If |
| 33 | ;; control sequences and tries to replace these with text-properties. | 34 | ;; `ansi-color-for-shell-mode' is non-nil, the SGR control sequences are |
| 35 | ;; translated into text-properties, colorizing the ls output. If | ||
| 36 | ;; `ansi-color-for-shell-mode' is nil, the SGR control sequences are | ||
| 37 | ;; stripped, making the ls output legible. | ||
| 34 | ;; | 38 | ;; |
| 35 | ;; I was unable to extract this functionality from term.el for another | 39 | ;; SGR control sequences are defined in section 3.8.117 of the ECMA-48 |
| 36 | ;; program I wanted to extend (the MUSH client TinyTalk.el), so I had to | 40 | ;; standard (identical to ISO/IEC 6429), which is freely available as a |
| 37 | ;; rewrite this. | 41 | ;; PDF file <URL:http://www.ecma.ch/ecma1/STAND/ECMA-048.HTM>. The |
| 42 | ;; "Graphic Rendition Combination Mode (GRCM)" implemented is | ||
| 43 | ;; "cumulative mode" as defined in section 7.2.8. Cumulative mode means | ||
| 44 | ;; that whenever possible, SGR control sequences are combined (ie. blue | ||
| 45 | ;; and bold). | ||
| 38 | 46 | ||
| 39 | ;;; Testing: | 47 | ;; The basic functions are: |
| 40 | 48 | ;; | |
| 41 | ;; If you want to test the setup, evaluate the following fragment in a | 49 | ;; `ansi-color-apply' to colorize a string containing SGR control |
| 42 | ;; buffer without font-lock-mode. This doesn't work in buffers that | 50 | ;; sequences. |
| 43 | ;; have font-lock-mode! | 51 | ;; |
| 52 | ;; `ansi-color-filter-apply' to filter SGR control sequences from a | ||
| 53 | ;; string. | ||
| 44 | ;; | 54 | ;; |
| 45 | ;; (insert (ansi-color-apply "\033[1mbold\033[0m and \033[34mblue\033[0m, \033[1m\033[34mbold and blue\033[0m!!")) | 55 | ;; `ansi-color-apply-on-region' to colorize a region containing SGR |
| 56 | ;; control sequences. | ||
| 57 | ;; | ||
| 58 | ;; `ansi-color-filter-region' to filter SGR control sequences from a | ||
| 59 | ;; region. | ||
| 60 | |||
| 61 | ;; Instead of defining lots of new faces, this package uses | ||
| 62 | ;; text-properties as described in the elisp manual | ||
| 63 | ;; *Note (elisp)Special Properties::. | ||
| 46 | 64 | ||
| 47 | ;; Usage with TinyMush.el: | 65 | ;;; Thanks |
| 48 | 66 | ||
| 49 | ;; In order to install this with TinyMush.el, add the following to your | 67 | ;; Georges Brun-Cottan <gbruncot@emc.com> for improving ansi-color.el |
| 50 | ;; .emacs file: | 68 | ;; substantially by adding the code needed to cope with arbitrary chunks |
| 69 | ;; of output and the filter functions. | ||
| 51 | ;; | 70 | ;; |
| 52 | ;; (setq tinymud-filter-line-hook 'my-ansi-color-filter) | 71 | ;; Markus Kuhn <Markus.Kuhn@cl.cam.ac.uk> for pointing me to ECMA-48. |
| 53 | ;; (autoload 'ansi-color-apply "ansi-color" | ||
| 54 | ;; "Translates ANSI color control sequences into text-properties." t) | ||
| 55 | ;; (defun my-ansi-color-filter (conn line) | ||
| 56 | ;; "Call `ansi-color-apply' and then processes things like `filter-line'." | ||
| 57 | ;; (setq line (ansi-color-apply line)) | ||
| 58 | ;; (if (not (get-value conn 'trigger-disable)) | ||
| 59 | ;; (progn | ||
| 60 | ;; (check-triggers conn line | ||
| 61 | ;; (get-value conn 'triggers)) | ||
| 62 | ;; (check-triggers conn line | ||
| 63 | ;; (get-value (get-value conn 'world) 'triggers)) | ||
| 64 | ;; (check-triggers conn line | ||
| 65 | ;; tinymud-global-triggers))) | ||
| 66 | ;; (display-line conn line) | ||
| 67 | ;; t) | ||
| 68 | |||
| 69 | ;; Usage with shell-mode: | ||
| 70 | |||
| 71 | ;; In order to enjoy the marvels of "ls --color=tty" you will have to | ||
| 72 | ;; enter shell-mode using M-x shell, possibly disable font-lock-mode | ||
| 73 | ;; using M-: (font-lock-mode 0), and add ansi-color-apply to | ||
| 74 | ;; comint-preoutput-filter-functions using M-: (add-hook | ||
| 75 | ;; 'comint-preoutput-filter-functions 'ansi-color-apply). | ||
| 76 | 72 | ||
| 77 | 73 | ||
| 78 | 74 | ||
| @@ -80,86 +76,331 @@ | |||
| 80 | 76 | ||
| 81 | ;; Customization | 77 | ;; Customization |
| 82 | 78 | ||
| 83 | (defvar ansi-color-faces-vector | 79 | (defgroup ansi-colors nil |
| 84 | [default bold default default underline bold default modeline] | 80 | "Translating SGR control sequences to text-properties. |
| 85 | "Faces used for ANSI control sequences determining a face. | 81 | This translation effectively colorizes strings and regions based upon |
| 82 | SGR control sequences embedded in the text. SGR (Select Graphic | ||
| 83 | Rendition) control sequences are defined in section 3.8.117 of the | ||
| 84 | ECMA-48 standard \(identical to ISO/IEC 6429), which is freely available | ||
| 85 | as a PDF file <URL:http://www.ecma.ch/ecma1/STAND/ECMA-048.HTM>." | ||
| 86 | :version "20.7" | ||
| 87 | :group 'processes) | ||
| 88 | |||
| 89 | (defcustom ansi-color-faces-vector | ||
| 90 | [default bold default italic underline bold bold-italic modeline] | ||
| 91 | "Faces used for SGR control sequences determining a face. | ||
| 92 | This vector holds the faces used for SGR control sequence parameters 0 | ||
| 93 | to 7. | ||
| 86 | 94 | ||
| 87 | Those are sequences like this one: \033[1m, where 1 could be one of the | 95 | Parameter Description Face used by default |
| 88 | following numbers: 0 (default), 1 (hilight, rendered as bold), 4 | 96 | 0 default default |
| 89 | (underline), 5 (flashing, rendered as bold), 7 (inverse, rendered the | 97 | 1 bold bold |
| 90 | same as the modeline)") | 98 | 2 faint default |
| 99 | 3 italic italic | ||
| 100 | 4 underlined underline | ||
| 101 | 5 slowly blinking bold | ||
| 102 | 6 rapidly blinking bold-italic | ||
| 103 | 7 negative image modeline | ||
| 91 | 104 | ||
| 92 | (defvar ansi-color-names-vector | 105 | This vector is used by `ansi-color-make-color-map' to create a color |
| 106 | map. This color map is stored in the variable `ansi-color-map'." | ||
| 107 | :type '(vector face face face face face face face face) | ||
| 108 | :set 'ansi-color-map-update | ||
| 109 | :initialize 'custom-initialize-default | ||
| 110 | :group 'ansi-colors) | ||
| 111 | |||
| 112 | (defcustom ansi-color-names-vector | ||
| 93 | ["black" "red" "green" "yellow" "blue" "magenta" "cyan" "white"] | 113 | ["black" "red" "green" "yellow" "blue" "magenta" "cyan" "white"] |
| 94 | "Array of colors. | 114 | "Colors used for SGR control sequences determining a color. |
| 115 | This vector holds the colors used for SGR control sequences parameters | ||
| 116 | 30 to 37 \(foreground colors) and 40 to 47 (background colors). | ||
| 117 | |||
| 118 | Parameter Color | ||
| 119 | 30 40 black | ||
| 120 | 31 41 red | ||
| 121 | 32 42 green | ||
| 122 | 33 43 yellow | ||
| 123 | 34 44 blue | ||
| 124 | 35 45 magenta | ||
| 125 | 36 46 cyan | ||
| 126 | 37 47 white | ||
| 127 | |||
| 128 | This vector is used by `ansi-color-make-color-map' to create a color | ||
| 129 | map. This color map is stored in the variable `ansi-color-map'." | ||
| 130 | :type '(vector string string string string string string string string) | ||
| 131 | :set 'ansi-color-map-update | ||
| 132 | :initialize 'custom-initialize-default | ||
| 133 | :group 'ansi-colors) | ||
| 134 | |||
| 135 | (defcustom ansi-color-for-shell-mode nil | ||
| 136 | "Determine wether font-lock or ansi-color get to fontify shell buffers. | ||
| 137 | |||
| 138 | If non-nil and `global-font-lock-mode' is non-nil, ansi-color will be | ||
| 139 | used. This adds `ansi-color-apply' to | ||
| 140 | `comint-preoutput-filter-functions' and removes | ||
| 141 | `ansi-color-filter-apply' for all shell-mode buffers. | ||
| 142 | |||
| 143 | If non-nil and global-font-lock-mode is nil, both `ansi-color-apply' and | ||
| 144 | `ansi-color-filter-apply' will be removed from | ||
| 145 | `comint-preoutput-filter-functions' for all shell-mode buffers. | ||
| 146 | |||
| 147 | If nil, font-lock will be used (if it is enabled). This adds | ||
| 148 | `ansi-color-filter-apply' to `comint-preoutput-filter-functions' and | ||
| 149 | removes `ansi-color-apply' for all shell-mode buffers." | ||
| 150 | :version "20.8" | ||
| 151 | :type 'boolean | ||
| 152 | :set (function (lambda (symbol value) | ||
| 153 | (set-default symbol value) | ||
| 154 | (save-excursion | ||
| 155 | (let ((buffers (buffer-list)) | ||
| 156 | buffer) | ||
| 157 | (while buffers | ||
| 158 | (setq buffer (car buffers) | ||
| 159 | buffers (cdr buffers)) | ||
| 160 | (set-buffer buffer) | ||
| 161 | (when (eq major-mode 'shell-mode) | ||
| 162 | (if value | ||
| 163 | (if global-font-lock-mode | ||
| 164 | (progn | ||
| 165 | (font-lock-mode 0) | ||
| 166 | (remove-hook 'comint-preoutput-filter-functions | ||
| 167 | 'ansi-color-filter-apply) | ||
| 168 | (add-hook 'comint-preoutput-filter-functions | ||
| 169 | 'ansi-color-apply)) | ||
| 170 | (remove-hook 'comint-preoutput-filter-functions | ||
| 171 | 'ansi-color-filter-apply) | ||
| 172 | (remove-hook 'comint-preoutput-filter-functions | ||
| 173 | 'ansi-color-apply)) | ||
| 174 | (if global-font-lock-mode | ||
| 175 | (font-lock-mode 1)) | ||
| 176 | (remove-hook 'comint-preoutput-filter-functions | ||
| 177 | 'ansi-color-apply) | ||
| 178 | (add-hook 'comint-preoutput-filter-functions | ||
| 179 | 'ansi-color-filter-apply)))))))) | ||
| 180 | :initialize 'custom-initialize-reset | ||
| 181 | :group 'ansi-colors) | ||
| 182 | |||
| 183 | (defconst ansi-color-regexp "\033\\[\\([0-9;]*\\)m" | ||
| 184 | "Regexp that matches SGR control sequences.") | ||
| 185 | |||
| 186 | (defconst ansi-color-parameter-regexp "\\([0-9]*\\)[m;]" | ||
| 187 | "Regexp that matches SGR control sequence parameters.") | ||
| 188 | |||
| 189 | |||
| 190 | ;; Main functions | ||
| 191 | |||
| 192 | |||
| 193 | (defun ansi-color-filter-apply (s) | ||
| 194 | "Filter out all SGR control sequences from S. | ||
| 195 | |||
| 196 | This function can be added to `comint-preoutput-filter-functions'." | ||
| 197 | (while (string-match ansi-color-regexp s) | ||
| 198 | (setq s (replace-match "" t t s))) | ||
| 199 | s) | ||
| 200 | |||
| 201 | |||
| 202 | (defun ansi-color-filter-region (begin end) | ||
| 203 | "Filter out all SGR control sequences from region START END. | ||
| 95 | 204 | ||
| 96 | Used for sequences like this one: \033[31m, where 1 could be an index to a | 205 | Returns the first point it is safe to start with. Used to speedup |
| 97 | foreground color (red, in this case), or \033[41m, where 1 could be an | 206 | further processing. |
| 98 | index to a background color. | ||
| 99 | 207 | ||
| 100 | The default colors are: black, red, green, yellow, blue, magenta, | 208 | Design to cope with arbitrary chunk of output such as the ones get by |
| 101 | cyan, and white. | 209 | comint-output-filter-functions, e.g.: |
| 102 | 210 | ||
| 103 | On a light background, I prefer: black, red, dark green, orange, blue, | 211 | \(defvar last-context nil) |
| 104 | magenta, turquoise, snow4") | 212 | \(make-variable-buffer-local 'last-context) |
| 213 | |||
| 214 | \(defun filter-out-color-in-buffer (s) | ||
| 215 | \(setq last-context | ||
| 216 | \(ansi-color-filter-region | ||
| 217 | \(if last-context | ||
| 218 | last-context | ||
| 219 | \(if (marker-position comint-last-output-start) | ||
| 220 | \(marker-position comint-last-output-start) | ||
| 221 | 1)) | ||
| 222 | \(marker-position (process-mark (get-buffer-process (current-buffer)))) )) | ||
| 223 | s) | ||
| 224 | |||
| 225 | \(add-hook 'comint-output-filter-functions 'filter-out-color-in-buffer) | ||
| 226 | " | ||
| 227 | (let ((endm (copy-marker end))) | ||
| 228 | (save-excursion | ||
| 229 | (goto-char begin) | ||
| 230 | (while (re-search-forward ansi-color-regexp endm t) | ||
| 231 | (replace-match "")) | ||
| 232 | (if (re-search-forward "\033" endm t) | ||
| 233 | (match-beginning 0) | ||
| 234 | (marker-position endm))))) | ||
| 105 | 235 | ||
| 106 | ;; Main function | ||
| 107 | 236 | ||
| 108 | (defun ansi-color-apply (string) | 237 | (defun ansi-color-apply (string) |
| 109 | "Translates ANSI color control sequences into text-properties. | 238 | "Translates SGR control sequences into text-properties. |
| 110 | 239 | ||
| 111 | Applies ANSI control sequences setting foreground and background colors | 240 | Applies SGR control sequences setting foreground and background colors |
| 112 | to STRING and returns the result. The colors used are given in | 241 | to STRING and returns the result. The colors used are given in |
| 113 | `ansi-color-faces-vector' and `ansi-color-names-vector'. | 242 | `ansi-color-faces-vector' and `ansi-color-names-vector'. |
| 114 | 243 | ||
| 115 | This function can be added to `comint-preoutput-filter-functions'." | 244 | This function can be added to `comint-preoutput-filter-functions'." |
| 116 | (let ((face) | 245 | (let (face (start 0) end escape-sequence null-sequence result) |
| 117 | (start 0) (end) (escape) | ||
| 118 | (result) | ||
| 119 | (params)) | ||
| 120 | ;; find the next escape sequence | 246 | ;; find the next escape sequence |
| 121 | (while (setq end (string-match "\033\\[\\([013457][01234567]?;\\)*[013457][01234567]?m" string start)) | 247 | (while (setq end (string-match ansi-color-regexp string start)) |
| 122 | ;; store escape sequence | 248 | ;; store escape sequence |
| 123 | (setq escape (match-string 0 string)) | 249 | (setq escape-sequence (match-string 1 string) |
| 250 | null-sequence (string-equal escape-sequence "")) | ||
| 124 | ;; colorize the old block from start to end using old face | 251 | ;; colorize the old block from start to end using old face |
| 125 | (if face | 252 | (if face |
| 126 | (put-text-property start end 'face face string)) | 253 | (put-text-property start end 'face face string)) |
| 127 | (setq result (concat result (substring string start end))) | 254 | (setq result (concat result (substring string start end)) |
| 255 | start (match-end 0)) | ||
| 128 | ;; create new face by applying all the parameters in the escape sequence | 256 | ;; create new face by applying all the parameters in the escape sequence |
| 129 | (let ((i 0)) | 257 | (if null-sequence |
| 130 | (while (setq i (string-match "[013457][01234567]?[;m]" escape i)) | 258 | (setq face nil) |
| 131 | (setq face (ansi-color-make-face face | 259 | (setq face (ansi-color-get-face escape-sequence)))) |
| 132 | (aref escape i) | ||
| 133 | (aref escape (1+ i)))) | ||
| 134 | (setq i (match-end 0)))) | ||
| 135 | (setq start (+ end (length escape)))) | ||
| 136 | (concat result (substring string start)))) | 260 | (concat result (substring string start)))) |
| 137 | 261 | ||
| 262 | |||
| 263 | (defun ansi-color-apply-on-region (begin end &optional context) | ||
| 264 | "Translates SGR control sequences into text-properties. | ||
| 265 | |||
| 266 | Applies SGR control sequences setting foreground and background colors | ||
| 267 | to text in region. The colors used are given in | ||
| 268 | `ansi-color-faces-vector' and `ansi-color-names-vector'. | ||
| 269 | Returns a context than can be used to speedup further processing. | ||
| 270 | Context is a (begin (start . face)) list. | ||
| 271 | |||
| 272 | Design to cope with arbitrary chunk of output such as the ones get by | ||
| 273 | comint-output-filter-functions, e.g.: | ||
| 274 | |||
| 275 | \(defvar last-context nil) | ||
| 276 | \(make-variable-buffer-local 'last-context) | ||
| 277 | |||
| 278 | \(defun ansi-output-filter (s) | ||
| 279 | \(setq last-context | ||
| 280 | \(ansi-color-apply-on-region | ||
| 281 | \(if last-context | ||
| 282 | \(car last-context) | ||
| 283 | \(if (marker-position comint-last-output-start) | ||
| 284 | \(marker-position comint-last-output-start) | ||
| 285 | 1)) | ||
| 286 | \(process-mark (get-buffer-process (current-buffer))) | ||
| 287 | last-context )) | ||
| 288 | s) | ||
| 289 | |||
| 290 | \(add-hook 'comint-output-filter-functions 'ansi-output-filter) | ||
| 291 | " | ||
| 292 | (let ((endm (copy-marker end)) | ||
| 293 | (face (if (and context (cdr context)) | ||
| 294 | (cdr (cdr context)))) | ||
| 295 | (face-start (if (and context (cdr context)) | ||
| 296 | (car (cdr context)))) | ||
| 297 | (next-safe-start begin) | ||
| 298 | escape-sequence | ||
| 299 | null-sequence | ||
| 300 | stop ) | ||
| 301 | (save-excursion | ||
| 302 | (goto-char begin) | ||
| 303 | ;; find the next escape sequence | ||
| 304 | (while (setq stop (re-search-forward ansi-color-regexp endm t)) | ||
| 305 | ;; store escape sequence | ||
| 306 | (setq escape-sequence (match-string 1)) | ||
| 307 | (setq null-sequence (string-equal (match-string 1) "")) | ||
| 308 | (setq next-safe-start (match-beginning 0)) | ||
| 309 | (if face | ||
| 310 | (put-text-property face-start next-safe-start 'face face)) ; colorize | ||
| 311 | (replace-match "") ; delete the ANSI sequence | ||
| 312 | (if null-sequence | ||
| 313 | (setq face nil) | ||
| 314 | (setq face-start next-safe-start) | ||
| 315 | (setq face (ansi-color-get-face escape-sequence)))) | ||
| 316 | (setq next-safe-start | ||
| 317 | (if (re-search-forward "\033" endm t) | ||
| 318 | (match-beginning 0) | ||
| 319 | (marker-position endm)))) | ||
| 320 | (cons next-safe-start | ||
| 321 | (if face | ||
| 322 | (cons face-start face))) )) | ||
| 323 | |||
| 138 | ;; Helper functions | 324 | ;; Helper functions |
| 139 | 325 | ||
| 140 | (defun ansi-color-make-face (face param1 param2) | 326 | (defun ansi-color-make-color-map () |
| 141 | "Return a face based on FACE and characters PARAM1 and PARAM2. | 327 | "Creates a vector of face definitions and returns it. |
| 142 | 328 | ||
| 143 | The face can be used in a call to `add-text-properties'. The PARAM1 and | 329 | The index into the vector is an ANSI code. See the documentation of |
| 144 | PARAM2 characters are the two numeric characters in ANSI control | 330 | `ansi-color-map' for an example. |
| 145 | sequences between ?[ and ?m. Unless the ANSI control sequence specifies | 331 | |
| 146 | a return to default face using PARAM1 ?0 and PARAM2 ?m (ie. \"\033[0m\"), the | 332 | The face definitions are based upon the variables |
| 147 | properties specified by PARAM1 and PARAM2 are added to face." | 333 | `ansi-color-faces-vector' and `ansi-color-names-vector'." |
| 148 | (cond ((= param1 ?0) | 334 | (let ((ansi-color-map (make-vector 50 nil)) |
| 149 | nil) | 335 | (index 0)) |
| 150 | ((= param2 ?m) | 336 | ;; miscellaneous attributes |
| 151 | (add-to-list 'face (aref ansi-color-faces-vector | 337 | (mapcar |
| 152 | (string-to-number (char-to-string param1))))) | 338 | (function (lambda (e) |
| 153 | ((= param1 ?3) | 339 | (aset ansi-color-map index e) |
| 154 | (add-to-list 'face (cons 'foreground-color | 340 | (setq index (1+ index)) )) |
| 155 | (aref ansi-color-names-vector | 341 | ansi-color-faces-vector) |
| 156 | (string-to-number (char-to-string param2)))))) | 342 | |
| 157 | ((= param1 ?4) | 343 | ;; foreground attributes |
| 158 | (add-to-list 'face (cons 'background-color | 344 | (setq index 30) |
| 159 | (aref ansi-color-names-vector | 345 | (mapcar |
| 160 | (string-to-number (char-to-string param2)))))) | 346 | (function (lambda (e) |
| 161 | (t (add-to-list 'face (aref ansi-color-faces-vector | 347 | (aset ansi-color-map index |
| 162 | (string-to-number (char-to-string param1))))))) | 348 | (cons 'foreground-color e)) |
| 349 | (setq index (1+ index)) )) | ||
| 350 | ansi-color-names-vector) | ||
| 351 | |||
| 352 | ;; background attributes | ||
| 353 | (setq index 40) | ||
| 354 | (mapcar | ||
| 355 | (function (lambda (e) | ||
| 356 | (aset ansi-color-map index | ||
| 357 | (cons 'background-color e)) | ||
| 358 | (setq index (1+ index)) )) | ||
| 359 | ansi-color-names-vector) | ||
| 360 | ansi-color-map)) | ||
| 361 | |||
| 362 | (defvar ansi-color-map (ansi-color-make-color-map) | ||
| 363 | "A brand new color map suitable for ansi-color-get-face. | ||
| 364 | |||
| 365 | The value of this variable is usually constructed by | ||
| 366 | `ansi-color-make-color-map'. The values in the array are such that the | ||
| 367 | numbers included in an SGR control sequences point to the correct | ||
| 368 | foreground or background colors. | ||
| 369 | |||
| 370 | Example: The sequence \033[34m specifies a blue foreground. Therefore: | ||
| 371 | (aref ansi-color-map 34) | ||
| 372 | => \(foreground-color . \"blue\")") | ||
| 373 | |||
| 374 | (defun ansi-color-map-update (symbol value) | ||
| 375 | "Update `ansi-color-map'. | ||
| 376 | |||
| 377 | Whenever the vectors used to construct `ansi-color-map' are changed, | ||
| 378 | this function is called. Therefore this function is listed as the :set | ||
| 379 | property of `ansi-color-faces-vector' and `ansi-color-names-vector'." | ||
| 380 | (set-default symbol value) | ||
| 381 | (setq ansi-color-map (ansi-color-make-color-map))) | ||
| 382 | |||
| 383 | (defun ansi-color-get-face-1 (ansi-code) | ||
| 384 | "Get face definition from `ansi-color-map'. | ||
| 385 | ANSI-CODE is used as an index into the vector." | ||
| 386 | (condition-case nil | ||
| 387 | (aref ansi-color-map ansi-code) | ||
| 388 | ('args-out-of-range nil))) | ||
| 389 | |||
| 390 | (defun ansi-color-get-face (escape-seq) | ||
| 391 | "Create a new face by applying all the parameters in ESCAPE-SEQ. | ||
| 392 | |||
| 393 | ESCAPE-SEQ is a SGR control sequences such as \033[34m. The parameter | ||
| 394 | 34 is used by `ansi-color-get-face-1' to return a face definition." | ||
| 395 | (let ((ansi-color-r "[0-9][0-9]?") | ||
| 396 | (i 0) | ||
| 397 | f) | ||
| 398 | (while (string-match ansi-color-r escape-seq i) | ||
| 399 | (setq i (match-end 0)) | ||
| 400 | (add-to-list 'f | ||
| 401 | (ansi-color-get-face-1 | ||
| 402 | (string-to-int (match-string 0 escape-seq) 10)))) | ||
| 403 | f)) | ||
| 163 | 404 | ||
| 164 | (provide 'ansi-color) | 405 | (provide 'ansi-color) |
| 165 | 406 | ||