source: release/1.3/source/cocoa-ide/hemlock/unused/archive/ts-buf.lisp

Last change on this file was 6567, checked in by Gary Byers, 18 years ago

Move lots of (currently unused, often unlikely to ever be used) stuff to an
archive directory.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.2 KB
Line 
1;;; -*- Package: Hemlock; Log: hemlock.log -*-
2;;;
3;;; **********************************************************************
4;;; This code was written as part of the CMU Common Lisp project at
5;;; Carnegie Mellon University, and has been placed in the public domain.
6;;;
7(hemlock-ext:file-comment
8 "$Header$")
9;;;
10;;; **********************************************************************
11;;;
12;;; This file contains code for processing input to and output from slaves
13;;; using typescript streams. It maintains the stuff that hacks on the
14;;; typescript buffer and maintains its state.
15;;;
16;;; Written by William Lott.
17;;;
18
19(in-package :hemlock)
20
21
22(defhvar "Input Wait Alarm"
23 "When non-nil, the user is informed when a typescript buffer goes into
24 an input wait, and it is not visible. Legal values are :message,
25 :loud-message (the default), and nil."
26 :value :loud-message)
27
28
29
30
31;;;; Structures.
32
33(defstruct (ts-data
34 (:print-function
35 (lambda (ts s d)
36 (declare (ignore ts d))
37 (write-string "#<TS Data>" s)))
38 (:constructor
39 make-ts-data (buffer
40 &aux
41 (fill-mark (copy-mark (buffer-end-mark buffer)
42 :right-inserting)))))
43 buffer ; The buffer we are in
44 stream ; Stream in the slave.
45 wire ; Wire to slave
46 server ; Server info struct.
47 fill-mark ; Mark where output goes. This is actually the
48 ; "Buffer Input Mark" which is :right-inserting,
49 ; and we make sure it is :left-inserting for
50 ; inserting output.
51 )
52
53
54
55;;;; Output routines.
56
57;;; TS-BUFFER-OUTPUT-STRING --- internal interface.
58;;;
59;;; Called by the slave to output stuff in the typescript. Can also be called
60;;; by other random parts of hemlock when they want to output stuff to the
61;;; buffer. Since this is called for value from the slave, we have to be
62;;; careful about what values we return, so the result can be sent back. It is
63;;; called for value only as a synchronization thing.
64;;;
65;;; Whenever the output is gratuitous, we want it to go behind the prompt.
66;;; When it's gratuitous, and we're not at the line-start, then we can output
67;;; it normally, but we also make sure we end the output in a newline for
68;;; visibility's sake.
69;;;
70(defun ts-buffer-output-string (ts string &optional gratuitous-p)
71 "Outputs STRING to the typescript described with TS. The output is inserted
72 before the fill-mark and the current input."
73 (when (hemlock.wire:remote-object-p ts)
74 (setf ts (hemlock.wire:remote-object-value ts)))
75 (hemlock-ext:without-interrupts
76 (let ((mark (ts-data-fill-mark ts)))
77 (cond ((and gratuitous-p (not (start-line-p mark)))
78 (with-mark ((m mark :left-inserting))
79 (line-start m)
80 (insert-string m string)
81 (unless (start-line-p m)
82 (insert-character m #\newline))))
83 (t
84 (setf (mark-kind mark) :left-inserting)
85 (insert-string mark string)
86 (when (and gratuitous-p (not (start-line-p mark)))
87 (insert-character mark #\newline))
88 (setf (mark-kind mark) :right-inserting)))))
89 (values))
90
91;;; TS-BUFFER-FINISH-OUTPUT --- internal interface.
92;;;
93;;; Redisplays the windows. Used by ts-stream in order to finish-output.
94;;;
95(defun ts-buffer-finish-output (ts)
96 (declare (ignore ts))
97 (redisplay)
98 nil)
99
100;;; TS-BUFFER-CHARPOS --- internal interface.
101;;;
102;;; Used by ts-stream in order to find the charpos.
103;;;
104(defun ts-buffer-charpos (ts)
105 (mark-charpos (ts-data-fill-mark (if (hemlock.wire:remote-object-p ts)
106 (hemlock.wire:remote-object-value ts)
107 ts))))
108
109;;; TS-BUFFER-LINE-LENGTH --- internal interface.
110;;;
111;;; Used by ts-stream to find out the line length. Returns the width of the
112;;; first window, or 80 if there are no windows.
113;;;
114(defun ts-buffer-line-length (ts)
115 (let* ((ts (if (hemlock.wire:remote-object-p ts)
116 (hemlock.wire:remote-object-value ts)
117 ts))
118 (window (car (buffer-windows (ts-data-buffer ts)))))
119 (if window
120 (window-width window)
121 80))) ; Seems like a good number to me.
122
123
124
125;;;; Input routines
126
127(defun ts-buffer-ask-for-input (remote)
128 (let* ((ts (hemlock.wire:remote-object-value remote))
129 (buffer (ts-data-buffer ts)))
130 (unless (buffer-windows buffer)
131 (let ((input-wait-alarm
132 (if (hemlock-bound-p 'input-wait-alarm
133 :buffer buffer)
134 (variable-value 'input-wait-alarm
135 :buffer buffer)
136 (variable-value 'input-wait-alarm
137 :global))))
138 (when input-wait-alarm
139 (when (eq input-wait-alarm :loud-message)
140 (beep))
141 (message "Waiting for input in buffer ~A."
142 (buffer-name buffer))))))
143 nil)
144
145(defun ts-buffer-clear-input (ts)
146 (let* ((ts (if (hemlock.wire:remote-object-p ts)
147 (hemlock.wire:remote-object-value ts)
148 ts))
149 (buffer (ts-data-buffer ts))
150 (mark (ts-data-fill-mark ts)))
151 (unless (mark= mark (buffer-end-mark buffer))
152 (with-mark ((start mark))
153 (line-start start)
154 (let ((prompt (region-to-string (region start mark)))
155 (end (buffer-end-mark buffer)))
156 (unless (zerop (mark-charpos end))
157 (insert-character end #\Newline))
158 (insert-string end "[Input Cleared]")
159 (insert-character end #\Newline)
160 (insert-string end prompt)
161 (move-mark mark end)))))
162 nil)
163
164(defun ts-buffer-set-stream (ts stream)
165 (let ((ts (if (hemlock.wire:remote-object-p ts)
166 (hemlock.wire:remote-object-value ts)
167 ts)))
168 (setf (ts-data-stream ts) stream)
169 (hemlock.wire:remote (ts-data-wire ts)
170 (ts-stream-set-line-length stream (ts-buffer-line-length ts))))
171 nil)
172
173
174
175;;;; Typescript mode.
176
177(defun setup-typescript (buffer)
178 (let ((ts (make-ts-data buffer)))
179 (defhvar "Current Package"
180 "The package used for evaluation of Lisp in this buffer."
181 :buffer buffer
182 :value nil)
183
184 (defhvar "Typescript Data"
185 "The ts-data structure for this buffer"
186 :buffer buffer
187 :value ts)
188
189 (defhvar "Buffer Input Mark"
190 "Beginning of typescript input in this buffer."
191 :value (ts-data-fill-mark ts)
192 :buffer buffer)
193
194 (defhvar "Interactive History"
195 "A ring of the regions input to the Hemlock typescript."
196 :buffer buffer
197 :value (make-ring (value interactive-history-length)))
198
199 (defhvar "Interactive Pointer"
200 "Pointer into the Hemlock typescript input history."
201 :buffer buffer
202 :value 0)
203
204 (defhvar "Searching Interactive Pointer"
205 "Pointer into \"Interactive History\"."
206 :buffer buffer
207 :value 0)))
208
209(defmode "Typescript"
210 :setup-function #'setup-typescript
211 :documentation "The Typescript mode is used to interact with slave lisps.")
212
213
214;;; TYPESCRIPTIFY-BUFFER -- Internal interface.
215;;;
216;;; Buffer creation code for eval server connections calls this to setup a
217;;; typescript buffer, tie things together, and make some local Hemlock
218;;; variables.
219;;;
220(defun typescriptify-buffer (buffer server wire)
221 (setf (buffer-minor-mode buffer "Typescript") t)
222 (let ((info (variable-value 'typescript-data :buffer buffer)))
223 (setf (ts-data-server info) server)
224 (setf (ts-data-wire info) wire)
225 (defhvar "Server Info"
226 "Server-info structure for this buffer."
227 :buffer buffer :value server)
228 (defhvar "Current Eval Server"
229 "The Server-Info object for the server currently used for evaluation and
230 compilation."
231 :buffer buffer :value server)
232 info))
233
234(defun ts-buffer-wire-died (ts)
235 (setf (ts-data-stream ts) nil)
236 (setf (ts-data-wire ts) nil)
237 (buffer-end (ts-data-fill-mark ts) (ts-data-buffer ts))
238 (ts-buffer-output-string ts (format nil "~%~%Slave died!~%")))
239
240(defun unwedge-typescript-buffer ()
241 (typescript-slave-to-top-level-command nil)
242 (buffer-end (current-point) (current-buffer)))
243
244(defhvar "Unwedge Interactive Input Fun"
245 "Function to call when input is confirmed, but the point is not past the
246 input mark."
247 :value #'unwedge-typescript-buffer
248 :mode "Typescript")
249
250(defhvar "Unwedge Interactive Input String"
251 "String to add to \"Point not past input mark. \" explaining what will
252 happen if the the user chooses to be unwedged."
253 :value "Cause the slave to throw to the top level? "
254 :mode "Typescript")
255
256;;; TYPESCRIPT-DATA-OR-LOSE -- internal
257;;;
258;;; Return the typescript-data for the current buffer, or die trying.
259;;;
260(defun typescript-data-or-lose ()
261 (if (hemlock-bound-p 'typescript-data)
262 (let ((ts (value typescript-data)))
263 (if ts
264 ts
265 (editor-error "Can't find the typescript data?")))
266 (editor-error "Not in a typescript buffer.")))
267
268(defcommand "Confirm Typescript Input" (p)
269 "Send the current input to the slave typescript."
270 "Send the current input to the slave typescript."
271 (declare (ignore p))
272 (let ((ts (typescript-data-or-lose)))
273 (let ((input (get-interactive-input)))
274 (when input
275 (let ((string (region-to-string input)))
276 (declare (simple-string string))
277 (insert-character (current-point) #\NewLine)
278 (hemlock.wire:remote (ts-data-wire ts)
279 (ts-stream-accept-input (ts-data-stream ts)
280 (concatenate 'simple-string
281 string
282 (string #\newline))))
283 (hemlock.wire:wire-force-output (ts-data-wire ts))
284 (buffer-end (ts-data-fill-mark ts)
285 (ts-data-buffer ts)))))))
286
287(defcommand "Typescript Slave Break" (p)
288 "Interrupt the slave Lisp process associated with this interactive buffer,
289 causing it to invoke BREAK."
290 "Interrupt the slave Lisp process associated with this interactive buffer,
291 causing it to invoke BREAK."
292 (declare (ignore p))
293 (send-oob-to-slave "B"))
294
295(defcommand "Typescript Slave to Top Level" (p)
296 "Interrupt the slave Lisp process associated with this interactive buffer,
297 causing it to throw to the top level REP loop."
298 "Interrupt the slave Lisp process associated with this interactive buffer,
299 causing it to throw to the top level REP loop."
300 (declare (ignore p))
301 (send-oob-to-slave "T"))
302
303(defcommand "Typescript Slave Status" (p)
304 "Interrupt the slave and cause it to print status information."
305 "Interrupt the slave and cause it to print status information."
306 (declare (ignore p))
307 (send-oob-to-slave "S"))
308
309#+NIL
310(defun send-oob-to-slave (string)
311 (let* ((ts (typescript-data-or-lose))
312 (wire (ts-data-wire ts))
313 (socket (hemlock.wire:wire-fd wire)))
314 (unless socket
315 (editor-error "The slave is no longer alive."))
316 (error "SEND-OOB-TO-SLAVE seeks an implementation.")
317 #+NIL
318 (hemlock-ext:send-character-out-of-band socket (schar string 0))))
Note: See TracBrowser for help on using the repository browser.