aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Blandy1991-05-08 07:47:45 +0000
committerJim Blandy1991-05-08 07:47:45 +0000
commita9ec2adb9c3c4624c3a3985c8fb549f96d0a301f (patch)
tree907cba72f9c5d4183e7b1a2f83b6b89be47fb9cb
parent7e1ea61285b501e43708a011841158d5121e0193 (diff)
downloademacs-a9ec2adb9c3c4624c3a3985c8fb549f96d0a301f.tar.gz
emacs-a9ec2adb9c3c4624c3a3985c8fb549f96d0a301f.zip
*** empty log message ***
-rw-r--r--lisp/shell.el286
1 files changed, 247 insertions, 39 deletions
diff --git a/lisp/shell.el b/lisp/shell.el
index 64c069bf05d..8a5c2b8479a 100644
--- a/lisp/shell.el
+++ b/lisp/shell.el
@@ -1,30 +1,29 @@
1;; -*-Emacs-Lisp-*- run a shell in an Emacs window 1;;; -*-Emacs-Lisp-*- General command interpreter in a window stuff
2;; Copyright (C) 1985, 1986, 1987, 1990 Free Software Foundation, Inc. 2;;; Copyright Olin Shivers (1988).
3 3;;; Please imagine a long, tedious, legalistic 5-page gnu-style copyright
4;; This file is part of GNU Emacs. 4;;; notice appearing here to the effect that you may use this code any
5;;; way you like, as long as you don't charge money for it, remove this
6;;; notice, or hold me liable for its results.
5 7
6;; GNU Emacs is free software; you can redistribute it and/or modify 8;;; The changelog is at the end of file.
7;; it under the terms of the GNU General Public License as published by
8;; the Free Software Foundation; either version 1, or (at your option)
9;; any later version.
10 9
11;; GNU Emacs is distributed in the hope that it will be useful, 10;;; Please send me bug reports, bug fixes, and extensions, so that I can
12;; but WITHOUT ANY WARRANTY; without even the implied warranty of 11;;; merge them into the master source.
13;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12;;; - Olin Shivers (shivers@cs.cmu.edu)
14;; GNU General Public License for more details.
15 13
16;; You should have received a copy of the GNU General Public License 14;;; This file defines a a shell-in-a-buffer package (shell mode) built
17;; along with GNU Emacs; see the file COPYING. If not, write to 15;;; on top of comint mode. This shell mode is similar to its
18;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 16;;; counterpart in the GNU Emacs 18 release, but is more featureful,
19 17;;; robust, and uniform than that version.
20;;; Hacked from tea.el and shell.el by Olin Shivers (shivers@cs.cmu.edu). 8/88
21 18
22;;; Since this mode is built on top of the general command-interpreter-in- 19;;; Since this mode is built on top of the general command-interpreter-in-
23;;; a-buffer mode (comint mode), it shares a common base functionality, 20;;; a-buffer mode (comint mode), it shares a common base functionality,
24;;; and a common set of bindings, with all modes derived from comint mode. 21;;; and a common set of bindings, with all modes derived from comint mode.
22;;; This makes these modes easier to use.
25 23
26;;; For documentation on the functionality provided by comint mode, and 24;;; For documentation on the functionality provided by comint mode, and
27;;; the hooks available for customising it, see the file comint.el. 25;;; the hooks available for customising it, see the file comint.el.
26;;; For further information on shell mode, see the comments below.
28 27
29;;; Needs fixin: 28;;; Needs fixin:
30;;; When sending text from a source file to a subprocess, the process-mark can 29;;; When sending text from a source file to a subprocess, the process-mark can
@@ -35,6 +34,118 @@
35(require 'comint) 34(require 'comint)
36(provide 'shell) 35(provide 'shell)
37 36
37;; YOUR .EMACS FILE
38;;=============================================================================
39;; Some suggestions for your .emacs file.
40;;
41;; ; If shell lives in some non-standard directory, you must tell emacs
42;; ; where to get it. This may or may not be necessary.
43;; (setq load-path (cons (expand-file-name "~jones/lib/emacs") load-path))
44;;
45;; ; Autoload shell from file shell.el
46;; (autoload 'shell "shell"
47;; "Run an inferior shell process."
48;; t)
49;;
50;; ; Define C-c t to run my favorite command in shell mode:
51;; (setq shell-load-hook
52;; '((lambda ()
53;; (define-key shell-mode-map "\C-ct" 'favorite-cmd))))
54
55
56;;; Brief Command Documentation:
57;;;============================================================================
58;;; Comint Mode Commands: (common to shell and all comint-derived modes)
59;;;
60;;; m-p comint-previous-input Cycle backwards in input history
61;;; m-n comint-next-input Cycle forwards
62;;; m-c-r comint-previous-input-matching Search backwards in input history
63;;; return comint-send-input
64;;; c-a comint-bol Beginning of line; skip prompt.
65;;; c-d comint-delchar-or-maybe-eof Delete char unless at end of buff.
66;;; c-c c-u comint-kill-input ^u
67;;; c-c c-w backward-kill-word ^w
68;;; c-c c-c comint-interrupt-subjob ^c
69;;; c-c c-z comint-stop-subjob ^z
70;;; c-c c-\ comint-quit-subjob ^\
71;;; c-c c-o comint-kill-output Delete last batch of process output
72;;; c-c c-r comint-show-output Show last batch of process output
73;;; send-invisible Read line w/o echo & send to proc
74;;; comint-continue-subjob Useful if you accidentally suspend
75;;; top-level job.
76;;; comint-mode-hook is the comint mode hook.
77
78;;; Shell Mode Commands:
79;;; shell Fires up the shell process.
80;;; tab comint-dynamic-complete Complete a partial file name
81;;; m-? comint-dynamic-list-completions List completions in help buffer
82;;; dirs Resync the buffer's dir stack.
83;;; dirtrack-toggle Turn dir tracking on/off.
84;;;
85;;; The shell mode hook is shell-mode-hook
86;;; The shell-load-hook is run after this file is loaded.
87;;; comint-prompt-regexp is initialised to shell-prompt-pattern, for backwards
88;;; compatibility.
89
90;;; Read the rest of this file for more information.
91
92;;; Emacs 18 SHELL.EL COMPATIBILITY
93;;;
94;;; The below notes were written before this shell package became the
95;;; official shell mode of the standard Emacs distribution, and talk
96;;; about getting this package to work well with the old shell package
97;;; and its users. This issue isn't quite as relevant now as it was
98;;; then, but the notes below should still be useful for people
99;;; modifying elisp packages that used the old shell mode to use this
100;;; one. Note that some of the variables referred to have lost their
101;;; `cmu-' prefix.
102;;;
103;;;============================================================================
104;;; In brief: this package should have no trouble coexisting with shell.el.
105;;;
106;;; Most customising variables -- e.g., explicit-shell-file-name -- are the
107;;; same, so the users shouldn't have much trouble. Hooks have different
108;;; names, however, so you can customise shell mode differently from shell
109;;; mode. You basically just have to remember to type M-x cmushell instead of
110;;; M-x shell.
111;;;
112;;; It would be nice if this file was completely plug-compatible with the old
113;;; shell package -- if you could just name this file shell.el, and have it
114;;; transparently replace the old one. But you can't. Several other packages
115;;; (tex-mode, background, dbx, gdb, kermit, monkey, prolog, telnet) are also
116;;; clients of shell mode. These packages assume detailed knowledge of shell
117;;; mode internals in ways that are incompatible with cmushell mode (mostly
118;;; because of cmushell mode's greater functionality). So, unless we are
119;;; willing to port all of these packages, we can't have this file be a
120;;; complete replacement for shell.el -- that is, we can't name this file
121;;; shell.el, and its main entry point (shell), because dbx.el will break
122;;; when it loads it in and tries to use it.
123;;;
124;;; There are two ways to fix this. One: rewrite these other modes to use the
125;;; new package. This is a win, but can't be assumed. The other, backwards
126;;; compatible route, is to make this package non-conflict with shell.el, so
127;;; both files can be loaded in at the same time. And *that* is why some
128;;; functions and variables have different names: (cmushell),
129;;; cmushell-mode-map, that sort of thing. All the names have been carefully
130;;; chosen so that shell.el and cmushell.el won't tromp on each other.
131
132;;; Customisation and Buffer Variables
133;;; ===========================================================================
134;;;
135
136;In loaddefs.el now.
137;(defconst shell-prompt-pattern
138; "^[^#$%>]*[#$%>] *"
139; "*Regexp used by Newline command to match subshell prompts.
140;;; Change the doc string for shell-prompt-pattern:
141(put 'shell-prompt-pattern 'variable-documentation
142 "Regexp to match prompts in the inferior shell.
143Defaults to \"^[^#$%>]*[#$%>] *\", which works pretty well.
144This variable is used to initialise comint-prompt-regexp in the
145shell buffer.
146
147This is a fine thing to set in your .emacs file.")
148
38(defvar shell-popd-regexp "popd" 149(defvar shell-popd-regexp "popd"
39 "*Regexp to match subshell commands equivalent to popd.") 150 "*Regexp to match subshell commands equivalent to popd.")
40 151
@@ -56,15 +167,18 @@
56 "*Args passed to inferior shell by M-x shell, if the shell is csh. 167 "*Args passed to inferior shell by M-x shell, if the shell is csh.
57Value is a list of strings, which may be nil.") 168Value is a list of strings, which may be nil.")
58 169
170;;; All the above vars aren't prefixed "shell-" to make them
171;;; backwards compatible w/shell.el and old .emacs files.
172
59(defvar shell-dirstack nil 173(defvar shell-dirstack nil
60 "List of directories saved by pushd in this buffer's shell.") 174 "List of directories saved by pushd in this buffer's shell.")
61 175
62(defvar shell-dirstack-query "dirs" 176(defvar shell-dirstack-query "dirs"
63 "Command used by shell-resync-dirlist to query shell.") 177 "Command used by shell-resync-dirlist to query shell.")
64 178
65(defvar shell-mode-map ()) 179(defvar shell-mode-map '())
66(cond ((not shell-mode-map) 180(cond ((not shell-mode-map)
67 (setq shell-mode-map (copy-keymap comint-mode-map)) 181 (setq shell-mode-map (full-copy-sparse-keymap comint-mode-map))
68 (define-key shell-mode-map "\t" 'comint-dynamic-complete) 182 (define-key shell-mode-map "\t" 'comint-dynamic-complete)
69 (define-key shell-mode-map "\M-?" 'comint-dynamic-list-completions))) 183 (define-key shell-mode-map "\M-?" 'comint-dynamic-list-completions)))
70 184
@@ -102,33 +216,34 @@ Variables shell-cd-regexp, shell-pushd-regexp and shell-popd-regexp are used
102to match their respective commands." 216to match their respective commands."
103 (interactive) 217 (interactive)
104 (comint-mode) 218 (comint-mode)
105 (setq major-mode 'shell-mode 219 (setq comint-prompt-regexp shell-prompt-pattern)
106 mode-name "Shell" 220 (setq major-mode 'shell-mode)
107 comint-prompt-regexp shell-prompt-pattern 221 (setq mode-name "shell")
108 comint-input-sentinel 'shell-directory-tracker)
109 (use-local-map shell-mode-map) 222 (use-local-map shell-mode-map)
110 (make-local-variable 'shell-dirstack) 223 (make-local-variable 'shell-dirstack)
111 (set (make-local-variable 'shell-dirtrackp) t) 224 (setq shell-dirstack nil)
225 (make-local-variable 'shell-dirtrackp)
226 (setq shell-dirtrackp t)
227 (setq comint-input-sentinel 'shell-directory-tracker)
112 (run-hooks 'shell-mode-hook)) 228 (run-hooks 'shell-mode-hook))
113 229
114 230
115(defun shell () 231(defun shell ()
116 "Run an inferior shell, with I/O through buffer *shell*. 232 "Run an inferior shell, with I/O through buffer *shell*.
117If buffer exists but shell process is not running, make new shell. 233If buffer exists but shell process is not running, make new shell.
118If buffer exists and shell process is running, just switch to buffer *shell*. 234If buffer exists and shell process is running,
119 235 just switch to buffer *shell*.
120The shell to use comes from the first non-nil variable found from these: 236Program used comes from variable explicit-shell-file-name,
121explicit-shell-file-name in Emacs, ESHELL in the environment or SHELL in the 237 or (if that is nil) from the ESHELL environment variable,
122environment. If none is found, /bin/sh is used. 238 or else from SHELL if there is no ESHELL.
123 239If a file ~/.emacs_SHELLNAME exists, it is given as initial input
124If a file ~/.emacs_SHELLNAME exists, it is given as initial input, simulating 240 (Note that this may lose due to a timing error if the shell
125a start-up file for the shell like .profile or .cshrc. Note that this may 241 discards input when it starts up.)
126lose due to a timing error if the shell discards input when it starts up.
127
128The buffer is put in shell-mode, giving commands for sending input 242The buffer is put in shell-mode, giving commands for sending input
129and controlling the subjobs of the shell. 243and controlling the subjobs of the shell. See shell-mode.
244See also variable shell-prompt-pattern.
130 245
131The shell file name, sans directories, is used to make a symbol name 246The shell file name (sans directories) is used to make a symbol name
132such as `explicit-csh-arguments'. If that symbol is a variable, 247such as `explicit-csh-arguments'. If that symbol is a variable,
133its value is used as a list of arguments when invoking the shell. 248its value is used as a list of arguments when invoking the shell.
134Otherwise, one argument `-i' is passed to the shell. 249Otherwise, one argument `-i' is passed to the shell.
@@ -139,7 +254,7 @@ Otherwise, one argument `-i' is passed to the shell.
139 (let* ((prog (or explicit-shell-file-name 254 (let* ((prog (or explicit-shell-file-name
140 (getenv "ESHELL") 255 (getenv "ESHELL")
141 (getenv "SHELL") 256 (getenv "SHELL")
142 "/bin/sh")) 257 "/bin/sh"))
143 (name (file-name-nondirectory prog)) 258 (name (file-name-nondirectory prog))
144 (startfile (concat "~/.emacs_" name)) 259 (startfile (concat "~/.emacs_" name))
145 (xargs-name (intern-soft (concat "explicit-" name "-args")))) 260 (xargs-name (intern-soft (concat "explicit-" name "-args"))))
@@ -160,7 +275,7 @@ Otherwise, one argument `-i' is passed to the shell.
160;;; changes the current directory of the shell buffer accordingly. 275;;; changes the current directory of the shell buffer accordingly.
161;;; 276;;;
162;;; This is basically a fragile hack, although it's more accurate than 277;;; This is basically a fragile hack, although it's more accurate than
163;;; the original version in shell.el. It has the following failings: 278;;; the released version in shell.el. It has the following failings:
164;;; 1. It doesn't know about the cdpath shell variable. 279;;; 1. It doesn't know about the cdpath shell variable.
165;;; 2. It only spots the first command in a command sequence. E.g., it will 280;;; 2. It only spots the first command in a command sequence. E.g., it will
166;;; miss the cd in "ls; cd foo" 281;;; miss the cd in "ls; cd foo"
@@ -173,7 +288,7 @@ Otherwise, one argument `-i' is passed to the shell.
173;;; messes it up. You run other processes under the shell; these each have 288;;; messes it up. You run other processes under the shell; these each have
174;;; separate working directories, and some have commands for manipulating 289;;; separate working directories, and some have commands for manipulating
175;;; their w.d.'s (e.g., the lcd command in ftp). Some of these programs have 290;;; their w.d.'s (e.g., the lcd command in ftp). Some of these programs have
176;;; commands that do *not* effect the current w.d. at all, but look like they 291;;; commands that do *not* affect the current w.d. at all, but look like they
177;;; do (e.g., the cd command in ftp). In shells that allow you job 292;;; do (e.g., the cd command in ftp). In shells that allow you job
178;;; control, you can switch between jobs, all having different w.d.'s. So 293;;; control, you can switch between jobs, all having different w.d.'s. So
179;;; simply saying %3 can shift your w.d.. 294;;; simply saying %3 can shift your w.d..
@@ -390,3 +505,96 @@ command again."
390 (setq msg (concat msg dir " ")) 505 (setq msg (concat msg dir " "))
391 (setq ds (cdr ds)))) 506 (setq ds (cdr ds))))
392 (message msg))) 507 (message msg)))
508
509
510
511;;; Interfacing to client packages (and converting them)
512;;;============================================================================
513;;; Several gnu packages (tex-mode, background, dbx, gdb, kermit, prolog,
514;;; telnet are some) use the shell package as clients. Most of them would
515;;; be better off using the comint package directly, but they predate it.
516;;; The catch is that most of these packages (dbx, gdb, prolog, telnet)
517;;; assume total knowledge of all the local variables that shell mode
518;;; functions depend on. So they (kill-all-local-variables), then create
519;;; the few local variables that shell.el functions depend on. Alas,
520;;; cmushell.el functions depend on a different set of vars (for example,
521;;; the input history ring is a local variable in cmushell.el's shell mode,
522;;; whereas there is no input history ring in shell.el's shell mode).
523;;; So we have a situation where the greater functionality of cmushell.el
524;;; is biting us -- you can't just replace shell will cmushell.
525;;;
526;;; Altering these packages to use comint mode directly should *greatly*
527;;; improve their functionality, and is actually pretty easy. It's
528;;; mostly a matter of renaming a few variable names. See comint.el for more.
529;;; -Olin
530
531
532
533;;; Do the user's customisation...
534;;;===============================
535(defvar shell-load-hook nil
536 "This hook is run when shell is loaded in.
537This is a good place to put keybindings.")
538
539(run-hooks 'shell-load-hook)
540
541;;; Change Log
542;;; ===========================================================================
543;;; Olin 8/88
544;;; Created.
545;;;
546;;; Olin 5/26/90
547;;; - Split cmulisp and cmushell modes into separate files.
548;;; Not only is this a good idea, it's apparently the way it'll be rel 19.
549;;; - Souped up the directory tracking; it now can handle pushd, pushd +n,
550;;; and popd +n.
551;;; - Added cmushell-dirtrack-toggle command to toggle the directory
552;;; tracking that cmushell tries to do. This is useful, for example,
553;;; when you are running ftp -- it prevents the ftp "cd" command from
554;;; spoofing the tracking machinery. This command is also named
555;;; dirtrack-toggle, so you need only type M-x dirtrack to run it.
556;;; - Added cmushell-resync-dirs command. This queries the shell
557;;; for the current directory stack, and resets the buffer's stack
558;;; accordingly. This command is also named dirs, so you need only type
559;;; M-x dirs to run it.
560;;; - Bits of the new directory tracking code were adapted from source
561;;; contributed by Vince Broman, Jeff Peck, and Barry Warsaw.
562;;; - See also the improvements made to comint.el at the same time.
563;;; - Renamed several variables. Mostly this comprised changing "shell"
564;;; to "cmushell" in the names. The only variables that are not prefixed
565;;; with "cmushell-" are the ones that are common with shell.el:
566;;; explicit-shell-file-name shell-prompt-pattern explicit-csh-args
567;;; and shell-cd/popd/pushd-regexp
568;;; The variables and functions that were changed to have "cmushell-"
569;;; prefixes are:
570;;; shell-directory-stack (v), shell-directory-tracker (f)
571;;; This should not affect users, only elisp hackers. Hopefully
572;;; one day shell.el will just go away, and we can drop all this
573;;; "cmushell" bullshit.
574;;; - Upgraded process sends to use comint-send-string instead of
575;;; process-send-string.
576;;;
577;;; Olin 6/14/90
578;;; - If your shell is named <shellname>, and a variable named
579;;; explicit-<shellname>-args exists, cmushell is supposed
580;;; to use its value as the arglist to the shell invocation.
581;;; E.g., if you define explicit-csh-args to be
582;;; ("-ifx"), then when cmushell cranks up a csh, it execs it
583;;; as "csh -ifx". This is what is documented. What has actually
584;;; been the case is that the variable checked is
585;;; explicit-<shellname>-arguments, not explicit-<shellname>-args.
586;;; The documentation has been changed to conform to the code (for
587;;; backwards compatibility with shell.el). This bug is inherited from
588;;; the same bug in shell.el.
589;;; This bug reported by Stephen Anderson.
590;;;
591;;; Olin 9/5/90
592;;; - Arguments to cd, popd, and pushd now have their env vars expanded
593;;; out by the tracking machinery. So if you say "cd $SRCDIR/funs", the
594;;; $SRCDIR var will be replaced by its value *in emacs' process
595;;; environment*. If this is different from the shell's binding of the
596;;; variable, you lose. Several users needed this feature, fragile
597;;; though it may be. The fix was contributed by sk@thp.Uni-Koeln.DE.
598;;;
599;;; Olin 3/12/91
600;;; - Moved comint-dynamic-complete (filename completion) from M-tab to tab.