aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerd Moellmann2000-09-14 12:38:09 +0000
committerGerd Moellmann2000-09-14 12:38:09 +0000
commit986b7dee46cb8885276d85c2e80d2f2df346ce45 (patch)
treefd60862894b17a29e37536ce53ab51794f0131be
parentb9ce5694b37a8f139bca81e5dfad288447e1472d (diff)
downloademacs-986b7dee46cb8885276d85c2e80d2f2df346ce45.tar.gz
emacs-986b7dee46cb8885276d85c2e80d2f2df346ce45.zip
(ansi-colors): Doc change.
(ansi-color-get-face): Simplified regexp. (ansi-color-faces-vector): Added more faces, doc change. (ansi-color-names-vector): Doc change. (ansi-color-regexp): Simplified regexp. (ansi-color-parameter-regexp): New regexp. (ansi-color-filter-apply): Doc change. (ansi-color-filter-region): Doc change. (ansi-color-apply): Use ansi-color-regexp and ansi-color-get-face, deal with zero length parameters. (ansi-color-apply-on-region): Doc change. (ansi-color-map): Doc change. (ansi-color-map-update): Removed debugging message. (ansi-color-get-face-1): Added condition-case to trap args-out-of-range errors. (ansi-color-get-face): Doc change. (ansi-color-make-face): Removed. (ansi-color-for-shell-mode): New option.
-rw-r--r--lisp/ChangeLog21
-rw-r--r--lisp/ansi-color.el439
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
52000-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
52000-09-13 Kenichi Handa <handa@etl.go.jp> 262000-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. 81This translation effectively colorizes strings and regions based upon
82SGR control sequences embedded in the text. SGR (Select Graphic
83Rendition) control sequences are defined in section 3.8.117 of the
84ECMA-48 standard \(identical to ISO/IEC 6429), which is freely available
85as 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.
92This vector holds the faces used for SGR control sequence parameters 0
93to 7.
86 94
87Those are sequences like this one: \033[1m, where 1 could be one of the 95Parameter Description Face used by default
88following 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
90same 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 105This vector is used by `ansi-color-make-color-map' to create a color
106map. 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.
115This vector holds the colors used for SGR control sequences parameters
11630 to 37 \(foreground colors) and 40 to 47 (background colors).
117
118Parameter 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
128This vector is used by `ansi-color-make-color-map' to create a color
129map. 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
138If non-nil and `global-font-lock-mode' is non-nil, ansi-color will be
139used. This adds `ansi-color-apply' to
140`comint-preoutput-filter-functions' and removes
141`ansi-color-filter-apply' for all shell-mode buffers.
142
143If 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
147If nil, font-lock will be used (if it is enabled). This adds
148`ansi-color-filter-apply' to `comint-preoutput-filter-functions' and
149removes `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
196This 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
96Used for sequences like this one: \033[31m, where 1 could be an index to a 205Returns the first point it is safe to start with. Used to speedup
97foreground color (red, in this case), or \033[41m, where 1 could be an 206further processing.
98index to a background color.
99 207
100The default colors are: black, red, green, yellow, blue, magenta, 208Design to cope with arbitrary chunk of output such as the ones get by
101cyan, and white. 209comint-output-filter-functions, e.g.:
102 210
103On a light background, I prefer: black, red, dark green, orange, blue, 211\(defvar last-context nil)
104magenta, 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
111Applies ANSI control sequences setting foreground and background colors 240Applies SGR control sequences setting foreground and background colors
112to STRING and returns the result. The colors used are given in 241to 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
115This function can be added to `comint-preoutput-filter-functions'." 244This 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
266Applies SGR control sequences setting foreground and background colors
267to text in region. The colors used are given in
268`ansi-color-faces-vector' and `ansi-color-names-vector'.
269Returns a context than can be used to speedup further processing.
270Context is a (begin (start . face)) list.
271
272Design to cope with arbitrary chunk of output such as the ones get by
273comint-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
143The face can be used in a call to `add-text-properties'. The PARAM1 and 329The index into the vector is an ANSI code. See the documentation of
144PARAM2 characters are the two numeric characters in ANSI control 330`ansi-color-map' for an example.
145sequences between ?[ and ?m. Unless the ANSI control sequence specifies 331
146a return to default face using PARAM1 ?0 and PARAM2 ?m (ie. \"\033[0m\"), the 332The face definitions are based upon the variables
147properties 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
365The value of this variable is usually constructed by
366`ansi-color-make-color-map'. The values in the array are such that the
367numbers included in an SGR control sequences point to the correct
368foreground or background colors.
369
370Example: 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
377Whenever the vectors used to construct `ansi-color-map' are changed,
378this function is called. Therefore this function is listed as the :set
379property 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'.
385ANSI-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
393ESCAPE-SEQ is a SGR control sequences such as \033[34m. The parameter
39434 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