Mercurial > emacs
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 |