|
|
1.1 root 1: ;;
2: ;; copyright (C) 1987, 1988 Franz Inc, Berkeley, Ca.
3: ;;
4: ;; The software, data and information contained herein are the property
5: ;; of Franz, Inc.
6: ;;
7: ;; This file (or any derivation of it) may be distributed without
8: ;; further permission from Franz Inc. as long as:
9: ;;
10: ;; * it is not part of a product for sale,
11: ;; * no charge is made for the distribution, other than a tape
12: ;; fee, and
13: ;; * all copyright notices and this notice are preserved.
14: ;;
15: ;; If you have any comments or questions on this interface, please feel
16: ;; free to contact Franz Inc. at
17: ;; Franz Inc.
18: ;; Attn: Kevin Layer
19: ;; 1995 University Ave
20: ;; Suite 275
21: ;; Berkeley, CA 94704
22: ;; (415) 548-3600
23: ;; or
24: ;; emacs-info%[email protected]
25: ;; ucbvax!franz!emacs-info
26:
27: ;; $Header: keys.el,v 1.19 89/02/14 17:17:52 layer Exp $
28:
29: ;;;;
30: ;;; Key defs
31: ;;;;
32:
33: (defun fi::subprocess-mode-super-keys (map mode)
34: "Setup keys in MAP as a subprocess super-key map. MODE is either
35: shell, rlogin, sub-lisp or tcp-lisp."
36: (define-key map "\C-a" 'fi:subprocess-beginning-of-line)
37: (define-key map "\C-k" 'fi:subprocess-kill-output)
38: (define-key map "\C-l" 'fi:list-input-ring)
39: (define-key map "\C-m" 'fi:subprocess-input-region)
40: (define-key map "\C-n" 'fi:push-input)
41: (define-key map "\C-o" 'fi:subprocess-send-flush)
42: (define-key map "\C-p" 'fi:pop-input)
43: (define-key map "\C-r" 'fi:re-search-backward-input)
44: (define-key map "\C-s" 'fi:re-search-forward-input)
45: (define-key map "\C-u" 'fi:subprocess-kill-input)
46: (define-key map "\C-v" 'fi:subprocess-show-output)
47: (define-key map "\C-w" 'fi:subprocess-backward-kill-word)
48:
49: (cond
50: ((memq mode '(sub-lisp shell))
51: (if (eq mode 'shell)
52: (define-key map "\C-z" 'fi:subprocess-suspend))
53: (define-key map "\C-c" 'fi:subprocess-interrupt)
54: (define-key map "\C-d" 'fi:subprocess-send-eof)
55: (define-key map "\C-\\" 'fi:subprocess-quit))
56: ((eq mode 'tcp-lisp)
57: (define-key map "\C-c" 'fi:tcp-lisp-interrupt-process)
58: (define-key map "\C-d" 'fi:tcp-lisp-send-eof)
59: (define-key map "\C-\\" 'fi:tcp-lisp-kill-process)))
60: map)
61:
62: (defun fi::subprocess-mode-commands (map supermap mode)
63: "Define subprocess mode commands on MAP, using SUPERMAP as the supermap.
64: MODE is either sub-lisp, tcp-lisp, shell or rlogin."
65: (define-key map "\C-m" 'fi:subprocess-send-input)
66: (if fi:subprocess-enable-superkeys
67: (progn
68: (define-key map "\C-a" 'fi:subprocess-superkey)
69: ;; \C-c points to supermap
70: (define-key map "\C-d" 'fi:subprocess-superkey)
71: (define-key map "\C-o" 'fi:subprocess-superkey)
72: (define-key map "\C-u" 'fi:subprocess-superkey)
73: (define-key map "\C-w" 'fi:subprocess-superkey)
74: (define-key map "\C-z" 'fi:subprocess-superkey)
75: (define-key map "\C-\\" 'fi:subprocess-superkey)))
76: (if supermap (define-key map "\C-c" supermap))
77: map)
78:
79: (defun fi::lisp-mode-commands (map supermap mode)
80: (define-key map "\e" (make-sparse-keymap))
81: (define-key map "\C-x" (make-sparse-keymap))
82:
83: (if supermap (define-key map "\C-c" supermap))
84:
85: (define-key map "\t" 'lisp-indent-line)
86: (define-key map "\e\C-q" 'indent-sexp)
87: (define-key map "\C-?" 'backward-delete-char-untabify)
88:
89: (cond
90: ((memq mode '(sub-lisp tcp-lisp))
91: (define-key map "\r" 'fi:inferior-lisp-newline)
92: (define-key map "\e\r" 'fi:inferior-lisp-input-sexp)
93: (define-key map "\C-x\r" 'fi:inferior-lisp-input-list))
94: (t (define-key map "\r" 'fi:lisp-reindent-newline-indent)))
95:
96: (cond
97: ((memq major-mode '(fi:common-lisp-mode fi:inferior-common-lisp-mode
98: fi:tcp-common-lisp-mode))
99: (define-key map "\e." 'fi:lisp-find-tag)
100: (define-key map "\e," 'fi:lisp-tags-loop-continue)
101: (define-key map "\e\t" 'fi:lisp-complete-symbol)
102: (define-key map "\eA" 'fi:lisp-arglist)
103: (define-key map "\eC" 'fi:lisp-who-calls)
104: (define-key map "\eD" 'fi:lisp-describe)
105: (define-key map "\eF" 'fi:lisp-function-documentation)
106: (define-key map "\eM" 'fi:lisp-macroexpand)
107: (define-key map "\eW" 'fi:lisp-walk)))
108: (cond
109: ((eq major-mode 'fi:emacs-lisp-mode)
110: (define-key map "\e\C-x" 'eval-defun))
111: ((memq major-mode '(fi:common-lisp-mode fi:franz-lisp-mode
112: fi:lisp-mode))
113: (define-key map "\e\C-x" 'fi:lisp-eval-defun)
114: (define-key map "\C-c\C-b" 'fi:lisp-eval-current-buffer)
115: (define-key map "\C-c\C-s" 'fi:lisp-eval-last-sexp)
116: (define-key map "\C-c\C-r" 'fi:lisp-eval-region)))
117: map)
118:
119: (defun fi::tcp-common-lisp-mode-commands (map supermap)
120: (fi::lisp-mode-commands (fi::subprocess-mode-commands map supermap 'tcp-lisp)
121: supermap
122: 'tcp-lisp))
123:
124: (defun fi::inferior-lisp-mode-commands (map supermap)
125: (fi::lisp-mode-commands (fi::subprocess-mode-commands map supermap 'sub-lisp)
126: supermap
127: 'sub-lisp))
128:
129: ;;;;;;;;;;;;;;;;;;;;; inferior lisp mode related functions
130:
131: (defun fi:lisp-reindent-newline-indent ()
132: "Indent the current line, insert a newline and indent to the proper
133: column."
134: (interactive)
135: (save-excursion (funcall indent-line-function))
136: (newline)
137: (funcall indent-line-function))
138:
139: (defun fi:inferior-lisp-newline ()
140: "Bound to RET in an inferior Lisp buffer. At the end of the buffer it
141: inserts a newline and performs automatic indentation. Whole expressions
142: are sent to Lisp (not each piece after each newline is typed). This allows
143: previously typed lines to be edited before Lisp is sent the input. Typed
144: anywhere else in the buffer, this functions causes the input previously
145: typed (around the point) to be copied to the end of the subprocess buffer
146: and send to Lisp."
147: (interactive)
148: (if (eobp)
149: (let ((start (marker-position
150: (process-mark (get-buffer-process (current-buffer)))))
151: (have-list nil))
152: (save-excursion
153: (goto-char start)
154: (if (looking-at "(") (setq have-list t)))
155: (if have-list
156: (let ((send-sexp t))
157: (goto-char start)
158: (condition-case nil
159: (forward-sexp 1)
160: (error (setq send-sexp nil)))
161: (end-of-buffer)
162: (if send-sexp
163: (fi:subprocess-send-input)
164: ;; not a complete sexp, so newline and indent
165: (progn
166: (newline)
167: (funcall indent-line-function))))
168: ;; a non-list s-exp, so just send it off...
169: (fi:subprocess-send-input)))
170: ;;NOT AT THE END OF THE BUFFER!
171: ;; find the user's input contained around the cursor and send that to
172: ;; the inferior lisp
173: (let ((start-of-last-prompt
174: (save-excursion
175: (or (and (re-search-backward subprocess-prompt-pattern nil t)
176: (point))
177: (point-max))))
178: start end)
179: (if (or (and (bolp) (looking-at "("))
180: (re-search-backward "^(" start-of-last-prompt t)
181: (prog1 (re-search-backward subprocess-prompt-pattern nil t)
182: (goto-char (match-end 0))))
183: (progn
184: (setq start (point))
185: (let* ((eol (save-excursion (end-of-line) (point)))
186: (state (save-excursion (parse-partial-sexp start eol)))
187: (depth (car state)))
188: (if (zerop depth)
189: (setq end eol)
190: (setq end
191: (condition-case ()
192: (save-excursion
193: (if (< depth 0)
194: (up-list (- depth))
195: (goto-char eol)
196: (up-list depth))
197: (point))
198: (error nil))))
199:
200: (if (or (null end) (= end (point-max)))
201: (progn
202: (goto-char (point-max))
203: (fi:inferior-lisp-newline))
204: (fi:subprocess-input-region start end))))
205: (error "couldn't find start of input")))))
206:
207: (defun fi:subprocess-input-region (start end)
208: "Send the region defined by the point and mark to the Lisp subprocess."
209: (interactive "r")
210: (let* ((process (get-buffer-process (current-buffer)))
211: (string (buffer-substring start end)))
212: (goto-char (point-max))
213: (setq start (point))
214: (move-marker fi::last-input-start (point))
215: (insert string)
216: (if (not (bolp)) (insert "\n"))
217: (setq end (point))
218: (move-marker fi::last-input-end (point))
219: (fi::send-region-split process start end fi:subprocess-map-nl-to-cr)
220: (fi::input-ring-save fi::last-input-start (1- fi::last-input-end))
221: (set-marker (process-mark process) (point))))
222:
223: (defun fi:inferior-lisp-input-sexp (&optional arg)
224: "Send the sexp on which the point resides to the Lisp subprocess. With a
225: numeric prefix argument, send that many sexps."
226: (interactive "P")
227: (fi:inferior-lisp-send-input arg 'sexp))
228:
229: (defun fi:inferior-lisp-input-list (&optional arg)
230: "Send the list before the point to the Lisp subprocess. With a numeric
231: prefix argument, send that many lists."
232: (interactive "P")
233: (fi:inferior-lisp-send-input arg 'lists))
234:
235: (defun fi:lisp-eval-last-sexp (compile-file-p)
236: "Send the sexp before the point to the Lisp subprocess associated with
237: this buffer. If a Lisp subprocess has not been started, then one is
238: started. With a prefix argument, the source sent to the subprocess is
239: compiled."
240: (interactive "P")
241: (let ((start (save-excursion
242: (forward-sexp -1)
243: (point))))
244: (fi::eval-send start (point) compile-file-p)))
245:
246: (defun fi:lisp-eval-defun (compile-file-p)
247: "Send the current top-level (or nearest previous) form to the Lisp
248: subprocess associated with this buffer. A `top-level' form is one that
249: starts in column 1. If a Lisp subprocess has not been started, then one is
250: started. With a prefix argument, the source sent to the subprocess is
251: compiled."
252: (interactive "P")
253: (let* ((end (save-excursion (end-of-defun) (point)))
254: (start (save-excursion
255: (beginning-of-defun)
256: (point))))
257: (fi::eval-send start end compile-file-p)))
258:
259: (defun fi:lisp-eval-region (compile-file-p)
260: "Send the text in the region to the Lisp subprocess associated with this
261: buffer, one expression at a time if there is more than one complete
262: expression. If a Lisp subprocess has not been started, then one is
263: started. With a prefix argument, the source sent to the subprocess is
264: compiled."
265: (interactive "P")
266: (fi::eval-send (min (point) (mark))
267: (max (point) (mark))
268: compile-file-p))
269:
270: (defun fi:lisp-eval-current-buffer (compile-file-p)
271: "Send the entire buffer to the Lisp subprocess associated with this
272: buffer. If a Lisp subprocess has not been started, then one is started.
273: With a prefix argument, the source sent to the subprocess is compiled."
274: (interactive "P")
275: (fi::eval-send (point-min) (point-max) compile-file-p))
276:
277:
278: ;;;;;;;;;;;;;;;;;;;;; TCP lisp mode related functions
279:
280: (defun fi::get-default-symbol (prompt &optional up-p)
281: (let* ((symbol-at-point
282: (condition-case ()
283: (save-excursion
284: (if up-p
285: (progn
286: (if (= (following-char) ?\() (forward-char 1))
287: (if (= (preceding-char) ?\)) (forward-char -1))
288: (up-list -1)
289: (forward-char 1)))
290: (while (looking-at "\\sw\\|\\s_")
291: (forward-char 1))
292: (if (re-search-backward "\\sw\\|\\s_" nil t)
293: (progn (forward-char 1)
294: (buffer-substring
295: (point)
296: (progn (forward-sexp -1)
297: (while (looking-at "\\s'")
298: (forward-char 1))
299: (point))))
300: nil))
301: (error nil)))
302: (read-symbol
303: (read-string
304: (if symbol-at-point
305: (format "%s: (default %s) " prompt symbol-at-point)
306: (format "%s: " prompt))))
307: (symbol (if (string= read-symbol "")
308: symbol-at-point
309: read-symbol))
310: (colonp (string-match ":?:" symbol nil)))
311: (if (and (not colonp) fi:package)
312: (setq symbol (format "%s::%s" fi:package symbol)))
313: (list symbol)))
314:
315: (defun fi:lisp-find-tag (tag &optional next)
316: "Find the Common Lisp source for a symbol, using the characters around
317: the point as the default tag."
318: (interactive (if current-prefix-arg
319: '(nil t)
320: (fi::get-default-symbol "Lisp locate source")))
321: (fi::lisp-find-tag-common tag next nil))
322:
323: (defun fi:lisp-find-tag-other-window (tag &optional next)
324: "Find the Common Lisp source for a symbol, using the characters around
325: the point as the default tag."
326: (interactive (if current-prefix-arg
327: '(nil t)
328: (fi::get-default-symbol "Lisp locate source other window")))
329: (fi::lisp-find-tag-common tag next t))
330:
331: (defun fi:lisp-tags-loop-continue ()
332: "Find the next occurrence of the tag last used by fi:lisp-find-tag."
333: (interactive)
334: (fi:lisp-tags-loop-continue-common))
335:
336: (defun fi:lisp-arglist (symbol)
337: "Print the arglist (using excl:arglist) for a symbol, which is read from
338: the minibuffer. The word around the point is used as the default."
339: (interactive (fi::get-default-symbol "Function" t))
340: (let ((string
341: (format "(progn
342: (format t \"~:[()~;~:*~{~a~^ ~}~]\"
343: (cond
344: ((macro-function '%s) '(\"%s is a macro\"))
345: ((special-form-p '%s) '(\"%s is a special form\"))
346: ((not (fboundp '%s)) '(\"%s has no function binding\"))
347: (t (excl::arglist '%s))))
348: (values))\n"
349: symbol symbol symbol symbol symbol symbol symbol)))
350: (if (fi::background-sublisp-process)
351: (process-send-string fi::backdoor-process string)
352: (fi::eval-string-send string nil t))))
353:
354: (defun fi:lisp-describe (symbol)
355: "Describe a symbol, which is read from the minibuffer. The word around
356: the point is used as the default."
357: (interactive (fi::get-default-symbol "Describe symbol"))
358: (let ((string (format "(progn (lisp:describe '%s) (values))\n" symbol)))
359: (if (fi::background-sublisp-process)
360: (process-send-string fi::backdoor-process string)
361: (fi::eval-string-send string nil t))))
362:
363: (defun fi:lisp-function-documentation (symbol)
364: "Print the function documentation for a symbol, which is read from the
365: minibuffer. The word around the point is used as the default."
366: (interactive
367: (fi::get-default-symbol "Function documentation for symbol"))
368: (let ((string (format "(princ (lisp:documentation '%s 'lisp:function))\n"
369: symbol)))
370: (if (fi::background-sublisp-process)
371: (process-send-string fi::backdoor-process string)
372: (fi::eval-string-send string nil t))))
373:
374: (defun fi:lisp-macroexpand ()
375: "Print the macroexpansion of the form at the point."
376: (interactive)
377: (fi::lisp-macroexpand-common "lisp:macroexpand" "macroexpand"))
378:
379: (defun fi:lisp-walk (arg)
380: "Print the full macroexpansion the form at the point.
381: With a prefix argument, macroexpand the code as the compiler would."
382: (interactive "P")
383: (fi::lisp-macroexpand-common
384: (if arg "excl::compiler-walk" "excl::walk")
385: "walk"))
386:
387: (defun fi::lisp-macroexpand-common (handler type)
388: (let* ((start (condition-case ()
389: (fi::find-other-end-of-list)
390: (error nil)))
391: (filename (format "%s/%s,mexp" fi:emacs-to-lisp-transaction-directory
392: (user-login-name)))
393: (string
394: (format fi::lisp-macroexpand-command
395: (if (and (boundp 'fi:package) fi:package)
396: (format "(or (find-package :%s) (make-package :%s))"
397: fi:package fi:package)
398: "*package*")
399: filename
400: handler)))
401: (if start
402: (write-region start (point) filename nil 'nomessage)
403: (let ((form (read-string (format "form to %s: " type)))
404: (obuf (current-buffer))
405: (tbuf (get-buffer-create "*cl-macroexpand-temp*")))
406: (set-buffer tbuf)
407: (erase-buffer)
408: (insert form)
409: (write-region (point-min) (point-max) filename nil 'nomessage)
410: (set-buffer obuf)))
411: (if (fi::background-sublisp-process)
412: (process-send-string fi::backdoor-process string)
413: (fi::eval-string-send string nil t))))
414:
415: (defun fi:lisp-who-calls (&optional symbol)
416: "Print all the callers of a function. The default symbol name is taken
417: from the sexp around the point."
418: (interactive (fi::get-default-symbol "Find references to symbol"))
419: ;; Since this takes a while, tell the user that it has started.
420: (message "finding callers of %s..." symbol)
421: (let ((string (format
422: "(progn (excl::who-references '%s) (values))\n" symbol)))
423: (if (fi::background-sublisp-process)
424: (process-send-string fi::backdoor-process string)
425: (fi::eval-string-send string nil t))))
426:
427: (defun fi:lisp-complete-symbol ()
428: "Perform completion on the Common Lisp symbol preceding the point. That
429: symbol is compared to symbols that exist in the Common Lisp, to which there
430: is a TCP/IP connection (see fi:eval-in-lisp). If the symbol starts just
431: after an open-parenthesis, then only symbols (in the Common Lisp) with
432: function defintions are considered. Otherwise all symbols are considered."
433: (interactive)
434: (let* ((end (point))
435: package real-beg
436: (beg (save-excursion
437: (backward-sexp 1)
438: (while (= (char-syntax (following-char)) ?\')
439: (forward-char 1))
440: (setq real-beg (point))
441: (let ((opoint (point)))
442: (if (re-search-forward ":?:" end t)
443: (setq package
444: (concat
445: ":" (buffer-substring opoint (match-beginning 0))))))
446: (point)))
447: (pattern (buffer-substring beg end))
448: (functions-only (if (eq (char-after (1- real-beg)) ?\() t nil))
449: (completions
450: (progn
451: ;; first, go into that package
452: (if (null (fi:eval-in-lisp "(packagep (in-package :%s))"
453: (or fi:package "user")))
454: (error "subprocess is in unknown package: %s" fi:package))
455: ;; then evaluate our expr
456: (fi:eval-in-lisp "(excl::list-all-completions \"%s\" %s %s)"
457: pattern package functions-only)))
458: (alist
459: (if (consp completions)
460: (apply 'list
461: (mapcar
462: (function
463: (lambda (x)
464: (let* ((whole-name (symbol-name x))
465: (name (progn
466: (string-match "^\\(.*::?\\)?\\(.*\\)$"
467: whole-name)
468: (substring whole-name
469: (match-beginning 2)
470: (match-end 2)))))
471: (cons name whole-name))))
472: completions))))
473: (completion (if alist (try-completion pattern alist))))
474: (cond ((eq completion t))
475: ((null completion)
476: (message "Can't find completion for \"%s\"" pattern)
477: (ding))
478: ((not (string= pattern completion))
479: (let ((new (cdr (assoc completion alist))))
480: (if new
481: (progn
482: (delete-region real-beg end)
483: (insert new))
484: (delete-region beg end)
485: (insert completion))))
486: (t
487: (message "Making completion list...")
488: (with-output-to-temp-buffer "*Help*"
489: (display-completion-list
490: (all-completions pattern alist)))
491: (message "Making completion list...done")))))
492:
493: (defun fi:tcp-lisp-send-eof ()
494: "Simulate an EOF on the tcp-lisp process via a db:debug-pop spoken to the
495: backdoor Common Lisp listener."
496: (interactive)
497: (fi:backdoor-eval
498: "(db:debug-pop (mp::process-name-to-process \"%s\"))\n"
499: (buffer-name (current-buffer))))
500:
501: (defun fi:tcp-lisp-kill-process ()
502: "Kill a tcp-lisp process via a mp:process-kill spoken to the backdoor
503: Common Lisp listener."
504: (interactive)
505: (fi:backdoor-eval
506: "(mp:process-kill (mp::process-name-to-process \"%s\"))\n"
507: (buffer-name (current-buffer))))
508:
509: (defun fi:tcp-lisp-interrupt-process ()
510: "Interrupt the tcp-lisp process via a mp:process-interrupt spoken to the
511: backdoor Common Lisp listener."
512: (interactive)
513: (fi:backdoor-eval
514: "(mp:process-interrupt
515: (mp::process-name-to-process \"%s\")
516: #'break \"interrupt from emacs\")\n"
517: (buffer-name (current-buffer))))
518:
519:
520: ;;;;;;;;;;;;;;;;;;;;; general subprocess related functions
521:
522: (defun fi:subprocess-superkey (&optional special-binding)
523: "This function implements superkeys in subprocess buffers.
524: A superkey is treated specially when at the end of a subprocess buffer,
525: but has its normal, global, binding when used elsewhere in the buffer.
526: At the end of the buffer the key has SPECIAL-BINDING. If SPECIAL-BINDING
527: is not given, the key takes its binding from the
528: fi:subprocess-super-key-map keymap."
529: (interactive)
530: (if (eobp)
531: (if special-binding
532: (call-interactively special-binding)
533: (fi::subprocess-reprocess-keys fi:subprocess-super-key-map))
534: (fi::subprocess-reprocess-keys global-map)))
535:
536: (defun fi::subprocess-reprocess-keys (&optional map key)
537: "Reprocess KEY or the last key sequence (which may be incomplete) in MAP.
538: This is used to reprocess a key sequence as if it were seen in another
539: context, e.g. to process global bindings of keys from a subprocess
540: buffer (in fi:shell-mode or fi:inferior-lisp-mode) when some keys are hit
541: other than at the end of the buffer."
542: (if (null map) (setq map global-map))
543: (let* ((last-key (if key
544: (if (integerp key)
545: (char-to-string key)
546: key)
547: (this-command-keys)))
548: (last-binding (lookup-key map last-key)))
549: (while (keymapp last-binding)
550: (setq last-binding
551: (lookup-key last-binding
552: (setq last-key (char-to-string (read-char))))))
553: (if (commandp last-binding)
554: (call-interactively last-binding)
555: (ding))))
556:
557: (defun fi:subprocess-beginning-of-line (arg)
558: "Moves point to beginning of line, just like (beginning-of-line),
559: except that if the pattern at the beginning of the line matches the
560: current subprocess prompt pattern, this function skips over it."
561: (interactive "P")
562: (beginning-of-line arg)
563: (if (looking-at subprocess-prompt-pattern)
564: (re-search-forward subprocess-prompt-pattern nil t)))
565:
566: (defun fi:subprocess-backward-kill-word (words)
567: "Kill previous word in current subprocess input line. This function
568: takes care not to delete past most recent subprocess output."
569: (interactive "p")
570: (save-restriction
571: (narrow-to-region
572: (marker-position (process-mark (get-buffer-process (current-buffer))))
573: (point))
574: (backward-kill-word words)))
575:
576: (defun fi:subprocess-send-input ()
577: "Send input to the subprocess. At end of buffer, sends all text after
578: last output as input to the subshell, including a newline inserted at the
579: end. Not at end, copies current line to the end of the buffer and sends it,
580: after first attempting to discard any prompt at the beginning of the line
581: by matching the regexp that is the value of subprocess-prompt-pattern if
582: possible. This regexp should start with \"^\"."
583: (interactive)
584: (if fi::shell-completions-window (fi::shell-completion-cleanup))
585: (end-of-line)
586: (if (eobp)
587: (progn
588: (move-marker fi::last-input-start
589: (process-mark (get-buffer-process (current-buffer))))
590: (insert "\n")
591: (move-marker fi::last-input-end (point)))
592: (let ((max (point)))
593: (beginning-of-line)
594: (re-search-forward subprocess-prompt-pattern max t))
595: (let ((copy (buffer-substring (point)
596: (progn (forward-line 1) (point)))))
597: (goto-char (point-max))
598: (move-marker fi::last-input-start (point))
599: (insert copy)
600: (move-marker fi::last-input-end (point))))
601: (fi::subprocess-watch-for-special-commands)
602: (let ((process (get-buffer-process (current-buffer))))
603: (fi::send-region-split process fi::last-input-start fi::last-input-end
604: fi:subprocess-map-nl-to-cr)
605: (fi::input-ring-save fi::last-input-start (1- fi::last-input-end))
606: (set-marker (process-mark process) (point))))
607:
608: (defun fi:subprocess-send-eof ()
609: "Send an end of file to the subprocess."
610: (interactive)
611: (process-send-eof))
612:
613: (defun fi:subprocess-kill-output ()
614: "Kill all output from the subprocess since the last input."
615: (interactive)
616: (goto-char (point-max))
617: (kill-region fi::last-input-end (point))
618: (insert "[output flushed]\n")
619: (set-marker (process-mark (get-buffer-process (current-buffer))) (point)))
620:
621: (defun fi:subprocess-send-flush ()
622: "Send the `flush output' character (^O) to subprocess."
623: (interactive)
624: (send-string (get-buffer-process (current-buffer)) "\C-o"))
625:
626: (defun fi:subprocess-show-output ()
627: "Display the start of this batch of shell output at top of window.
628: Also move the point there."
629: (interactive)
630: (set-window-start (selected-window) fi::last-input-end)
631: (goto-char fi::last-input-end))
632:
633: (defun fi:subprocess-interrupt ()
634: "Interrupt the current subprocess."
635: (interactive)
636: (interrupt-process nil t))
637:
638: (defun fi:subprocess-kill ()
639: "Send a `kill' (SIGKILL) signal to the current subprocess."
640: (interactive)
641: (kill-process nil t))
642:
643: (defun fi:subprocess-quit ()
644: "Send a quit signal to the subprocess."
645: (interactive)
646: (quit-process nil t))
647:
648: (defun fi:subprocess-suspend ()
649: "Suspend, with a SIGSTOP, the current subprocess."
650: (interactive)
651: (stop-process nil t))
652:
653: (defun fi:subprocess-kill-input ()
654: "Kill all input since the last output by the subprocess."
655: (interactive)
656: (kill-region (process-mark (get-buffer-process (current-buffer)))
657: (point)))
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.