declare smobs in alloc.c
[bpt/emacs.git] / lisp / shell.el
1 ;;; shell.el --- specialized comint.el for running the shell -*- lexical-binding: t -*-
2
3 ;; Copyright (C) 1988, 1993-1997, 2000-2014 Free Software Foundation, Inc.
4
5 ;; Author: Olin Shivers <shivers@cs.cmu.edu>
6 ;; Simon Marshall <simon@gnu.org>
7 ;; Maintainer: emacs-devel@gnu.org
8 ;; Keywords: processes
9
10 ;; This file is part of GNU Emacs.
11
12 ;; GNU Emacs is free software: you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation, either version 3 of the License, or
15 ;; (at your option) any later version.
16
17 ;; GNU Emacs is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
24
25 ;;; Commentary:
26
27 ;; This file defines a shell-in-a-buffer package (shell mode) built on
28 ;; top of comint mode. This is actually cmushell with things renamed
29 ;; to replace its counterpart in Emacs 18. cmushell is more
30 ;; featureful, robust, and uniform than the Emacs 18 version.
31
32 ;; Since this mode is built on top of the general command-interpreter-in-
33 ;; a-buffer mode (comint mode), it shares a common base functionality,
34 ;; and a common set of bindings, with all modes derived from comint mode.
35 ;; This makes these modes easier to use.
36
37 ;; For documentation on the functionality provided by comint mode, and
38 ;; the hooks available for customizing it, see the file comint.el.
39 ;; For further information on shell mode, see the comments below.
40
41 ;; Needs fixin:
42 ;; When sending text from a source file to a subprocess, the process-mark can
43 ;; move off the window, so you can lose sight of the process interactions.
44 ;; Maybe I should ensure the process mark is in the window when I send
45 ;; text to the process? Switch selectable?
46
47 ;; YOUR .EMACS FILE
48 ;;=============================================================================
49 ;; Some suggestions for your init file.
50 ;;
51 ;; ;; Define M-# to run some strange command:
52 ;; (eval-after-load "shell"
53 ;; '(define-key shell-mode-map "\M-#" 'shells-dynamic-spell))
54
55 ;; Brief Command Documentation:
56 ;;============================================================================
57 ;; Comint Mode Commands: (common to shell and all comint-derived modes)
58 ;;
59 ;; m-p comint-previous-input Cycle backwards in input history
60 ;; m-n comint-next-input Cycle forwards
61 ;; m-r comint-previous-matching-input Previous input matching a regexp
62 ;; m-s comint-next-matching-input Next input that matches
63 ;; m-c-l comint-show-output Show last batch of process output
64 ;; return comint-send-input
65 ;; c-d comint-delchar-or-maybe-eof Delete char unless at end of buff.
66 ;; c-c c-a comint-bol Beginning of line; skip prompt
67 ;; c-c c-u comint-kill-input ^u
68 ;; c-c c-w backward-kill-word ^w
69 ;; c-c c-c comint-interrupt-subjob ^c
70 ;; c-c c-z comint-stop-subjob ^z
71 ;; c-c c-\ comint-quit-subjob ^\
72 ;; c-c c-o comint-delete-output Delete last batch of process output
73 ;; c-c c-r comint-show-output Show last batch of process output
74 ;; c-c c-l comint-dynamic-list-input-ring List input history
75 ;; send-invisible Read line w/o echo & send to proc
76 ;; comint-continue-subjob Useful if you accidentally suspend
77 ;; top-level job
78 ;; comint-mode-hook is the comint mode hook.
79
80 ;; Shell Mode Commands:
81 ;; shell Fires up the shell process
82 ;; tab completion-at-point Complete filename/command/history
83 ;; m-? comint-dynamic-list-filename-completions
84 ;; List completions in help buffer
85 ;; m-c-f shell-forward-command Forward a shell command
86 ;; m-c-b shell-backward-command Backward a shell command
87 ;; dirs Resync the buffer's dir stack
88 ;; shell-dirtrack-mode Turn dir tracking on/off
89 ;; comint-strip-ctrl-m Remove trailing ^Ms from output
90 ;;
91 ;; The shell mode hook is shell-mode-hook
92 ;; comint-prompt-regexp is initialized to shell-prompt-pattern, for backwards
93 ;; compatibility.
94
95 ;; Read the rest of this file for more information.
96
97 ;;; Code:
98
99 (require 'comint)
100 (require 'pcomplete)
101
102 ;;; Customization and Buffer Variables
103
104 (defgroup shell nil
105 "Running shell from within Emacs buffers."
106 :group 'processes
107 :group 'unix)
108
109 (defgroup shell-directories nil
110 "Directory support in shell mode."
111 :group 'shell)
112
113 ;; Unused.
114 ;;; (defgroup shell-faces nil
115 ;;; "Faces in shell buffers."
116 ;;; :group 'shell)
117
118 ;;;###autoload
119 (defcustom shell-dumb-shell-regexp (purecopy "cmd\\(proxy\\)?\\.exe")
120 "Regexp to match shells that don't save their command history, and
121 don't handle the backslash as a quote character. For shells that
122 match this regexp, Emacs will write out the command history when the
123 shell finishes, and won't remove backslashes when it unquotes shell
124 arguments."
125 :type 'regexp
126 :group 'shell)
127
128 (defcustom shell-prompt-pattern "^[^#$%>\n]*[#$%>] *"
129 "Regexp to match prompts in the inferior shell.
130 Defaults to \"^[^#$%>\\n]*[#$%>] *\", which works pretty well.
131 This variable is used to initialize `comint-prompt-regexp' in the
132 shell buffer.
133
134 If `comint-use-prompt-regexp' is nil, then this variable is only used
135 to determine paragraph boundaries. See Info node `Shell Prompts' for
136 how Shell mode treats paragraphs.
137
138 The pattern should probably not match more than one line. If it does,
139 Shell mode may become confused trying to distinguish prompt from input
140 on lines which don't start with a prompt."
141 :type 'regexp
142 :group 'shell)
143
144 (defcustom shell-completion-fignore nil
145 "List of suffixes to be disregarded during file/command completion.
146 This variable is used to initialize `comint-completion-fignore' in the shell
147 buffer. The default is nil, for compatibility with most shells.
148 Some people like (\"~\" \"#\" \"%\")."
149 :type '(repeat (string :tag "Suffix"))
150 :group 'shell)
151
152 (defcustom shell-delimiter-argument-list '(?\| ?& ?< ?> ?\( ?\) ?\;)
153 "List of characters to recognize as separate arguments.
154 This variable is used to initialize `comint-delimiter-argument-list' in the
155 shell buffer. The value may depend on the operating system or shell."
156 :type '(choice (const nil)
157 (repeat :tag "List of characters" character))
158 :group 'shell)
159
160 (defcustom shell-file-name-chars
161 (if (memq system-type '(ms-dos windows-nt cygwin))
162 "~/A-Za-z0-9_^$!#%&{}@`'.,:()-"
163 "[]~/A-Za-z0-9+@:_.$#%,={}-")
164 "String of characters valid in a file name.
165 This variable is used to initialize `comint-file-name-chars' in the
166 shell buffer. The value may depend on the operating system or shell."
167 :type 'string
168 :group 'shell)
169
170 (defcustom shell-file-name-quote-list
171 (if (memq system-type '(ms-dos windows-nt))
172 nil
173 (append shell-delimiter-argument-list '(?\s ?$ ?\* ?\! ?\" ?\' ?\` ?\# ?\\)))
174 "List of characters to quote when in a file name.
175 This variable is used to initialize `comint-file-name-quote-list' in the
176 shell buffer. The value may depend on the operating system or shell."
177 :type '(repeat character)
178 :group 'shell)
179
180 (defcustom shell-dynamic-complete-functions
181 '(comint-c-a-p-replace-by-expanded-history
182 shell-environment-variable-completion
183 shell-command-completion
184 shell-c-a-p-replace-by-expanded-directory
185 pcomplete-completions-at-point
186 shell-filename-completion
187 comint-filename-completion)
188 "List of functions called to perform completion.
189 This variable is used to initialize `comint-dynamic-complete-functions' in the
190 shell buffer."
191 :type '(repeat function)
192 :group 'shell)
193
194 (defcustom shell-command-regexp "[^;&|\n]+"
195 "Regexp to match a single command within a pipeline.
196 This is used for directory tracking and does not do a perfect job."
197 :type 'regexp
198 :group 'shell)
199
200 (defcustom shell-command-separator-regexp "[;&|\n \t]*"
201 "Regexp to match a single command within a pipeline.
202 This is used for directory tracking and does not do a perfect job."
203 :type 'regexp
204 :group 'shell)
205
206 (defcustom shell-completion-execonly t
207 "If non-nil, use executable files only for completion candidates.
208 This mirrors the optional behavior of tcsh.
209
210 Detecting executability of files may slow command completion considerably."
211 :type 'boolean
212 :group 'shell)
213
214 (defcustom shell-popd-regexp "popd"
215 "Regexp to match subshell commands equivalent to popd."
216 :type 'regexp
217 :group 'shell-directories)
218
219 (defcustom shell-pushd-regexp "pushd"
220 "Regexp to match subshell commands equivalent to pushd."
221 :type 'regexp
222 :group 'shell-directories)
223
224 (defcustom shell-pushd-tohome nil
225 "If non-nil, make pushd with no arg behave as \"pushd ~\" (like cd).
226 This mirrors the optional behavior of tcsh."
227 :type 'boolean
228 :group 'shell-directories)
229
230 (defcustom shell-pushd-dextract nil
231 "If non-nil, make \"pushd +n\" pop the nth dir to the stack top.
232 This mirrors the optional behavior of tcsh."
233 :type 'boolean
234 :group 'shell-directories)
235
236 (defcustom shell-pushd-dunique nil
237 "If non-nil, make pushd only add unique directories to the stack.
238 This mirrors the optional behavior of tcsh."
239 :type 'boolean
240 :group 'shell-directories)
241
242 (defcustom shell-cd-regexp "cd"
243 "Regexp to match subshell commands equivalent to cd."
244 :type 'regexp
245 :group 'shell-directories)
246
247 (defcustom shell-chdrive-regexp
248 (if (memq system-type '(ms-dos windows-nt))
249 ; NetWare allows the five chars between upper and lower alphabetics.
250 "[]a-zA-Z^_`\\[\\\\]:"
251 nil)
252 "If non-nil, is regexp used to track drive changes."
253 :type '(choice regexp
254 (const nil))
255 :group 'shell-directories)
256
257 (defcustom shell-dirtrack-verbose t
258 "If non-nil, show the directory stack following directory change.
259 This is effective only if directory tracking is enabled.
260 The `dirtrack' package provides an alternative implementation of this feature -
261 see the function `dirtrack-mode'."
262 :type 'boolean
263 :group 'shell-directories)
264
265 (defcustom explicit-shell-file-name nil
266 "If non-nil, is file name to use for explicitly requested inferior shell."
267 :type '(choice (const :tag "None" nil) file)
268 :group 'shell)
269
270 ;; Note: There are no explicit references to the variable `explicit-csh-args'.
271 ;; It is used implicitly by M-x shell when the shell is `csh'.
272 (defcustom explicit-csh-args
273 (if (eq system-type 'hpux)
274 ;; -T persuades HP's csh not to think it is smarter
275 ;; than us about what terminal modes to use.
276 '("-i" "-T")
277 '("-i"))
278 "Args passed to inferior shell by \\[shell], if the shell is csh.
279 Value is a list of strings, which may be nil."
280 :type '(repeat (string :tag "Argument"))
281 :group 'shell)
282
283 ;; Note: There are no explicit references to the variable `explicit-bash-args'.
284 ;; It is used implicitly by M-x shell when the interactive shell is `bash'.
285 (defcustom explicit-bash-args
286 ;; Tell bash not to use readline. It's safe to assume --noediting now,
287 ;; as it was introduced in 1996 in Bash version 2.
288 '("--noediting" "-i")
289 "Args passed to inferior shell by \\[shell], if the shell is bash.
290 Value is a list of strings, which may be nil."
291 :type '(repeat (string :tag "Argument"))
292 :group 'shell)
293
294 (defcustom shell-input-autoexpand 'history
295 "If non-nil, expand input command history references on completion.
296 This mirrors the optional behavior of tcsh (its autoexpand and histlit).
297
298 If the value is `input', then the expansion is seen on input.
299 If the value is `history', then the expansion is only when inserting
300 into the buffer's input ring. See also `comint-magic-space' and
301 `comint-dynamic-complete-functions'.
302
303 This variable supplies a default for `comint-input-autoexpand',
304 for Shell mode only."
305 :type '(choice (const :tag "off" nil)
306 (const input)
307 (const history)
308 (const :tag "on" t))
309 :group 'shell)
310
311 (defvar shell-dirstack nil
312 "List of directories saved by pushd in this buffer's shell.
313 Thus, this does not include the shell's current directory.")
314
315 (defvar shell-dirtrackp t
316 "Non-nil in a shell buffer means directory tracking is enabled.")
317
318 (defvar shell-last-dir nil
319 "Keep track of last directory for ksh `cd -' command.")
320
321 (defvar shell-dirstack-query nil
322 "Command used by `shell-resync-dirs' to query the shell.")
323
324 (defvar shell-mode-map
325 (let ((map (nconc (make-sparse-keymap) comint-mode-map)))
326 (define-key map "\C-c\C-f" 'shell-forward-command)
327 (define-key map "\C-c\C-b" 'shell-backward-command)
328 (define-key map "\t" 'completion-at-point)
329 (define-key map (kbd "M-RET") 'shell-resync-dirs)
330 (define-key map "\M-?" 'comint-dynamic-list-filename-completions)
331 (define-key map [menu-bar completion]
332 (cons "Complete"
333 (copy-keymap (lookup-key comint-mode-map [menu-bar completion]))))
334 (define-key-after (lookup-key map [menu-bar completion])
335 [complete-env-variable] '("Complete Env. Variable Name" .
336 shell-dynamic-complete-environment-variable)
337 'complete-file)
338 (define-key-after (lookup-key map [menu-bar completion])
339 [expand-directory] '("Expand Directory Reference" .
340 shell-replace-by-expanded-directory)
341 'complete-expand)
342 map))
343
344 (defcustom shell-mode-hook '()
345 "Hook for customizing Shell mode."
346 :type 'hook
347 :group 'shell)
348
349 (defvar shell-font-lock-keywords
350 '(("[ \t]\\([+-][^ \t\n]+\\)" 1 font-lock-comment-face)
351 ("^[^ \t\n]+:.*" . font-lock-string-face)
352 ("^\\[[1-9][0-9]*\\]" . font-lock-string-face))
353 "Additional expressions to highlight in Shell mode.")
354
355 ;;; Basic Procedures
356
357 (defun shell--unquote&requote-argument (qstr &optional upos)
358 (unless upos (setq upos 0))
359 (let* ((qpos 0)
360 (dquotes nil)
361 (ustrs '())
362 (re (concat
363 "[\"']"
364 "\\|\\$\\(?:\\([[:alpha:]][[:alnum:]]*\\)"
365 "\\|{\\(?1:[^{}]+\\)}\\)"
366 (when (memq system-type '(ms-dos windows-nt))
367 "\\|%\\(?1:[^\\\\/]*\\)%")
368 (when comint-file-name-quote-list
369 "\\|\\\\\\(.\\)")))
370 (qupos nil)
371 (push (lambda (str end)
372 (push str ustrs)
373 (setq upos (- upos (length str)))
374 (unless (or qupos (> upos 0))
375 (setq qupos (if (< end 0) (- end) (+ upos end))))))
376 match)
377 (while (setq match (string-match re qstr qpos))
378 (funcall push (substring qstr qpos match) match)
379 (cond
380 ((match-beginning 2) (funcall push (match-string 2 qstr) (match-end 0)))
381 ((match-beginning 1) (funcall push (getenv (match-string 1 qstr))
382 (- (match-end 0))))
383 ((eq (aref qstr match) ?\") (setq dquotes (not dquotes)))
384 ((eq (aref qstr match) ?\')
385 (cond
386 (dquotes (funcall push "'" (match-end 0)))
387 ((< match (1+ (length qstr)))
388 (let ((end (string-match "'" qstr (1+ match))))
389 (funcall push (substring qstr (1+ match) end)
390 (or end (length qstr)))))
391 (t nil)))
392 (t (error "Unexpected case in shell--unquote&requote-argument!")))
393 (setq qpos (match-end 0)))
394 (funcall push (substring qstr qpos) (length qstr))
395 (list (mapconcat #'identity (nreverse ustrs) "")
396 qupos #'comint-quote-filename)))
397
398 (defun shell--unquote-argument (str)
399 (car (shell--unquote&requote-argument str)))
400 (defun shell--requote-argument (upos qstr)
401 ;; See `completion-table-with-quoting'.
402 (let ((res (shell--unquote&requote-argument qstr upos)))
403 (cons (nth 1 res) (nth 2 res))))
404
405 (defun shell--parse-pcomplete-arguments ()
406 "Parse whitespace separated arguments in the current region."
407 ;; FIXME: share code with shell--unquote&requote-argument.
408 (let ((begin (save-excursion (shell-backward-command 1) (point)))
409 (end (point))
410 begins args)
411 (save-excursion
412 (goto-char begin)
413 (while (< (point) end)
414 (skip-chars-forward " \t\n")
415 (push (point) begins)
416 (let ((arg ()))
417 (while (looking-at
418 (eval-when-compile
419 (concat
420 "\\(?:[^\s\t\n\\\"']+"
421 "\\|'\\([^']*\\)'?"
422 "\\|\"\\(\\(?:[^\"\\]\\|\\\\.\\)*\\)\"?"
423 "\\|\\\\\\(\\(?:.\\|\n\\)?\\)\\)")))
424 (goto-char (match-end 0))
425 (cond
426 ((match-beginning 3) ;Backslash escape.
427 (push (cond
428 ((null comint-file-name-quote-list)
429 (goto-char (match-beginning 3)) "\\")
430 ((= (match-beginning 3) (match-end 3)) "\\")
431 (t (match-string 3)))
432 arg))
433 ((match-beginning 2) ;Double quote.
434 (push (if (null comint-file-name-quote-list) (match-string 2)
435 (replace-regexp-in-string
436 "\\\\\\(.\\)" "\\1" (match-string 2)))
437 arg))
438 ((match-beginning 1) ;Single quote.
439 (push (match-string 1) arg))
440 (t (push (match-string 0) arg))))
441 (push (mapconcat #'identity (nreverse arg) "") args)))
442 (cons (nreverse args) (nreverse begins)))))
443
444 (defun shell-command-completion-function ()
445 "Completion function for shell command names.
446 This is the value of `pcomplete-command-completion-function' for
447 Shell buffers. It implements `shell-completion-execonly' for
448 `pcomplete' completion."
449 (pcomplete-here (pcomplete-entries nil
450 (if shell-completion-execonly
451 'file-executable-p))))
452
453 (defun shell-completion-vars ()
454 "Setup completion vars for `shell-mode' and `read-shell-command'."
455 (set (make-local-variable 'comint-completion-fignore)
456 shell-completion-fignore)
457 (set (make-local-variable 'comint-delimiter-argument-list)
458 shell-delimiter-argument-list)
459 (set (make-local-variable 'comint-file-name-chars) shell-file-name-chars)
460 (set (make-local-variable 'comint-file-name-quote-list)
461 shell-file-name-quote-list)
462 (set (make-local-variable 'comint-dynamic-complete-functions)
463 shell-dynamic-complete-functions)
464 (setq-local comint-unquote-function #'shell--unquote-argument)
465 (setq-local comint-requote-function #'shell--requote-argument)
466 (set (make-local-variable 'pcomplete-parse-arguments-function)
467 #'shell--parse-pcomplete-arguments)
468 (set (make-local-variable 'pcomplete-termination-string)
469 (cond ((not comint-completion-addsuffix) "")
470 ((stringp comint-completion-addsuffix)
471 comint-completion-addsuffix)
472 ((not (consp comint-completion-addsuffix)) " ")
473 (t (cdr comint-completion-addsuffix))))
474 (set (make-local-variable 'pcomplete-command-completion-function)
475 #'shell-command-completion-function)
476 ;; Don't use pcomplete's defaulting mechanism, rely on
477 ;; shell-dynamic-complete-functions instead.
478 (set (make-local-variable 'pcomplete-default-completion-function) #'ignore)
479 (setq comint-input-autoexpand shell-input-autoexpand)
480 ;; Not needed in shell-mode because it's inherited from comint-mode, but
481 ;; placed here for read-shell-command.
482 (add-hook 'completion-at-point-functions 'comint-completion-at-point nil t))
483
484 (put 'shell-mode 'mode-class 'special)
485
486 (define-derived-mode shell-mode comint-mode "Shell"
487 "Major mode for interacting with an inferior shell.\\<shell-mode-map>
488 \\[comint-send-input] after the end of the process' output sends the text from
489 the end of process to the end of the current line.
490 \\[comint-send-input] before end of process output copies the current line minus the prompt to
491 the end of the buffer and sends it (\\[comint-copy-old-input] just copies the current line).
492 \\[send-invisible] reads a line of text without echoing it, and sends it to
493 the shell. This is useful for entering passwords. Or, add the function
494 `comint-watch-for-password-prompt' to `comint-output-filter-functions'.
495
496 If you want to make multiple shell buffers, rename the `*shell*' buffer
497 using \\[rename-buffer] or \\[rename-uniquely] and start a new shell.
498
499 If you want to make shell buffers limited in length, add the function
500 `comint-truncate-buffer' to `comint-output-filter-functions'.
501
502 If you accidentally suspend your process, use \\[comint-continue-subjob]
503 to continue it.
504
505 `cd', `pushd' and `popd' commands given to the shell are watched by Emacs to
506 keep this buffer's default directory the same as the shell's working directory.
507 While directory tracking is enabled, the shell's working directory is displayed
508 by \\[list-buffers] or \\[mouse-buffer-menu] in the `File' field.
509 \\[dirs] queries the shell and resyncs Emacs's idea of what the current
510 directory stack is.
511 \\[shell-dirtrack-mode] turns directory tracking on and off.
512 \(The `dirtrack' package provides an alternative implementation of this
513 feature - see the function `dirtrack-mode'.)
514
515 \\{shell-mode-map}
516 Customization: Entry to this mode runs the hooks on `comint-mode-hook' and
517 `shell-mode-hook' (in that order). Before each input, the hooks on
518 `comint-input-filter-functions' are run. After each shell output, the hooks
519 on `comint-output-filter-functions' are run.
520
521 Variables `shell-cd-regexp', `shell-chdrive-regexp', `shell-pushd-regexp'
522 and `shell-popd-regexp' are used to match their respective commands,
523 while `shell-pushd-tohome', `shell-pushd-dextract' and `shell-pushd-dunique'
524 control the behavior of the relevant command.
525
526 Variables `comint-completion-autolist', `comint-completion-addsuffix',
527 `comint-completion-recexact' and `comint-completion-fignore' control the
528 behavior of file name, command name and variable name completion. Variable
529 `shell-completion-execonly' controls the behavior of command name completion.
530 Variable `shell-completion-fignore' is used to initialize the value of
531 `comint-completion-fignore'.
532
533 Variables `comint-input-ring-file-name' and `comint-input-autoexpand' control
534 the initialization of the input ring history, and history expansion.
535
536 Variables `comint-output-filter-functions', a hook, and
537 `comint-scroll-to-bottom-on-input' and `comint-scroll-to-bottom-on-output'
538 control whether input and output cause the window to scroll to the end of the
539 buffer."
540 (setq comint-prompt-regexp shell-prompt-pattern)
541 (shell-completion-vars)
542 (set (make-local-variable 'paragraph-separate) "\\'")
543 (set (make-local-variable 'paragraph-start) comint-prompt-regexp)
544 (set (make-local-variable 'font-lock-defaults) '(shell-font-lock-keywords t))
545 (set (make-local-variable 'shell-dirstack) nil)
546 (set (make-local-variable 'shell-last-dir) nil)
547 (shell-dirtrack-mode 1)
548
549 ;; By default, ansi-color applies faces using overlays. This is
550 ;; very inefficient in Shell buffers (e.g. Bug#10835). We use a
551 ;; custom `ansi-color-apply-face-function' to convert color escape
552 ;; sequences into `font-lock-face' properties.
553 (setq-local ansi-color-apply-face-function #'shell-apply-ansi-color)
554 (shell-reapply-ansi-color)
555
556 ;; This is not really correct, since the shell buffer does not really
557 ;; edit this directory. But it is useful in the buffer list and menus.
558 (setq list-buffers-directory (expand-file-name default-directory))
559 ;; shell-dependent assignments.
560 (when (ring-empty-p comint-input-ring)
561 (let ((shell (file-name-nondirectory (car
562 (process-command (get-buffer-process (current-buffer))))))
563 (hsize (getenv "HISTSIZE")))
564 (and (stringp hsize)
565 (integerp (setq hsize (string-to-number hsize)))
566 (> hsize 0)
567 (set (make-local-variable 'comint-input-ring-size) hsize))
568 (setq comint-input-ring-file-name
569 (or (getenv "HISTFILE")
570 (cond ((string-equal shell "bash") "~/.bash_history")
571 ((string-equal shell "ksh") "~/.sh_history")
572 (t "~/.history"))))
573 (if (or (equal comint-input-ring-file-name "")
574 (equal (file-truename comint-input-ring-file-name)
575 (file-truename "/dev/null")))
576 (setq comint-input-ring-file-name nil))
577 ;; Arrange to write out the input ring on exit, if the shell doesn't
578 ;; do this itself.
579 (if (and comint-input-ring-file-name
580 (string-match shell-dumb-shell-regexp shell))
581 (set-process-sentinel (get-buffer-process (current-buffer))
582 #'shell-write-history-on-exit))
583 (setq shell-dirstack-query
584 (cond ((string-equal shell "sh") "pwd")
585 ((string-equal shell "ksh") "echo $PWD ~-")
586 ;; Bypass any aliases. TODO all shells could use this.
587 ((string-equal shell "bash") "command dirs")
588 (t "dirs")))
589 ;; Bypass a bug in certain versions of bash.
590 (when (string-equal shell "bash")
591 (add-hook 'comint-preoutput-filter-functions
592 'shell-filter-ctrl-a-ctrl-b nil t)))
593 (comint-read-input-ring t)))
594
595 (defun shell-apply-ansi-color (beg end face)
596 "Apply FACE as the ansi-color face for the text between BEG and END."
597 (when face
598 (put-text-property beg end 'ansi-color-face face)
599 (put-text-property beg end 'font-lock-face face)))
600
601 (defun shell-reapply-ansi-color ()
602 "Reapply ansi-color faces to the existing contents of the buffer."
603 (save-restriction
604 (widen)
605 (let* ((pos (point-min))
606 (end (or (next-single-property-change pos 'ansi-color-face)
607 (point-max)))
608 face)
609 (while end
610 (if (setq face (get-text-property pos 'ansi-color-face))
611 (put-text-property pos (or end (point-max))
612 'font-lock-face face))
613 (setq pos end
614 end (next-single-property-change pos 'ansi-color-face))))))
615
616 (defun shell-filter-ctrl-a-ctrl-b (string)
617 "Remove `^A' and `^B' characters from comint output.
618
619 Bash uses these characters as internal quoting characters in its
620 prompt. Due to a bug in some bash versions (including 2.03,
621 2.04, and 2.05b), they may erroneously show up when bash is
622 started with the `--noediting' option and Select Graphic
623 Rendition (SGR) control sequences (formerly known as ANSI escape
624 sequences) are used to color the prompt.
625
626 This function can be put on `comint-preoutput-filter-functions'."
627 (if (string-match "[\C-a\C-b]" string)
628 (replace-regexp-in-string "[\C-a\C-b]" "" string t t)
629 string))
630
631 (defun shell-write-history-on-exit (process event)
632 "Called when the shell process is stopped.
633
634 Writes the input history to a history file
635 `comint-input-ring-file-name' using `comint-write-input-ring'
636 and inserts a short message in the shell buffer.
637
638 This function is a sentinel watching the shell interpreter process.
639 Sentinels will always get the two parameters PROCESS and EVENT."
640 ;; Write history.
641 (comint-write-input-ring)
642 (let ((buf (process-buffer process)))
643 (when (buffer-live-p buf)
644 (with-current-buffer buf
645 (insert (format "\nProcess %s %s\n" process event))))))
646
647 ;;;###autoload
648 (defun shell (&optional buffer)
649 "Run an inferior shell, with I/O through BUFFER (which defaults to `*shell*').
650 Interactively, a prefix arg means to prompt for BUFFER.
651 If `default-directory' is a remote file name, it is also prompted
652 to change if called with a prefix arg.
653
654 If BUFFER exists but shell process is not running, make new shell.
655 If BUFFER exists and shell process is running, just switch to BUFFER.
656 Program used comes from variable `explicit-shell-file-name',
657 or (if that is nil) from the ESHELL environment variable,
658 or (if that is nil) from `shell-file-name'.
659 If a file `~/.emacs_SHELLNAME' exists, or `~/.emacs.d/init_SHELLNAME.sh',
660 it is given as initial input (but this may be lost, due to a timing
661 error, if the shell discards input when it starts up).
662 The buffer is put in Shell mode, giving commands for sending input
663 and controlling the subjobs of the shell. See `shell-mode'.
664 See also the variable `shell-prompt-pattern'.
665
666 To specify a coding system for converting non-ASCII characters
667 in the input and output to the shell, use \\[universal-coding-system-argument]
668 before \\[shell]. You can also specify this with \\[set-buffer-process-coding-system]
669 in the shell buffer, after you start the shell.
670 The default comes from `process-coding-system-alist' and
671 `default-process-coding-system'.
672
673 The shell file name (sans directories) is used to make a symbol name
674 such as `explicit-csh-args'. If that symbol is a variable,
675 its value is used as a list of arguments when invoking the shell.
676 Otherwise, one argument `-i' is passed to the shell.
677
678 \(Type \\[describe-mode] in the shell buffer for a list of commands.)"
679 (interactive
680 (list
681 (and current-prefix-arg
682 (prog1
683 (read-buffer "Shell buffer: "
684 ;; If the current buffer is an inactive
685 ;; shell buffer, use it as the default.
686 (if (and (eq major-mode 'shell-mode)
687 (null (get-buffer-process (current-buffer))))
688 (buffer-name)
689 (generate-new-buffer-name "*shell*")))
690 (if (file-remote-p default-directory)
691 ;; It must be possible to declare a local default-directory.
692 ;; FIXME: This can't be right: it changes the default-directory
693 ;; of the current-buffer rather than of the *shell* buffer.
694 (setq default-directory
695 (expand-file-name
696 (read-directory-name
697 "Default directory: " default-directory default-directory
698 t nil))))))))
699 (setq buffer (if (or buffer (not (derived-mode-p 'shell-mode))
700 (comint-check-proc (current-buffer)))
701 (get-buffer-create (or buffer "*shell*"))
702 ;; If the current buffer is a dead shell buffer, use it.
703 (current-buffer)))
704
705 ;; On remote hosts, the local `shell-file-name' might be useless.
706 (if (and (called-interactively-p 'any)
707 (file-remote-p default-directory)
708 (null explicit-shell-file-name)
709 (null (getenv "ESHELL")))
710 (with-current-buffer buffer
711 (set (make-local-variable 'explicit-shell-file-name)
712 (file-remote-p
713 (expand-file-name
714 (read-file-name
715 "Remote shell path: " default-directory shell-file-name
716 t shell-file-name))
717 'localname))))
718
719 ;; The buffer's window must be correctly set when we call comint (so
720 ;; that comint sets the COLUMNS env var properly).
721 (pop-to-buffer-same-window buffer)
722 (unless (comint-check-proc buffer)
723 (let* ((prog (or explicit-shell-file-name
724 (getenv "ESHELL") shell-file-name))
725 (name (file-name-nondirectory prog))
726 (startfile (concat "~/.emacs_" name))
727 (xargs-name (intern-soft (concat "explicit-" name "-args"))))
728 (unless (file-exists-p startfile)
729 (setq startfile (concat user-emacs-directory "init_" name ".sh")))
730 (apply 'make-comint-in-buffer "shell" buffer prog
731 (if (file-exists-p startfile) startfile)
732 (if (and xargs-name (boundp xargs-name))
733 (symbol-value xargs-name)
734 '("-i")))
735 (shell-mode)))
736 buffer)
737
738 ;;; Directory tracking
739 ;;
740 ;; This code provides the shell mode input sentinel
741 ;; SHELL-DIRECTORY-TRACKER
742 ;; that tracks cd, pushd, and popd commands issued to the shell, and
743 ;; changes the current directory of the shell buffer accordingly.
744 ;;
745 ;; This is basically a fragile hack, although it's more accurate than
746 ;; the version in Emacs 18's shell.el. It has the following failings:
747 ;; 1. It doesn't know about the cdpath shell variable.
748 ;; 2. It cannot infallibly deal with command sequences, though it does well
749 ;; with these and with ignoring commands forked in another shell with ()s.
750 ;; 3. More generally, any complex command is going to throw it. Otherwise,
751 ;; you'd have to build an entire shell interpreter in Emacs Lisp. Failing
752 ;; that, there's no way to catch shell commands where cd's are buried
753 ;; inside conditional expressions, aliases, and so forth.
754 ;;
755 ;; The whole approach is a crock. Shell aliases mess it up. File sourcing
756 ;; messes it up. You run other processes under the shell; these each have
757 ;; separate working directories, and some have commands for manipulating
758 ;; their w.d.'s (e.g., the lcd command in ftp). Some of these programs have
759 ;; commands that do *not* affect the current w.d. at all, but look like they
760 ;; do (e.g., the cd command in ftp). In shells that allow you job
761 ;; control, you can switch between jobs, all having different w.d.'s. So
762 ;; simply saying %3 can shift your w.d..
763 ;;
764 ;; The solution is to relax, not stress out about it, and settle for
765 ;; a hack that works pretty well in typical circumstances. Remember
766 ;; that a half-assed solution is more in keeping with the spirit of Unix,
767 ;; anyway. Blech.
768 ;;
769 ;; One good hack not implemented here for users of programmable shells
770 ;; is to program up the shell w.d. manipulation commands to output
771 ;; a coded command sequence to the tty. Something like
772 ;; ESC | <cwd> |
773 ;; where <cwd> is the new current working directory. Then trash the
774 ;; directory tracking machinery currently used in this package, and
775 ;; replace it with a process filter that watches for and strips out
776 ;; these messages.
777
778 (defun shell-directory-tracker (str)
779 "Tracks cd, pushd and popd commands issued to the shell.
780 This function is called on each input passed to the shell.
781 It watches for cd, pushd and popd commands and sets the buffer's
782 default directory to track these commands.
783
784 You may toggle this tracking on and off with \\[shell-dirtrack-mode].
785 If Emacs gets confused, you can resync with the shell with \\[dirs].
786 \(The `dirtrack' package provides an alternative implementation of this
787 feature - see the function `dirtrack-mode'.)
788
789 See variables `shell-cd-regexp', `shell-chdrive-regexp', `shell-pushd-regexp',
790 and `shell-popd-regexp', while `shell-pushd-tohome', `shell-pushd-dextract',
791 and `shell-pushd-dunique' control the behavior of the relevant command.
792
793 Environment variables are expanded, see function `substitute-in-file-name'."
794 (if shell-dirtrackp
795 ;; We fail gracefully if we think the command will fail in the shell.
796 ;;; (with-demoted-errors "Directory tracker failure: %s"
797 ;; This fails so often that it seems better to just ignore errors (?).
798 ;; Eg even: foo=/tmp; cd $foo is beyond us (bug#17159).
799 (ignore-errors
800 (let ((start (progn (string-match
801 (concat "^" shell-command-separator-regexp)
802 str) ; skip whitespace
803 (match-end 0)))
804 (case-fold-search)
805 end cmd arg1)
806 (while (string-match shell-command-regexp str start)
807 (setq end (match-end 0)
808 cmd (comint-arguments (substring str start end) 0 0)
809 arg1 (comint-arguments (substring str start end) 1 1))
810 (if arg1
811 (setq arg1 (shell-unquote-argument arg1)))
812 (cond ((string-match (concat "\\`\\(" shell-popd-regexp
813 "\\)\\($\\|[ \t]\\)")
814 cmd)
815 (shell-process-popd (comint-substitute-in-file-name arg1)))
816 ((string-match (concat "\\`\\(" shell-pushd-regexp
817 "\\)\\($\\|[ \t]\\)")
818 cmd)
819 (shell-process-pushd (comint-substitute-in-file-name arg1)))
820 ((string-match (concat "\\`\\(" shell-cd-regexp
821 "\\)\\($\\|[ \t]\\)")
822 cmd)
823 (shell-process-cd (comint-substitute-in-file-name arg1)))
824 ((and shell-chdrive-regexp
825 (string-match (concat "\\`\\(" shell-chdrive-regexp
826 "\\)\\($\\|[ \t]\\)")
827 cmd))
828 (shell-process-cd (comint-substitute-in-file-name cmd))))
829 (setq start (progn (string-match shell-command-separator-regexp
830 str end)
831 ;; skip again
832 (match-end 0))))))))
833
834 (defun shell-unquote-argument (string)
835 "Remove all kinds of shell quoting from STRING."
836 (save-match-data
837 (let ((idx 0) next inside
838 (quote-chars
839 (if (string-match shell-dumb-shell-regexp
840 (file-name-nondirectory
841 (car (process-command (get-buffer-process (current-buffer))))))
842 "['`\"]"
843 "[\\'`\"]")))
844 (while (and (< idx (length string))
845 (setq next (string-match quote-chars string next)))
846 (cond ((= (aref string next) ?\\)
847 (setq string (replace-match "" nil nil string))
848 (setq next (1+ next)))
849 ((and inside (= (aref string next) inside))
850 (setq string (replace-match "" nil nil string))
851 (setq inside nil))
852 (inside
853 (setq next (1+ next)))
854 (t
855 (setq inside (aref string next))
856 (setq string (replace-match "" nil nil string)))))
857 string)))
858
859 ;; popd [+n]
860 (defun shell-process-popd (arg)
861 (let ((num (or (shell-extract-num arg) 0)))
862 (cond ((and num (= num 0) shell-dirstack)
863 (shell-cd (shell-prefixed-directory-name (car shell-dirstack)))
864 (setq shell-dirstack (cdr shell-dirstack))
865 (shell-dirstack-message))
866 ((and num (> num 0) (<= num (length shell-dirstack)))
867 (let* ((ds (cons nil shell-dirstack))
868 (cell (nthcdr (1- num) ds)))
869 (rplacd cell (cdr (cdr cell)))
870 (setq shell-dirstack (cdr ds))
871 (shell-dirstack-message)))
872 (t
873 (error "Couldn't popd")))))
874
875 ;; Return DIR prefixed with comint-file-name-prefix as appropriate.
876 (defun shell-prefixed-directory-name (dir)
877 (if (= (length comint-file-name-prefix) 0)
878 dir
879 (if (file-name-absolute-p dir)
880 ;; The name is absolute, so prepend the prefix.
881 (concat comint-file-name-prefix dir)
882 ;; For relative name we assume default-directory already has the prefix.
883 (expand-file-name dir))))
884
885 ;; cd [dir]
886 (defun shell-process-cd (arg)
887 (let ((new-dir (cond ((zerop (length arg)) (concat comint-file-name-prefix
888 "~"))
889 ((string-equal "-" arg) shell-last-dir)
890 (t (shell-prefixed-directory-name arg)))))
891 (setq shell-last-dir default-directory)
892 (shell-cd new-dir)
893 (shell-dirstack-message)))
894
895 ;; pushd [+n | dir]
896 (defun shell-process-pushd (arg)
897 (let ((num (shell-extract-num arg)))
898 (cond ((zerop (length arg))
899 ;; no arg -- swap pwd and car of stack unless shell-pushd-tohome
900 (cond (shell-pushd-tohome
901 (shell-process-pushd (concat comint-file-name-prefix "~")))
902 (shell-dirstack
903 (let ((old default-directory))
904 (shell-cd (car shell-dirstack))
905 (setq shell-dirstack (cons old (cdr shell-dirstack)))
906 (shell-dirstack-message)))
907 (t
908 (message "Directory stack empty."))))
909 ((numberp num)
910 ;; pushd +n
911 (cond ((> num (length shell-dirstack))
912 (message "Directory stack not that deep."))
913 ((= num 0)
914 (error "Couldn't cd"))
915 (shell-pushd-dextract
916 (let ((dir (nth (1- num) shell-dirstack)))
917 (shell-process-popd arg)
918 (shell-process-pushd default-directory)
919 (shell-cd dir)
920 (shell-dirstack-message)))
921 (t
922 (let* ((ds (cons default-directory shell-dirstack))
923 (dslen (length ds))
924 (front (nthcdr num ds))
925 (back (reverse (nthcdr (- dslen num) (reverse ds))))
926 (new-ds (append front back)))
927 (shell-cd (car new-ds))
928 (setq shell-dirstack (cdr new-ds))
929 (shell-dirstack-message)))))
930 (t
931 ;; pushd <dir>
932 (let ((old-wd default-directory))
933 (shell-cd (shell-prefixed-directory-name arg))
934 (if (or (null shell-pushd-dunique)
935 (not (member old-wd shell-dirstack)))
936 (setq shell-dirstack (cons old-wd shell-dirstack)))
937 (shell-dirstack-message))))))
938
939 ;; If STR is of the form +n, for n>0, return n. Otherwise, nil.
940 (defun shell-extract-num (str)
941 (and (string-match "^\\+[1-9][0-9]*$" str)
942 (string-to-number str)))
943
944 (defvaralias 'shell-dirtrack-mode 'shell-dirtrackp)
945 (define-minor-mode shell-dirtrack-mode
946 "Toggle directory tracking in this shell buffer (Shell Dirtrack mode).
947 With a prefix argument ARG, enable Shell Dirtrack mode if ARG is
948 positive, and disable it otherwise. If called from Lisp, enable
949 the mode if ARG is omitted or nil.
950
951 The `dirtrack' package provides an alternative implementation of
952 this feature; see the function `dirtrack-mode'."
953 nil nil nil
954 (setq list-buffers-directory (if shell-dirtrack-mode default-directory))
955 (if shell-dirtrack-mode
956 (add-hook 'comint-input-filter-functions 'shell-directory-tracker nil t)
957 (remove-hook 'comint-input-filter-functions 'shell-directory-tracker t)))
958
959 (define-obsolete-function-alias 'shell-dirtrack-toggle 'shell-dirtrack-mode
960 "23.1")
961
962 (defun shell-cd (dir)
963 "Do normal `cd' to DIR, and set `list-buffers-directory'."
964 (cd dir)
965 (if shell-dirtrackp
966 (setq list-buffers-directory default-directory)))
967
968 (defun shell-resync-dirs ()
969 "Resync the buffer's idea of the current directory stack.
970 This command queries the shell with the command bound to
971 `shell-dirstack-query' (default \"dirs\"), reads the next
972 line output and parses it to form the new directory stack.
973 DON'T issue this command unless the buffer is at a shell prompt.
974 Also, note that if some other subprocess decides to do output
975 immediately after the query, its output will be taken as the
976 new directory stack -- you lose. If this happens, just do the
977 command again."
978 (interactive)
979 (let* ((proc (get-buffer-process (current-buffer)))
980 (pmark (process-mark proc))
981 (started-at-pmark (= (point) (marker-position pmark))))
982 (save-excursion
983 (goto-char pmark)
984 ;; If the process echoes commands, don't insert a fake command in
985 ;; the buffer or it will appear twice.
986 (unless comint-process-echoes
987 (insert shell-dirstack-query) (insert "\n"))
988 (sit-for 0) ; force redisplay
989 (comint-send-string proc shell-dirstack-query)
990 (comint-send-string proc "\n")
991 (set-marker pmark (point))
992 (let ((pt (point))
993 (regexp
994 (concat
995 (if comint-process-echoes
996 ;; Skip command echo if the process echoes
997 (concat "\\(" (regexp-quote shell-dirstack-query) "\n\\)")
998 "\\(\\)")
999 "\\(.+\n\\)")))
1000 ;; This extra newline prevents the user's pending input from spoofing us.
1001 (insert "\n") (backward-char 1)
1002 ;; Wait for one line.
1003 (while (not (looking-at regexp))
1004 (accept-process-output proc)
1005 (goto-char pt)))
1006 (goto-char pmark) (delete-char 1) ; remove the extra newline
1007 ;; That's the dirlist. grab it & parse it.
1008 (let* ((dl (buffer-substring (match-beginning 2) (1- (match-end 2))))
1009 (dl-len (length dl))
1010 (ds '()) ; new dir stack
1011 (i 0))
1012 (while (< i dl-len)
1013 ;; regexp = optional whitespace, (non-whitespace), optional whitespace
1014 (string-match "\\s *\\(\\S +\\)\\s *" dl i) ; pick off next dir
1015 (setq ds (cons (concat comint-file-name-prefix
1016 (substring dl (match-beginning 1)
1017 (match-end 1)))
1018 ds))
1019 (setq i (match-end 0)))
1020 (let ((ds (nreverse ds)))
1021 (with-demoted-errors "Couldn't cd: %s"
1022 (shell-cd (car ds))
1023 (setq shell-dirstack (cdr ds)
1024 shell-last-dir (car shell-dirstack))
1025 (shell-dirstack-message)))))
1026 (if started-at-pmark (goto-char (marker-position pmark)))))
1027
1028 ;; For your typing convenience:
1029 (defalias 'dirs 'shell-resync-dirs)
1030
1031
1032 ;; Show the current dirstack on the message line.
1033 ;; Pretty up dirs a bit by changing "/usr/jqr/foo" to "~/foo".
1034 ;; (This isn't necessary if the dirlisting is generated with a simple "dirs".)
1035 ;; All the commands that mung the buffer's dirstack finish by calling
1036 ;; this guy.
1037 (defun shell-dirstack-message ()
1038 (when shell-dirtrack-verbose
1039 (let* ((msg "")
1040 (ds (cons default-directory shell-dirstack))
1041 (home (expand-file-name (concat comint-file-name-prefix "~/")))
1042 (homelen (length home)))
1043 (while ds
1044 (let ((dir (car ds)))
1045 (and (>= (length dir) homelen)
1046 (string= home (substring dir 0 homelen))
1047 (setq dir (concat "~/" (substring dir homelen))))
1048 ;; Strip off comint-file-name-prefix if present.
1049 (and comint-file-name-prefix
1050 (>= (length dir) (length comint-file-name-prefix))
1051 (string= comint-file-name-prefix
1052 (substring dir 0 (length comint-file-name-prefix)))
1053 (setq dir (substring dir (length comint-file-name-prefix)))
1054 (setcar ds dir))
1055 (setq msg (concat msg (directory-file-name dir) " "))
1056 (setq ds (cdr ds))))
1057 (message "%s" msg))))
1058
1059 ;; This was mostly copied from shell-resync-dirs.
1060 (defun shell-snarf-envar (var)
1061 "Return as a string the shell's value of environment variable VAR."
1062 (let* ((cmd (format "printenv '%s'\n" var))
1063 (proc (get-buffer-process (current-buffer)))
1064 (pmark (process-mark proc)))
1065 (goto-char pmark)
1066 (insert cmd)
1067 (sit-for 0) ; force redisplay
1068 (comint-send-string proc cmd)
1069 (set-marker pmark (point))
1070 (let ((pt (point))) ; wait for 1 line
1071 ;; This extra newline prevents the user's pending input from spoofing us.
1072 (insert "\n") (backward-char 1)
1073 (while (not (looking-at ".+\n"))
1074 (accept-process-output proc)
1075 (goto-char pt)))
1076 (goto-char pmark) (delete-char 1) ; remove the extra newline
1077 (buffer-substring (match-beginning 0) (1- (match-end 0)))))
1078
1079 (defun shell-copy-environment-variable (variable)
1080 "Copy the environment variable VARIABLE from the subshell to Emacs.
1081 This command reads the value of the specified environment variable
1082 in the shell, and sets the same environment variable in Emacs
1083 \(what `getenv' in Emacs would return) to that value.
1084 That value will affect any new subprocesses that you subsequently start
1085 from Emacs."
1086 (interactive (list (read-envvar-name "\
1087 Copy Shell environment variable to Emacs: ")))
1088 (setenv variable (shell-snarf-envar variable)))
1089
1090 (defun shell-forward-command (&optional arg)
1091 "Move forward across ARG shell command(s). Does not cross lines.
1092 See `shell-command-regexp'."
1093 (interactive "p")
1094 (let ((limit (line-end-position)))
1095 (if (re-search-forward (concat shell-command-regexp "\\([;&|][\t ]*\\)+")
1096 limit 'move arg)
1097 (skip-syntax-backward " "))))
1098
1099
1100 (defun shell-backward-command (&optional arg)
1101 "Move backward across ARG shell command(s). Does not cross lines.
1102 See `shell-command-regexp'."
1103 (interactive "p")
1104 (let ((limit (save-excursion (comint-bol nil) (point))))
1105 (when (> limit (point))
1106 (setq limit (line-beginning-position)))
1107 (skip-syntax-backward " " limit)
1108 (if (re-search-backward
1109 (format "[;&|]+[\t ]*\\(%s\\)" shell-command-regexp) limit 'move arg)
1110 (progn (goto-char (match-beginning 1))
1111 (skip-chars-forward ";&|")))))
1112
1113 (defun shell-dynamic-complete-command ()
1114 "Dynamically complete the command at point.
1115 This function is similar to `comint-dynamic-complete-filename', except that it
1116 searches `exec-path' (minus trailing `exec-directory') for completion
1117 candidates. Note that this may not be the same as the shell's idea of the
1118 path.
1119
1120 Completion is dependent on the value of `shell-completion-execonly',
1121 `shell-completion-fignore', plus those that affect file completion. See Info
1122 node `Shell Options'.
1123
1124 Returns t if successful."
1125 (interactive)
1126 (let ((data (shell-command-completion)))
1127 (if data
1128 (prog2 (unless (window-minibuffer-p)
1129 (message "Completing command name..."))
1130 (apply #'completion-in-region data)))))
1131
1132 (defun shell-command-completion ()
1133 "Return the completion data for the command at point, if any."
1134 (let ((filename (comint-match-partial-filename)))
1135 (if (and filename
1136 (save-match-data (not (string-match "[~/]" filename)))
1137 (eq (match-beginning 0)
1138 (save-excursion (shell-backward-command 1) (point))))
1139 (shell--command-completion-data))))
1140
1141 (defun shell--command-completion-data ()
1142 "Return the completion data for the command at point."
1143 (let* ((filename (or (comint-match-partial-filename) ""))
1144 (start (if (zerop (length filename)) (point) (match-beginning 0)))
1145 (end (if (zerop (length filename)) (point) (match-end 0)))
1146 (filenondir (file-name-nondirectory filename))
1147 ; why cdr? see `shell-dynamic-complete-command'
1148 (path-dirs (append (cdr (reverse exec-path))
1149 (if (memq system-type '(windows-nt ms-dos)) '("."))))
1150 (cwd (file-name-as-directory (expand-file-name default-directory)))
1151 (ignored-extensions
1152 (and comint-completion-fignore
1153 (mapconcat (function (lambda (x) (concat (regexp-quote x) "\\'")))
1154 comint-completion-fignore "\\|")))
1155 (dir "") (comps-in-dir ())
1156 (file "") (abs-file-name "") (completions ()))
1157 ;; Go thru each dir in the search path, finding completions.
1158 (while path-dirs
1159 (setq dir (file-name-as-directory (comint-directory (or (car path-dirs) ".")))
1160 comps-in-dir (and (file-accessible-directory-p dir)
1161 (file-name-all-completions filenondir dir)))
1162 ;; Go thru each completion found, to see whether it should be used.
1163 (while comps-in-dir
1164 (setq file (car comps-in-dir)
1165 abs-file-name (concat dir file))
1166 (if (and (not (member file completions))
1167 (not (and ignored-extensions
1168 (string-match ignored-extensions file)))
1169 (or (string-equal dir cwd)
1170 (not (file-directory-p abs-file-name)))
1171 (or (null shell-completion-execonly)
1172 (file-executable-p abs-file-name)))
1173 (setq completions (cons file completions)))
1174 (setq comps-in-dir (cdr comps-in-dir)))
1175 (setq path-dirs (cdr path-dirs)))
1176 ;; OK, we've got a list of completions.
1177 (list
1178 start end
1179 (lambda (string pred action)
1180 (if (string-match "/" string)
1181 (completion-file-name-table string pred action)
1182 (complete-with-action action completions string pred)))
1183 :exit-function
1184 (lambda (_string finished)
1185 (when (memq finished '(sole finished))
1186 (if (looking-at " ")
1187 (goto-char (match-end 0))
1188 (insert " ")))))))
1189
1190 ;; (defun shell-dynamic-complete-as-command ()
1191 ;; "Dynamically complete at point as a command.
1192 ;; See `shell-dynamic-complete-filename'. Returns t if successful."
1193 ;; (apply #'completion-in-region shell--command-completion-data))
1194
1195 (defun shell-dynamic-complete-filename ()
1196 "Dynamically complete the filename at point.
1197 This completes only if point is at a suitable position for a
1198 filename argument."
1199 (interactive)
1200 (let ((data (shell-filename-completion)))
1201 (if data (apply #'completion-in-region data))))
1202
1203 (defun shell-filename-completion ()
1204 "Return the completion data for file name at point, if any."
1205 (let ((opoint (point))
1206 (beg (comint-line-beginning-position)))
1207 (when (save-excursion
1208 (goto-char (if (re-search-backward "[;|&]" beg t)
1209 (match-end 0)
1210 beg))
1211 (re-search-forward "[^ \t][ \t]" opoint t))
1212 (comint-filename-completion))))
1213
1214 (defun shell-match-partial-variable ()
1215 "Return the shell variable at point, or nil if none is found."
1216 (save-excursion
1217 (if (re-search-backward "[^A-Za-z0-9_{(]" nil 'move)
1218 (or (looking-at "\\$") (forward-char 1)))
1219 (if (or (eolp) (looking-at "[^A-Za-z0-9_{($]"))
1220 nil
1221 (looking-at "\\$?[{(]?[A-Za-z0-9_]*[})]?")
1222 (buffer-substring (match-beginning 0) (match-end 0)))))
1223
1224 (defun shell-dynamic-complete-environment-variable ()
1225 "Dynamically complete the environment variable at point.
1226 Completes if after a variable, i.e., if it starts with a \"$\".
1227
1228 This function is similar to `comint-dynamic-complete-filename', except that it
1229 searches `process-environment' for completion candidates. Note that this may
1230 not be the same as the interpreter's idea of variable names. The main problem
1231 with this type of completion is that `process-environment' is the environment
1232 which Emacs started with. Emacs does not track changes to the environment made
1233 by the interpreter. Perhaps it would be more accurate if this function was
1234 called `shell-dynamic-complete-process-environment-variable'.
1235
1236 Returns non-nil if successful."
1237 (interactive)
1238 (let ((data (shell-environment-variable-completion)))
1239 (if data
1240 (prog2 (unless (window-minibuffer-p)
1241 (message "Completing variable name..."))
1242 (apply #'completion-in-region data)))))
1243
1244
1245 (defun shell-environment-variable-completion ()
1246 "Completion data for an environment variable at point, if any."
1247 (let* ((var (shell-match-partial-variable))
1248 (end (match-end 0)))
1249 (when (and (not (zerop (length var))) (eq (aref var 0) ?$))
1250 (let* ((start
1251 (save-excursion
1252 (goto-char (match-beginning 0))
1253 (looking-at "\\$?[({]*")
1254 (match-end 0)))
1255 (variables (mapcar (lambda (x)
1256 (substring x 0 (string-match "=" x)))
1257 process-environment))
1258 (suffix (pcase (char-before start) (?\{ "}") (?\( ")") (_ ""))))
1259 (list start end variables
1260 :exit-function
1261 (lambda (s finished)
1262 (when (memq finished '(sole finished))
1263 (let ((suf (concat suffix
1264 (if (file-directory-p
1265 (comint-directory (getenv s)))
1266 "/"))))
1267 (if (looking-at (regexp-quote suf))
1268 (goto-char (match-end 0))
1269 (insert suf))))))))))
1270
1271
1272 (defun shell-c-a-p-replace-by-expanded-directory ()
1273 "Expand directory stack reference before point.
1274 For use on `completion-at-point-functions'."
1275 (when (comint-match-partial-filename)
1276 (save-excursion
1277 (goto-char (match-beginning 0))
1278 (let ((stack (cons default-directory shell-dirstack))
1279 (index (cond ((looking-at "=-/?")
1280 (length shell-dirstack))
1281 ((looking-at "=\\([0-9]+\\)/?")
1282 (string-to-number
1283 (buffer-substring
1284 (match-beginning 1) (match-end 1)))))))
1285 (when index
1286 (let ((start (match-beginning 0))
1287 (end (match-end 0))
1288 (replacement (file-name-as-directory (nth index stack))))
1289 (lambda ()
1290 (cond
1291 ((>= index (length stack))
1292 (error "Directory stack not that deep"))
1293 (t
1294 (save-excursion
1295 (goto-char start)
1296 (insert replacement)
1297 (delete-char (- end start)))
1298 (message "Directory item: %d" index)
1299 t)))))))))
1300
1301 (defun shell-replace-by-expanded-directory ()
1302 "Expand directory stack reference before point.
1303 Directory stack references are of the form \"=digit\" or \"=-\".
1304 See `default-directory' and `shell-dirstack'.
1305
1306 Returns t if successful."
1307 (interactive)
1308 (let ((f (shell-c-a-p-replace-by-expanded-directory)))
1309 (if f (funcall f))))
1310
1311 (provide 'shell)
1312
1313 ;;; shell.el ends here