]> code.delx.au - gnu-emacs/blobdiff - lisp/shell.el
(set-selection-coding-system): Make it
[gnu-emacs] / lisp / shell.el
index 66a5653cbdbf822b041fe7311b5ed223ee618323..03d06cae7e888b74b06f821ec72398d1acad0f05 100644 (file)
@@ -2,8 +2,9 @@
 
 ;; Copyright (C) 1988, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
 
 
 ;; Copyright (C) 1988, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
 
-;; Author: Olin Shivers <shivers@cs.cmu.edu>
-;; Maintainer: Simon Marshall <simon@gnu.ai.mit.edu>
+;; Author: Olin Shivers <shivers@cs.cmu.edu> then
+;;     Simon Marshall <simon@gnu.ai.mit.edu>
+;; Maintainer: FSF
 ;; Keywords: processes
 
 ;; This file is part of GNU Emacs.
 ;; Keywords: processes
 
 ;; This file is part of GNU Emacs.
 ;;============================================================================
 ;; Comint Mode Commands: (common to shell and all comint-derived modes)
 ;;
 ;;============================================================================
 ;; Comint Mode Commands: (common to shell and all comint-derived modes)
 ;;
-;; m-p     comint-previous-input           Cycle backwards in input history
-;; m-n     comint-next-input               Cycle forwards
+;; m-p    comint-previous-input           Cycle backwards in input history
+;; m-n    comint-next-input               Cycle forwards
 ;; m-r     comint-previous-matching-input  Previous input matching a regexp
 ;; m-s     comint-next-matching-input      Next input that matches
 ;; m-r     comint-previous-matching-input  Previous input matching a regexp
 ;; m-s     comint-next-matching-input      Next input that matches
-;; m-c-l   comint-show-output              Show last batch of process output
+;; m-c-l   comint-show-output             Show last batch of process output
 ;; return  comint-send-input
 ;; return  comint-send-input
-;; c-d     comint-delchar-or-maybe-eof     Delete char unless at end of buff.
+;; c-d    comint-delchar-or-maybe-eof     Delete char unless at end of buff.
 ;; c-c c-a comint-bol                      Beginning of line; skip prompt
 ;; c-c c-a comint-bol                      Beginning of line; skip prompt
-;; c-c c-u comint-kill-input               ^u
-;; c-c c-w backward-kill-word              ^w
-;; c-c c-c comint-interrupt-subjob         ^c
-;; c-c c-z comint-stop-subjob              ^z
-;; c-c c-\ comint-quit-subjob              ^\
-;; c-c c-o comint-kill-output              Delete last batch of process output
-;; c-c c-r comint-show-output              Show last batch of process output
+;; c-c c-u comint-kill-input              ^u
+;; c-c c-w backward-kill-word             ^w
+;; c-c c-c comint-interrupt-subjob        ^c
+;; c-c c-z comint-stop-subjob             ^z
+;; c-c c-\ comint-quit-subjob             ^\
+;; c-c c-o comint-kill-output             Delete last batch of process output
+;; c-c c-r comint-show-output             Show last batch of process output
 ;; c-c c-h comint-dynamic-list-input-ring  List input history
 ;;         send-invisible                  Read line w/o echo & send to proc
 ;; c-c c-h comint-dynamic-list-input-ring  List input history
 ;;         send-invisible                  Read line w/o echo & send to proc
-;;         comint-continue-subjob          Useful if you accidentally suspend
+;;         comint-continue-subjob         Useful if you accidentally suspend
 ;;                                             top-level job
 ;; comint-mode-hook is the comint mode hook.
 
 ;;                                             top-level job
 ;; comint-mode-hook is the comint mode hook.
 
@@ -90,8 +91,8 @@
 ;;                                     List completions in help buffer
 ;; m-c-f   shell-forward-command       Forward a shell command
 ;; m-c-b   shell-backward-command      Backward a shell command
 ;;                                     List completions in help buffer
 ;; m-c-f   shell-forward-command       Forward a shell command
 ;; m-c-b   shell-backward-command      Backward a shell command
-;;         dirs                        Resync the buffer's dir stack
-;;         dirtrack-toggle             Turn dir tracking on/off
+;;        dirs                         Resync the buffer's dir stack
+;;        dirtrack-mode                Turn dir tracking on/off
 ;;         comint-strip-ctrl-m         Remove trailing ^Ms from output
 ;;
 ;; The shell mode hook is shell-mode-hook
 ;;         comint-strip-ctrl-m         Remove trailing ^Ms from output
 ;;
 ;; The shell mode hook is shell-mode-hook
