comparison lisp/comint/background.el @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children b82b59fe008d
comparison
equal deleted inserted replaced
-1:000000000000 0:376386a54a3c
1 ;;; background.el --- fun with background jobs
2
3 ;; Copyright (C) 1988 Joe Keane <jk3k+@andrew.cmu.edu>
4 ;; Keywords: processes
5
6 ;; This file is part of XEmacs.
7 ;;
8 ;; XEmacs is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2 of the License, or
11 ;; (at your option) any later version.
12 ;;
13 ;; XEmacs is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17 ;;
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with XEmacs; if not, write to the Free Software
20 ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 ;; - Adapted to use comint and cleaned up somewhat. Olin Shivers 5/90
23 ;; - Background failed to set the process buffer's working directory
24 ;; in some cases. Fixed. Olin 6/14/90
25 ;; - Background failed to strip leading cd's off the command string
26 ;; after performing them. This screwed up relative pathnames.
27 ;; Furthermore, the proc buffer's default dir wasn't initialised
28 ;; to the user's buffer's default dir before doing the leading cd.
29 ;; This also screwed up relative pathnames if the proc buffer already
30 ;; existed and was set to a different default dir. Hopefully we've
31 ;; finally got it right. The pwd is now reported in the buffer
32 ;; just to let the user know. Bug reported by Piet Van Oostrum.
33 ;; Olin 10/19/90
34 ;; - Fixed up the sentinel to protect match-data around invocations.
35 ;; Also slightly rearranged the cd match code for similar reasons.
36 ;; Olin 7/16/91
37 ;; - Dec 29 1995: changed for new stuff (shell-command-switch, second
38 ;; arg to shell-command --> BUFFER-NAME arg to background) from
39 ;; FSF 19.30. Ben Wing
40
41 (provide 'background)
42 (require 'comint)
43
44 ;; user variables
45 (defvar background-show t
46 "*If non-nil, background jobs' buffers are shown when they're started.")
47 (defvar background-select nil
48 "*If non-nil, background jobs' buffers are selected when they're started.")
49
50 (defun background (command &optional buffer-name)
51 "Run COMMAND in the background like csh.
52 A message is displayed when the job starts and finishes. The buffer is in
53 comint mode, so you can send input and signals to the job. The process object
54 is returned if anyone cares. See also comint-mode and the variables
55 background-show and background-select.
56
57 Optional second argument BUFFER-NAME is a buffer to insert the output into.
58 If omitted, a buffer name is constructed from the command run."
59 (interactive "s%% ")
60 (let ((job-number 1)
61 job-name
62 (dir default-directory))
63 (while (get-process (setq job-name (format "background-%d" job-number)))
64 (setq job-number (1+ job-number)))
65 (or buffer-name
66 (setq buffer-name (format "*%s*" job-name)))
67 (if background-select (pop-to-buffer buffer-name)
68 (if background-show (with-output-to-temp-buffer buffer-name)) ; cute
69 (set-buffer (get-buffer-create buffer-name)))
70 (erase-buffer)
71
72 (setq default-directory dir) ; Do this first, in case cd is relative path.
73 (if (string-match "^cd[\t ]+\\([^\t ;]+\\)[\t ]*;[\t ]*" command)
74 (let ((dir (substring command (match-beginning 1) (match-end 1))))
75 (setq command (substring command (match-end 0)))
76 (setq default-directory
77 (file-name-as-directory (expand-file-name dir)))))
78
79 (insert "--- working directory: " default-directory
80 "\n% " command ?\n)
81
82 (let ((proc (get-buffer-process
83 (comint-exec buffer-name job-name shell-file-name
84 nil (list shell-command-switch command)))))
85 (comint-mode)
86 ;; COND because the proc may have died before the G-B-P is called.
87 (cond (proc (set-process-sentinel proc 'background-sentinel)
88 (message "[%d] %d" job-number (process-id proc))))
89 (setq mode-name "Background")
90 proc)))
91
92
93 (defun background-sentinel (process msg)
94 "Called when a background job changes state."
95 (let ((ms (match-data))) ; barf
96 (unwind-protect
97 (let ((msg (cond ((string= msg "finished\n") "Done")
98 ((string-match "^exited" msg)
99 (concat "Exit " (substring msg 28 -1)))
100 ((zerop (length msg)) "Continuing")
101 (t (concat (upcase (substring msg 0 1))
102 (substring msg 1 -1))))))
103 (message "[%s] %s %s" (process-name process)
104 msg
105 (nth 2 (process-command process)))
106 (if (null (buffer-name (process-buffer process)))
107 (set-process-buffer process nil) ; WHY? Olin.
108 (if (memq (process-status process) '(signal exit))
109 (save-excursion
110 (set-buffer (process-buffer process))
111 (let ((at-end (eobp)))
112 (save-excursion
113 (goto-char (point-max))
114 (insert ?\n msg ?
115 (substring (current-time-string) 11 19) ?\n))
116 (if at-end (goto-char (point-max))))
117 (set-buffer-modified-p nil)))))
118 (store-match-data ms))))