shell.el 52.8 KB
Newer Older
1
;;; shell.el --- specialized comint.el for running the shell -*- lexical-binding: t -*-
2

Paul Eggert's avatar
Paul Eggert committed
3 4
;; Copyright (C) 1988, 1993-1997, 2000-2015 Free Software Foundation,
;; Inc.
Eric S. Raymond's avatar
Eric S. Raymond committed
5

6
;; Author: Olin Shivers <shivers@cs.cmu.edu>
Karl Heuer's avatar
Karl Heuer committed
7
;;	Simon Marshall <simon@gnu.org>
8
;; Maintainer: emacs-devel@gnu.org
Eric S. Raymond's avatar
Eric S. Raymond committed
9
;; Keywords: processes
Eric S. Raymond's avatar
Eric S. Raymond committed
10

11
;; This file is part of GNU Emacs.
Eric S. Raymond's avatar
Eric S. Raymond committed
12

13
;; GNU Emacs is free software: you can redistribute it and/or modify
14
;; it under the terms of the GNU General Public License as published by
15 16
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
Eric S. Raymond's avatar
Eric S. Raymond committed
17

18 19 20 21
;; 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.
Eric S. Raymond's avatar
Eric S. Raymond committed
22

23
;; You should have received a copy of the GNU General Public License
24
;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
David Lawrence's avatar
David Lawrence committed
25

Eric S. Raymond's avatar
Eric S. Raymond committed
26 27
;;; Commentary:

Juanma Barranquero's avatar
Juanma Barranquero committed
28 29 30
;; This file defines a shell-in-a-buffer package (shell mode) built on
;; top of comint mode.  This is actually cmushell with things renamed
;; to replace its counterpart in Emacs 18.  cmushell is more
Erik Naggum's avatar
Erik Naggum committed
31
;; featureful, robust, and uniform than the Emacs 18 version.
David Lawrence's avatar
David Lawrence committed
32

Erik Naggum's avatar
Erik Naggum committed
33
;; Since this mode is built on top of the general command-interpreter-in-
34
;; a-buffer mode (comint mode), it shares a common base functionality,
Erik Naggum's avatar
Erik Naggum committed
35 36
;; and a common set of bindings, with all modes derived from comint mode.
;; This makes these modes easier to use.
David Lawrence's avatar
David Lawrence committed
37

Erik Naggum's avatar
Erik Naggum committed
38
;; For documentation on the functionality provided by comint mode, and
Paul Eggert's avatar
Paul Eggert committed
39
;; the hooks available for customizing it, see the file comint.el.
Erik Naggum's avatar
Erik Naggum committed
40
;; For further information on shell mode, see the comments below.
David Lawrence's avatar
David Lawrence committed
41

Erik Naggum's avatar
Erik Naggum committed
42
;; Needs fixin:
43
;; When sending text from a source file to a subprocess, the process-mark can
Erik Naggum's avatar
Erik Naggum committed
44 45 46
;; move off the window, so you can lose sight of the process interactions.
;; Maybe I should ensure the process mark is in the window when I send
;; text to the process? Switch selectable?
David Lawrence's avatar
David Lawrence committed
47

Jim Blandy's avatar
Jim Blandy committed
48 49
;; YOUR .EMACS FILE
;;=============================================================================
50
;; Some suggestions for your init file.
Jim Blandy's avatar
Jim Blandy committed
51
;;
52 53 54
;; ;; Define M-# to run some strange command:
;; (eval-after-load "shell"
;;  '(define-key shell-mode-map "\M-#" 'shells-dynamic-spell))
55

Erik Naggum's avatar
Erik Naggum committed
56 57 58 59
;; Brief Command Documentation:
;;============================================================================
;; Comint Mode Commands: (common to shell and all comint-derived modes)
;;
60 61
;; m-p	   comint-previous-input    	   Cycle backwards in input history
;; m-n	   comint-next-input  	    	   Cycle forwards
Erik Naggum's avatar
Erik Naggum committed
62 63
;; m-r     comint-previous-matching-input  Previous input matching a regexp
;; m-s     comint-next-matching-input      Next input that matches
64
;; m-c-l   comint-show-output		   Show last batch of process output
Erik Naggum's avatar
Erik Naggum committed
65
;; return  comint-send-input
66
;; c-d	   comint-delchar-or-maybe-eof	   Delete char unless at end of buff.
Erik Naggum's avatar
Erik Naggum committed
67
;; c-c c-a comint-bol                      Beginning of line; skip prompt
68 69 70 71 72
;; 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	    	   ^\
73
;; c-c c-o comint-delete-output		   Delete last batch of process output
74
;; c-c c-r comint-show-output		   Show last batch of process output
Karl Heuer's avatar
Karl Heuer committed
75
;; c-c c-l comint-dynamic-list-input-ring  List input history
Erik Naggum's avatar
Erik Naggum committed
76
;;         send-invisible                  Read line w/o echo & send to proc
77
;;         comint-continue-subjob	   Useful if you accidentally suspend
Erik Naggum's avatar
Erik Naggum committed
78 79 80 81 82
;;					        top-level job
;; comint-mode-hook is the comint mode hook.