@@ -151,7 +152,7 @@ This is a fine thing to set in your `.emacs' file.")
 
 (defvar shell-file-name-chars
   (if (memq system-type '(ms-dos windows-nt))
 
 (defvar shell-file-name-chars
   (if (memq system-type '(ms-dos windows-nt))
-      "~/A-Za-z0-9_^$!#%&{}@`'.()-"
+      "~/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
     "~/A-Za-z0-9+@:_.$#%,={}-")
   "String of characters valid in a file name.
 This variable is used to initialize `comint-file-name-chars' in the
@@ -234,7 +235,8 @@ This mirrors the optional behavior of tcsh."
       "[]a-zA-Z^_`\\[\\\\]:"
     nil)
   "*If non-nil, is regexp used to track drive changes."
       "[]a-zA-Z^_`\\[\\\\]:"
     nil)
   "*If non-nil, is regexp used to track drive changes."
-  :type 'regexp
+  :type '(choice regexp
+                (const nil))
   :group 'shell-directories)
 
 (defcustom explicit-shell-file-name nil
   :group 'shell-directories)
 
 (defcustom explicit-shell-file-name nil
@@ -313,6 +315,8 @@ Thus, this does not include the shell's current directory.")
 \f
 ;;; Basic Procedures
 
 \f
 ;;; Basic Procedures
 
+(put 'shell-mode 'mode-class 'special)
+
 (defun shell-mode ()
   "Major mode for interacting with an inferior shell.
 \\[comint-send-input] after the end of the process' output sends the text from
 (defun shell-mode ()
   "Major mode for interacting with an inferior shell.
 \\[comint-send-input] after the end of the process' output sends the text from
@@ -338,7 +342,7 @@ While directory tracking is enabled, the shell's working directory is displayed
 by \\[list-buffers] or \\[mouse-buffer-menu] in the `File' field.
 \\[dirs] queries the shell and resyncs Emacs' idea of what the current 
     directory stack is.
 by \\[list-buffers] or \\[mouse-buffer-menu] in the `File' field.
 \\[dirs] queries the shell and resyncs Emacs' idea of what the current 
     directory stack is.
-\\[dirtrack-toggle] turns directory tracking on and off.
+\\[dirtrack-mode] turns directory tracking on and off.
 
 \\{shell-mode-map}
 Customization: Entry to this mode runs the hooks on `comint-mode-hook' and
 
 \\{shell-mode-map}
 Customization: Entry to this mode runs the hooks on `comint-mode-hook' and
@@ -382,13 +386,16 @@ buffer."
   (setq font-lock-defaults '(shell-font-lock-keywords t))
   (make-local-variable 'shell-dirstack)
   (setq shell-dirstack nil)
   (setq font-lock-defaults '(shell-font-lock-keywords t))
   (make-local-variable 'shell-dirstack)
   (setq shell-dirstack nil)
+  (make-local-variable 'shell-last-dir)
   (setq shell-last-dir nil)
   (make-local-variable 'shell-dirtrackp)
   (setq shell-dirtrackp t)
   (add-hook 'comint-input-filter-functions 'shell-directory-tracker nil t)
   (setq comint-input-autoexpand shell-input-autoexpand)
   (setq shell-last-dir nil)
   (make-local-variable 'shell-dirtrackp)
   (setq shell-dirtrackp t)
   (add-hook 'comint-input-filter-functions 'shell-directory-tracker nil t)
   (setq comint-input-autoexpand shell-input-autoexpand)
-  ;; We used to set list-buffers-directory here, but that was wrong.
-  ;; A shell buffer is not a way of editing a directory.
+  ;; 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.
+  (make-local-variable 'list-buffers-directory)
+  (setq list-buffers-directory (expand-file-name default-directory))
   ;; shell-dependent assignments.
   (let ((shell (file-name-nondirectory (car
                 (process-command (get-buffer-process (current-buffer)))))))
   ;; shell-dependent assignments.
   (let ((shell (file-name-nondirectory (car
                 (process-command (get-buffer-process (current-buffer)))))))
@@ -423,6 +430,13 @@ The buffer is put in Shell mode, giving commands for sending input
 and controlling the subjobs of the shell.  See `shell-mode'.
 See also the variable `shell-prompt-pattern'.
 
 and controlling the subjobs of the shell.  See `shell-mode'.
 See also the variable `shell-prompt-pattern'.
 
+To specify a coding system for converting non-ASCII characters
+in the input and output to the shell, use \\[universal-coding-system-argument]
+before \\[shell].  You can also specify this with \\[set-buffer-process-coding-system]
+in the shell buffer, after you start the shell.
+The default comes from `process-coding-system-alist' and
+`default-process-coding-system'.
+
 The shell file name (sans directories) is used to make a symbol name
 such as `explicit-csh-args'.  If that symbol is a variable,
 its value is used as a list of arguments when invoking the shell.
 The shell file name (sans directories) is used to make a symbol name
 such as `explicit-csh-args'.  If that symbol is a variable,
 its value is used as a list of arguments when invoking the shell.
@@ -499,7 +513,7 @@ This function is called on each input passed to the shell.
 It watches for cd, pushd and popd commands and sets the buffer's
 default directory to track these commands.
 
 It watches for cd, pushd and popd commands and sets the buffer's
 default directory to track these commands.
 
-You may toggle this tracking on and off with M-x dirtrack-toggle.
+You may toggle this tracking on and off with M-x dirtrack-mode.
 If emacs gets confused, you can resync with the shell with M-x dirs.
 
 See variables `shell-cd-regexp', `shell-chdrive-regexp', `shell-pushd-regexp',
 If emacs gets confused, you can resync with the shell with M-x dirs.
 
 See variables `shell-cd-regexp', `shell-chdrive-regexp', `shell-pushd-regexp',
@@ -624,7 +638,7 @@ Environment variables are expanded, see function `substitute-in-file-name'."
        (string-to-int str)))
 
 
        (string-to-int str)))
 
 
-(defun shell-dirtrack-toggle ()
+(defun shell-dirtrack-mode ()
   "Turn directory tracking on and off in a shell buffer."
   (interactive)
   (if (setq shell-dirtrackp (not shell-dirtrackp))
   "Turn directory tracking on and off in a shell buffer."
   (interactive)
   (if (setq shell-dirtrackp (not shell-dirtrackp))
@@ -633,7 +647,9 @@ Environment variables are expanded, see function `substitute-in-file-name'."
   (message "Directory tracking %s" (if shell-dirtrackp "ON" "OFF")))
 
 ;;; For your typing convenience:
   (message "Directory tracking %s" (if shell-dirtrackp "ON" "OFF")))
 
 ;;; For your typing convenience:
-(defalias 'dirtrack-toggle 'shell-dirtrack-toggle)
+(defalias 'shell-dirtrack-toggle 'shell-dirtrack-mode)
+(defalias 'dirtrack-toggle 'shell-dirtrack-mode)
+(defalias 'dirtrack-mode 'shell-dirtrack-mode)
 
 (defun shell-cd (dir)
   "Do normal `cd' to DIR, and set `list-buffers-directory'."
 
 (defun shell-cd (dir)
   "Do normal `cd' to DIR, and set `list-buffers-directory'."
@@ -718,6 +734,37 @@ command again."
        (setq ds (cdr ds))))
     (message "%s" msg)))
 \f
        (setq ds (cdr ds))))
     (message "%s" msg)))
 \f
+;; This was mostly copied from shell-resync-dirs.
+(defun shell-snarf-envar (var)
+  "Return as a string the shell's value of environment variable VAR."
+  (let* ((cmd (format "printenv '%s'\n" var))
+        (proc (get-buffer-process (current-buffer)))
+        (pmark (process-mark proc)))
+    (goto-char pmark)
+    (insert cmd)
+    (sit-for 0)                                ; force redisplay
+    (comint-send-string proc cmd)
+    (set-marker pmark (point))
+    (let ((pt (point)))                        ; wait for 1 line
+      ;; This extra newline prevents the user's pending input from spoofing us.
+      (insert "\n") (backward-char 1)
+      (while (not (looking-at ".+\n"))
+       (accept-process-output proc)
+       (goto-char pt)))
+    (goto-char pmark) (delete-char 1)  ; remove the extra newline
+    (buffer-substring (match-beginning 0) (1- (match-end 0)))))
+
+(defun shell-copy-environment-variable (variable)
+  "Copy the environment variable VARIABLE from the subshell to Emacs.
+This command reads the value of the specified environment variable
+in the shell, and sets the same environment variable in Emacs
+\(what `getenv' in Emacs would return) to that value.
+That value will affect any new subprocesses that you subsequently start
+from Emacs."
+  (interactive (list (read-envvar-name "\
+Copy Shell environment variable to Emacs: ")))
+  (setenv variable (shell-snarf-envar variable)))
+\f
 (defun shell-forward-command (&optional arg)
   "Move forward across ARG shell command(s).  Does not cross lines.
 See `shell-command-regexp'."
 (defun shell-forward-command (&optional arg)
   "Move forward across ARG shell command(s).  Does not cross lines.
 See `shell-command-regexp'."