Merge from emacs-24; up to 2012-12-24T15:56:17Z!eliz@gnu.org
[bpt/emacs.git] / lisp / shell.el
index b98efce..d09d7ae 100644 (file)
@@ -1,6 +1,7 @@
 ;;; shell.el --- specialized comint.el for running the shell -*- lexical-binding: t -*-
 
-;; Copyright (C) 1988, 1993-1997, 2000-2012 Free Software Foundation, Inc.
+;; Copyright (C) 1988, 1993-1997, 2000-2013 Free Software Foundation,
+;; Inc.
 
 ;; Author: Olin Shivers <shivers@cs.cmu.edu>
 ;;     Simon Marshall <simon@gnu.org>
@@ -46,7 +47,7 @@
 
 ;; YOUR .EMACS FILE
 ;;=============================================================================
-;; Some suggestions for your .emacs file.
+;; Some suggestions for your init file.
 ;;
 ;; ;; Define M-# to run some strange command:
 ;; (eval-after-load "shell"
@@ -136,9 +137,7 @@ how Shell mode treats paragraphs.
 
 The pattern should probably not match more than one line.  If it does,
 Shell mode may become confused trying to distinguish prompt from input
-on lines which don't start with a prompt.
-
-This is a fine thing to set in your `.emacs' file."
+on lines which don't start with a prompt."
   :type 'regexp
   :group 'shell)
 
@@ -146,9 +145,7 @@ This is a fine thing to set in your `.emacs' file."
   "List of suffixes to be disregarded during file/command completion.
 This variable is used to initialize `comint-completion-fignore' in the shell
 buffer.  The default is nil, for compatibility with most shells.
-Some people like (\"~\" \"#\" \"%\").
-
-This is a fine thing to set in your `.emacs' file."
+Some people like (\"~\" \"#\" \"%\")."
   :type '(repeat (string :tag "Suffix"))
   :group 'shell)
 
@@ -158,31 +155,29 @@ This variable is used to initialize `comint-delimiter-argument-list' in the
 shell buffer.  The value may depend on the operating system or shell."
   :type '(choice (const nil)
                 (repeat :tag "List of characters" character))
-  ;; Reverted.
-;;  :version "24.1"                    ; changed to nil (bug#8027)
   :group 'shell)
 
-(defvar shell-file-name-chars
+(defcustom shell-file-name-chars
   (if (memq system-type '(ms-dos windows-nt cygwin))
       "~/A-Za-z0-9_^$!#%&{}@`'.,:()-"
     "[]~/A-Za-z0-9+@:_.$#%,={}-")
   "String of characters valid in a file name.
 This variable is used to initialize `comint-file-name-chars' in the
-shell buffer.  The value may depend on the operating system or shell.
-
-This is a fine thing to set in your `.emacs' file.")
+shell buffer.  The value may depend on the operating system or shell."
+  :type 'string
+  :group 'shell)
 
-(defvar shell-file-name-quote-list
+(defcustom shell-file-name-quote-list
   (if (memq system-type '(ms-dos windows-nt))
       nil
     (append shell-delimiter-argument-list '(?\s ?$ ?\* ?\! ?\" ?\' ?\` ?\# ?\\)))
   "List of characters to quote when in a file name.
 This variable is used to initialize `comint-file-name-quote-list' in the
-shell buffer.  The value may depend on the operating system or shell.
-
-This is a fine thing to set in your `.emacs' file.")
+shell buffer.  The value may depend on the operating system or shell."
+  :type '(repeat character)
+  :group 'shell)
 
-(defvar shell-dynamic-complete-functions
+(defcustom shell-dynamic-complete-functions
   '(comint-c-a-p-replace-by-expanded-history
     shell-environment-variable-completion
     shell-command-completion
@@ -192,9 +187,9 @@ This is a fine thing to set in your `.emacs' file.")
     comint-filename-completion)
   "List of functions called to perform completion.
 This variable is used to initialize `comint-dynamic-complete-functions' in the
-shell buffer.
-
-This is a fine thing to set in your `.emacs' file.")
+shell buffer."
+  :type '(repeat function)
+  :group 'shell)
 
 (defcustom shell-command-regexp "[^;&|\n]+"
   "Regexp to match a single command within a pipeline.
@@ -567,10 +562,8 @@ buffer."
   ;; very inefficient in Shell buffers (e.g. Bug#10835).  We use a
   ;; custom `ansi-color-apply-face-function' to convert color escape
   ;; sequences into `font-lock-face' properties.
-  (set (make-local-variable 'ansi-color-apply-face-function)
-       (lambda (beg end face)
-        (when face
-          (put-text-property beg end 'font-lock-face face))))
+  (setq-local ansi-color-apply-face-function #'shell-apply-ansi-color)
+  (shell-reapply-ansi-color)
 
   ;; This is not really correct, since the shell buffer does not really
   ;; edit this directory.  But it is useful in the buffer list and menus.
@@ -609,6 +602,27 @@ buffer."
                   'shell-filter-ctrl-a-ctrl-b nil t)))
     (comint-read-input-ring t)))
 
+(defun shell-apply-ansi-color (beg end face)
+  "Apply FACE as the ansi-color face for the text between BEG and END."
+  (when face
+    (put-text-property beg end 'ansi-color-face face)
+    (put-text-property beg end 'font-lock-face face)))
+
+(defun shell-reapply-ansi-color ()
+  "Reapply ansi-color faces to the existing contents of the buffer."
+  (save-restriction
+    (widen)
+    (let* ((pos (point-min))
+          (end (or (next-single-property-change pos 'ansi-color-face)
+                   (point-max)))
+          face)
+      (while end
+       (if (setq face (get-text-property pos 'ansi-color-face))
+           (put-text-property pos (or end (point-max))
+                              'font-lock-face face))
+       (setq pos end
+             end (next-single-property-change pos 'ansi-color-face))))))
+
 (defun shell-filter-ctrl-a-ctrl-b (string)
   "Remove `^A' and `^B' characters from comint output.
 
@@ -677,7 +691,12 @@ Otherwise, one argument `-i' is passed to the shell.
     (and current-prefix-arg
         (prog1
             (read-buffer "Shell buffer: "
-                         (generate-new-buffer-name "*shell*"))
+                         ;; If the current buffer is an inactive
+                         ;; shell buffer, use it as the default.
+                         (if (and (eq major-mode 'shell-mode)
+                                  (null (get-buffer-process (current-buffer))))
+                             (buffer-name)
+                           (generate-new-buffer-name "*shell*")))
           (if (file-remote-p default-directory)
               ;; It must be possible to declare a local default-directory.
                ;; FIXME: This can't be right: it changes the default-directory