;; Shell Mode Commands:
;;         shell			Fires up the shell process
83
;; tab     completion-at-point		Complete filename/command/history
Erik Naggum's avatar
Erik Naggum committed
84 85 86 87
;; m-?     comint-dynamic-list-filename-completions
;;					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
88
;; 	   dirs				Resync the buffer's dir stack
89
;; 	   shell-dirtrack-mode		Turn dir tracking on/off
Erik Naggum's avatar
Erik Naggum committed
90 91 92
;;         comint-strip-ctrl-m		Remove trailing ^Ms from output
;;
;; The shell mode hook is shell-mode-hook
Paul Eggert's avatar
Paul Eggert committed
93
;; comint-prompt-regexp is initialized to shell-prompt-pattern, for backwards
Erik Naggum's avatar
Erik Naggum committed
94
;; compatibility.
Jim Blandy's avatar
Jim Blandy committed
95

Erik Naggum's avatar
Erik Naggum committed
96
;; Read the rest of this file for more information.
97

Eric S. Raymond's avatar
Eric S. Raymond committed
98 99 100
;;; Code:

(require 'comint)
101
(require 'pcomplete)
Eric S. Raymond's avatar
Eric S. Raymond committed
102

Erik Naggum's avatar
Erik Naggum committed
103 104
;;; Customization and Buffer Variables

105
(defgroup shell nil
106
  "Running shell from within Emacs buffers."
107 108 109 110
  :group 'processes
  :group 'unix)

(defgroup shell-directories nil
111
  "Directory support in shell mode."
112 113
  :group 'shell)

Glenn Morris's avatar
Glenn Morris committed
114 115 116 117
;; Unused.
;;; (defgroup shell-faces nil
;;;   "Faces in shell buffers."
;;;   :group 'shell)
118

Eric S. Raymond's avatar
Eric S. Raymond committed
119
;;;###autoload
120
(defcustom shell-dumb-shell-regexp (purecopy "cmd\\(proxy\\)?\\.exe")
121 122 123 124 125
  "Regexp to match shells that don't save their command history, and
don't handle the backslash as a quote character.  For shells that
match this regexp, Emacs will write out the command history when the
shell finishes, and won't remove backslashes when it unquotes shell
arguments."
126 127 128
  :type 'regexp
  :group 'shell)

129
(defcustom shell-prompt-pattern "^[^#$%>\n]*[#$%>] *"
Jim Blandy's avatar
Jim Blandy committed
130
  "Regexp to match prompts in the inferior shell.
131
Defaults to \"^[^#$%>\\n]*[#$%>] *\", which works pretty well.
132
This variable is used to initialize `comint-prompt-regexp' in the
Jim Blandy's avatar
Jim Blandy committed
133 134
shell buffer.

135 136 137
If `comint-use-prompt-regexp' is nil, then this variable is only used
to determine paragraph boundaries.  See Info node `Shell Prompts' for
how Shell mode treats paragraphs.
138

139
The pattern should probably not match more than one line.  If it does,
140
Shell mode may become confused trying to distinguish prompt from input
141
on lines which don't start with a prompt."
142 143
  :type 'regexp
  :group 'shell)
Jim Blandy's avatar
Jim Blandy committed
144

145
(defcustom shell-completion-fignore nil
146
  "List of suffixes to be disregarded during file/command completion.
147 148
This variable is used to initialize `comint-completion-fignore' in the shell
buffer.  The default is nil, for compatibility with most shells.
149
Some people like (\"~\" \"#\" \"%\")."
150 151
  :type '(repeat (string :tag "Suffix"))
  :group 'shell)
152

153
(defcustom shell-delimiter-argument-list '(?\| ?& ?< ?> ?\( ?\) ?\;)
154
  "List of characters to recognize as separate arguments.
155
This variable is used to initialize `comint-delimiter-argument-list' in the
156 157 158 159
shell buffer.  The value may depend on the operating system or shell."
  :type '(choice (const nil)
		 (repeat :tag "List of characters" character))
  :group 'shell)
160

161
(defcustom shell-file-name-chars
Juanma Barranquero's avatar
Juanma Barranquero committed
162
  (if (memq system-type '(ms-dos windows-nt cygwin))
163
      "~/A-Za-z0-9_^$!#%&{}@`'.,:()-"
164
    "[]~/A-Za-z0-9+@:_.$#%,={}-")
165 166
  "String of characters valid in a file name.
This variable is used to initialize `comint-file-name-chars' in the
167 168 169
shell buffer.  The value may depend on the operating system or shell."
  :type 'string
  :group 'shell)
170

171
(defcustom shell-file-name-quote-list
172 173
  (if (memq system-type '(ms-dos windows-nt))
      nil
174
    (append shell-delimiter-argument-list '(?\s ?$ ?\* ?\! ?\" ?\' ?\` ?\# ?\\)))
175 176
  "List of characters to quote when in a file name.
This variable is used to initialize `comint-file-name-quote-list' in the
177 178 179
shell buffer.  The value may depend on the operating system or shell."
  :type '(repeat character)
  :group 'shell)
180

181
(defcustom shell-dynamic-complete-functions
182 183 184 185
  '(comint-c-a-p-replace-by-expanded-history
    shell-environment-variable-completion
    shell-command-completion
    shell-c-a-p-replace-by-expanded-directory
186
    pcomplete-completions-at-point
187
    shell-filename-completion
188
    comint-filename-completion)
189
  "List of functions called to perform completion.
190
This variable is used to initialize `comint-dynamic-complete-functions' in the
191 192 193
shell buffer."
  :type '(repeat function)
  :group 'shell)
194

195
(defcustom shell-command-regexp "[^;&|\n]+"
196
  "Regexp to match a single command within a pipeline.
197 198 199
This is used for directory tracking and does not do a perfect job."
  :type 'regexp
  :group 'shell)
200

201
(defcustom shell-command-separator-regexp "[;&|\n \t]*"
202
  "Regexp to match a single command within a pipeline.
203 204 205 206
This is used for directory tracking and does not do a perfect job."
  :type 'regexp
  :group 'shell)

207
(defcustom shell-completion-execonly t
208
  "If non-nil, use executable files only for completion candidates.
Richard M. Stallman's avatar
Richard M. Stallman committed
209
This mirrors the optional behavior of tcsh.
210

211 212 213
Detecting executability of files may slow command completion considerably."
  :type 'boolean
  :group 'shell)
214

215
(defcustom shell-popd-regexp "popd"
216
  "Regexp to match subshell commands equivalent to popd."
217 218
  :type 'regexp
  :group 'shell-directories)
David Lawrence's avatar
David Lawrence committed
219

220
(defcustom shell-pushd-regexp "pushd"
221
  "Regexp to match subshell commands equivalent to pushd."
222 223
  :type 'regexp
  :group 'shell-directories)
David Lawrence's avatar
David Lawrence committed
224

225
(defcustom shell-pushd-tohome nil
226
  "If non-nil, make pushd with no arg behave as \"pushd ~\" (like cd).
227 228 229
This mirrors the optional behavior of tcsh."
  :type 'boolean
  :group 'shell-directories)
230

231
(defcustom shell-pushd-dextract nil
232
  "If non-nil, make \"pushd +n\" pop the nth dir to the stack top.
233 234 235
This mirrors the optional behavior of tcsh."
  :type 'boolean
  :group 'shell-directories)
236

237
(defcustom shell-pushd-dunique nil
238
  "If non-nil, make pushd only add unique directories to the stack.
239 240 241
This mirrors the optional behavior of tcsh."
  :type 'boolean
  :group 'shell-directories)
242

243
(defcustom shell-cd-regexp "cd"
244
  "Regexp to match subshell commands equivalent to cd."
245 246
  :type 'regexp
  :group 'shell-directories)
David Lawrence's avatar
David Lawrence committed
247

248
(defcustom shell-chdrive-regexp
249
  (if (memq system-type '(ms-dos windows-nt))
250 251 252
      ; NetWare allows the five chars between upper and lower alphabetics.
      "[]a-zA-Z^_`\\[\\\\]:"
    nil)
253
  "If non-nil, is regexp used to track drive changes."
254 255
  :type '(choice regexp
		 (const nil))
256
  :group 'shell-directories)
257

258
(defcustom shell-dirtrack-verbose t
259
  "If non-nil, show the directory stack following directory change.
260
This is effective only if directory tracking is enabled.
261 262
The `dirtrack' package provides an alternative implementation of this feature -
see the function `dirtrack-mode'."
263 264 265
  :type 'boolean
  :group 'shell-directories)

266
(defcustom explicit-shell-file-name nil
267
  "If non-nil, is file name to use for explicitly requested inferior shell."
268 269
  :type '(choice (const :tag "None" nil) file)
  :group 'shell)
David Lawrence's avatar
David Lawrence committed
270

271 272
;; Note: There are no explicit references to the variable `explicit-csh-args'.
;; It is used implicitly by M-x shell when the shell is `csh'.
273
(defcustom explicit-csh-args
David Lawrence's avatar
David Lawrence committed
274 275 276 277 278
  (if (eq system-type 'hpux)
      ;; -T persuades HP's csh not to think it is smarter
      ;; than us about what terminal modes to use.
      '("-i" "-T")
    '("-i"))
279
  "Args passed to inferior shell by \\[shell], if the shell is csh.
280 281 282
Value is a list of strings, which may be nil."
  :type '(repeat (string :tag "Argument"))
  :group 'shell)
David Lawrence's avatar
David Lawrence committed
283

284 285
;; Note: There are no explicit references to the variable `explicit-bash-args'.
;; It is used implicitly by M-x shell when the interactive shell is `bash'.
286
(defcustom explicit-bash-args
287 288 289
  ;; Tell bash not to use readline.  It's safe to assume --noediting now,
  ;; as it was introduced in 1996 in Bash version 2.
  '("--noediting" "-i")
290
  "Args passed to inferior shell by \\[shell], if the shell is bash.
291 292 293 294
Value is a list of strings, which may be nil."
  :type '(repeat (string :tag "Argument"))
  :group 'shell)

295
(defcustom shell-input-autoexpand 'history
296
  "If non-nil, expand input command history references on completion.
297 298 299 300 301
This mirrors the optional behavior of tcsh (its autoexpand and histlit).

If the value is `input', then the expansion is seen on input.
If the value is `history', then the expansion is only when inserting
into the buffer's input ring.  See also `comint-magic-space' and
302
`comint-dynamic-complete-functions'.
303 304

This variable supplies a default for `comint-input-autoexpand',
305
for Shell mode only."
306 307 308 309
  :type '(choice (const :tag "off" nil)
		 (const input)
		 (const history)
		 (const :tag "on" t))
310
  :group 'shell)
311

David Lawrence's avatar
David Lawrence committed
312
(defvar shell-dirstack nil
Eric S. Raymond's avatar
Eric S. Raymond committed
313 314
  "List of directories saved by pushd in this buffer's shell.
Thus, this does not include the shell's current directory.")
David Lawrence's avatar
David Lawrence committed
315

316 317 318
(defvar shell-dirtrackp t
  "Non-nil in a shell buffer means directory tracking is enabled.")

319 320 321
(defvar shell-last-dir nil
  "Keep track of last directory for ksh `cd -' command.")

322
(defvar shell-dirstack-query nil
323
  "Command used by `shell-resync-dirs' to query the shell.")
David Lawrence's avatar
David Lawrence committed
324

325 326 327 328
(defvar shell-mode-map
  (let ((map (nconc (make-sparse-keymap) comint-mode-map)))
    (define-key map "\C-c\C-f" 'shell-forward-command)
    (define-key map "\C-c\C-b" 'shell-backward-command)
329
    (define-key map "\t" 'completion-at-point)
330 331 332 333 334 335 336 337 338 339 340 341 342 343
    (define-key map (kbd "M-RET") 'shell-resync-dirs)
    (define-key map "\M-?" 'comint-dynamic-list-filename-completions)
    (define-key map [menu-bar completion]
      (cons "Complete"
	    (copy-keymap (lookup-key comint-mode-map [menu-bar completion]))))
    (define-key-after (lookup-key map [menu-bar completion])
      [complete-env-variable] '("Complete Env. Variable Name" .
				shell-dynamic-complete-environment-variable)
      'complete-file)
    (define-key-after (lookup-key map [menu-bar completion])
      [expand-directory] '("Expand Directory Reference" .
			   shell-replace-by-expanded-directory)
      'complete-expand)
    map))
David Lawrence's avatar
David Lawrence committed
344

345
(defcustom shell-mode-hook '()
Juanma Barranquero's avatar
Juanma Barranquero committed
346
  "Hook for customizing Shell mode."
347 348
  :type 'hook
  :group 'shell)
David Lawrence's avatar
David Lawrence committed
349

350
(defvar shell-font-lock-keywords
351
  '(("[ \t]\\([+-][^ \t\n]+\\)" 1 font-lock-comment-face)
352 353
    ("^[^ \t\n]+:.*" . font-lock-string-face)
    ("^\\[[1-9][0-9]*\\]" . font-lock-string-face))
354
  "Additional expressions to highlight in Shell mode.")
355

David Lawrence's avatar
David Lawrence committed
356 357
;;; Basic Procedures

358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
(defun shell--unquote&requote-argument (qstr &optional upos)
  (unless upos (setq upos 0))
  (let* ((qpos 0)
         (dquotes nil)
         (ustrs '())
         (re (concat
              "[\"']"
              "\\|\\$\\(?:\\([[:alpha:]][[:alnum:]]*\\)"
              "\\|{\\(?1:[^{}]+\\)}\\)"
              (when (memq system-type '(ms-dos windows-nt))
                "\\|%\\(?1:[^\\\\/]*\\)%")
              (when comint-file-name-quote-list
                "\\|\\\\\\(.\\)")))
         (qupos nil)
         (push (lambda (str end)
                 (push str ustrs)
                 (setq upos (- upos (length str)))
                 (unless (or qupos (> upos 0))
                   (setq qupos (if (< end 0) (- end) (+ upos end))))))
         match)
    (while (setq match (string-match re qstr qpos))
      (funcall push (substring qstr qpos match) match)
      (cond
       ((match-beginning 2) (funcall push (match-string 2 qstr) (match-end 0)))
       ((match-beginning 1) (funcall push (getenv (match-string 1 qstr))
                                     (- (match-end 0))))
       ((eq (aref qstr match) ?\") (setq dquotes (not dquotes)))
       ((eq (aref qstr match) ?\')
        (cond
         (dquotes (funcall push "'" (match-end 0)))
         ((< match (1+ (length qstr)))
          (let ((end (string-match "'" qstr (1+ match))))
            (funcall push (substring qstr (1+ match) end)
                     (or end (length qstr)))))
         (t nil)))
       (t (error "Unexpected case in shell--unquote&requote-argument!")))
      (setq qpos (match-end 0)))
    (funcall push (substring qstr qpos) (length qstr))
    (list (mapconcat #'identity (nreverse ustrs) "")
          qupos #'comint-quote-filename)))

(defun shell--unquote-argument (str)
  (car (shell--unquote&requote-argument str)))
(defun shell--requote-argument (upos qstr)
  ;; See `completion-table-with-quoting'.
  (let ((res (shell--unquote&requote-argument qstr upos)))
    (cons (nth 1 res) (nth 2 res))))

(defun shell--parse-pcomplete-arguments ()
407
  "Parse whitespace separated arguments in the current region."
408
  ;; FIXME: share code with shell--unquote&requote-argument.
409 410 411 412 413 414 415 416
  (let ((begin (save-excursion (shell-backward-command 1) (point)))
	(end (point))
	begins args)
    (save-excursion
      (goto-char begin)
      (while (< (point) end)
	(skip-chars-forward " \t\n")
	(push (point) begins)
417 418 419 420 421 422 423 424 425 426 427
        (let ((arg ()))
          (while (looking-at
                  (eval-when-compile
                    (concat
                     "\\(?:[^\s\t\n\\\"']+"
                     "\\|'\\([^']*\\)'?"
                     "\\|\"\\(\\(?:[^\"\\]\\|\\\\.\\)*\\)\"?"
                     "\\|\\\\\\(\\(?:.\\|\n\\)?\\)\\)")))
            (goto-char (match-end 0))
            (cond
             ((match-beginning 3)       ;Backslash escape.
428
              (push (cond
429
                     ((null comint-file-name-quote-list)
430 431 432
                      (goto-char (match-beginning 3)) "\\")
                     ((= (match-beginning 3) (match-end 3)) "\\")
                     (t (match-string 3)))
433 434
                    arg))
             ((match-beginning 2)       ;Double quote.
435
              (push (if (null comint-file-name-quote-list) (match-string 2)
436 437
                      (replace-regexp-in-string
                       "\\\\\\(.\\)" "\\1" (match-string 2)))
438 439 440 441 442
                    arg))
             ((match-beginning 1)       ;Single quote.
              (push (match-string 1) arg))
             (t (push (match-string 0) arg))))
          (push (mapconcat #'identity (nreverse arg) "") args)))
443
      (cons (nreverse args) (nreverse begins)))))
444

445 446 447 448 449 450 451 452 453
(defun shell-command-completion-function ()
  "Completion function for shell command names.
This is the value of `pcomplete-command-completion-function' for
Shell buffers.  It implements `shell-completion-execonly' for
`pcomplete' completion."
  (pcomplete-here (pcomplete-entries nil
				     (if shell-completion-execonly
					 'file-executable-p))))

454 455 456 457 458 459 460 461 462 463 464
(defun shell-completion-vars ()
  "Setup completion vars for `shell-mode' and `read-shell-command'."
  (set (make-local-variable 'comint-completion-fignore)
       shell-completion-fignore)
  (set (make-local-variable 'comint-delimiter-argument-list)
       shell-delimiter-argument-list)
  (set (make-local-variable 'comint-file-name-chars) shell-file-name-chars)
  (set (make-local-variable 'comint-file-name-quote-list)
       shell-file-name-quote-list)
  (set (make-local-variable 'comint-dynamic-complete-functions)
       shell-dynamic-complete-functions)
465 466
  (setq-local comint-unquote-function #'shell--unquote-argument)
  (setq-local comint-requote-function #'shell--requote-argument)
467
  (set (make-local-variable 'pcomplete-parse-arguments-function)
468
       #'shell--parse-pcomplete-arguments)
469 470 471 472 473 474
  (set (make-local-variable 'pcomplete-termination-string)
       (cond ((not comint-completion-addsuffix) "")
             ((stringp comint-completion-addsuffix)
              comint-completion-addsuffix)
             ((not (consp comint-completion-addsuffix)) " ")
             (t (cdr comint-completion-addsuffix))))
475 476
  (set (make-local-variable 'pcomplete-command-completion-function)
       #'shell-command-completion-function)
477 478 479
  ;; Don't use pcomplete's defaulting mechanism, rely on
  ;; shell-dynamic-complete-functions instead.
  (set (make-local-variable 'pcomplete-default-completion-function) #'ignore)
480 481 482 483 484
  (setq comint-input-autoexpand shell-input-autoexpand)
  ;; Not needed in shell-mode because it's inherited from comint-mode, but
  ;; placed here for read-shell-command.
  (add-hook 'completion-at-point-functions 'comint-completion-at-point nil t))

485 486
(put 'shell-mode 'mode-class 'special)

487
(define-derived-mode shell-mode comint-mode "Shell"
488
  "Major mode for interacting with an inferior shell.\\<shell-mode-map>
489 490 491 492
\\[comint-send-input] after the end of the process' output sends the text from
    the end of process to the end of the current line.
\\[comint-send-input] before end of process output copies the current line minus the prompt to
    the end of the buffer and sends it (\\[comint-copy-old-input] just copies the current line).
493
\\[send-invisible] reads a line of text without echoing it, and sends it to
494 495
    the shell.  This is useful for entering passwords.  Or, add the function
    `comint-watch-for-password-prompt' to `comint-output-filter-functions'.
David Lawrence's avatar
David Lawrence committed
496

497 498 499
If you want to make multiple shell buffers, rename the `*shell*' buffer
using \\[rename-buffer] or \\[rename-uniquely] and start a new shell.

500
If you want to make shell buffers limited in length, add the function
501
`comint-truncate-buffer' to `comint-output-filter-functions'.
502

David Lawrence's avatar
David Lawrence committed
503 504 505
If you accidentally suspend your process, use \\[comint-continue-subjob]
to continue it.

506 507
`cd', `pushd' and `popd' commands given to the shell are watched by Emacs to
keep this buffer's default directory the same as the shell's working directory.
508 509
While directory tracking is enabled, the shell's working directory is displayed
by \\[list-buffers] or \\[mouse-buffer-menu] in the `File' field.
510
\\[dirs] queries the shell and resyncs Emacs's idea of what the current
David Lawrence's avatar
David Lawrence committed
511
    directory stack is.
512 513
\\[shell-dirtrack-mode] turns directory tracking on and off.
\(The `dirtrack' package provides an alternative implementation of this
514
feature - see the function `dirtrack-mode'.)
David Lawrence's avatar
David Lawrence committed
515 516

\\{shell-mode-map}
517
Customization: Entry to this mode runs the hooks on `comint-mode-hook' and
518
`shell-mode-hook' (in that order).  Before each input, the hooks on
519 520
`comint-input-filter-functions' are run.  After each shell output, the hooks
on `comint-output-filter-functions' are run.
David Lawrence's avatar
David Lawrence committed
521

522 523 524
Variables `shell-cd-regexp', `shell-chdrive-regexp', `shell-pushd-regexp'
and `shell-popd-regexp' are used to match their respective commands,
while `shell-pushd-tohome', `shell-pushd-dextract' and `shell-pushd-dunique'
525
control the behavior of the relevant command.
526

527 528 529 530
Variables `comint-completion-autolist', `comint-completion-addsuffix',
`comint-completion-recexact' and `comint-completion-fignore' control the
behavior of file name, command name and variable name completion.  Variable
`shell-completion-execonly' controls the behavior of command name completion.
531
Variable `shell-completion-fignore' is used to initialize the value of
532
`comint-completion-fignore'.
533 534

Variables `comint-input-ring-file-name' and `comint-input-autoexpand' control
535
the initialization of the input ring history, and history expansion.
536

537
Variables `comint-output-filter-functions', a hook, and
538
`comint-scroll-to-bottom-on-input' and `comint-scroll-to-bottom-on-output'
539 540
control whether input and output cause the window to scroll to the end of the
buffer."
541
  (setq comint-prompt-regexp shell-prompt-pattern)
542
  (shell-completion-vars)
543
  (set (make-local-variable 'paragraph-separate) "\\'")
544 545 546 547
  (set (make-local-variable 'paragraph-start) comint-prompt-regexp)
  (set (make-local-variable 'font-lock-defaults) '(shell-font-lock-keywords t))
  (set (make-local-variable 'shell-dirstack) nil)
  (set (make-local-variable 'shell-last-dir) nil)
548
  (shell-dirtrack-mode 1)
549 550 551 552 553

  ;; By default, ansi-color applies faces using overlays.  This is
  ;; 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.
554 555
  (setq-local ansi-color-apply-face-function #'shell-apply-ansi-color)
  (shell-reapply-ansi-color)
556

557 558 559
  ;; 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.
  (setq list-buffers-directory (expand-file-name default-directory))
560
  ;; shell-dependent assignments.
561
  (when (ring-empty-p comint-input-ring)
562
    (let ((shell (file-name-nondirectory (car
563 564 565 566 567 568
		   (process-command (get-buffer-process (current-buffer))))))
	  (hsize (getenv "HISTSIZE")))
      (and (stringp hsize)
	   (integerp (setq hsize (string-to-number hsize)))
	   (> hsize 0)
	   (set (make-local-variable 'comint-input-ring-size) hsize))
569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586
      (setq comint-input-ring-file-name
	    (or (getenv "HISTFILE")
		(cond ((string-equal shell "bash") "~/.bash_history")
		      ((string-equal shell "ksh") "~/.sh_history")
		      (t "~/.history"))))
      (if (or (equal comint-input-ring-file-name "")
	      (equal (file-truename comint-input-ring-file-name)
		     (file-truename "/dev/null")))
	  (setq comint-input-ring-file-name nil))
      ;; Arrange to write out the input ring on exit, if the shell doesn't
      ;; do this itself.
      (if (and comint-input-ring-file-name
	       (string-match shell-dumb-shell-regexp shell))
	  (set-process-sentinel (get-buffer-process (current-buffer))
				#'shell-write-history-on-exit))
      (setq shell-dirstack-query
	    (cond ((string-equal shell "sh") "pwd")
		  ((string-equal shell "ksh") "echo $PWD ~-")
587 588
		  ;; Bypass any aliases.  TODO all shells could use this.
		  ((string-equal shell "bash") "command dirs")
589 590 591
		  (t "dirs")))
      ;; Bypass a bug in certain versions of bash.
      (when (string-equal shell "bash")
592
        (add-hook 'comint-preoutput-filter-functions
593
                  'shell-filter-ctrl-a-ctrl-b nil t)))
594
    (comint-read-input-ring t)))
595

596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616
(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))))))

617
(defun shell-filter-ctrl-a-ctrl-b (string)
618 619 620 621 622 623 624 625 626
  "Remove `^A' and `^B' characters from comint output.

Bash uses these characters as internal quoting characters in its
prompt.  Due to a bug in some bash versions (including 2.03,
2.04, and 2.05b), they may erroneously show up when bash is
started with the `--noediting' option and Select Graphic
Rendition (SGR) control sequences (formerly known as ANSI escape
sequences) are used to color the prompt.

627 628 629 630
This function can be put on `comint-preoutput-filter-functions'."
  (if (string-match "[\C-a\C-b]" string)
      (replace-regexp-in-string "[\C-a\C-b]" "" string t t)
    string))
631

632 633 634 635
(defun shell-write-history-on-exit (process event)
  "Called when the shell process is stopped.

Writes the input history to a history file
636
`comint-input-ring-file-name' using `comint-write-input-ring'
637 638 639 640 641 642
and inserts a short message in the shell buffer.

This function is a sentinel watching the shell interpreter process.
Sentinels will always get the two parameters PROCESS and EVENT."
  ;; Write history.
  (comint-write-input-ring)
643 644 645 646 647
  (let ((buf (process-buffer process)))
    (when (buffer-live-p buf)
      (with-current-buffer buf
        (insert (format "\nProcess %s %s\n" process event))))))

Eric S. Raymond's avatar
Eric S. Raymond committed
648
;;;###autoload
Miles Bader's avatar
Miles Bader committed
649 650 651
(defun shell (&optional buffer)
  "Run an inferior shell, with I/O through BUFFER (which defaults to `*shell*').
Interactively, a prefix arg means to prompt for BUFFER.
652 653 654
If `default-directory' is a remote file name, it is also prompted
to change if called with a prefix arg.

Miles Bader's avatar
Miles Bader committed
655 656
If BUFFER exists but shell process is not running, make new shell.
If BUFFER exists and shell process is running, just switch to BUFFER.
657
Program used comes from variable `explicit-shell-file-name',
Jim Blandy's avatar
Jim Blandy committed
658
 or (if that is nil) from the ESHELL environment variable,
Richard M. Stallman's avatar
Richard M. Stallman committed
659
 or (if that is nil) from `shell-file-name'.
660
If a file `~/.emacs_SHELLNAME' exists, or `~/.emacs.d/init_SHELLNAME.sh',
Richard M. Stallman's avatar
Richard M. Stallman committed
661 662
it is given as initial input (but this may be lost, due to a timing
error, if the shell discards input when it starts up).
Richard M. Stallman's avatar
Richard M. Stallman committed
663 664 665
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'.
David Lawrence's avatar
David Lawrence committed
666

Richard M. Stallman's avatar
Richard M. Stallman committed
667 668 669 670 671 672 673
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'.

Jim Blandy's avatar
Jim Blandy committed
674
The shell file name (sans directories) is used to make a symbol name
Richard M. Stallman's avatar
Richard M. Stallman committed
675
such as `explicit-csh-args'.  If that symbol is a variable,
David Lawrence's avatar
David Lawrence committed
676 677 678 679
its value is used as a list of arguments when invoking the shell.
Otherwise, one argument `-i' is passed to the shell.

\(Type \\[describe-mode] in the shell buffer for a list of commands.)"
Miles Bader's avatar
Miles Bader committed
680 681 682
  (interactive
   (list
    (and current-prefix-arg
683 684
	 (prog1
	     (read-buffer "Shell buffer: "
685 686 687 688 689 690
			  ;; 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*")))
691 692
	   (if (file-remote-p default-directory)
	       ;; It must be possible to declare a local default-directory.
693 694
               ;; FIXME: This can't be right: it changes the default-directory
               ;; of the current-buffer rather than of the *shell* buffer.
695 696
	       (setq default-directory
		     (expand-file-name
697
		      (read-directory-name
698
		       "Default directory: " default-directory default-directory
699
		       t nil))))))))
700 701 702 703 704
  (setq buffer (if (or buffer (not (derived-mode-p 'shell-mode))
                       (comint-check-proc (current-buffer)))
                   (get-buffer-create (or buffer "*shell*"))
                 ;; If the current buffer is a dead shell buffer, use it.
                 (current-buffer)))
705 706

  ;; On remote hosts, the local `shell-file-name' might be useless.
707
  (if (and (called-interactively-p 'any)
708 709 710 711 712 713 714 715 716 717 718 719
	   (file-remote-p default-directory)
	   (null explicit-shell-file-name)
	   (null (getenv "ESHELL")))
      (with-current-buffer buffer
	(set (make-local-variable 'explicit-shell-file-name)
	     (file-remote-p
	      (expand-file-name
	       (read-file-name
		"Remote shell path: " default-directory shell-file-name
		t shell-file-name))
	      'localname))))

720 721
  ;; The buffer's window must be correctly set when we call comint (so
  ;; that comint sets the COLUMNS env var properly).
722
  (pop-to-buffer buffer)
Stefan Monnier's avatar
Stefan Monnier committed
723 724 725 726 727 728
  (unless (comint-check-proc buffer)
    (let* ((prog (or explicit-shell-file-name
		     (getenv "ESHELL") shell-file-name))
	   (name (file-name-nondirectory prog))
	   (startfile (concat "~/.emacs_" name))
	   (xargs-name (intern-soft (concat "explicit-" name "-args"))))
729
      (unless (file-exists-p startfile)
730
	(setq startfile (concat user-emacs-directory "init_" name ".sh")))
Stefan Monnier's avatar
Stefan Monnier committed
731 732 733 734 735 736 737
      (apply 'make-comint-in-buffer "shell" buffer prog
	     (if (file-exists-p startfile) startfile)
	     (if (and xargs-name (boundp xargs-name))
		 (symbol-value xargs-name)
	       '("-i")))
      (shell-mode)))
  buffer)
738

David Lawrence's avatar
David Lawrence committed
739
;;; Directory tracking
740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777
;;
;; This code provides the shell mode input sentinel
;;     SHELL-DIRECTORY-TRACKER
;; that tracks cd, pushd, and popd commands issued to the shell, and
;; changes the current directory of the shell buffer accordingly.
;;
;; This is basically a fragile hack, although it's more accurate than
;; the version in Emacs 18's shell.el. It has the following failings:
;; 1. It doesn't know about the cdpath shell variable.
;; 2. It cannot infallibly deal with command sequences, though it does well
;;    with these and with ignoring commands forked in another shell with ()s.
;; 3. More generally, any complex command is going to throw it. Otherwise,
;;    you'd have to build an entire shell interpreter in Emacs Lisp.  Failing
;;    that, there's no way to catch shell commands where cd's are buried
;;    inside conditional expressions, aliases, and so forth.
;;
;; The whole approach is a crock. Shell aliases mess it up. File sourcing
;; messes it up. You run other processes under the shell; these each have
;; separate working directories, and some have commands for manipulating
;; their w.d.'s (e.g., the lcd command in ftp). Some of these programs have
;; commands that do *not* affect the current w.d. at all, but look like they
;; do (e.g., the cd command in ftp).  In shells that allow you job
;; control, you can switch between jobs, all having different w.d.'s. So
;; simply saying %3 can shift your w.d..
;;
;; The solution is to relax, not stress out about it, and settle for
;; a hack that works pretty well in typical circumstances. Remember
;; that a half-assed solution is more in keeping with the spirit of Unix,
;; anyway. Blech.
;;
;; One good hack not implemented here for users of programmable shells
;; is to program up the shell w.d. manipulation commands to output
;; a coded command sequence to the tty. Something like
;;     ESC | <cwd> |
;; where <cwd> is the new current working directory. Then trash the
;; directory tracking machinery currently used in this package, and
;; replace it with a process filter that watches for and strips out
;; these messages.
David Lawrence's avatar
David Lawrence committed
778 779 780 781 782 783 784

(defun shell-directory-tracker (str)
  "Tracks cd, pushd and popd commands issued to the shell.
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.

785
You may toggle this tracking on and off with \\[shell-dirtrack-mode].
786
If Emacs gets confused, you can resync with the shell with \\[dirs].
787 788
\(The `dirtrack' package provides an alternative implementation of this
feature - see the function `dirtrack-mode'.)
David Lawrence's avatar
David Lawrence committed
789

790
See variables `shell-cd-regexp', `shell-chdrive-regexp', `shell-pushd-regexp',
791
and  `shell-popd-regexp', while `shell-pushd-tohome', `shell-pushd-dextract',
792
and `shell-pushd-dunique' control the behavior of the relevant command.
793

794
Environment variables are expanded, see function `substitute-in-file-name'."
795 796
  (if shell-dirtrackp
      ;; We fail gracefully if we think the command will fail in the shell.
797 798 799 800 801
;;;      (with-demoted-errors "Directory tracker failure: %s"
      ;; This fails so often that it seems better to just ignore errors (?).
      ;; Eg even: foo=/tmp; cd $foo is beyond us (bug#17159).
      (ignore-errors
        (let ((start (progn (string-match
802 803
			       (concat "^" shell-command-separator-regexp)
			       str) ; skip whitespace
804
			      (match-end 0)))
805
		(case-fold-search)
806 807 808 809 810
		end cmd arg1)
	    (while (string-match shell-command-regexp str start)
	      (setq end (match-end 0)
		    cmd (comint-arguments (substring str start end) 0 0)
		    arg1 (comint-arguments (substring str start end) 1 1))
811 812
	      (if arg1
		  (setq arg1 (shell-unquote-argument arg1)))
813 814 815
	      (cond ((string-match (concat "\\`\\(" shell-popd-regexp
					   "\\)\\($\\|[ \t]\\)")
				   cmd)
816
		     (shell-process-popd (comint-substitute-in-file-name arg1)))
817 818 819
		    ((string-match (concat "\\`\\(" shell-pushd-regexp
					   "\\)\\($\\|[ \t]\\)")
				   cmd)
820
		     (shell-process-pushd (comint-substitute-in-file-name arg1)))
821 822 823
		    ((string-match (concat "\\`\\(" shell-cd-regexp
					   "\\)\\($\\|[ \t]\\)")
				   cmd)
824 825 826 827 828 829
		     (shell-process-cd (comint-substitute-in-file-name arg1)))
		    ((and shell-chdrive-regexp
			  (string-match (concat "\\`\\(" shell-chdrive-regexp
						"\\)\\($\\|[ \t]\\)")
					cmd))
		     (shell-process-cd (comint-substitute-in-file-name cmd))))
830 831 832
	      (setq start (progn (string-match shell-command-separator-regexp
					       str end)
				 ;; skip again
833
				 (match-end 0))))))))
834

835 836 837
(defun shell-unquote-argument (string)
  "Remove all kinds of shell quoting from STRING."
  (save-match-data
838 839 840 841 842 843 844
    (let ((idx 0) next inside
	  (quote-chars
	   (if (string-match shell-dumb-shell-regexp
			     (file-name-nondirectory
			      (car (process-command (get-buffer-process (current-buffer))))))
	       "['`\"]"
	     "[\\'`\"]")))
845
      (while (and (< idx (length string))
846
		  (setq next (string-match quote-chars string next)))
847 848 849 850 851 852 853 854 855 856 857 858 859
	(cond ((= (aref string next) ?\\)
	       (setq string (replace-match "" nil nil string))
	       (setq next (1+ next)))
	      ((and inside (= (aref string next) inside))
	       (setq string (replace-match "" nil nil string))
	       (setq inside nil))
	      (inside
	       (setq next (1+ next)))
	      (t
	       (setq inside (aref string next))
	       (setq string (replace-match "" nil nil string)))))
      string)))

860
;; popd [+n]
David Lawrence's avatar
David Lawrence committed
861
(defun shell-process-popd (arg)
862 863
  (let ((num (or (shell-extract-num arg) 0)))
    (cond ((and num (= num 0) shell-dirstack)
864
	   (shell-cd (shell-prefixed-directory-name (car shell-dirstack)))
865 866 867 868 869 870 871 872 873
	   (setq shell-dirstack (cdr shell-dirstack))
	   (shell-dirstack-message))
	  ((and num (> num 0) (<= num (length shell-dirstack)))
	   (let* ((ds (cons nil shell-dirstack))
		  (cell (nthcdr (1- num) ds)))
	     (rplacd cell (cdr (cdr cell)))
	     (setq shell-dirstack (cdr ds))
	     (shell-dirstack-message)))
	  (t
874
	   (error "Couldn't popd")))))
David Lawrence's avatar
David Lawrence committed
875

Roland McGrath's avatar
Roland McGrath committed
876
;; Return DIR prefixed with comint-file-name-prefix as appropriate.
877 878 879 880 881 882
(defun shell-prefixed-directory-name (dir)
  (if (= (length comint-file-name-prefix) 0)
      dir
    (if (file-name-absolute-p dir)
	;; The name is absolute, so prepend the prefix.
	(concat comint-file-name-prefix dir)
883
      ;; For relative name we assume default-directory already has the prefix.
884
      (expand-file-name dir))))
Roland McGrath's avatar
Roland McGrath committed
885

886
;; cd [dir]
David Lawrence's avatar
David Lawrence committed
887
(defun shell-process-cd (arg)
Roland McGrath's avatar
Roland McGrath committed
888 889
  (let ((new-dir (cond ((zerop (length arg)) (concat comint-file-name-prefix
						     "~"))