2009-11-13 Carsten Dominik <carsten.dominik@gmail.com>
[bpt/emacs.git] / lisp / ansi-color.el
index 51421ad..e343f56 100644 (file)
@@ -1,6 +1,7 @@
 ;;; ansi-color.el --- translate ANSI escape sequences into faces
 
-;; Copyright (C) 1999, 2000, 2001  Free Software Foundation, Inc.
+;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004,
+;;   2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
 ;; Author: Alex Schroeder <alex@gnu.org>
 ;; Maintainer: Alex Schroeder <alex@gnu.org>
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify it
-;; under the terms of the GNU General Public License as published by the
-;; Free Software Foundation; either version 2, or (at your option) any
-;; later version.
-;;
-;; GNU Emacs is distributed in the hope that it will be useful, but
-;; WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-;; General Public License for more details.
-;;
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
@@ -46,7 +45,6 @@
 ;;
 ;; If you decide you like this, add the following to your .emacs file:
 ;;
-;; (autoload 'ansi-color-for-comint-mode-on "ansi-color" nil t)
 ;; (add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)
 ;;
 ;; SGR control sequences are defined in section 3.8.117 of the ECMA-48
@@ -86,6 +84,8 @@
 
 ;;; Code:
 
+(defvar comint-last-output-start)
+
 ;; Customization
 
 (defgroup ansi-colors nil
@@ -147,7 +147,7 @@ map.  This color map is stored in the variable `ansi-color-map'."
   :initialize 'custom-initialize-default
   :group 'ansi-colors)
 
-(defconst ansi-color-regexp "\033\\[\\([0-9;]*\\)m"
+(defconst ansi-color-regexp "\033\\[\\([0-9;]*m\\)"
   "Regexp that matches SGR control sequences.")
 
 (defconst ansi-color-parameter-regexp "\\([0-9]*\\)[m;]"
@@ -194,7 +194,7 @@ in shell buffers.  You set this variable by calling one of:
   (setq ansi-color-for-comint-mode 'filter))
 
 ;;;###autoload
-(defun ansi-color-process-output (string)
+(defun ansi-color-process-output (ignored)
   "Maybe translate SGR control sequences of comint output into text-properties.
 
 Depending on variable `ansi-color-for-comint-mode' the comint output is
@@ -221,23 +221,6 @@ This is a good function to put in `comint-output-filter-functions'."
 
 ;; Alternative font-lock-unfontify-region-function for Emacs only
 
-
-(eval-when-compile
-  ;; We use this to preserve or protect things when modifying text
-  ;; properties.  Stolen from lazy-lock and font-lock.  Ugly!!!
-  ;; Probably most of this is not needed?
-  (defmacro save-buffer-state (varlist &rest body)
-    "Bind variables according to VARLIST and eval BODY restoring buffer state."
-    (` (let* ((,@ (append varlist
-                  '((modified (buffer-modified-p)) (buffer-undo-list t)
-                    (inhibit-read-only t) (inhibit-point-motion-hooks t)
-                    before-change-functions after-change-functions
-                    deactivate-mark buffer-file-name buffer-file-truename))))
-        (,@ body)
-        (when (and (not modified) (buffer-modified-p))
-          (set-buffer-modified-p nil)))))
-  (put 'save-buffer-state 'lisp-indent-function 1))
-
 (defun ansi-color-unfontify-region (beg end &rest xemacs-stuff)
   "Replacement function for `font-lock-default-unfontify-region'.
 
@@ -260,21 +243,20 @@ A possible way to install this would be:
          \(function (lambda ()
                      \(setq font-lock-unfontify-region-function
                            'ansi-color-unfontify-region))))"
-  ;; save-buffer-state is a macro in font-lock.el!
-  (save-buffer-state nil
-    (when (boundp 'font-lock-syntactic-keywords)
-      (remove-text-properties beg end '(syntax-table nil)))
-    ;; instead of just using (remove-text-properties beg end '(face
-    ;; nil)), we find regions with a non-nil face test-property, skip
-    ;; positions with the ansi-color property set, and remove the
-    ;; remaining face test-properties.
-    (while (setq beg (text-property-not-all beg end 'face nil))
-      (setq beg (or (text-property-not-all beg end 'ansi-color t) end))
-      (when (get-text-property beg 'face)
-       (let ((end-face (or (text-property-any beg end 'face nil)
-                           end)))
-         (remove-text-properties beg end-face '(face nil))
-         (setq beg end-face))))))
+  ;; Simplified now that font-lock-unfontify-region uses save-buffer-state.
+  (when (boundp 'font-lock-syntactic-keywords)
+    (remove-text-properties beg end '(syntax-table nil)))
+  ;; instead of just using (remove-text-properties beg end '(face
+  ;; nil)), we find regions with a non-nil face test-property, skip
+  ;; positions with the ansi-color property set, and remove the
+  ;; remaining face test-properties.
+  (while (setq beg (text-property-not-all beg end 'face nil))
+    (setq beg (or (text-property-not-all beg end 'ansi-color t) end))
+    (when (get-text-property beg 'face)
+      (let ((end-face (or (text-property-any beg end 'face nil)
+                         end)))
+       (remove-text-properties beg end-face '(face nil))
+       (setq beg end-face)))))
 
 ;; Working with strings
 
@@ -415,7 +397,7 @@ information will be used for the next call to
 start of the region and set the face with which to start.  Set
 `ansi-color-context-region' to nil if you don't want this."
   (let ((face (car ansi-color-context-region))
-       (start-marker (or (cadr ansi-color-context-region) 
+       (start-marker (or (cadr ansi-color-context-region)
                          (copy-marker begin)))
        (end-marker (copy-marker end))
        escape-sequence)
@@ -481,7 +463,7 @@ start of the region and set the face with which to start.  Set
 
 (defun ansi-color-make-face (property color)
   "Return a face with PROPERTY set to COLOR.
-PROPERTY can be either symbol `foreground' or symbol `background'.  
+PROPERTY can be either symbol `foreground' or symbol `background'.
 
 For Emacs, we just return the cons cell \(PROPERTY . COLOR).
 For XEmacs, we create a temporary face and return it."
@@ -504,7 +486,7 @@ For XEmacs, we create a temporary face and return it."
 OBJECT defaults to the current buffer.  XEmacs uses `make-extent', Emacs
 uses `make-overlay'.  XEmacs can use a buffer or a string for OBJECT,
 Emacs requires OBJECT to be a buffer."
-  (if (functionp 'make-extent)
+  (if (fboundp 'make-extent)
       (make-extent from to object)
     ;; In Emacs, the overlay might end at the process-mark in comint
     ;; buffers.  In that case, new text will be inserted before the
@@ -529,7 +511,7 @@ property."
 (defun ansi-color-set-extent-face (extent face)
   "Set the `face' property of EXTENT to FACE.
 XEmacs uses `set-extent-face', Emacs  uses `overlay-put'."
-  (if (functionp 'set-extent-face)
+  (if (featurep 'xemacs)
       (set-extent-face extent face)
     (overlay-put extent 'face face)))
 
@@ -554,7 +536,13 @@ case we return nil."
          ((eq (car new-faces) 'default)
           (cdr new-faces))
          (t
-          (append new-faces faces)))))
+          ;; Like (append NEW-FACES FACES)
+          ;; but delete duplicates in FACES.
+          (let ((modified-faces (copy-sequence faces)))
+            (dolist (face (nreverse new-faces))
+              (setq modified-faces (delete face modified-faces))
+              (push face modified-faces))
+            modified-faces)))))
 
 (defun ansi-color-make-color-map ()
   "Creates a vector of face definitions and returns it.
@@ -567,14 +555,14 @@ The face definitions are based upon the variables
   (let ((ansi-color-map (make-vector 50 nil))
         (index 0))
     ;; miscellaneous attributes
-    (mapcar
+    (mapc
      (function (lambda (e)
                  (aset ansi-color-map index e)
                  (setq index (1+ index)) ))
      ansi-color-faces-vector)
     ;; foreground attributes
     (setq index 30)
-    (mapcar
+    (mapc
      (function (lambda (e)
                  (aset ansi-color-map index
                       (ansi-color-make-face 'foreground e))
@@ -582,7 +570,7 @@ The face definitions are based upon the variables
      ansi-color-names-vector)
     ;; background attributes
     (setq index 40)
-    (mapcar
+    (mapc
      (function (lambda (e)
                  (aset ansi-color-map index
                       (ansi-color-make-face 'background e))
@@ -616,7 +604,7 @@ property of `ansi-color-faces-vector' and `ansi-color-names-vector'."
 ANSI-CODE is used as an index into the vector."
   (condition-case nil
       (aref ansi-color-map ansi-code)
-    ('args-out-of-range nil)))
+    (args-out-of-range nil)))
 
 (defun ansi-color-get-face (escape-seq)
   "Create a new face by applying all the parameters in ESCAPE-SEQ.
@@ -626,20 +614,21 @@ the parameter 0), then the effect of all previous parameters is cancelled.
 
 ESCAPE-SEQ is a SGR control sequences such as \\033[34m.  The parameter
 34 is used by `ansi-color-get-face-1' to return a face definition."
-  (let ((ansi-color-r "[0-9][0-9]?")
-        (i 0)
+  (let ((i 0)
         f val)
-    (while (string-match ansi-color-r escape-seq i)
+    (while (string-match ansi-color-parameter-regexp escape-seq i)
       (setq i (match-end 0)
            val (ansi-color-get-face-1
-                (string-to-int (match-string 0 escape-seq) 10)))
+                (string-to-number (match-string 1 escape-seq) 10)))
       (cond ((not val))
            ((eq val 'default)
             (setq f (list val)))
            (t
-            (add-to-list 'f val))))
+            (unless (member val f)
+              (push val f)))))
     f))
 
 (provide 'ansi-color)
 
+;; arch-tag: 00726118-9432-44fd-b72d-d2af7591c99c
 ;;; ansi-color.el ends here