comparison lisp/shell.el @ 35659:aa45cec8f927

shell-write-history-on-exit: make sure the error message goes to the right buffer
author Sam Steingold <sds@gnu.org>
date Sun, 28 Jan 2001 03:43:35 +0000
parents cafc43e2ccfd
children 153f1b1f2efd
comparison
equal deleted inserted replaced
35658:3551e8549d4e 35659:aa45cec8f927
35 ;; on top of comint mode. This is actually cmushell with things 35 ;; on top of comint mode. This is actually cmushell with things
36 ;; renamed to replace its counterpart in Emacs 18. cmushell is more 36 ;; renamed to replace its counterpart in Emacs 18. cmushell is more
37 ;; featureful, robust, and uniform than the Emacs 18 version. 37 ;; featureful, robust, and uniform than the Emacs 18 version.
38 38
39 ;; Since this mode is built on top of the general command-interpreter-in- 39 ;; Since this mode is built on top of the general command-interpreter-in-
40 ;; a-buffer mode (comint mode), it shares a common base functionality, 40 ;; a-buffer mode (comint mode), it shares a common base functionality,
41 ;; and a common set of bindings, with all modes derived from comint mode. 41 ;; and a common set of bindings, with all modes derived from comint mode.
42 ;; This makes these modes easier to use. 42 ;; This makes these modes easier to use.
43 43
44 ;; For documentation on the functionality provided by comint mode, and 44 ;; For documentation on the functionality provided by comint mode, and
45 ;; the hooks available for customising it, see the file comint.el. 45 ;; the hooks available for customising it, see the file comint.el.
46 ;; For further information on shell mode, see the comments below. 46 ;; For further information on shell mode, see the comments below.
47 47
48 ;; Needs fixin: 48 ;; Needs fixin:
49 ;; When sending text from a source file to a subprocess, the process-mark can 49 ;; When sending text from a source file to a subprocess, the process-mark can
50 ;; move off the window, so you can lose sight of the process interactions. 50 ;; move off the window, so you can lose sight of the process interactions.
51 ;; Maybe I should ensure the process mark is in the window when I send 51 ;; Maybe I should ensure the process mark is in the window when I send
52 ;; text to the process? Switch selectable? 52 ;; text to the process? Switch selectable?
53 53
54 ;; YOUR .EMACS FILE 54 ;; YOUR .EMACS FILE
56 ;; Some suggestions for your .emacs file. 56 ;; Some suggestions for your .emacs file.
57 ;; 57 ;;
58 ;; ;; Define M-# to run some strange command: 58 ;; ;; Define M-# to run some strange command:
59 ;; (eval-after-load "shell" 59 ;; (eval-after-load "shell"
60 ;; '(define-key shell-mode-map "\M-#" 'shells-dynamic-spell)) 60 ;; '(define-key shell-mode-map "\M-#" 'shells-dynamic-spell))
61 61
62 ;; Brief Command Documentation: 62 ;; Brief Command Documentation:
63 ;;============================================================================ 63 ;;============================================================================
64 ;; Comint Mode Commands: (common to shell and all comint-derived modes) 64 ;; Comint Mode Commands: (common to shell and all comint-derived modes)
65 ;; 65 ;;
66 ;; m-p comint-previous-input Cycle backwards in input history 66 ;; m-p comint-previous-input Cycle backwards in input history
98 ;; The shell mode hook is shell-mode-hook 98 ;; The shell mode hook is shell-mode-hook
99 ;; comint-prompt-regexp is initialised to shell-prompt-pattern, for backwards 99 ;; comint-prompt-regexp is initialised to shell-prompt-pattern, for backwards
100 ;; compatibility. 100 ;; compatibility.
101 101
102 ;; Read the rest of this file for more information. 102 ;; Read the rest of this file for more information.
103 103
104 ;;; Code: 104 ;;; Code:
105 105
106 (require 'comint) 106 (require 'comint)
107 107
108 ;;; Customization and Buffer Variables 108 ;;; Customization and Buffer Variables
131 :group 'shell) 131 :group 'shell)
132 132
133 (defcustom shell-prompt-pattern "^[^#$%>\n]*[#$%>] *" 133 (defcustom shell-prompt-pattern "^[^#$%>\n]*[#$%>] *"
134 "Regexp to match prompts in the inferior shell. 134 "Regexp to match prompts in the inferior shell.
135 Defaults to \"^[^#$%>\\n]*[#$%>] *\", which works pretty well. 135 Defaults to \"^[^#$%>\\n]*[#$%>] *\", which works pretty well.
136 This variable is used to initialise `comint-prompt-regexp' in the 136 This variable is used to initialise `comint-prompt-regexp' in the
137 shell buffer. 137 shell buffer.
138 138
139 This variable is only used if the variable 139 This variable is only used if the variable
140 `comint-use-prompt-regexp-instead-of-fields' is non-nil. 140 `comint-use-prompt-regexp-instead-of-fields' is non-nil.
141 141
242 "*Regexp to match subshell commands equivalent to cd." 242 "*Regexp to match subshell commands equivalent to cd."
243 :type 'regexp 243 :type 'regexp
244 :group 'shell-directories) 244 :group 'shell-directories)
245 245
246 (defcustom shell-chdrive-regexp 246 (defcustom shell-chdrive-regexp
247 (if (memq system-type '(ms-dos windows-nt)) 247 (if (memq system-type '(ms-dos windows-nt))
248 ; NetWare allows the five chars between upper and lower alphabetics. 248 ; NetWare allows the five chars between upper and lower alphabetics.
249 "[]a-zA-Z^_`\\[\\\\]:" 249 "[]a-zA-Z^_`\\[\\\\]:"
250 nil) 250 nil)
251 "*If non-nil, is regexp used to track drive changes." 251 "*If non-nil, is regexp used to track drive changes."
252 :type '(choice regexp 252 :type '(choice regexp
332 (defvar shell-font-lock-keywords 332 (defvar shell-font-lock-keywords
333 '(("[ \t]\\([+-][^ \t\n]+\\)" 1 font-lock-comment-face) 333 '(("[ \t]\\([+-][^ \t\n]+\\)" 1 font-lock-comment-face)
334 ("^[^ \t\n]+:.*" . font-lock-string-face) 334 ("^[^ \t\n]+:.*" . font-lock-string-face)
335 ("^\\[[1-9][0-9]*\\]" . font-lock-string-face)) 335 ("^\\[[1-9][0-9]*\\]" . font-lock-string-face))
336 "Additional expressions to highlight in Shell mode.") 336 "Additional expressions to highlight in Shell mode.")
337 337
338 ;;; Basic Procedures 338 ;;; Basic Procedures
339 339
340 (put 'shell-mode 'mode-class 'special) 340 (put 'shell-mode 'mode-class 'special)
341 341
342 (define-derived-mode shell-mode comint-mode "Shell" 342 (define-derived-mode shell-mode comint-mode "Shell"
360 360
361 `cd', `pushd' and `popd' commands given to the shell are watched by Emacs to 361 `cd', `pushd' and `popd' commands given to the shell are watched by Emacs to
362 keep this buffer's default directory the same as the shell's working directory. 362 keep this buffer's default directory the same as the shell's working directory.
363 While directory tracking is enabled, the shell's working directory is displayed 363 While directory tracking is enabled, the shell's working directory is displayed
364 by \\[list-buffers] or \\[mouse-buffer-menu] in the `File' field. 364 by \\[list-buffers] or \\[mouse-buffer-menu] in the `File' field.
365 \\[dirs] queries the shell and resyncs Emacs' idea of what the current 365 \\[dirs] queries the shell and resyncs Emacs' idea of what the current
366 directory stack is. 366 directory stack is.
367 \\[dirtrack-mode] turns directory tracking on and off. 367 \\[dirtrack-mode] turns directory tracking on and off.
368 368
369 \\{shell-mode-map} 369 \\{shell-mode-map}
370 Customization: Entry to this mode runs the hooks on `comint-mode-hook' and 370 Customization: Entry to this mode runs the hooks on `comint-mode-hook' and
371 `shell-mode-hook' (in that order). Before each input, the hooks on 371 `shell-mode-hook' (in that order). Before each input, the hooks on
372 `comint-input-filter-functions' are run. After each shell output, the hooks 372 `comint-input-filter-functions' are run. After each shell output, the hooks
373 on `comint-output-filter-functions' are run. 373 on `comint-output-filter-functions' are run.
374 374
375 Variables `shell-cd-regexp', `shell-chdrive-regexp', `shell-pushd-regexp' 375 Variables `shell-cd-regexp', `shell-chdrive-regexp', `shell-pushd-regexp'
376 and `shell-popd-regexp' are used to match their respective commands, 376 and `shell-popd-regexp' are used to match their respective commands,
377 while `shell-pushd-tohome', `shell-pushd-dextract' and `shell-pushd-dunique' 377 while `shell-pushd-tohome', `shell-pushd-dextract' and `shell-pushd-dunique'
378 control the behavior of the relevant command. 378 control the behavior of the relevant command.
379 379
380 Variables `comint-completion-autolist', `comint-completion-addsuffix', 380 Variables `comint-completion-autolist', `comint-completion-addsuffix',
381 `comint-completion-recexact' and `comint-completion-fignore' control the 381 `comint-completion-recexact' and `comint-completion-fignore' control the
382 behavior of file name, command name and variable name completion. Variable 382 behavior of file name, command name and variable name completion. Variable
439 439
440 (defun shell-write-history-on-exit (process event) 440 (defun shell-write-history-on-exit (process event)
441 "Called when the shell process is stopped. 441 "Called when the shell process is stopped.
442 442
443 Writes the input history to a history file 443 Writes the input history to a history file
444 `comint-comint-input-ring-file-name' using `comint-write-input-ring' 444 `comint-input-ring-file-name' using `comint-write-input-ring'
445 and inserts a short message in the shell buffer. 445 and inserts a short message in the shell buffer.
446 446
447 This function is a sentinel watching the shell interpreter process. 447 This function is a sentinel watching the shell interpreter process.
448 Sentinels will always get the two parameters PROCESS and EVENT." 448 Sentinels will always get the two parameters PROCESS and EVENT."
449 ;; Write history. 449 ;; Write history.
450 (comint-write-input-ring) 450 (comint-write-input-ring)
451 (if (buffer-live-p (process-buffer process)) 451 (let ((buf (process-buffer process)))
452 (insert (format "\nProcess %s %s\n" process event)))) 452 (when (buffer-live-p buf)
453 453 (with-current-buffer buf
454 (insert (format "\nProcess %s %s\n" process event))))))
455
454 ;;;###autoload 456 ;;;###autoload
455 (defun shell (&optional buffer) 457 (defun shell (&optional buffer)
456 "Run an inferior shell, with I/O through BUFFER (which defaults to `*shell*'). 458 "Run an inferior shell, with I/O through BUFFER (which defaults to `*shell*').
457 Interactively, a prefix arg means to prompt for BUFFER. 459 Interactively, a prefix arg means to prompt for BUFFER.
458 If BUFFER exists but shell process is not running, make new shell. 460 If BUFFER exists but shell process is not running, make new shell.
488 (setq buffer "*shell*")) 490 (setq buffer "*shell*"))
489 (if (not (comint-check-proc buffer)) 491 (if (not (comint-check-proc buffer))
490 (let* ((prog (or explicit-shell-file-name 492 (let* ((prog (or explicit-shell-file-name
491 (getenv "ESHELL") 493 (getenv "ESHELL")
492 (getenv "SHELL") 494 (getenv "SHELL")
493 "/bin/sh")) 495 "/bin/sh"))
494 (name (file-name-nondirectory prog)) 496 (name (file-name-nondirectory prog))
495 (startfile (concat "~/.emacs_" name)) 497 (startfile (concat "~/.emacs_" name))
496 (xargs-name (intern-soft (concat "explicit-" name "-args"))) 498 (xargs-name (intern-soft (concat "explicit-" name "-args")))
497 shell-buffer) 499 shell-buffer)
498 (save-excursion 500 (save-excursion
506 (pop-to-buffer shell-buffer)) 508 (pop-to-buffer shell-buffer))
507 (pop-to-buffer buffer))) 509 (pop-to-buffer buffer)))
508 510
509 ;;; Don't do this when shell.el is loaded, only while dumping. 511 ;;; Don't do this when shell.el is loaded, only while dumping.
510 ;;;###autoload (add-hook 'same-window-buffer-names "*shell*") 512 ;;;###autoload (add-hook 'same-window-buffer-names "*shell*")
511 513
512 ;;; Directory tracking 514 ;;; Directory tracking
513 ;;; 515 ;;;
514 ;;; This code provides the shell mode input sentinel 516 ;;; This code provides the shell mode input sentinel
515 ;;; SHELL-DIRECTORY-TRACKER 517 ;;; SHELL-DIRECTORY-TRACKER
516 ;;; that tracks cd, pushd, and popd commands issued to the shell, and 518 ;;; that tracks cd, pushd, and popd commands issued to the shell, and
535 ;;; control, you can switch between jobs, all having different w.d.'s. So 537 ;;; control, you can switch between jobs, all having different w.d.'s. So
536 ;;; simply saying %3 can shift your w.d.. 538 ;;; simply saying %3 can shift your w.d..
537 ;;; 539 ;;;
538 ;;; The solution is to relax, not stress out about it, and settle for 540 ;;; The solution is to relax, not stress out about it, and settle for
539 ;;; a hack that works pretty well in typical circumstances. Remember 541 ;;; a hack that works pretty well in typical circumstances. Remember
540 ;;; that a half-assed solution is more in keeping with the spirit of Unix, 542 ;;; that a half-assed solution is more in keeping with the spirit of Unix,
541 ;;; anyway. Blech. 543 ;;; anyway. Blech.
542 ;;; 544 ;;;
543 ;;; One good hack not implemented here for users of programmable shells 545 ;;; One good hack not implemented here for users of programmable shells
544 ;;; is to program up the shell w.d. manipulation commands to output 546 ;;; is to program up the shell w.d. manipulation commands to output
545 ;;; a coded command sequence to the tty. Something like 547 ;;; a coded command sequence to the tty. Something like
557 559
558 You may toggle this tracking on and off with M-x dirtrack-mode. 560 You may toggle this tracking on and off with M-x dirtrack-mode.
559 If emacs gets confused, you can resync with the shell with M-x dirs. 561 If emacs gets confused, you can resync with the shell with M-x dirs.
560 562
561 See variables `shell-cd-regexp', `shell-chdrive-regexp', `shell-pushd-regexp', 563 See variables `shell-cd-regexp', `shell-chdrive-regexp', `shell-pushd-regexp',
562 and `shell-popd-regexp', while `shell-pushd-tohome', `shell-pushd-dextract', 564 and `shell-popd-regexp', while `shell-pushd-tohome', `shell-pushd-dextract',
563 and `shell-pushd-dunique' control the behavior of the relevant command. 565 and `shell-pushd-dunique' control the behavior of the relevant command.
564 566
565 Environment variables are expanded, see function `substitute-in-file-name'." 567 Environment variables are expanded, see function `substitute-in-file-name'."
566 (if shell-dirtrackp 568 (if shell-dirtrackp
567 ;; We fail gracefully if we think the command will fail in the shell. 569 ;; We fail gracefully if we think the command will fail in the shell.
727 (expand-file-name dir)))) 729 (expand-file-name dir))))
728 (cd dir)) 730 (cd dir))
729 731
730 (defun shell-resync-dirs () 732 (defun shell-resync-dirs ()
731 "Resync the buffer's idea of the current directory stack. 733 "Resync the buffer's idea of the current directory stack.
732 This command queries the shell with the command bound to 734 This command queries the shell with the command bound to
733 `shell-dirstack-query' (default \"dirs\"), reads the next 735 `shell-dirstack-query' (default \"dirs\"), reads the next
734 line output and parses it to form the new directory stack. 736 line output and parses it to form the new directory stack.
735 DON'T issue this command unless the buffer is at a shell prompt. 737 DON'T issue this command unless the buffer is at a shell prompt.
736 Also, note that if some other subprocess decides to do output 738 Also, note that if some other subprocess decides to do output
737 immediately after the query, its output will be taken as the 739 immediately after the query, its output will be taken as the
741 (let* ((proc (get-buffer-process (current-buffer))) 743 (let* ((proc (get-buffer-process (current-buffer)))
742 (pmark (process-mark proc))) 744 (pmark (process-mark proc)))
743 (goto-char pmark) 745 (goto-char pmark)
744 (insert shell-dirstack-query) (insert "\n") 746 (insert shell-dirstack-query) (insert "\n")
745 (sit-for 0) ; force redisplay 747 (sit-for 0) ; force redisplay
746 (comint-send-string proc shell-dirstack-query) 748 (comint-send-string proc shell-dirstack-query)
747 (comint-send-string proc "\n") 749 (comint-send-string proc "\n")
748 (set-marker pmark (point)) 750 (set-marker pmark (point))
749 (let ((pt (point))) ; wait for 1 line 751 (let ((pt (point))) ; wait for 1 line
750 ;; This extra newline prevents the user's pending input from spoofing us. 752 ;; This extra newline prevents the user's pending input from spoofing us.
751 (insert "\n") (backward-char 1) 753 (insert "\n") (backward-char 1)
802 (setq dir (substring dir (length comint-file-name-prefix))) 804 (setq dir (substring dir (length comint-file-name-prefix)))
803 (setcar ds dir)) 805 (setcar ds dir))
804 (setq msg (concat msg (directory-file-name dir) " ")) 806 (setq msg (concat msg (directory-file-name dir) " "))
805 (setq ds (cdr ds)))) 807 (setq ds (cdr ds))))
806 (message "%s" msg)))) 808 (message "%s" msg))))
807 809
808 ;; This was mostly copied from shell-resync-dirs. 810 ;; This was mostly copied from shell-resync-dirs.
809 (defun shell-snarf-envar (var) 811 (defun shell-snarf-envar (var)
810 "Return as a string the shell's value of environment variable VAR." 812 "Return as a string the shell's value of environment variable VAR."
811 (let* ((cmd (format "printenv '%s'\n" var)) 813 (let* ((cmd (format "printenv '%s'\n" var))
812 (proc (get-buffer-process (current-buffer))) 814 (proc (get-buffer-process (current-buffer)))
833 That value will affect any new subprocesses that you subsequently start 835 That value will affect any new subprocesses that you subsequently start
834 from Emacs." 836 from Emacs."
835 (interactive (list (read-envvar-name "\ 837 (interactive (list (read-envvar-name "\
836 Copy Shell environment variable to Emacs: "))) 838 Copy Shell environment variable to Emacs: ")))
837 (setenv variable (shell-snarf-envar variable))) 839 (setenv variable (shell-snarf-envar variable)))
838 840
839 (defun shell-forward-command (&optional arg) 841 (defun shell-forward-command (&optional arg)
840 "Move forward across ARG shell command(s). Does not cross lines. 842 "Move forward across ARG shell command(s). Does not cross lines.
841 See `shell-command-regexp'." 843 See `shell-command-regexp'."
842 (interactive "p") 844 (interactive "p")
843 (let ((limit (save-excursion (end-of-line nil) (point)))) 845 (let ((limit (save-excursion (end-of-line nil) (point))))
1004 (error "Directory stack not that deep.")) 1006 (error "Directory stack not that deep."))
1005 (t 1007 (t
1006 (replace-match (file-name-as-directory (nth index stack)) t t) 1008 (replace-match (file-name-as-directory (nth index stack)) t t)
1007 (message "Directory item: %d" index) 1009 (message "Directory item: %d" index)
1008 t)))))) 1010 t))))))
1009 1011
1010 (provide 'shell) 1012 (provide 'shell)
1011 1013
1012 ;;; shell.el ends here 1014 ;;; shell.el ends here