Mercurial > hg > xemacs-beta
comparison lisp/ilisp/comint-v18.el @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | ac2d302a0011 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
1 ;;; -*-Emacs-Lisp-*- General command interpreter in a window stuff | |
2 ;;; Copyright Olin Shivers (1988). | |
3 ;;; Please imagine a long, tedious, legalistic 5-page gnu-style copyright | |
4 ;;; notice appearing here to the effect that you may use this code any | |
5 ;;; way you like, as long as you don't charge money for it, remove this | |
6 ;;; notice, or hold me liable for its results. | |
7 | |
8 ;;; This hopefully generalises shell mode, lisp mode, tea mode, soar mode,... | |
9 ;;; Hacked from tea.el and shell.el by Olin Shivers (shivers@cs.cmu.edu). 8/88 | |
10 | |
11 ;;; This file defines a general command-interpreter-in-a-buffer package | |
12 ;;; (comint mode). The idea is that you can build specific process-in-a-buffer | |
13 ;;; modes on top of comint mode -- e.g., lisp, shell, scheme, T, soar, .... | |
14 ;;; This way, all these specific packages share a common base functionality, | |
15 ;;; and a common set of bindings, which makes them easier to use (and | |
16 ;;; saves code, implementation time, etc., etc.). | |
17 ;;; | |
18 ;;; Several packages are already defined using comint mode: | |
19 ;;; - The file cmushell.el defines cmushell and cmulisp mode. | |
20 ;;; Cmushell and cmulisp mode are similar to, and intended to replace, | |
21 ;;; their counterparts in the standard gnu emacs release (in shell.el). | |
22 ;;; These replacements are more featureful, robust, and uniform than the | |
23 ;;; released versions. The key bindings in lisp mode are also more compatible | |
24 ;;; with the bindings of Hemlock and Zwei (the Lisp Machine emacs). | |
25 ;;; | |
26 ;;; - The file cmuscheme.el defines inferior-scheme mode. | |
27 ;;; - The file tea.el tunes scheme and inferior-scheme modes for T. | |
28 ;;; - The file soar.el tunes lisp and inferior-lisp modes for Soar. | |
29 | |
30 ;;; For documentation on the functionality provided by comint mode, and | |
31 ;;; the hooks available for customising it, see the comments below. | |
32 ;;; For further information on the standard derived modes (shell, | |
33 ;;; inferior-lisp, inferior-scheme, ...), see the relevant source files. | |
34 | |
35 ;;; Please send me bug reports, bug fixes, and extensions, so that I can | |
36 ;;; merge them into the master source. | |
37 | |
38 ;;; For hints on converting existing process modes (e.g., tex-mode, | |
39 ;;; background, dbx, gdb, kermit, prolog, telnet) to use comint-mode | |
40 ;;; instead of shell-mode, see the notes at the end of this file. | |
41 | |
42 (provide 'comint) | |
43 | |
44 | |
45 ;;; Brief Command Documentation: | |
46 ;;;============================================================================ | |
47 ;;; Comint Mode Commands: (common to all derived modes, like cmushell & cmulisp | |
48 ;;; mode) | |
49 ;;; | |
50 ;;; m-p comint-previous-input Cycle backwards in input history | |
51 ;;; m-n comint-next-input Cycle forwards | |
52 ;;; c-c r comint-previous-input-matching Search backwards in input history | |
53 ;;; return comint-send-input | |
54 ;;; c-a comint-bol Beginning of line; skip prompt. | |
55 ;;; c-d comint-delchar-or-maybe-eof Delete char unless at end of buff. | |
56 ;;; c-c c-u comint-kill-input ^u | |
57 ;;; c-c c-w backward-kill-word ^w | |
58 ;;; c-c c-c comint-interrupt-subjob ^c | |
59 ;;; c-c c-z comint-stop-subjob ^z | |
60 ;;; c-c c-\ comint-quit-subjob ^\ | |
61 ;;; c-c c-o comint-kill-output Delete last batch of process output | |
62 ;;; c-c c-r comint-show-output Show last batch of process output | |
63 ;;; | |
64 ;;; Not bound by default in comint-mode | |
65 ;;; send-invisible Read a line w/o echo, and send to proc | |
66 ;;; (These are bound in shell-mode) | |
67 ;;; comint-dynamic-complete Complete filename at point. | |
68 ;;; comint-dynamic-list-completions List completions in help buffer. | |
69 ;;; comint-replace-by-expanded-filename Expand and complete filename at point; | |
70 ;;; replace with expanded/completed name. | |
71 ;;; comint-kill-subjob No mercy. | |
72 ;;; comint-continue-subjob Send CONT signal to buffer's process | |
73 ;;; group. Useful if you accidentally | |
74 ;;; suspend your process (with C-c C-z). | |
75 ;;; | |
76 ;;; Bound for RMS -- I prefer the input history stuff, but you might like 'em. | |
77 ;;; m-P comint-msearch-input Search backwards for prompt | |
78 ;;; m-N comint-psearch-input Search forwards for prompt | |
79 ;;; C-cR comint-msearch-input-matching Search backwards for prompt & string | |
80 | |
81 ;;; comint-mode-hook is the comint mode hook. Basically for your keybindings. | |
82 ;;; comint-load-hook is run after loading in this package. | |
83 | |
84 | |
85 ;;; Buffer Local Variables: | |
86 ;;;============================================================================ | |
87 ;;; Comint mode buffer local variables: | |
88 ;;; comint-prompt-regexp - string comint-bol uses to match prompt. | |
89 ;;; comint-last-input-end - marker For comint-kill-output command | |
90 ;;; input-ring-size - integer For the input history | |
91 ;;; input-ring - ring mechanism | |
92 ;;; input-ring-index - marker ... | |
93 ;;; comint-last-input-match - string ... | |
94 ;;; comint-get-old-input - function Hooks for specific | |
95 ;;; comint-input-sentinel - function process-in-a-buffer | |
96 ;;; comint-input-filter - function modes. | |
97 (defvar comint-prompt-regexp "^" | |
98 "Regexp to recognise prompts in the inferior process. | |
99 Defaults to \"^\", the null string at BOL. | |
100 | |
101 Good choices: | |
102 Canonical Lisp: \"^[^> ]*>+:? *\" (Lucid, franz, kcl, T, cscheme, oaklisp) | |
103 Lucid Common Lisp: \"^\\(>\\|\\(->\\)+\\) *\" | |
104 franz: \"^\\(->\\|<[0-9]*>:\\) *\" | |
105 kcl: \"^>+ *\" | |
106 shell: \"^[^#$%>]*[#$%>] *\" | |
107 T: \"^>+ *\" | |
108 | |
109 This is a good thing to set in mode hooks.") | |
110 | |
111 (defvar input-ring-size 30 | |
112 "Size of input history ring.") | |
113 | |
114 ;;; Here are the per-interpreter hooks. | |
115 (defvar comint-get-old-input (function comint-get-old-input-default) | |
116 "Function that submits old text in comint mode. | |
117 This function is called when return is typed while the point is in old text. | |
118 It returns the text to be submitted as process input. The default is | |
119 comint-get-old-input-default, which grabs the current line, and strips off | |
120 leading text matching comint-prompt-regexp") | |
121 | |
122 (defvar comint-input-sentinel (function ignore) | |
123 "Called on each input submitted to comint mode process by comint-send-input. | |
124 Thus it can, for instance, track cd/pushd/popd commands issued to the csh.") | |
125 | |
126 (defvar comint-input-filter | |
127 (function (lambda (str) (not (string-match "\\`\\s *\\'" str)))) | |
128 "Predicate for filtering additions to input history. | |
129 Only inputs answering true to this function are saved on the input | |
130 history list. Default is to save anything that isn't all whitespace") | |
131 | |
132 (defvar comint-mode-hook '() | |
133 "Called upon entry into comint-mode") | |
134 | |
135 (defvar comint-mode-map nil) | |
136 | |
137 ;; Added for ILISP | |
138 (defvar comint-input-chunk-size 512) | |
139 | |
140 | |
141 | |
142 (defun comint-mode () | |
143 "Major mode for interacting with an inferior interpreter. | |
144 Interpreter name is same as buffer name, sans the asterisks. | |
145 Return at end of buffer sends line as input. | |
146 Return not at end copies rest of line to end and sends it. | |
147 | |
148 This mode is typically customised to create inferior-lisp-mode, | |
149 shell-mode, etc.. This can be done by setting the hooks | |
150 comint-input-sentinel, comint-input-filter, and comint-get-old-input to | |
151 appropriate functions, and the variable comint-prompt-regexp to | |
152 the appropriate regular expression. | |
153 | |
154 An input history is maintained of size input-ring-size, and | |
155 can be accessed with the commands comint-next-input [\\[comint-next-input]] and | |
156 comint-previous-input [\\[comint-previous-input]]. Commands not keybound by | |
157 default are send-invisible, comint-dynamic-complete, and | |
158 comint-list-dynamic-completions. | |
159 \\{comint-mode-map} | |
160 If you accidentally suspend your process, use \\[comint-continue-subjob] | |
161 to continue it. | |
162 | |
163 Entry to this mode runs the hooks on comint-mode-hook" | |
164 (interactive) | |
165 (let ((old-ring (and (assq 'input-ring (buffer-local-variables)) | |
166 (boundp 'input-ring) | |
167 input-ring))) | |
168 (kill-all-local-variables) | |
169 (setq major-mode 'comint-mode) | |
170 (setq mode-name "Comint") | |
171 (setq mode-line-process '(": %s")) | |
172 (use-local-map comint-mode-map) | |
173 (make-local-variable 'comint-last-input-end) | |
174 (setq comint-last-input-end (make-marker)) | |
175 (make-local-variable 'comint-last-input-match) | |
176 (setq comint-last-input-match "") | |
177 (make-variable-buffer-local 'comint-prompt-regexp) ; Don't set; default | |
178 (make-variable-buffer-local 'input-ring-size) ; ...to global val. | |
179 (make-local-variable 'input-ring) | |
180 (make-local-variable 'input-ring-index) | |
181 (setq input-ring-index 0) | |
182 (make-variable-buffer-local 'comint-get-old-input) | |
183 (make-variable-buffer-local 'comint-input-sentinel) | |
184 (make-variable-buffer-local 'comint-input-filter) | |
185 (run-hooks 'comint-mode-hook) | |
186 ;Do this after the hook so the user can mung INPUT-RING-SIZE w/his hook. | |
187 ;The test is so we don't lose history if we run comint-mode twice in | |
188 ;a buffer. | |
189 (setq input-ring (if (ring-p old-ring) old-ring | |
190 (make-ring input-ring-size))))) | |
191 | |
192 (if comint-mode-map | |
193 nil | |
194 (setq comint-mode-map (make-sparse-keymap)) | |
195 (define-key comint-mode-map "\ep" 'comint-previous-input) | |
196 (define-key comint-mode-map "\en" 'comint-next-input) | |
197 (define-key comint-mode-map "\C-m" 'comint-send-input) | |
198 (define-key comint-mode-map "\C-d" 'comint-delchar-or-maybe-eof) | |
199 (define-key comint-mode-map "\C-a" 'comint-bol) | |
200 (define-key comint-mode-map "\C-c\C-u" 'comint-kill-input) | |
201 (define-key comint-mode-map "\C-c\C-w" 'backward-kill-word) | |
202 (define-key comint-mode-map "\C-c\C-c" 'comint-interrupt-subjob) | |
203 (define-key comint-mode-map "\C-c\C-z" 'comint-stop-subjob) | |
204 (define-key comint-mode-map "\C-c\C-\\" 'comint-quit-subjob) | |
205 (define-key comint-mode-map "\C-c\C-o" 'comint-kill-output) | |
206 (define-key comint-mode-map "\C-cr" 'comint-previous-input-matching) | |
207 (define-key comint-mode-map "\C-c\C-r" 'comint-show-output) | |
208 ;;; Here's the prompt-search stuff I installed for RMS to try... | |
209 (define-key comint-mode-map "\eP" 'comint-msearch-input) | |
210 (define-key comint-mode-map "\eN" 'comint-psearch-input) | |
211 (define-key comint-mode-map "\C-cR" 'comint-msearch-input-matching)) | |
212 | |
213 | |
214 ;;; This function is used to make a full copy of the comint mode map, | |
215 ;;; so that client modes won't interfere with each other. This function | |
216 ;;; isn't necessary in emacs 18.5x, but we keep it around for 18.4x versions. | |
217 (defun full-copy-sparse-keymap (km) | |
218 "Recursively copy the sparse keymap KM" | |
219 (cond ((consp km) | |
220 (cons (full-copy-sparse-keymap (car km)) | |
221 (full-copy-sparse-keymap (cdr km)))) | |
222 (t km))) | |
223 | |
224 (defun comint-check-proc (buffer-name) | |
225 "True if there is a process associated w/buffer BUFFER-NAME, and | |
226 it is alive (status RUN or STOP)." | |
227 (let ((proc (get-buffer-process buffer-name))) | |
228 (and proc (memq (process-status proc) '(run stop))))) | |
229 | |
230 ;;; Note that this guy, unlike shell.el's make-shell, barfs if you pass it () | |
231 ;;; for the second argument (program). | |
232 (defun make-comint (name program &optional startfile &rest switches) | |
233 (let* ((buffer (get-buffer-create (concat "*" name "*"))) | |
234 (proc (get-buffer-process buffer))) | |
235 ;; If no process, or nuked process, crank up a new one and put buffer in | |
236 ;; comint mode. Otherwise, leave buffer and existing process alone. | |
237 (cond ((or (not proc) (not (memq (process-status proc) '(run stop)))) | |
238 (comint-exec buffer name program startfile switches) | |
239 (save-excursion | |
240 (set-buffer buffer) | |
241 (comint-mode)))) ; Install local vars, mode, keymap, ... | |
242 buffer)) | |
243 | |
244 (defun comint-exec (buffer name command startfile switches) | |
245 "Fires up a process in buffer for comint modes. | |
246 Blasts any old process running in the buffer. Doesn't set the buffer mode. | |
247 You can use this to cheaply run a series of processes in the same comint | |
248 buffer." | |
249 (save-excursion | |
250 (set-buffer buffer) | |
251 (let ((proc (get-buffer-process buffer))) ; Blast any old process. | |
252 (if proc (delete-process proc))) | |
253 ;; Crank up a new process | |
254 (let ((proc (apply 'start-process name buffer (concat exec-directory "env") | |
255 (format "TERMCAP=emacs:co#%d:tc=unknown:" | |
256 (screen-width)) | |
257 "TERM=emacs" "EMACS=t" "-" command switches))) | |
258 ;; Feed it the startfile. | |
259 (cond (startfile | |
260 ;;This is guaranteed to wait long enough | |
261 ;;but has bad results if the comint does not prompt at all | |
262 ;; (while (= size (buffer-size)) | |
263 ;; (sleep-for 1)) | |
264 ;;I hope 1 second is enough! | |
265 (sleep-for 1) | |
266 (goto-char (point-max)) | |
267 (insert-file-contents startfile) | |
268 (setq startfile (buffer-substring (point) (point-max))) | |
269 (delete-region (point) (point-max)) | |
270 (process-send-string proc startfile))) | |
271 ;; Jump to the end, and set the process mark. | |
272 (goto-char (point-max)) | |
273 (set-marker (process-mark proc) (point))) | |
274 buffer)) | |
275 | |
276 | |
277 | |
278 ;;; Ring Code | |
279 ;;;============================================================================ | |
280 ;;; This code defines a ring data structure. A ring is a | |
281 ;;; (hd-index tl-index . vector) | |
282 ;;; list. You can insert to, remove from, and rotate a ring. When the ring | |
283 ;;; fills up, insertions cause the oldest elts to be quietly dropped. | |
284 ;;; | |
285 ;;; HEAD = index of the newest item on the ring. | |
286 ;;; TAIL = index of the oldest item on the ring. | |
287 ;;; | |
288 ;;; These functions are used by the input history mechanism, but they can | |
289 ;;; be used for other purposes as well. | |
290 | |
291 (defun ring-p (x) | |
292 "T if X is a ring; NIL otherwise." | |
293 (and (consp x) (integerp (car x)) | |
294 (consp (cdr x)) (integerp (car (cdr x))) | |
295 (vectorp (cdr (cdr x))))) | |
296 | |
297 (defun make-ring (size) | |
298 "Make a ring that can contain SIZE elts" | |
299 (cons 1 (cons 0 (make-vector (+ size 1) nil)))) | |
300 | |
301 (defun ring-plus1 (index veclen) | |
302 "INDEX+1, with wraparound" | |
303 (let ((new-index (+ index 1))) | |
304 (if (= new-index veclen) 0 new-index))) | |
305 | |
306 (defun ring-minus1 (index veclen) | |
307 "INDEX-1, with wraparound" | |
308 (- (if (= 0 index) veclen index) 1)) | |
309 | |
310 (defun ring-length (ring) | |
311 (let ((hd (car ring)) (tl (car (cdr ring))) (siz (length (cdr (cdr ring))))) | |
312 (let ((len (if (<= hd tl) (+ 1 (- tl hd)) (+ 1 tl (- siz hd))))) | |
313 (if (= len siz) 0 len)))) | |
314 | |
315 (defun ring-empty-p (ring) | |
316 (= 0 (ring-length ring))) | |
317 | |
318 (defun ring-insert (ring item) | |
319 "Insert a new item onto the ring. If the ring is full, dump the oldest | |
320 item to make room." | |
321 (let* ((vec (cdr (cdr ring))) (len (length vec)) | |
322 (new-hd (ring-minus1 (car ring) len))) | |
323 (setcar ring new-hd) | |
324 (aset vec new-hd item) | |
325 (if (ring-empty-p ring) ;overflow -- dump one off the tail. | |
326 (setcar (cdr ring) (ring-minus1 (car (cdr ring)) len))))) | |
327 | |
328 (defun ring-remove (ring) | |
329 "Remove the oldest item retained on the ring." | |
330 (if (ring-empty-p ring) (error "Ring empty") | |
331 (let ((tl (car (cdr ring))) (vec (cdr (cdr ring)))) | |
332 (set-car (cdr ring) (ring-minus1 tl (length vec))) | |
333 (aref vec tl)))) | |
334 | |
335 ;;; This isn't actually used in this package. I just threw it in in case | |
336 ;;; someone else wanted it. If you want rotating-ring behavior on your history | |
337 ;;; retrieval (analagous to kill ring behavior), this function is what you | |
338 ;;; need. I should write the yank-input and yank-pop-input-or-kill to go with | |
339 ;;; this, and not bind it to a key by default, so it would be available to | |
340 ;;; people who want to bind it to a key. But who would want it? Blech. | |
341 (defun ring-rotate (ring n) | |
342 (if (not (= n 0)) | |
343 (if (ring-empty-p ring) ;Is this the right error check? | |
344 (error "ring empty") | |
345 (let ((hd (car ring)) (tl (car (cdr ring))) (vec (cdr (cdr ring)))) | |
346 (let ((len (length vec))) | |
347 (while (> n 0) | |
348 (setq tl (ring-plus1 tl len)) | |
349 (aset ring tl (aref ring hd)) | |
350 (setq hd (ring-plus1 hd len)) | |
351 (setq n (- n 1))) | |
352 (while (< n 0) | |
353 (setq hd (ring-minus1 hd len)) | |
354 (aset vec hd (aref vec tl)) | |
355 (setq tl (ring-minus1 tl len)) | |
356 (setq n (- n 1)))) | |
357 (set-car ring hd) | |
358 (set-car (cdr ring) tl))))) | |
359 | |
360 (defun comint-mod (n m) | |
361 "Returns N mod M. M is positive. Answer is guaranteed to be non-negative, | |
362 and less than m." | |
363 (let ((n (% n m))) | |
364 (if (>= n 0) n | |
365 (+ n | |
366 (if (>= m 0) m (- m)))))) ; (abs m) | |
367 | |
368 (defun ring-ref (ring index) | |
369 (let ((numelts (ring-length ring))) | |
370 (if (= numelts 0) (error "indexed empty ring") | |
371 (let* ((hd (car ring)) (tl (car (cdr ring))) (vec (cdr (cdr ring))) | |
372 (index (comint-mod index numelts)) | |
373 (vec-index (comint-mod (+ index hd) | |
374 (length vec)))) | |
375 (aref vec vec-index))))) | |
376 | |
377 | |
378 ;;; Input history retrieval commands | |
379 ;;; M-p -- previous input M-n -- next input | |
380 ;;; C-c r -- previous input matching | |
381 ;;; =========================================================================== | |
382 | |
383 (defun comint-previous-input (arg) | |
384 "Cycle backwards through input history." | |
385 (interactive "*p") | |
386 (let ((len (ring-length input-ring))) | |
387 (cond ((<= len 0) | |
388 (message "Empty input ring") | |
389 (ding)) | |
390 ((not (comint-after-pmark-p)) | |
391 (message "Not after process mark") | |
392 (ding)) | |
393 (t | |
394 (cond ((eq last-command 'comint-previous-input) | |
395 (delete-region (mark) (point)) | |
396 (set-mark (point))) | |
397 (t | |
398 (setq input-ring-index | |
399 (if (> arg 0) -1 | |
400 (if (< arg 0) 1 0))) | |
401 (push-mark (point)))) | |
402 (setq input-ring-index (comint-mod (+ input-ring-index arg) len)) | |
403 (message "%d" (1+ input-ring-index)) | |
404 (insert (ring-ref input-ring input-ring-index)) | |
405 (setq this-command 'comint-previous-input)) | |
406 (t (ding))))) | |
407 | |
408 (defun comint-next-input (arg) | |
409 "Cycle forwards through input history." | |
410 (interactive "*p") | |
411 (comint-previous-input (- arg))) | |
412 | |
413 (defvar comint-last-input-match "" | |
414 "Last string searched for by comint input history search, for defaulting. | |
415 Buffer local variable.") | |
416 | |
417 (defun comint-previous-input-matching (str) | |
418 "Searches backwards through input history for substring match" | |
419 (interactive (let ((s (read-from-minibuffer | |
420 (format "Command substring (default %s): " | |
421 comint-last-input-match)))) | |
422 (list (if (string= s "") comint-last-input-match s)))) | |
423 ; (interactive "sCommand substring: ") | |
424 (setq comint-last-input-match str) ; update default | |
425 (let ((str (regexp-quote str)) | |
426 (len (ring-length input-ring)) | |
427 (n 0)) | |
428 (while (and (<= n len) (not (string-match str (ring-ref input-ring n)))) | |
429 (setq n (+ n 1))) | |
430 (cond ((<= n len) (comint-previous-input (+ n 1))) | |
431 (t (error "Not found."))))) | |
432 | |
433 ;;; These next three commands are alternatives to the input history commands -- | |
434 ;;; comint-next-input, comint-previous-input and | |
435 ;;; comint-previous-input-matching. They search through the process buffer | |
436 ;;; text looking for occurrences of the prompt. RMS likes them better; | |
437 ;;; I don't. Bound to M-P, M-N, and C-c R (uppercase P, N, and R) for | |
438 ;;; now. Try'em out. Go with what you like... | |
439 | |
440 ;;; comint-msearch-input-matching prompts for a string, not a regexp. | |
441 ;;; This could be considered to be the wrong thing. I decided to keep it | |
442 ;;; simple, and not make the user worry about regexps. This, of course, | |
443 ;;; limits functionality. | |
444 | |
445 (defun comint-psearch-input () | |
446 "Search forwards for next occurrence of prompt and skip to end of line. | |
447 \(prompt is anything matching regexp comint-prompt-regexp)" | |
448 (interactive) | |
449 (if (re-search-forward comint-prompt-regexp (point-max) t) | |
450 (end-of-line) | |
451 (error "No occurrence of prompt found"))) | |
452 | |
453 (defun comint-msearch-input () | |
454 "Search backwards for previous occurrence of prompt and skip to end of line. | |
455 Search starts from beginning of current line." | |
456 (interactive) | |
457 (let ((p (save-excursion | |
458 (beginning-of-line) | |
459 (cond ((re-search-backward comint-prompt-regexp (point-min) t) | |
460 (end-of-line) | |
461 (point)) | |
462 (t nil))))) | |
463 (if p (goto-char p) | |
464 (error "No occurrence of prompt found")))) | |
465 | |
466 (defun comint-msearch-input-matching (str) | |
467 "Search backwards for occurrence of prompt followed by STRING. | |
468 STRING is prompted for, and is NOT a regular expression." | |
469 (interactive (let ((s (read-from-minibuffer | |
470 (format "Command (default %s): " | |
471 comint-last-input-match)))) | |
472 (list (if (string= s "") comint-last-input-match s)))) | |
473 ; (interactive "sCommand: ") | |
474 (setq comint-last-input-match str) ; update default | |
475 (let* ((r (concat comint-prompt-regexp (regexp-quote str))) | |
476 (p (save-excursion | |
477 (beginning-of-line) | |
478 (cond ((re-search-backward r (point-min) t) | |
479 (end-of-line) | |
480 (point)) | |
481 (t nil))))) | |
482 (if p (goto-char p) | |
483 (error "No match")))) | |
484 | |
485 (defun comint-send-input () | |
486 "Send input to process. After the process output mark, sends all text | |
487 from the process mark to point as input to the process. Before the | |
488 process output mark, calls value of variable comint-get-old-input to retrieve | |
489 old input, copies it to the end of the buffer, and sends it. A terminal | |
490 newline is also inserted into the buffer and sent to the process. In either | |
491 case, value of variable comint-input-sentinel is called on the input before | |
492 sending it. The input is entered into the input history ring, if value of | |
493 variable comint-input-filter returns T when called on the input. | |
494 | |
495 comint-get-old-input, comint-input-sentinel, and comint-input-filter are chosen | |
496 according to the command interpreter running in the buffer. E.g., | |
497 If the interpreter is the csh, | |
498 comint-get-old-input is the default: take the current line, discard any | |
499 initial string matching regexp comint-prompt-regexp. | |
500 comint-input-sentinel monitors input for \"cd\", \"pushd\", and \"popd\" | |
501 commands. When it sees one, it cd's the buffer. | |
502 comint-input-filter is the default: returns T if the input isn't all white | |
503 space. | |
504 | |
505 If the comint is Lucid Common Lisp, | |
506 comint-get-old-input snarfs the sexp ending at point. | |
507 comint-input-sentinel does nothing. | |
508 comint-input-filter returns NIL if the input matches input-filter-regexp, | |
509 which matches (1) all whitespace (2) :a, :c, etc. | |
510 | |
511 Similarly for Soar, Scheme, etc.." | |
512 (interactive) | |
513 ;; Note that the input string does not include its terminal newline. | |
514 (let ((proc (get-buffer-process (current-buffer)))) | |
515 (if (not proc) (error "Current buffer has no process") | |
516 (let* ((pmark (process-mark proc)) | |
517 (pmark-val (marker-position pmark)) | |
518 (input (if (>= (point) pmark-val) | |
519 (buffer-substring pmark (point)) | |
520 (let ((copy (funcall comint-get-old-input))) | |
521 (goto-char pmark) | |
522 (insert copy) | |
523 copy)))) | |
524 (insert ?\n) | |
525 (if (funcall comint-input-filter input) (ring-insert input-ring input)) | |
526 (funcall comint-input-sentinel input) | |
527 (process-send-string proc input) | |
528 (process-send-string proc "\n") | |
529 (set-marker (process-mark proc) (point)) | |
530 (set-marker comint-last-input-end (point)))))) | |
531 | |
532 (defun comint-get-old-input-default () | |
533 "Default for comint-get-old-input: take the current line, and discard | |
534 any initial text matching comint-prompt-regexp." | |
535 (save-excursion | |
536 (beginning-of-line) | |
537 (comint-skip-prompt) | |
538 (let ((beg (point))) | |
539 (end-of-line) | |
540 (buffer-substring beg (point))))) | |
541 | |
542 (defun comint-skip-prompt () | |
543 "Skip past the text matching regexp comint-prompt-regexp. | |
544 If this takes us past the end of the current line, don't skip at all." | |
545 (let ((eol (save-excursion (end-of-line) (point)))) | |
546 (if (and (looking-at comint-prompt-regexp) | |
547 (<= (match-end 0) eol)) | |
548 (goto-char (match-end 0))))) | |
549 | |
550 | |
551 (defun comint-after-pmark-p () | |
552 "Is point after the process output marker?" | |
553 ;; Since output could come into the buffer after we looked at the point | |
554 ;; but before we looked at the process marker's value, we explicitly | |
555 ;; serialise. This is just because I don't know whether or not emacs | |
556 ;; services input during execution of lisp commands. | |
557 (let ((proc-pos (marker-position | |
558 (process-mark (get-buffer-process (current-buffer)))))) | |
559 (<= proc-pos (point)))) | |
560 | |
561 (defun comint-bol (arg) | |
562 "Goes to the beginning of line, then skips past the prompt, if any. | |
563 If a prefix argument is given (\\[universal-argument]), then no prompt skip | |
564 -- go straight to column 0. | |
565 | |
566 The prompt skip is done by skipping text matching the regular expression | |
567 comint-prompt-regexp, a buffer local variable. | |
568 | |
569 If you don't like this command, reset c-a to beginning-of-line | |
570 in your hook, comint-mode-hook." | |
571 (interactive "P") | |
572 (beginning-of-line) | |
573 (if (null arg) (comint-skip-prompt))) | |
574 | |
575 ;;; These two functions are for entering text you don't want echoed or | |
576 ;;; saved -- typically passwords to ftp, telnet, or somesuch. | |
577 ;;; Just enter m-x send-invisible and type in your line. | |
578 | |
579 (defun comint-read-noecho (prompt) | |
580 "Prompt the user with argument PROMPT. Read a single line of text | |
581 without echoing, and return it. Note that the keystrokes comprising | |
582 the text can still be recovered (temporarily) with \\[view-lossage]. This | |
583 may be a security bug for some applications." | |
584 (let ((echo-keystrokes 0) | |
585 (answ "") | |
586 tem) | |
587 (if (and (stringp prompt) (not (string= (message prompt) ""))) | |
588 (message prompt)) | |
589 (while (not(or (= (setq tem (read-char)) ?\^m) | |
590 (= tem ?\n))) | |
591 (setq answ (concat answ (char-to-string tem)))) | |
592 (message "") | |
593 answ)) | |
594 | |
595 (defun send-invisible (str) | |
596 "Read a string without echoing, and send it to the process running | |
597 in the current buffer. A new-line is additionally sent. String is not | |
598 saved on comint input history list. | |
599 Security bug: your string can still be temporarily recovered with | |
600 \\[view-lossage]." | |
601 ; (interactive (list (comint-read-noecho "Enter non-echoed text"))) | |
602 (interactive "P") ; Defeat snooping via C-x esc | |
603 (let ((proc (get-buffer-process (current-buffer)))) | |
604 (if (not proc) (error "Current buffer has no process") | |
605 (process-send-string proc | |
606 (if (stringp str) str | |
607 (comint-read-noecho "Enter non-echoed text"))) | |
608 (process-send-string proc "\n")))) | |
609 | |
610 ;;; Random input hackage | |
611 | |
612 (defun comint-kill-output () | |
613 "Kill all output from interpreter since last input." | |
614 (interactive) | |
615 (let ((pmark (process-mark (get-buffer-process (current-buffer))))) | |
616 (kill-region comint-last-input-end pmark) | |
617 (goto-char pmark) | |
618 (insert "*** output flushed ***\n") | |
619 (set-marker pmark (point)))) | |
620 | |
621 (defun comint-show-output () | |
622 "Display start of this batch of interpreter output at top of window. | |
623 Also put cursor there." | |
624 (interactive) | |
625 (goto-char comint-last-input-end) | |
626 (backward-char) | |
627 (beginning-of-line) | |
628 (set-window-start (selected-window) (point)) | |
629 (end-of-line)) | |
630 | |
631 (defun comint-interrupt-subjob () | |
632 "Interrupt the current subjob." | |
633 (interactive) | |
634 (interrupt-process nil t)) | |
635 | |
636 (defun comint-kill-subjob () | |
637 "Send kill signal to the current subjob." | |
638 (interactive) | |
639 (kill-process nil t)) | |
640 | |
641 (defun comint-quit-subjob () | |
642 "Send quit signal to the current subjob." | |
643 (interactive) | |
644 (quit-process nil t)) | |
645 | |
646 (defun comint-stop-subjob () | |
647 "Stop the current subjob. | |
648 WARNING: if there is no current subjob, you can end up suspending | |
649 the top-level process running in the buffer. If you accidentally do | |
650 this, use \\[comint-continue-subjob] to resume the process. (This | |
651 is not a problem with most shells, since they ignore this signal.)" | |
652 (interactive) | |
653 (stop-process nil t)) | |
654 | |
655 (defun comint-continue-subjob () | |
656 "Send CONT signal to process buffer's process group. | |
657 Useful if you accidentally suspend the top-level process." | |
658 (interactive) | |
659 (continue-process nil t)) | |
660 | |
661 (defun comint-kill-input () | |
662 "Kill all text from last stuff output by interpreter to point." | |
663 (interactive) | |
664 (let* ((pmark (process-mark (get-buffer-process (current-buffer)))) | |
665 (p-pos (marker-position pmark))) | |
666 (if (> (point) p-pos) | |
667 (kill-region pmark (point))))) | |
668 | |
669 (defun comint-delchar-or-maybe-eof (arg) | |
670 "Delete ARG characters forward, or send an EOF to lisp if at end of buffer." | |
671 (interactive "p") | |
672 (if (eobp) | |
673 (process-send-eof) | |
674 (delete-char arg))) | |
675 | |
676 | |
677 | |
678 | |
679 ;;; Support for source-file processing commands. | |
680 ;;;============================================================================ | |
681 ;;; Many command-interpreters (e.g., Lisp, Scheme, Soar) have | |
682 ;;; commands that process files of source text (e.g. loading or compiling | |
683 ;;; files). So the corresponding process-in-a-buffer modes have commands | |
684 ;;; for doing this (e.g., lisp-load-file). The functions below are useful | |
685 ;;; for defining these commands. | |
686 ;;; | |
687 ;;; Alas, these guys don't do exactly the right thing for Lisp, Scheme | |
688 ;;; and Soar, in that they don't know anything about file extensions. | |
689 ;;; So the compile/load interface gets the wrong default occasionally. | |
690 ;;; The load-file/compile-file default mechanism could be smarter -- it | |
691 ;;; doesn't know about the relationship between filename extensions and | |
692 ;;; whether the file is source or executable. If you compile foo.lisp | |
693 ;;; with compile-file, then the next load-file should use foo.bin for | |
694 ;;; the default, not foo.lisp. This is tricky to do right, particularly | |
695 ;;; because the extension for executable files varies so much (.o, .bin, | |
696 ;;; .lbin, .mo, .vo, .ao, ...). | |
697 | |
698 | |
699 ;;; COMINT-SOURCE-DEFAULT -- determines defaults for source-file processing | |
700 ;;; commands. | |
701 ;;; | |
702 ;;; COMINT-CHECK-SOURCE -- if FNAME is in a modified buffer, asks you if you | |
703 ;;; want to save the buffer before issuing any process requests to the command | |
704 ;;; interpreter. | |
705 ;;; | |
706 ;;; COMINT-GET-SOURCE -- used by the source-file processing commands to prompt | |
707 ;;; for the file to process. | |
708 | |
709 ;;; (COMINT-SOURCE-DEFAULT previous-dir/file source-modes) | |
710 ;;;============================================================================ | |
711 ;;; This function computes the defaults for the load-file and compile-file | |
712 ;;; commands for tea, soar, cmulisp, and cmuscheme modes. | |
713 ;;; | |
714 ;;; - PREVIOUS-DIR/FILE is a pair (directory . filename) from the last | |
715 ;;; source-file processing command. NIL if there hasn't been one yet. | |
716 ;;; - SOURCE-MODES is a list used to determine what buffers contain source | |
717 ;;; files: if the major mode of the buffer is in SOURCE-MODES, it's source. | |
718 ;;; Typically, (lisp-mode) or (scheme-mode). | |
719 ;;; | |
720 ;;; If the command is given in a file buffer whose major modes is in | |
721 ;;; SOURCE-MODES, then the the filename is the default file, and the | |
722 ;;; file's directory is the default directory. | |
723 ;;; | |
724 ;;; If the buffer isn't a source file buffer (e.g., it's the process buffer), | |
725 ;;; then the default directory & file are what was used in the last source-file | |
726 ;;; processing command (i.e., PREVIOUS-DIR/FILE). If this is the first time | |
727 ;;; the command has been run (PREVIOUS-DIR/FILE is nil), the default directory | |
728 ;;; is the cwd, with no default file. (\"no default file\" = nil) | |
729 ;;; | |
730 ;;; SOURCE-REGEXP is typically going to be something like (tea-mode) | |
731 ;;; for T programs, (lisp-mode) for Lisp programs, (soar-mode lisp-mode) | |
732 ;;; for Soar programs, etc. | |
733 ;;; | |
734 ;;; The function returns a pair: (default-directory . default-file). | |
735 | |
736 (defun comint-source-default (previous-dir/file source-modes) | |
737 (cond ((and buffer-file-name (memq major-mode source-modes)) | |
738 (cons (file-name-directory buffer-file-name) | |
739 (file-name-nondirectory buffer-file-name))) | |
740 (previous-dir/file) | |
741 (t | |
742 (cons default-directory nil)))) | |
743 | |
744 | |
745 ;;; (COMINT-CHECK-SOURCE fname) | |
746 ;;;============================================================================ | |
747 ;;; Prior to loading or compiling (or otherwise processing) a file (in the CMU | |
748 ;;; process-in-a-buffer modes), this function can be called on the filename. | |
749 ;;; If the file is loaded into a buffer, and the buffer is modified, the user | |
750 ;;; is queried to see if he wants to save the buffer before proceeding with | |
751 ;;; the load or compile. | |
752 | |
753 (defun comint-check-source (fname) | |
754 (let ((buff (get-file-buffer fname))) | |
755 (if (and buff | |
756 (buffer-modified-p buff) | |
757 (y-or-n-p (format "Save buffer %s first? " | |
758 (buffer-name buff)))) | |
759 ;; save BUFF. | |
760 (let ((old-buffer (current-buffer))) | |
761 (set-buffer buff) | |
762 (save-buffer) | |
763 (set-buffer old-buffer))))) | |
764 | |
765 | |
766 ;;; (COMINT-GET-SOURCE prompt prev-dir/file source-modes mustmatch-p) | |
767 ;;;============================================================================ | |
768 ;;; COMINT-GET-SOURCE is used to prompt for filenames in command-interpreter | |
769 ;;; commands that process source files (like loading or compiling a file). | |
770 ;;; It prompts for the filename, provides a default, if there is one, | |
771 ;;; and returns the result filename. | |
772 ;;; | |
773 ;;; See COMINT-SOURCE-DEFAULT for more on determining defaults. | |
774 ;;; | |
775 ;;; PROMPT is the prompt string. PREV-DIR/FILE is the (directory . file) pair | |
776 ;;; from the last source processing command. SOURCE-MODES is a list of major | |
777 ;;; modes used to determine what file buffers contain source files. (These | |
778 ;;; two arguments are used for determining defaults). If MUSTMATCH-P is true, | |
779 ;;; then the filename reader will only accept a file that exists. | |
780 ;;; | |
781 ;;; A typical use: | |
782 ;;; (interactive (comint-get-source "Compile file: " prev-lisp-dir/file | |
783 ;;; "\\.lisp\\'" t)) | |
784 | |
785 (defun comint-get-source (prompt prev-dir/file source-regexp mustmatch-p) | |
786 (let* ((def (comint-source-default prev-dir/file source-regexp)) | |
787 (defdir (car def)) | |
788 (deffile (cdr def)) | |
789 (ans (read-file-name (if deffile (format "%s(default %s) " | |
790 prompt deffile) | |
791 prompt) | |
792 defdir | |
793 (concat defdir deffile) | |
794 mustmatch-p))) | |
795 (list (expand-file-name (substitute-in-file-name ans))))) | |
796 | |
797 | |
798 ;;; Filename completion in a buffer | |
799 ;;; =========================================================================== | |
800 ;;; Useful completion functions, courtesy of the Ergo group. | |
801 ;;; M-<Tab> will complete the filename at the cursor as much as possible | |
802 ;;; M-? will display a list of completions in the help buffer. | |
803 | |
804 ;;; Three commands: | |
805 ;;; comint-dynamic-complete Complete filename at point. | |
806 ;;; comint-dynamic-list-completions List completions in help buffer. | |
807 ;;; comint-replace-by-expanded-filename Expand and complete filename at point; | |
808 ;;; replace with expanded/completed name. | |
809 | |
810 ;;; These are not installed in the comint-mode keymap. But they are | |
811 ;;; available for people who want them. Shell-mode installs them: | |
812 ;;; (define-key cmushell-mode-map "\M-\t" 'comint-dynamic-complete) | |
813 ;;; (define-key cmushell-mode-map "\M-?" 'comint-dynamic-list-completions))) | |
814 ;;; | |
815 ;;; Commands like this are fine things to put in load hooks if you | |
816 ;;; want them present in specific modes. Example: | |
817 ;;; (setq cmushell-load-hook | |
818 ;;; '((lambda () (define-key lisp-mode-map "\M-\t" | |
819 ;;; 'comint-replace-by-expanded-filename)))) | |
820 ;;; | |
821 | |
822 | |
823 (defun comint-match-partial-pathname () | |
824 "Returns the string of an existing filename or causes and error." | |
825 (if (save-excursion (backward-char 1) (looking-at "\\s ")) "" | |
826 (save-excursion | |
827 (re-search-backward "[^~/A-Za-z0-9---_.$#,]+") | |
828 (re-search-forward "[~/A-Za-z0-9---_.$#,]+") | |
829 (substitute-in-file-name | |
830 (buffer-substring (match-beginning 0) (match-end 0)))))) | |
831 | |
832 (defun comint-replace-by-expanded-filename () | |
833 "Replace filename at point with expanded, completed name" | |
834 (interactive) | |
835 (let* ((pathname (comint-match-partial-pathname)) | |
836 (pathdir (file-name-directory pathname)) | |
837 (pathnondir (file-name-nondirectory pathname)) | |
838 (completion (file-name-completion pathnondir | |
839 (or pathdir default-directory)))) | |
840 (cond ((null completion) | |
841 (message "No completions of %s." pathname) | |
842 (ding)) | |
843 ((eql completion t) | |
844 (message "Unique completion.")) | |
845 (t ; this means a string was returned. | |
846 (delete-region (match-beginning 0) (match-end 0)) | |
847 (insert pathdir completion))))) | |
848 | |
849 (defun comint-dynamic-complete () | |
850 "Dynamically complete the filename at point." | |
851 (interactive) | |
852 (let* ((pathname (comint-match-partial-pathname)) | |
853 (pathdir (file-name-directory pathname)) | |
854 (pathnondir (file-name-nondirectory pathname)) | |
855 (completion (file-name-completion pathnondir | |
856 (or pathdir default-directory)))) | |
857 (cond ((null completion) | |
858 (message "No completions of %s." pathname) | |
859 (ding)) | |
860 ((eql completion t) | |
861 (message "Unique completion.")) | |
862 (t ; this means a string was returned. | |
863 (insert (substring completion (length pathnondir))))))) | |
864 | |
865 (defun comint-dynamic-list-completions () | |
866 "List in help buffer all possible completions of the filename at point." | |
867 (interactive) | |
868 (let* ((pathname (comint-match-partial-pathname)) | |
869 (pathdir (file-name-directory pathname)) | |
870 (pathnondir (file-name-nondirectory pathname)) | |
871 (completions | |
872 (file-name-all-completions pathnondir | |
873 (or pathdir default-directory)))) | |
874 (cond ((null completions) | |
875 (message "No completions of %s." pathname) | |
876 (ding)) | |
877 (t (with-output-to-temp-buffer "*Help*" | |
878 (display-completion-list completions)))))) | |
879 | |
880 ; Ergo bindings | |
881 ; (global-set-key "\M-\t" 'comint-replace-by-expanded-filename) | |
882 ; (global-set-key "\M-?" 'comint-dynamic-list-completions) | |
883 ; (define-key shell-mode-map "\M-\t" 'comint-dynamic-complete) | |
884 | |
885 ;;; Log the user, so I know who's using the package during the beta test | |
886 ;;; period. This just inserts the user's name and current time into a | |
887 ;;; central file. | |
888 (defun comint-log-user () | |
889 (interactive) | |
890 (if (file-writable-p "/afs/cs/user/shivers/lib/emacs/logdir/comint.log") | |
891 (let ((u (getenv "USER")) | |
892 (old-buff (current-buffer))) | |
893 (message "logging user in beta test database...") | |
894 (find-file "/afs/cs/user/shivers/lib/emacs/logdir/comint.log") | |
895 (cond ((search-forward u nil 'to-end) | |
896 (search-forward "| ") | |
897 (kill-line 1)) | |
898 (t (insert (format "%s\t%s\t| " u (current-time-string))))) | |
899 (insert (format "%s\n" (current-time-string))) | |
900 (let ((make-backup-files nil)) (save-buffer)) | |
901 (kill-buffer (current-buffer)) | |
902 (set-buffer old-buff)))) | |
903 (comint-log-user) | |
904 | |
905 | |
906 ;;; Converting process modes to use comint mode | |
907 ;;; =========================================================================== | |
908 ;;; Several gnu packages (tex-mode, background, dbx, gdb, kermit, prolog, | |
909 ;;; telnet are some) use the shell package as clients. Most of them would | |
910 ;;; be better off using the comint package, but they predate it. | |
911 ;;; | |
912 ;;; Altering these packages to use comint mode should greatly | |
913 ;;; improve their functionality, and is fairly easy. | |
914 ;;; | |
915 ;;; Renaming variables | |
916 ;;; Most of the work is renaming variables and functions. These are the common | |
917 ;;; ones: | |
918 ;;; Local variables: | |
919 ;;; last-input-end comint-last-input-end | |
920 ;;; last-input-start <unnecessary> | |
921 ;;; shell-prompt-pattern comint-prompt-regexp | |
922 ;;; shell-set-directory-error-hook <no equivalent> | |
923 ;;; Miscellaneous: | |
924 ;;; shell-set-directory <unnecessary> | |
925 ;;; shell-mode-map comint-mode-map | |
926 ;;; Commands: | |
927 ;;; shell-send-input comint-send-input | |
928 ;;; shell-send-eof comint-delchar-or-maybe-eof | |
929 ;;; kill-shell-input comint-kill-input | |
930 ;;; interrupt-shell-subjob comint-interrupt-subjob | |
931 ;;; stop-shell-subjob comint-stop-subjob | |
932 ;;; quit-shell-subjob comint-quit-subjob | |
933 ;;; kill-shell-subjob comint-kill-subjob | |
934 ;;; kill-output-from-shell comint-kill-output | |
935 ;;; show-output-from-shell comint-show-output | |
936 ;;; copy-last-shell-input Use comint-previous-input/comint-next-input | |
937 ;;; | |
938 ;;; LAST-INPUT-START is no longer necessary because inputs are stored on the | |
939 ;;; input history ring. SHELL-SET-DIRECTORY is gone, its functionality taken | |
940 ;;; over by SHELL-DIRECTORY-TRACKER, the shell mode's comint-input-sentinel. | |
941 ;;; Comint mode does not provide functionality equivalent to | |
942 ;;; shell-set-directory-error-hook; it is gone. | |
943 ;;; | |
944 ;;; If you are implementing some process-in-a-buffer mode, called foo-mode, do | |
945 ;;; *not* create the comint-mode local variables in your foo-mode function. | |
946 ;;; This is not modular. Instead, call comint-mode, and let *it* create the | |
947 ;;; necessary comint-specific local variables. Then create the | |
948 ;;; foo-mode-specific local variables in foo-mode. Set the buffer's keymap to | |
949 ;;; be foo-mode-map, and it's mode to be foo-mode. Set the comint-mode hooks | |
950 ;;; (comint-prompt-regexp, comint-input-filter, comint-input-sentinel, | |
951 ;;; comint-get-old-input) that need to be different from the defaults. Call | |
952 ;;; foo-mode-hook, and you're done. Don't run the comint-mode hook yourself; | |
953 ;;; comint-mode will take care of it. The following example, from cmushell.el, | |
954 ;;; is typical: | |
955 ;;; | |
956 ;;; (defun shell-mode () | |
957 ;;; (interactive) | |
958 ;;; (comint-mode) | |
959 ;;; (setq comint-prompt-regexp shell-prompt-pattern) | |
960 ;;; (setq major-mode 'shell-mode) | |
961 ;;; (setq mode-name "Shell") | |
962 ;;; (cond ((not shell-mode-map) | |
963 ;;; (setq shell-mode-map (full-copy-sparse-keymap comint-mode-map)) | |
964 ;;; (define-key shell-mode-map "\M-\t" 'comint-dynamic-complete) | |
965 ;;; (define-key shell-mode-map "\M-?" | |
966 ;;; 'comint-dynamic-list-completions))) | |
967 ;;; (use-local-map shell-mode-map) | |
968 ;;; (make-local-variable 'shell-directory-stack) | |
969 ;;; (setq shell-directory-stack nil) | |
970 ;;; (setq comint-input-sentinel 'shell-directory-tracker) | |
971 ;;; (run-hooks 'shell-mode-hook)) | |
972 ;;; | |
973 ;;; | |
974 ;;; Note that make-comint is different from make-shell in that it | |
975 ;;; doesn't have a default program argument. If you give make-shell | |
976 ;;; a program name of NIL, it cleverly chooses one of explicit-shell-name, | |
977 ;;; $ESHELL, $SHELL, or /bin/sh. If you give make-comint a program argument | |
978 ;;; of NIL, it barfs. Adjust your code accordingly... | |
979 ;;; | |
980 | |
981 ;;; Do the user's customisation... | |
982 | |
983 (defvar comint-load-hook nil | |
984 "This hook is run when comint is loaded in. | |
985 This is a good place to put keybindings.") | |
986 | |
987 (run-hooks 'comint-load-hook) |