(FILECREATED "17-AUG-83 12:53:18" {PHYLUM}<LISPCORE>SOURCES>TTYIN.;5 713265Q      changes to:  (FNS TTYIN.READ \SET.TTYINBOLDFONT)		   (VARS TTYINCOMS)      previous date: " 1-AUG-83 17:28:51" {PHYLUM}<LISPCORE>SOURCES>TTYIN.;4)(* Copyright (c) 1982, 1983 by Xerox Corporation)(PRETTYCOMPRINT TTYINCOMS)(RPAQQ TTYINCOMS [(E (RESETSAVE (RADIX 10Q)))		  (FNS * TTYINFNS)		  (FNS * TTDISPLAYFNS)		  (COMS (* Mouse handling)			(FNS DO.MOUSE DO.SHIFTED.SELECTION COPY.SEGMENT DELETE.LONG.SEGMENT 			     DELETE.LONG.SEGMENT1 INVERT.LONG.SEGMENT INVERT.SEGMENT 			     BRACKET.CURRENT.WORD TTBEFOREPOS TTNEXTPOS TTRACKMOUSE TTYINBUTTONFN))		  (COMS (* Support functions. These are all macros or for debugging)			(FNS * TTSUPPORTFNS))		  [COMS (* Auxiliary fns. These are outside the TTYIN block, and are provided to aid 			   the outside world in special interfaces to TTYIN)			(FNS SETREADFN TTYINREADP TTYINREAD TTYINFIX CHARMACRO? TTYINMETA 			     \SET.TTYINBOLDFONT TTYIN.LASTINPUT)			(FNS TTED DO.EE TTYINEDIT SIMPLETEXTEDIT SET.TTYINEDIT.WINDOW TTYIN.PPTOFILE 			     TTYIN.SCRATCHFILE)			(USERMACROS EE ED BUF)			(LISPXMACROS TV BUF)			(INITVARS (TTYINEDITWINDOW)				  (TTYINEDIT.SCRATCH)				  (TTYINEDITPROMPT T)				  (TTYINAUTOCLOSEFLG)				  (TTYINPRINTFN)				  (TTYIN?=FN))			(ADDVARS (AFTERSYSOUTFORMS (SETQ TTYINEDIT.SCRATCH NIL]		  (DECLARE: DOEVAL@COMPILE DONTCOPY (COMS * TTCOMPILETIME))		  (INITVARS (TTYINBUFFER)			    (?ACTIVATEFLG T)			    (EDITPREFIXCHAR 301Q)			    (EMACSFLG T)			    (SHOWPARENFLG T)			    (TTYINBSFLG T)			    (TTYINCOMPLETEFLG T)			    (TTYINUSERFN)			    (TYPEAHEADFLG T)			    (null "")			    (DEFAULTPROMPT "** ")			    (TTYJUSTLENGTH -10Q)			    (\INSIDE.TTYIN)			    (TTYINERRORSETFLG)			    (TTYINRAISEFLG T)			    (\TTYIN.RESTOREBUFCODE 302Q)			    (\TTYIN.METASTATE)			    (TTYINAUTOFILLMARGIN 10Q)			    (TTYINFIXLIMIT 62Q))		  (P (MOVD? (QUOTE NILL)			    (QUOTE GUESTUSER?))		     (MOVD? (QUOTE FIXSPELL)			    (QUOTE FIXSPELL!!))		     (MOVD? (QUOTE HELPSYS)			    (QUOTE XHELPSYS))		     (PUTDQ? SPRINTT [LAMBDA (X)					     (PRIN1 X])		     (MOVD? (QUOTE NILL)			    (QUOTE WINDOWWORLD))		     (MOVD? (QUOTE LISPXFIX)			    (QUOTE NONTTYINLISPXFIX)))		  (ADDVARS (TTYINREADMACROS)			   (TTYINRESPONSES)			   (LISPXCOMS (STOP . OK)))		  (PROP VARTYPE TTYINREADMACROS)		  [DECLARE: DONTEVAL@LOAD DOCOPY (P [COND ((CCODEP (QUOTE TTYIN))							   (CHANGENAME (QUOTE PROMPTCHAR)								       (QUOTE LISPXREADP)								       (QUOTE TTYINREADP))							   (SETREADFN)							   (MOVD (QUOTE TTYINFIX)								 (QUOTE LISPXFIX]						    (\SET.TTYINBOLDFONT (DEFAULTFONT (QUOTE DISPLAY]		  (GLOBALRESOURCES (\TTWAITBOX (CREATECELL \FIXP)))		  (DECLARE: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY COMPILERVARS			    (ADDVARS (NLAMA TTBOUTN TTBOUT)				     (NLAML TTED CHARMACRO? CAPABILITY?)				     (LAMA])(RPAQQ TTYINFNS (TTYIN TTYIN.SETUP TTYIN.CLEANUP TTYIN1 TTYIN1RESTART TTYIN.FINISH TTYIN.READ 		       TTYIN.BALANCE ADDCHAR ADDCHARS.INSERTING ADDNAKEDCHAR ADDSILENTCHAR ADDTAB 		       ADJUSTLINE ADJUSTLINE.AND.RESTORE AT.END.OF.SCREEN AT.END.OF.TEXT AUTOCR? 		       BACKSKREAD BACKWARD.DELETE.TO BREAKLINE BUFCHARCOUNT BUFTAILP CHECK.MARGIN 		       CLEAR.LINE? CREATE.LINE CURRENT.WORD DELETE.TO.END DELETELINE DELETETO 		       DELETETO1 DO.EDIT.COMMAND DO.EDIT.PP DO?CMD TTYIN.PRINTARGS TTYIN.READ?=ARGS 		       DOTABS EDITCOLUMN EDITNUMBERP END.DELETE.MODE ENDREAD? FIND.LINE 		       FIND.LINE.BREAK FIND.MATCHING.QUOTE FIND.MATCHING.WORD FIND.NEXT.WORD 		       FIND.NON.SPACE FIND.START.OF.WORD FORWARD.DELETE.TO GO.TO.ADDRESSING 		       GO.TO.FREELINE GO.TO.RELATIVE INIT.CURSOR INSERT.CHAR.IN.BUF INSERT.NODE 		       INSERTLINE KILL.LINES KILLSEGMENT L-CASECODE MOVE.BACK.TO MOVE.FORWARD.TO 		       MOVE.TO.LINE MOVE.TO.NEXT.LINE MOVE.TO.START.OF.WORD MOVE.TO.WHEREVER 		       NTH.COLUMN.OF NTH.RELATIVE.COLUMN.OF OVERFLOW? OVERFLOWLINE? PREVLINE PREVWORD 		       PROPERTAILP READFROMBUF RENUMBER.LINES RESTORE.CURSOR RESTOREBUF RETYPE.BUFFER 		       SAVE.CURSOR SCANBACK SCANFORWARD SCRATCHCONS SEGMENT.LENGTH SEGMENT.BIT.LENGTH 		       SETLASTC SETTAIL? SHOW.MATCHING.PAREN SKIP/ZAP START.NEW.LINE 		       START.OF.PARAGRAPH? TTADJUSTWORD TTBIN TTBITWIDTH TTCOMPLETEWORD TTCRLF 		       TTCRLF.ACCOUNT TTDELETECHAR TTDELETELINE TTDELETEWORD TTECHO.TO.FILE 		       TTGIVEHELP TTGIVEHELP1 TTGIVEHELP2 TTLASTLINE TTLOADBUF TTNEXTCHAR TTNEXTLINE 		       TTNEXTNODE TTNLEFT TTNTH TTNTHLINE TTPRIN1 TTPRIN2 TTPROMPTCHAR TTRATOM TTREAD 		       TTREADLIST TTRUBOUT TTSKIPSEPR TTSKREAD TTUNREADBUF TTWAITFORINPUT TTYINSTRING 		       TYPE.BUFFER U-CASECODE U/L-CASE WORD.MATCHES.BUFFER))(DEFINEQ(TTYIN  [LAMBDA (PROMPT SPLST HELP OPTIONS ECHOTOFILE TABS UNREADBUF RDTBL)                                                             (* bvm: " 1-AUG-83 17:18")    (DECLARE (SPECVARS SPLST HELP TABS UNREADBUF RDTBL ECHOTOFILE))          (* * TTYIN is a general input function. See TTYIN.DOC for details on the arguments and use of this fn.	  TTYIN was designed and implemented by Bill van Melle at Stanford.)          (* * Some implementation notes: The bulk of the code here is oriented toward smart use on display terminals, 	  specifically the datamedia. If on a dm, TTYIN puts the terminal in binary mode so it can read the 200q bit 	  supplied by the EDIT key. Most of the cursor-moving commands from TVEDIT are available or slightly modified, and a	  few extra are supplied as well.)          (* The text being typed in is represented as a list of character codes, with a data structure on top of it which 	  partitions it by line. Thus, you can view the text as one string, or broken into lines, depending on the function 	  desired. \BUFFER is the pointer to the start of the buffer, \ENDBUFFER points one past the end.	  TTYIN saves up cons cells between calls and reuses them; \ENDBUFFER points to this list of free cells.	  TTYINBUFFER is the master record, which keeps assorted global information about where the cursor is, and saves 	  some state info from one call to the next, enabling the restore previous buffer command. See BUFFIELDS for 	  documentation of its fields; the fields are accessed by the ! construct for efficiency. One of the fields points 	  to the LINE records which describe the two-dimensional structure of the input. Each record points to the region of	  the buffer containing the text for one line, and has fields indicating the first and last columns, and a pointer 	  to the next line record. \ARROW always points to the current LINE record -	  \CURSOR points to where in the buffer the cursor appears. -	  This representation is not terribly space-efficient for large buffers, but it is easily manipulated, and fast.	  If there is a particularly long input, there will be many cons cells tied up in TTYINBUFFER, so a good thing to do	  when trying to free up space is reset TTYINBUFFER to NIL to force its regeneration from scratch.)    (RESETLST (PROG ((\INSIDE.TTYIN T)		     (\TTYINSTATE TTYINBUFFER)		     (\DSP (TTYDISPLAYSTREAM))		     (\RDTBLSA (fetch READSA of (\GTREADTABLE RDTBL)))		     (\RAISEINPUT (OR TTYINRAISEFLG (fetch RAISEFLG of \PRIMTERMTABLE)))		     (\FIRSTTIME T)		     (TYPEAHEAD TYPEAHEADFLG)		     \INITPOS \BMARG \LMARG \RMARG \CHARWIDTH \CHARHEIGHT \DESCENT \FONT 		     \VARIABLEFONT \TEXTURE \TTPAGELENGTH \CURSORROW \CURSORCOL \HOMEROW \HOMECOL 		     \PROMPT1 \PROMPT2 \FIRSTLINE \LASTAIL \LASTAILCOL \LASTAILROW \FIX \LOC.ROW.0 		     \LASTCHAR \SPLSTFLG X VALUE \BUFFER \ENDBUFFER \CURSOR \ARROW \DELETING 		     \INSERTING \EDITBIT \DONTCOMPLETE \AUTOFILL \NOVALUE \NOFIXSPELL \STRINGVALUE 		     \REPEAT \COMMAND \READING \LISPXREADING DIRECTORY/FILE \NOPROMPT \FILLINGBUFFER 		     \LAST.DELETION)		    (SETQ TTYINBUFFER)                       (* Global resource. Any ttyin calls while we are running							     need to create their own)		    [OR (LISTP \TTYINSTATE)			(SETQ \TTYINSTATE (create TTYINBUFFER						  FIRSTLINE _(create LINE								     START _(CONS 0)								     ROW _ 0]		    (TTYIN.SETUP)		    [COND		      ((AND SPLST (NLISTP SPLST))			(SETQ SPLST (CONS SPLST]		    (for OP inside OPTIONS do (SELECTQ OP						       ((NOFIXSPELL MUSTAPPROVE CRCOMPLETE)							 (SETQ \NOFIXSPELL (SETQ \DONTCOMPLETE OP)))						       (\NOVALUE (SETQ \NOVALUE OP))						       (STRING (SETQ \STRINGVALUE OP))						       (COMMAND (SETQ \COMMAND OP))						       (REPEAT (SETQ \REPEAT OP))						       (NORAISE (SETQ \RAISEINPUT))						       (RAISE (SETQ \RAISEINPUT T))						       (TEXT (SETQ \REPEAT (SETQ \NOVALUE								 (SETQ \AUTOFILL OP)))							     (SETQ \RAISEINPUT))						       (FIX (SETQ \FIX OP))						       (READ (SETQ \READING (SETQ \AUTOFILL OP)))						       (LISPXREAD [SETQ TYPEAHEAD (SETQ \LISPXREADING								      (SETQ \READING (SETQ \AUTOFILL 									  OP]								  (SETQ \RAISEINPUT								    (fetch RAISEFLG of \PRIMTERMTABLE)								    ))						       (EVALQT                                                              (* like LISPXREAD, but with added proviso about checking							     for EVALQT right-bracket hacks)							       [SETQ TYPEAHEAD (SETQ \LISPXREADING								   (SETQ \READING (SETQ \AUTOFILL OP]							       (SETQ \RAISEINPUT								 (fetch RAISEFLG of \PRIMTERMTABLE)))						       ((FILE DIRECTORY USER)							 (SETQ DIRECTORY/FILE OP))						       (TYPEAHEAD (SETQ TYPEAHEAD OP))						       (FILLBUFFER (SETQ \FILLINGBUFFER OP))						       (NOPROMPT (SETQ \NOPROMPT (SETQ \FIRSTTIME OP))								 )						       NIL))		    [COND		      ((EQ PROMPT T)			(SETQ \PROMPT1 (SETQ \PROMPT2)))		      (T [COND			   ((NOT PROMPT)			     (SETQ PROMPT DEFAULTPROMPT))			   [(LISTP PROMPT)			     (COND			       ((NLISTP (CDR PROMPT))        (* User has already supplied us with a dotted pair of 							     prompts)				 (SETQ \PROMPT1 (CAR PROMPT))				 (SETQ \PROMPT2 (CDR PROMPT)))			       (T (SETQ PROMPT (SUBSTRING PROMPT 2 -2]			   ((AND (NOT (STRINGP PROMPT))				 (NOT (LITATOM PROMPT)))			     (SETQ PROMPT (MKSTRING PROMPT]			 (COND			   ((NLISTP PROMPT)                  (* Now create 2 prompts out of one)			     (SETQ \PROMPT1 PROMPT)			     (SETQ \PROMPT2 (COND				 ((AND \LISPXREADING (LITATOM PROMPT))				   NIL)				 ((AND (OR \REPEAT \LISPXREADING)				       (ILESSP (NCHARS PROMPT)					       14Q))         (* Okay to use this short prompt as a secondary prompt)				   PROMPT)				 (T (QUOTE ...]		    (COND		      ((NOT SPLST)			(SETQ \DONTCOMPLETE T)))		    (COND		      (\READING (SETQ \REPEAT)))		    (COND		      ((AND TTYINMAILFLG (NEQ \READING (QUOTE EVALQT))			    (ILESSP \INITPOS 5))			(MAILWATCH)))		    (COND		      ((NOT TYPEAHEAD)			(CLEARBUF T)))		LP  (SETQ VALUE (NLSETQ (TTYIN1)))		    (COND		      ((NOT VALUE)                           (* NLSETQ aborted. Try again.)			(COND			  ((OR (NOT TTYINERRORSETFLG)			       \LISPXREADING)                (* LISPXREAD is not errorset-protected, so why should 							     this be?)			    (GO.TO.FREELINE)			    (RESTOREMOD)			    (COND			      ((NEQ \BUFFER \ENDBUFFER)				(replace OLDTAIL of \TTYINSTATE with \ENDBUFFER)))			    (ERROR!)))			(GO LP)))		    (SELECTQ (SYSTEMTYPE)			     [D (COND				  ((AND (NEQ \BUFFER \ENDBUFFER)					(IGREATERP (add (fetch STORAGECOUNTER of \TTYINSTATE)							1)						   12Q))     (* Release some storage, since it seems to accumulate 							     and fragment)				    (replace STORAGECOUNTER of \TTYINSTATE with 0)				    (FRPLACD \ENDBUFFER]			     NIL)		    (SETQ VALUE (CAR VALUE))		    (POSITION T 0)		    [COND		      ((AND CTRLUFLG (NEQ VALUE T))          (* user typed ^U to edit input)			(SETQ CTRLUFLG)			(PROG ((\INSIDE.TTYIN))			      (COND				((OR (LITATOM VALUE)				     (GUESTUSER?))           (* guests may not edit)				  )				((LISTP VALUE)				  (EDITE VALUE))				(T (SETQ VALUE (CAR (EDITE (LIST VALUE)							   (QUOTE (REPACK]		    (COND		      ((AND TTYINMAILFLG (NEQ \READING (QUOTE EVALQT)))                                                             (* Note time of last user input)			(MWNOTE)))		    (RETURN VALUE])(TTYIN.SETUP  [LAMBDA NIL                                                (* bvm: " 1-AUG-83 17:00")    (SELECTQ (SYSTEMTYPE)	     [D (PROCESS.PREPARE.FOR.INPUT)		[SETQ \CHARWIDTH (FCHARWIDTH (CHARCODE A)					     (SETQ \FONT (DSPFONT NIL \DSP]		(SETQ \VARIABLEFONT (NEQ \CHARWIDTH (FCHARWIDTH (CHARCODE i)								\FONT)))		(SETQ \CHARHEIGHT (FONTPROP \FONT (QUOTE HEIGHT)))		(SETQ \DESCENT (FONTPROP \FONT (QUOTE DESCENT)))                                                             (* How many pixels below the baseline this font goes)		(SETQ \TEXTURE (DSPTEXTURE NIL \DSP))		(SETQ \TTPAGELENGTH (PAGEHEIGHT NIL \DSP))		(SETQ \LMARG (DSPLEFTMARGIN NIL \DSP))       (* bit pos of left margin)		(SETQ \RMARG (DSPRIGHTMARGIN NIL \DSP))      (* bit pos of right margin, dsp relative)		(SETQ \INITPOS (IDIFFERENCE (DSPXPOSITION NIL \DSP)					    \LMARG))		(COND		  ((WINDOWWORLD)                             (* Disable buttons so we can do selection)		    (replace TTOLDRIGHTFN of \TTYINSTATE with (WINDOWPROP \DSP (QUOTE RIGHTBUTTONFN)									  (QUOTE TTYINBUTTONFN)))		    (replace TTOLDBUTTONFN of \TTYINSTATE with (WINDOWPROP \DSP (QUOTE BUTTONEVENTFN)									   (QUOTE TTYINBUTTONFN)))		    (replace TTYINDSP of \TTYINSTATE with \DSP)		    (RESETSAVE NIL (LIST (FUNCTION TTYIN.CLEANUP)					 \TTYINSTATE]	     (PROGN                                          (* On Twenex...)		    (SETQ DISPLAYTERMFLG (DISPLAYTERMP))		    (COND		      ([AND CHECKNIL? (SETQ VALUE (OR (CAR NIL)						      (CDR NIL]			(PRIN2 (COND				 ((CAR NIL)				   (QUOTE CAR))				 (T (QUOTE CDR)))			       T)			(PRIN1 " of NIL was smashed with " T)			(PRINT (SETQ CAR/CDRNIL VALUE)			       T)			(SETQ VALUE (FRPLNODE NIL NIL NIL])(TTYIN.CLEANUP  [LAMBDA (\TTYINSTATE)                                      (* bvm: " 1-AUG-83 16:50")    (PROG ((DSP (fetch TTYINDSP of \TTYINSTATE)))          [COND	    (DSP (WINDOWPROP DSP (QUOTE RIGHTBUTTONFN)			     (fetch TTOLDRIGHTFN of \TTYINSTATE))		 (WINDOWPROP DSP (QUOTE BUTTONEVENTFN)			     (fetch TTOLDBUTTONFN of \TTYINSTATE]          (SETQ TTYINBUFFER \TTYINSTATE])(TTYIN1  [LAMBDA NIL                                                (* bvm: "21-APR-83 11:44")          (* * The main moby subfn of TTYIN. Is errorset protected in caller)    (PROG (CHAR MATCHED RESULT STARTOFWORD X TMP (DRIBFL (DRIBBLEFILE)))          (SETQ \LASTAIL)      RESTART      PROMPT0          (TTYIN1RESTART)          (COND	    ((NOT \FIRSTTIME)                                (* Space over to where we started)	      (GO.TO.ADDRESSING \INITPOS 0)))          (SETQ RESULT NIL)      PROMPT1          (INIT.CURSOR \INITPOS)          (COND	    [(AND (EQ \FIRSTTIME (QUOTE NOPROMPT))		  \PROMPT1)                                  (* Prompting has already happened;							     account for it)	      (COND		((ILESSP (SETQ X (IDIFFERENCE \INITPOS (STRINGWIDTH \PROMPT1 \FONT)))			 0)                                  (* Caller is consfused; prompt couldn't have fit.							     Typically happens when LISPXREAD is called by other than							     LISPX)		  (SETQ \PROMPT1))		(T (SETQ \INITPOS X]	    (T (TTPROMPTCHAR \ARROW)))          (replace FIRSTCOL of \ARROW with (replace LASTCOL of \ARROW with \CURSORCOL))          [COND	    ([OR (NLISTP TABS)		 (NOT (SMALLP (CAR TABS]	      (SETQ TABS))	    ((NOT (IGREATERP (ITIMES (SUB1 (CAR TABS))				     \CHARWIDTH)			     \CURSORCOL))                    (* Caller specified first tabstop as the position of the							     first char; we don't treat that as a tabstop, so peel it							     off)	      (SETQ TABS (CDR TABS]          [COND	    [UNREADBUF                                       (* something to preload buffer with)		       (COND			 ((FIXP UNREADBUF)			   (SETQ CHAR UNREADBUF)             (* interpret number as character code of something to 							     type ahead, usually altmode)			   (SETQ UNREADBUF NIL)			   (GO SELECTCHAR))			 (T (TTLOADBUF (PROG1 UNREADBUF (SETQ UNREADBUF NIL]	    (\FIRSTTIME           (* (for FORM in AFTERPROMPTCHARFORMS bind REFRESH when (EVAL FORM) do (SETQ REFRESH T) (* User forms to do after 	  prompt is printed but before we do anything more. If one returns T, means it altered the display) finally 	  (COND (REFRESH (SETQ \FIRSTTIME) (GO PROMPT1)))))]          (SETQ \FIRSTTIME)      CHAR(AND CHAR (SETQ \LASTCHAR CHAR))          (SETQ CHAR (TTBIN))      SELECTCHAR          [COND	    ([AND (SETQ X (FASSOC (COND				    (\EDITBIT (LOGOR CHAR 200Q))				    (T CHAR))				  TTYINREADMACROS))		  (OR [NLISTP (SETQ X (CDR (SETQ TMP X]		      (AND (COND			     ((EQ (CAR X)				  T)			       (EMPTY.BUFFER))			     ((LISTP (CAR X))			       (EVAL (CAR X)))			     (T                              (* Old style macros that worked only at start of buffer)				(SETQ X TMP)				(EMPTY.BUFFER)))			   (OR (NLISTP (SETQ X (CDR X)))			       (SETQ X (EVAL X]          (* Simple read macros: if you type the char on a blank line, and the macro returns something, use it as the value 	  of the READ (or whatever))	      (COND		[(FIXP X)                                    (* Special: means pretend this CHARACTER code was typed)		  (SELECTQ X			   (0                                (* No action)			      (GO CHAR))			   (-1                               (* Means refresh line, (QUOTE cause) terminal control 							     was taken away)			       (GO PROMPT1))			   (PROGN [COND				    ((ZEROP (SETQ CHAR (LOGAND X 177Q)))                                                             (* another way to get edit prefix)				      (SETQ CHAR (TTBIN]				  (SETQ \EDITBIT (NOT (ZEROP (LOGAND X 200Q]		((EMPTY.BUFFER)                              (* For now I'm not handling funny results in the middle)		  (SETQ RESULT (OR (LISTP X)				   (LIST X)))		  (GO DOCRLF]          (COND	    (\EDITBIT (SETQ \INSERTING)                      (* Edit bit on any command stops insert mode)		      (COND			((NOT (SETQ CHAR (DO.EDIT.COMMAND CHAR)))			  (GO CHAR)))                        (* Fall thru if edit char gave us something to chomp on)		      ))          [COND	    ((AND (ILESSP CHAR 400Q)		  (SELECTC (fetch TERMCLASS of (\SYNCODE \PRIMTERMSA CHAR))			   (CHARDELETE.TC (TTDELETECHAR)					  T)			   (LINEDELETE.TC (TTDELETELINE)					  T)			   (WORDDELETE.TC (TTDELETEWORD)					  T)			   (RETYPE.TC                        (* ^R retype)				      [RETYPE.BUFFER (COND						       ((OR (ON.FIRST.LINE)							    (NOT (EMPTY.LINE)))							 \ARROW)						       (T    (* If sitting on empty line, refresh the previous line)							  (PREVLINE \ARROW 1]				      (COND					((EQ CHAR (SETQ CHAR (TTBIN)))                                                             (* two ^R's means retype whole buffer)					  (OR DISPLAYTERMFLG (TTCRLF))                                                             (* set off full retype by double line)					  (RETYPE.BUFFER \FIRSTLINE T))					(T (GO SELECTCHAR)))				      T)			   NIL)))	    ((AND \FILLINGBUFFER (EQ (fetch WAKEUP of (\SYNCODE \RDTBLSA CHAR))				     IMMEDIATE.RMW)		  (AT.END.OF.TEXT \CURSOR))                  (* Immediate read macro--return now)	      (GO DOCRLF))	    (T (SELECTC CHAR			[(CHARCODE ESCAPE)			  (COND			    (SPLST                           (* try to complete from spelling list)				   (OR (TTCOMPLETEWORD)				       (BEEP)))			    ((TENEXCOMPLETE CHAR DIRECTORY/FILE)                                                             (* altmode indicated file/directory completion, done in 							     TENEXCOMPLETE)			      NIL)			    ((AND TTYINCOMPLETEFLG \LISPXREADING (COND				    ((SETQ STARTOFWORD (CURRENT.WORD))				      (SETQ MATCHED (FIND.MATCHING.WORD USERWORDS STARTOFWORD)))				    ((AND (NEQ TTYINCOMPLETEFLG 0)					  (NOT (EMPTY.BUFFER)))                                                             (* naked altmode stands for LASTWORD.							     Don't do this on empty buffer, so as not to interfere 							     with P.A.'s * command)				      (SETQ MATCHED (FRPLACA (CONSTANT (CONS))							     LASTWORD))				      LASTWORD)))            (* special option -- do altmode completion on USERWORDS,							     a list of fns/vars referenced recently)			      (SETQ CHAR (CONSTANT DIDESCAPECODE))                                                             (* Kludge used by ? routine below)			      (OR (TTCOMPLETEWORD NIL NIL MATCHED (OR STARTOFWORD \CURSOR))				  (BEEP)))			    (T                               (* no special significance)			       (ADDNAKEDCHAR (CHARCODE ESCAPE]			((CHARCODE (%" *))			  (ADDCHAR CHAR)			  (DOTABS TABS))			((CHARCODE TAB)			  (OR \DONTCOMPLETE (TTCOMPLETEWORD T))			  (OR (DOTABS TABS)			      (ADDTAB)))			((CHARCODE (SPACE %( , %[))          (* break or sepr: try to complete what we have)			  (OR \DONTCOMPLETE (TTCOMPLETEWORD T))			  (OR (AND (EQ CHAR (CHARCODE SPACE))				   (AUTOCR?))			      (ADDCHAR CHAR)))			[(CHARCODE (%) %]))                  (* Right paren/bracket. See if it terminates read)			  (OR \DONTCOMPLETE (TTCOMPLETEWORD T))			  (SETQ STARTOFWORD \CURSOR)			  (ADDCHAR CHAR)			  (COND			    (\READING (COND					((ENDREAD?)					  (GO DOCRLF))					((AND SHOWPARENFLG (CAPABILITY? \CURSOR)					      (NOT (TYPEAHEAD?)))                                                             (* prime conditions for hack to show which paren it 							     matched)					  (SHOW.MATCHING.PAREN STARTOFWORD]			[(CHARCODE ?)                        (* supply alternative completions)			  (COND			    ([NOT (AND ?ACTIVATEFLG (OR SPLST (EQ \LASTCHAR DIDESCAPECODE))				       (AT.END.OF.BUF)				       (SETQ STARTOFWORD (CURRENT.WORD))				       [NOT (FMEMB (CAR (NLEFT STARTOFWORD 1 \ENDBUFFER))						   (CHARCODE (? %%]				       (NOT (PROGN (FRPLACA \ENDBUFFER (CHARCODE ?))						   (FIND.MATCHING.WORD SPLST STARTOFWORD								       (CDR \ENDBUFFER]          (* Cases where ? is not acted on: ?ACTIVATEFLG not set; no spelling list; line is a comment;	  no word is in progress; previous char is also a ? (allows ?? etc.) or %%; or ? is a valid completion)			      (ADDCHAR CHAR))			    ((NOT (SETQ MATCHED (FIND.MATCHING.WORD (OR SPLST USERWORDS)								    STARTOFWORD)))			      (BEEP)                         (* No match. Ring the bell, but accept the ? as is)			      (ADDCHAR CHAR))			    ((TTCOMPLETEWORD NIL T MATCHED STARTOFWORD)                                                             (* there was a unique completion)			      )			    (T (SAVE.CURSOR)			       (GO.TO.FREELINE)			       (TTPRIN1 "one of ")			       [do (TTPRIN1 (INPART (CAR MATCHED)))				   (COND				     ((SETQ MATCHED (FIND.MATCHING.WORD (CDR MATCHED)									STARTOFWORD))				       (TTPRIN1 ", "))				     (T (RETURN]			       (COND				 (DISPLAYTERMFLG (RESTORE.CURSOR))				 (T (RETYPE.BUFFER \ARROW]			[(CHARCODE CR)                       (* terminate line)			  [COND			    ((NOT \EDITBIT)                  (* i.e. not edit-CR)			      [COND				((OR (AT.END.OF.LINE)				     (INSERTING))            (* Check for ? and ?= macros)				  (PROG ((START (fetch START of \ARROW))					 TAIL)				        (COND					  ((EQ \CURSOR START)					    (RETURN)))				        (SETQ TAIL (NLEFT START 1 \CURSOR))                                                             (* Look at last char on line)				        (SELCHARQ (CAR TAIL)						  [? (COND						       ((AND [OR (EQ TAIL START)								 (BREAK.OR.SEPRP (CAR (NLEFT START 1 											     TAIL]							     (DO?CMD (QUOTE ?)								     TAIL))                                                             (* restore buffer after help is given, and now delete 							     the ?)							 (TTRUBOUT)							 (SAVE.CURSOR)							 (GO RETYPEBUFFER]						  [= (COND						       ((AND (NEQ TAIL START)							     (EQ (CAR (SETQ TAIL									(NLEFT START 1 TAIL)))								 (CHARCODE ?))							     [OR (EQ TAIL START)								 (BREAK.OR.SEPRP (CAR (NLEFT START 1 											     TAIL]							     (DO?CMD (QUOTE ?=)								     TAIL))							 (COND							   ((CAPABILITY? MOVEMENT)							     (RESTORE.CURSOR)							     (BACKWARD.DELETE.TO TAIL))							   (T (BACKWARD.DELETE.TO TAIL)                                                             (* Delete BEFORE retyping, since we can't erase ?= as 							     above)							      (RETYPE.BUFFER \ARROW)))							 (GO CHAR]						  NIL]			      (COND				((AND (INSERTING)				      (NOT (AT.END.OF.TEXT \CURSOR)))				  (COND				    ((OR \REPEAT \READING)   (* Insert a <cr> and continue reading)				      (BREAKLINE EOLCHARCODE)				      (GO CHAR))				    (T                       (* <cr> typed here would terminate, so unread what's 							     left)				       (TTUNREADBUF)				       (SETQ \INSERTING]			  (COND			    [(NOT (AT.END.OF.BUF))			      (COND				((ON.LAST.LINE)				  (SETQ \CURSOR \ENDBUFFER))				((AND \READING (NOT \PROMPT2)				      (AT.END.OF.TEXT (fetch END of \ARROW)))          (* Really the same condition as previous clause: there are lines after this one, but they're blank, so it looks 	  like we're on the last line)				  (MOVE.FORWARD.TO (fetch END of \ARROW))                                                             (* have to make the extra stuff go away so the finishing							     routines are happy)				  (DELETE.TO.END))				(T (DO.EDIT.COMMAND (CHARCODE CR))                                                             (* CR on other than last line just means go down one)				   (GO CHAR]			    ((AND (EQ (CAR \BUFFER)				      (CHARCODE B))				  (EQ (CADR \BUFFER)				      (CHARCODE L))				  (EQ (CDDR \BUFFER)				      \ENDBUFFER)				  DISPLAYTERMFLG)            (* BL command)			      (ERASE.SCREEN)			      (GO PROMPT0))			    ((OR (NOT \DONTCOMPLETE)				 (EQ \DONTCOMPLETE (QUOTE CRCOMPLETE)))			      (TTCOMPLETEWORD T)))			  (COND			    ((COND				(\READING (TTSKREAD \BUFFER))				[\REPEAT (AND (ON.FIRST.LINE)					      (OR (EQ (CAR \BUFFER)						      (CHARCODE ;))						  (AND \COMMAND (EQ (FIND.NEXT.WORD (FIND.NON.SPACE										      \BUFFER))								    \ENDBUFFER]				(T T))                       (* Terminating conditions: no REPEAT, or first line is a							     comment or has a single command on it)			      (SETQ CTRLVFLG (SETQ RESULT))			      (SETQ CHAR (CHARCODE EOL))     (* Lisp likes to treat cr as 							     (choke) EOL)			      (GO DOCRLF))			    (T (START.NEW.LINE EOLCHARCODE]			[(CHARCODE ^X)                       (* Go to end of expression, return if parens balance)			  (COND			    ((TTYIN.BALANCE)			      (SETQ CHAR (CHARCODE EOL))			      (GO DOCRLF))			    (T (BEEP]			[(CHARCODE ^V)			  (COND			    [\READING                        (* Means enter control char)				      (ADDNAKEDCHAR (SETQ CHAR (SELCHARQ (SETQ CHAR (TTBIN))									 ((RUBOUT ?)                                                             (* DELETE is ^?)									   177Q)									 (LOGAND CHAR 37Q]			    ((AND (EQ \REPEAT (QUOTE TEXT))				  (AT.END.OF.BUF))           (* terminate multiline input and sets special flag)			      (SETQ CTRLVFLG T)			      (TTBOUT ^ V)			      (GO DOCRLF))			    (T (BEEP]			[(CHARCODE ^Z)                       (* ^Z terminates multiline input)			  (COND			    ((AND \REPEAT (AT.END.OF.BUF))			      (TTBOUT ^ Z)			      (SETQ CTRLVFLG)			      (GO DOCRLF))			    (T (BEEP]			[(CHARCODE ^Y)                       (* ^Y invokes user exec)			  (COND			    ((AND \READING (NOT \EDITBIT))   (* let ^Y read macro work instead)			      (ADDNAKEDCHAR CHAR))			    ((GUESTUSER?)			      (BEEP))			    (T (SETTAIL?)			       (SAVE.CURSOR)			       (GO.TO.FREELINE)			       (COND				 (DRIBFL                     (* Make typescript understandable)					 (AND \PROMPT1 (PRIN1 \PROMPT1 DRIBFL))					 (PRINT (QUOTE ^Y)						DRIBFL)))			       (PRIN1 "lisp:" T)			       (COND				 (TTYINMAILFLG (MWNOTE)))			       (RESTOREMOD)			       (PROG ((\INSIDE.TTYIN))				     (USEREXEC (QUOTE __)))			       (GO RETYPEBUFFER]			(0                                   (* ignore NULL))			(MOUSECODE                           (* Mouse event, indicated by appearance of this char in 							     buffer)				   (SETQ CHAR)				   (DO.MOUSE))			((CHARCODE (^A BS RUBOUT))			  (TTDELETECHAR))			((CHARCODE (^Q ^U))                  (* ^Q delete line; ^U on tops20)			  (TTDELETELINE))			((CHARCODE ^W)                       (* ^W delete last word)			  (TTDELETEWORD))			(COND			  ((EQ CHAR \TTYIN.RESTOREBUFCODE)   (* Blank middle: restore buffer's previous contents.							     \TTYIN.RESTOREBUFCODE is dynamic, since code on that key							     may change)			    (RESTOREBUF))			  ((IGREATERP CHAR 177Q)             (* a funny char. I don't know how to handle)			    (BEEP))			  [(IGREATERP CHAR 40Q)              (* not a control char)			    (ADDCHAR (COND				       (\RAISEINPUT (U-CASECODE CHAR))				       (T CHAR]			  (\READING (ADDNAKEDCHAR CHAR))			  (T                                 (* object to control chars)			     (BEEP]          (GO CHAR)      RETYPEBUFFER          (SETQ \INSERTING)          (RETYPE.BUFFER \FIRSTLINE T T)          (GO CHAR)      DOCRLF          (* * Come here when it is time to terminate line)          (COND	    ((EQ (SETQ RESULT (TTYIN.FINISH CHAR DRIBFL RESULT))		 (QUOTE ABORT))                              (* Aborted, try again)	      (GO PROMPT0))	    (T (RETURN RESULT])(TTYIN1RESTART  [LAMBDA NIL                                                (* bvm: " 2-APR-82 14:19")    (\RESETLINE)                                             (* clear some terminal-related stuff, including the info							     about where to hold scroll)    (\SETEOFPTR \LINEBUF.OFD 0)                              (* Clear the line buffer)    (SETQ \ARROW (SETQ \FIRSTLINE (fetch FIRSTLINE of \TTYINSTATE)))    [replace END of \ARROW with (SETQ \CURSOR (SETQ \BUFFER (SETQ \ENDBUFFER (fetch START										of \ARROW]    [PROG ((MORELINES (fetch NEXTLINE of \ARROW)))          (COND	    (MORELINES                                       (* Return old line records to cons pool)		       (replace NEXTLINE of \ARROW with NIL)		       (KILL.LINES MORELINES]    (SETQ \INSERTING (SETQ \DELETING])(TTYIN.FINISH  [LAMBDA (FINALCHAR DRIBFL RESULT)                          (* bvm: "24-JUL-83 01:30")    (PROG (LASTC WORD X ORIGBUFFER)          (SELECTQ (SYSTEMTYPE)		   (TOPS20                                   (* Save this for funny tops20 check at end)			   (SETQ \LASTCHAR FINALCHAR))		   NIL)          (TTCRLF)          (CLEAR.LINE? T)          [COND	    ((EQ FINALCHAR (CHARCODE EOL))	      (bind TAIL (START _(fetch START of \ARROW))		 while (AND (NEQ START \ENDBUFFER)			    (EQ (CAR (SETQ TAIL (TTNLEFT \ENDBUFFER 1 START)))				(CHARCODE SPACE))			    (NEQ (CAR (TTNLEFT TAIL 1 START))				 (CHARCODE %%)))		 do           (* Strip blanks, e.g., resulting from escape completion, so that Lispx does not do its silly ...	  thing. Be careful not to strip a quoted space)		    (SETQ \ENDBUFFER TAIL]          (COND	    (DRIBFL                                          (* print answer on typescript file)		    (TTECHO.TO.FILE DRIBFL T)))          (for X inside ECHOTOFILE do (TTECHO.TO.FILE X))          (COND	    [(EMPTY.BUFFER)                                  (* blank line. RESULT is NIL unless set above by a read 							     macro)	      (COND		((OR RESULT (EQ FINALCHAR (CHARCODE EOL)))		  (SETLASTC (CHARCODE EOL))		  (RETURN RESULT]	    ((EQ (CAR \BUFFER)		 (CHARCODE ;))                               (* comment)	      (RETURN (QUOTE ABORT)))	    ((AND (EQ (CDR \BUFFER)		      \ENDBUFFER)		  (EQ (CAR \BUFFER)		      (CHARCODE ?))		  (OR HELP (AND \NOVALUE \REPEAT)))          (* a bare ?)	      (TTGIVEHELP (OR HELP "Terminate text with control-Z."))	      (RETURN (QUOTE ABORT)))	    (T                                               (* Save last buffer position for posterity)	       (replace OLDTAIL of \TTYINSTATE with \ENDBUFFER)))          [COND	    [\READING (SELECTQ (SYSTEMTYPE)			       (D (SETQ RESULT (TTYIN.READ FINALCHAR \FILLINGBUFFER \LINEBUF.OFD)))			       (PROGN                        (* This is the old way)				      (SETQ RESULT (TTREADLIST))				      [COND					((NEQ \BUFFER \ENDBUFFER)                                                             (* Line terminated with unbalanced right paren.							     If there was only one thing on line, read the terminator							     as a NIL)					  [COND					    ((AND (EQ \READING (QUOTE EVALQT))						  [NOT (CDR (SETQ X (COND								((EQ (CAR RESULT)								     (QUOTE E))                                                             (* A hack on a hack: this is probably the editor's E 							     command, and CDR is the real input)								  (CDR RESULT))								(T RESULT]						  (NLISTP (CAR X)))					      (SETQ RESULT (NCONC1 RESULT NIL]					  (SETQ \BUFFER (CDR \BUFFER))					  (TTSKIPSEPR)					  (while [AND (NEQ \BUFFER \ENDBUFFER)						      (FMEMB (CAR \BUFFER)							     (CHARCODE (%) %]]					     do (SETQ \BUFFER (CDR \BUFFER)))                                                             (* skip over any extra right parens or brackets)					  (COND					    ((NEQ \BUFFER \ENDBUFFER)					      (MOVE.TO.WHEREVER \BUFFER)          (* There was stuff after the read terminated, probably because user deleted or added a paren somewhere in the 	  middle. Probably didn't want to throw it away, so unread it so user can see it)					      (TTUNREADBUF)					      (TTCRLF]				      (COND					((AND (EQ FINALCHAR (CHARCODE TENEXEOL))					      (NOT (CDR RESULT))					      (LISTP (CAR RESULT)))                                                             (* User terminated with <cr>, but read a list.							     Pretend he terminated with a "]" to be consistent with 							     lisp READ conventions)					  (SETLASTC (CHARCODE %]]	    (T	      (SETQ ORIGBUFFER \BUFFER)	      (SETQ WORD (TTRATOM))	      [COND		((EQ (TTSKIPSEPR)		     \ENDBUFFER)                             (* this was the only word in buffer)		  (COND		    ((SELECTQ WORD			      ((? HELP)                      (* Only special if HELP provided)				(AND HELP (TTGIVEHELP HELP)))			      NIL)                           (* special response handled; restart now)		      (TERPRI T)		      (RETURN (QUOTE ABORT]	      [for RESPONSE in TTYINRESPONSES when (AND (EQMEMB WORD (CAR RESPONSE))							(OR (EQ \BUFFER \ENDBUFFER)							    (CADDR RESPONSE)))		 do           (* Process global user option. RESPONSE is a triple (commands response-form rest-of-line-arg); if user gives one 	  of the commands, the response form is evaluated with \COMMAND set to the command and LINE set to the remainder of 	  the line; the third component says how to compute LINE: as a STRING or as a LIST; if NIL, means there should be 	  nothing else on the line. If the response form returns the atom IGNORE, the input is not considered to be a 	  special response and the normal computation proceeds; otherwise it is assumed the response has been processed, and	  we return to the original TTYIN prompt for more input. Response-form may be an atom, in which case it is APPLYed 	  to \COMMAND and LINE.)		    (COND		      ((NEQ [PROG [(\COMMAND WORD)				   (\BUFFER \BUFFER)				   (LINE (COND					   ((EQ \BUFFER \ENDBUFFER)					     NIL)					   ((EQ (CADDR RESPONSE)						(QUOTE STRING))					     (TTYINSTRING \BUFFER))					   (T (TTREADLIST]			          (DECLARE (SPECVARS \COMMAND \BUFFER LINE))			          (RETURN (COND					    ((LITATOM (CADR RESPONSE))					      (APPLY* (CADR RESPONSE)						      \COMMAND LINE))					    (T (EVAL (CADR RESPONSE]			    (QUOTE IGNORE))			(RETFROM (QUOTE TTYIN.FINISH)				 (QUOTE ABORT)))		      (T           (* That response was ignored. We could quit the iteration now, but continue in case there is another entry with 	  the same command. I.e. user can "redefine" special responses this way, but still let the old definition happen if 	  the input looks wrong)]	      [SETQ WORD (OR (TTADJUSTWORD WORD)			     (RETURN (QUOTE ABORT]	      [SETQ RESULT (COND		  [(EQ \BUFFER \ENDBUFFER)		    (COND		      (\COMMAND (LIST WORD))		      (\NOVALUE T)		      (\STRINGVALUE           (* Can't just MKSTRING WORD here, since in the process of making the atom we might have changed something, e.g. 	  stripped leading zeros from a number, or changed radix)				    (TTYINSTRING ORIGBUFFER))		      (T (LIST WORD]		  [\STRINGVALUE (COND				  (\COMMAND (CONS WORD (TTYINSTRING \BUFFER)))				  (T (TTYINSTRING ORIGBUFFER]		  (\NOVALUE (COND			      (\COMMAND (CONS WORD T))			      (T T)))		  (T (bind NEXTWORD while (NEQ (TTSKIPSEPR)					       \ENDBUFFER)			collect (SETQ NEXTWORD (TTRATOM))    (* go back for more)				[COND				  (\COMMAND                  (* only check first word typed)					    NEXTWORD)				  ((TTADJUSTWORD NEXTWORD))				  (T (RETURN (QUOTE ABORT]			finally (RETURN (CONS WORD $$VAL]	      (SETLASTC FINALCHAR)	      (PROGN                                         (* All this nonsense is just to convince prettyprint to 							     keep the indentation down to a reasonable amount)		(PROGN		  (PROGN		    (PROGN		      (PROGN			(PROGN			  (PROGN			    (PROGN (PROGN (PROGN (PROGN (PROGN (PROGN (PROGN (PROGN (PROGN NIL]          (* * We have now processed the line, with the relevant value being RESULT...)          [COND	    ((AND TTYINUSERFN (LISTP RESULT))	      (COND		((EQ (SETQ X (APPLY* TTYINUSERFN RESULT))		     T)                                      (* Special response has been processed;							     try again)		  (RETURN (QUOTE ABORT)))		(X                                           (* this is what we should return)		   (RETURN X]          (SETQ \CURRENTDISPLAYLINE 0)                       (* get scrolling right (again))                                                             (* see system \CLOSELINE)          (RETURN RESULT])(TTYIN.READ  [LAMBDA (FINALCHAR DONTREAD STREAM)                        (* bvm: "17-AUG-83 12:25")    (DECLARE (FILESLOAD (LOADCOMP)			ATERM))                              (* Get linebuf definitions)    (PROG (LASTC)          [COND	    ((NOT DONTREAD)                                  (* We are doing our own READ, so surround user's input 							     with parens before we stuff it away)	      (\BOUT STREAM (CHARCODE %[]          (while (NEQ \BUFFER \ENDBUFFER)	     do [\BOUT STREAM (SETQ LASTC (REALBITS (CAR \BUFFER]		(SETQ \BUFFER (TTNEXTCHAR \BUFFER)))         (* Fill the buffer)          (COND	    ((NOT DONTREAD)	      (\BOUT STREAM (CHARCODE %]))                   (* Close with two right brackets: one may be needed to 							     match a user open bracket, the other matches ours)	      (\BOUT STREAM (CHARCODE %])))	    ((SELCHARQ FINALCHAR		       (EOL (SELCHARQ LASTC				      ((%) %])					(\SETFILEPTR STREAM (IDIFFERENCE (\GETFILEPTR STREAM)									 2))					(COND					  ((EQ (\BIN STREAM)					       (CHARCODE %%))                                                             (* If it ended in a quoted right paren, then it's just 							     like any other character)					    (\BIN STREAM))					  (T                 (* Line ended in paren. Change to right bracket so 							     READLINE doesn't get confused)					     (\BOUT STREAM (CHARCODE %]))					     NIL)))				      T))		       ((%) %])			 NIL)		       T)	      (\BOUT STREAM FINALCHAR)))          (\SETEOFPTR STREAM (\GETFILEPTR STREAM))          (\SETFILEPTR STREAM 0)          (RETURN (COND		    (DONTREAD                                (* STREAM = \LINEBUF.OFD and caller will take care of 							     reading buf)			      (AND (EQ STREAM \LINEBUF.OFD)				   (replace (LINEBUFFER LINEBUFSTATE) of STREAM with READING.LBS))			      T)		    (T                                       (* Read from buffer until it's empty)		       (PROG1 (READ STREAM RDTBL)			      (\SETFILEPTR STREAM 0)         (* Now clear the stream so nobody reads extra garbage 							     after us)			      (\SETEOFPTR STREAM 0])(TTYIN.BALANCE  [LAMBDA NIL                                                (* bvm: "23-MAR-82 23:09")    (PROG ((X (TTSKREAD \BUFFER)))          (RETURN (PROG1 [OR (EQ X \ENDBUFFER)			     (AND (EQ (CAR X)				      (CHARCODE %]))				  (AT.END.OF.TEXT (CDR X]			 (MOVE.TO.WHEREVER (OR X \ENDBUFFER])(ADDCHAR  [LAMBDA (CHAR)    (DECLARE (USEDFREE \ARROW \CURSORCOL \AUTOFILL \CURSOR))                                                             (* bvm: " 1-JUN-82 22:39")          (* * Add CHAR to buffer and print it, advancing cursor position appropriately)    (PROG ((WIDTH (TTBITWIDTH CHAR)))          (END.DELETE.MODE)          [COND	    ((AT.END.OF.LINE)	      (OVERFLOW? WIDTH)	      (TTBOUT CHAR)	      (INSERT.CHAR.IN.BUF CHAR)                      (* i.e. inserting at end of line)	      (add \CURSORCOL WIDTH)	      (replace LASTCOL of \ARROW with \CURSORCOL))	    [(INSERTING)	      (INSERTNCHARS 1 CHAR)	      (INSERT.CHAR.IN.BUF CHAR)                      (* Wedge char into the buffer, and advance the final 							     column)	      (add \CURSORCOL WIDTH)	      (PROG ((OVFL (IDIFFERENCE (add (fetch LASTCOL of \ARROW)					     WIDTH)					\RMARG)))		    (COND		      ((OR (IGREATERP OVFL 0)			   (AND (ZEROP OVFL)				\AUTOFILL))			(ADJUSTLINE (AND \AUTOFILL 1))			(MOVE.TO.WHEREVER \CURSOR]	    (T [COND		 ((PREFIXCHAR (CAR \CURSOR))                 (* Overwriting a multi-position char, so need to flush 							     the extra garbage)		   (SELCHARQ (REALBITS (CAR \CURSOR))			     [(TAB SPACE)                    (* tab or pseudo-tab: change the padding spaces to 							     ordinary spaces)			       (KILLSEGMENT \CURSOR (CDR \CURSOR))                                                             (* flush the tab itself, leaving only its spaces)			       (for (BUF _ \CURSOR) by (CDR BUF) while (EQ (CAR BUF)									   (PADCHARCODE SPACE))				  do (FRPLACA BUF (CHARCODE SPACE]			     (PROGN                          (* Delete all but one of the printing chars)				    (FORWARD.DELETE.TO (NLEFT \CURSOR 1 (TTNEXTCHAR \CURSOR]	       (TTBOUT CHAR)	       (add \CURSORCOL WIDTH)	       (FRPLACA \CURSOR CHAR)	       (SETQ \CURSOR (CDR \CURSOR]          (OVERFLOW? 0)      NIL])(ADDCHARS.INSERTING  [LAMBDA (N CHAR)                                           (* bvm: " 1-JUN-82 22:49")          (* * Inserts CHAR N times. Works independent of setting of \INSERTING)    (PROG [(WIDTH (ITIMES N (TTBITWIDTH CHAR]          (OVERFLOW? WIDTH)          (COND	    ((AT.END.OF.LINE)	      (TTBOUTN N CHAR))	    (T (INSERTNCHARS N CHAR)))          (FRPTQ N (INSERT.CHAR.IN.BUF CHAR))          (add \CURSORCOL WIDTH)          (* * Now clean up any resulting overflow. Could have done this character by character in ADDCHAR, but if N gt 1 	  that can be slow.)          (COND	    ((IGREATERP (replace LASTCOL of \ARROW with (IPLUS WIDTH (fetch LASTCOL of \ARROW)))			\RMARG)	      (ADJUSTLINE.AND.RESTORE))	    (T (OVERFLOW? 0])(ADDNAKEDCHAR  [LAMBDA (CHAR NOAUTOFILL)                                  (* bvm: "20-FEB-82 22:34")          (* * Adds CHAR with no special processing, e.g. most control chars (except cr and lf, which I can't figure out 	  yet) go thru ok.)    (COND      ((AND (IGREATERP CHAR 40Q)	    (NEQ CHAR 177Q))	(ADDCHAR CHAR))      (T (SELCHARQ CHAR		   [CR                                       (* CR can be attempted if at end)		       (COND			 ((AT.END.OF.BUF)			   (START.NEW.LINE EOLCHARCODE))			 (T (BEEP]		   [SPACE (OR (AND (NOT NOAUTOFILL)				   (AUTOCR?))			      (ADDCHAR (CHARCODE SPACE]		   (ESCAPE (INSERT.CHAR.IN.BUF (PREFIXCHARCODE ESCAPE))                                                             (* Altmode will echo as $)			   (ADDCHAR (PADCHARCODE $)))		   (TAB (ADDTAB))		   (PROGN (OVERFLOW? 1)			  (INSERT.CHAR.IN.BUF (LOGOR CHAR (CONSTANT PREFIXCODE)))                                                             (* Insert naked char with prefix bit)			  (ADDCHAR (PADCHARCODE ^))			  (ADDCHARS.INSERTING 1 (COND						((EQ CHAR (CHARCODE DEL))                                                             (* DELETE is represented as ^?)						  (PADCHARCODE ?))						(T (LOGOR CHAR 100Q (CONSTANT PADCODE])(ADDSILENTCHAR  [LAMBDA (CHAR)                                             (* bvm: " 1-JUN-82 18:22")          (* Like ADDCHAR, but doesn't echo the char, assuming that echoing has already been done. Assumes we are at end of 	  line so we don't have to do any messiness)    (COND      [(ILESSP CHAR (CHARCODE SPACE))                        (* bleah. do a control char. The line is probably 							     screwed up, but at least let ^R do the right thing)	(INSERT.CHAR.IN.BUF (LOGOR CHAR (CONSTANT PREFIXCODE)))                                                             (* Prefix bit on)	(COND	  ((EQ CHAR (CHARCODE ESCAPE))	    (INSERT.CHAR.IN.BUF (PADCHARCODE $)))	  (T (INSERT.CHAR.IN.BUF (PADCHARCODE ^))	     (INSERT.CHAR.IN.BUF (LOGOR (SETQ CHAR (LOGOR CHAR 100Q))					(CONSTANT PADCODE)))                                                             (* controlified letter)	     (ADD1POS (CHARCODE ^]      (T (INSERT.CHAR.IN.BUF CHAR)))    (ADD1POS CHAR)    (COND      ((NOT (ILESSP (replace LASTCOL of \ARROW with \CURSORCOL)		    \RMARG))	(START.NEW.LINE)))    NIL])(ADDTAB  [LAMBDA NIL                                                (* bvm: " 1-JUN-82 22:49")    (COND      ((AND (NOT (AT.END.OF.BUF))	    (NOT \INSERTING)	    (EQ (CAR \CURSOR)		(PREFIXCHARCODE TAB)))                       (* We're on a tab. Unless we're explicitly inserting, 							     just move cursor over it)	(MOVE.FORWARD.TO (TTNEXTCHAR \CURSOR)))      (T           (* Represent <tab> in buffer as a tab with 200Q bit on, followed by the appropriate number of spaces, each with 	  400Q bit on. Tab is always self-inserting, i.e. it never overwrites anything (except itself, as above))	 (INSERT.CHAR.IN.BUF (PREFIXCHARCODE TAB))           (* the actual tab)	 (ADDCHARS.INSERTING (IDIFFERENCE 10Q (LOGAND (IQUOTIENT (IDIFFERENCE \CURSORCOL									      (fetch FIRSTCOL										 of \ARROW))								 \CHARWIDTH)						      7))			     (PADCHARCODE SPACE])(ADJUSTLINE  [LAMBDA (JUSTIFYING LINE)                                  (* bvm: " 1-JUN-82 22:08")          (* Handles patching up lines that are too long or short. Assures that the current line, ARROW, is correct with 	  regard to overflows. If JUSTIFYING is true, it is a number specifying how many lines to "justify", by which we 	  mean moving text around so that each line has as many words as possible for the linelength, but does not overflow.	  We don't do anything very fancy with that, like take care of deleting extra spaces.)    (PROG [#BITS BREAK LASTCOL NEWENDLINE NEXTLINE OLDENDLINE OVFL START USECR ROW		 (IDEALLENGTH (COND				((IGREATERP TTYJUSTLENGTH 0)				  (IMIN \RMARG (ITIMES TTYJUSTLENGTH \CHARWIDTH)))				(T                           (* Relative to right margin)				   (IMAX (IDIFFERENCE \RMARG (ITIMES (IMINUS TTYJUSTLENGTH)								     \CHARWIDTH))					 (LRSH \RMARG 1]          (OR LINE (SETQ LINE \ARROW))          (SETQ ROW (fetch ROW of LINE))      LP  (SETQ NEXTLINE (fetch NEXTLINE of LINE))          (SETQ OVFL (OVERFLOWLINE? LINE))          (SETQ #BITS (IDIFFERENCE \RMARG (fetch LASTCOL of LINE)))          (SETQ USECR (SETQ BREAK NIL))          (SETQ START (fetch START of LINE))          (COND	    ((ILESSP #BITS 0)          (* Too much on line; need to break it somewhere, preferably at a space if permissible. If justifying, try to break	  at the appropriate length)	      (COND		([OR (AND JUSTIFYING (ILESSP (IPLUS (fetch FIRSTCOL of LINE)						    IDEALLENGTH)					     \RMARG)			  (SETQ BREAK (FIND.LINE.BREAK START (NTH.RELATIVE.COLUMN.OF LINE IDEALLENGTH)						       T)))		     (PROGN (SETQ NEWENDLINE (NTH.COLUMN.OF LINE \RMARG))			    (AND (OR JUSTIFYING \AUTOFILL)				 (SETQ BREAK (FIND.LINE.BREAK START NEWENDLINE T]		  (SETQ USECR T))		(T (SETQ BREAK NEWENDLINE)))	      (GO DOBREAK))	    [(AND OVFL (NEQ #BITS 0)		  (NEQ (SETQ NEWENDLINE (NTH.RELATIVE.COLUMN.OF NEXTLINE #BITS))		       (fetch START of NEXTLINE)))          (* Line is too short, but is an overflow line, so text MUST be moved to fill the gap; alternatively, if we are 	  justifying, we could break the line sooner)                                                             (* NEWENDLINE = where the line should end, based on 							     linelength)	      (COND		([OR (EQ (fetch END of LINE)			 NEWENDLINE)		     (AND (OR \AUTOFILL JUSTIFYING)			  (SETQ BREAK (FIND.LINE.BREAK (fetch END of LINE)						       NEWENDLINE JUSTIFYING))			  (SETQ NEWENDLINE BREAK))		     (NOT JUSTIFYING)		     (NOT (SETQ BREAK (FIND.LINE.BREAK START (fetch END of LINE)						       T]		  (GO DOJOIN))		(T (SETQ USECR T)		   (GO DOBREAK]	    ((NOT JUSTIFYING)	      (RETURN))	    [(OR OVFL (AND (NEQ JUSTIFYING T)			   (IGREATERP (IDIFFERENCE (fetch LASTCOL of LINE)						   (fetch FIRSTCOL of LINE))				      IDEALLENGTH)))         (* line is longer than we'd like)	      (COND		((SETQ BREAK (FIND.LINE.BREAK START (NTH.RELATIVE.COLUMN.OF LINE IDEALLENGTH)					      T))		  (SETQ USECR T)		  (GO DOBREAK]	    [(AND (NOT (EMPTY.LINE LINE))		  (NOT (START.OF.PARAGRAPH? NEXTLINE))		  (OR (NEQ JUSTIFYING T)		      (EQ (CAR (fetch END of LINE))			  PSEUDOCRCODE)))                    (* Don't move up text from next line if it is blank or 							     starts with tab -- treat those as paragraph breaks)	      (COND		((OR (EQ [SETQ BREAK (NTH.RELATIVE.COLUMN.OF			     NEXTLINE			     (SUB1 (IMIN (IDIFFERENCE (IPLUS IDEALLENGTH (fetch FIRSTCOL									    of LINE))						      (fetch LASTCOL of LINE))					 #BITS]			 (fetch END of NEXTLINE))		     (SETQ BREAK (FIND.LINE.BREAK (fetch START of NEXTLINE)						  BREAK T)))		  (SETQ NEWENDLINE BREAK)                    (* At least one more word from next line will fit up 							     here)		  (GO DOJOIN))		(T                                           (* No text movement, but if there was a real <cr>, make 							     it pseudo now)		   (FRPLACA (fetch END of LINE)			    (CONSTANT PSEUDOCRCODE]	    ((EQ JUSTIFYING T)                               (* If this line is fine, quit)	      ))          (SETQ LINE NEXTLINE)          (GO BOTTOM)      DOJOIN          (* * Move text from next line up to this one. NEWENDLINE is where line should end when done.	  BREAK=NEWENDLINE if this new end line is a pseudo-cr break)          (COND	    ((EQ (SETQ OLDENDLINE (fetch END of LINE))		 NEWENDLINE)	      (SETQ #BITS 0))	    (T (GO.TO.RELATIVE (fetch LASTCOL of LINE)			       ROW)	       (SETQ #BITS (SEGMENT.BIT.LENGTH OLDENDLINE NEWENDLINE))                                                             (* # chars to delete from next line)	       [COND		 ((NOT OVFL)                                 (* Joining toa non-overflow line: turn its cr into a 							     space)		   (FRPLACA OLDENDLINE (CHARCODE SPACE))		   (while (AND (NEQ (CDR OLDENDLINE)				    NEWENDLINE)			       (EQ (CADR OLDENDLINE)				   (CHARCODE SPACE)))		      do                                     (* strip leading spaces from next line)			 (KILLSEGMENT OLDENDLINE (CDR OLDENDLINE)))		   (COND		     ((EQ (CAR (NLEFT (fetch START of LINE)				      1 OLDENDLINE))			  (CHARCODE %.))                     (* LINE ends in period, so space twice)		       (FRPLACA (INSERT.NODE OLDENDLINE)				(CHARCODE SPACE]	       (TYPE.BUFFER OLDENDLINE NEWENDLINE)	       (replace END of LINE with NEWENDLINE)	       (replace LASTCOL of LINE with \CURSORCOL)))          (GO.TO.RELATIVE (QUOTE LINE)			  NEXTLINE)          (replace START of NEXTLINE with (COND					    (BREAK (FRPLACA BREAK (CONSTANT PSEUDOCRCODE))                                                             (* Turn BREAK's space into a pseudo-cr, if anyone cares)						   (COND						     (OVFL (add #BITS (TTBITWIDTH (CHARCODE SPACE)))                                                             (* will delete space also)							   ))						   (CDR NEWENDLINE))					    (T NEWENDLINE)))          (COND	    ((EQ (fetch END of NEXTLINE)		 NEWENDLINE)	      (DELETELINE NEXTLINE T)                        (* Nothing left here, so kill it)	      [COND		(JUSTIFYING                                  (* maybe we can move from next line, too)			    (COND			      ([AND (NEQ JUSTIFYING T)				    (NOT (ZEROP (SUB1VAR JUSTIFYING]				(GO LP))			      (T (RETURN]	      (SETQ LINE (fetch NEXTLINE of LINE)))	    (T (TTDELSECTION #BITS)	       (replace LASTCOL of NEXTLINE with (IDIFFERENCE (fetch LASTCOL of NEXTLINE)							      #BITS))	       (SETQ LINE NEXTLINE)))          (GO BOTTOM)      DOBREAK          (* Break line at BREAK, moving excess down to next line or a new line. USECR is true if break is a cr break;	  otherwise we are breaking a too-long line at the right margin)          [replace LASTCOL of LINE with (SETQ LASTCOL (IPLUS (SEGMENT.BIT.LENGTH (fetch START										    of LINE)										 BREAK)							     (fetch FIRSTCOL of LINE]                                                             (* Column where break will occur)          [SETQ #BITS (SEGMENT.BIT.LENGTH BREAK (SETQ OLDENDLINE (fetch END of LINE]                                                             (* length of segment being moved)          (COND	    ((NEQ LASTCOL \RMARG)	      (GO.TO.RELATIVE LASTCOL ROW)                   (* Go wipe out what was there.							     Don't need to do this if the break is right at the 							     margin)	      (ERASE.TO.END.OF.LINE)))          (replace END of LINE with BREAK)          [COND	    (USECR (FRPLACA BREAK (CONSTANT PSEUDOCRCODE))   (* Turn break space into pseudo-cr.							     Of course, that means we have counted one char too many 							     above...)		   [SETQ #BITS (IDIFFERENCE #BITS (TTBITWIDTH (CHARCODE SPACE]		   (SETQ BREAK (CDR BREAK]          (COND	    [[AND NEXTLINE (OR OVFL (AND (OR JUSTIFYING (AND (EQ (CAR OLDENDLINE)								 (CONSTANT PSEUDOCRCODE))							     (ILESSP (IPLUS (fetch LASTCOL									       of NEXTLINE)									    #BITS)								     \RMARG)))					 (NOT (START.OF.PARAGRAPH? NEXTLINE]          (* Insert the text on the next line, rather than starting new line, if justifying, overflow 	  (forced), or the text will fit, i.e. not cause anything to be bumped off the next line)	      (GO.TO.RELATIVE (QUOTE LINE)			      (SETQ LINE NEXTLINE))	      (COND		((NOT OVFL)                                  (* Turn the terminating <cr> into ordinary space;							     this space also needs to be inserted and counted, of 							     course)		  (add #BITS (TTBITWIDTH (CHARCODE SPACE)))		  (SETQ OLDENDLINE (CDR (FRPLACA OLDENDLINE (CHARCODE SPACE]	    (T (SETQ LINE (INSERTLINE LINE))	       (replace END of LINE with OLDENDLINE)))          (replace START of LINE with BREAK)          (INSERT.TEXT BREAK OLDENDLINE (fetch END of LINE))          (add (fetch LASTCOL of LINE)	       #BITS)      BOTTOM          (COND	    (LINE (ADD1VAR ROW)		  (COND		    ((AND JUSTIFYING (NEQ JUSTIFYING T)			  (ZEROP (SUB1VAR JUSTIFYING)))		      (SETQ JUSTIFYING NIL)))		  (GO LP])(ADJUSTLINE.AND.RESTORE  [LAMBDA (JUSTIFYING)                                 (* bvm: "19-MAR-81 11:55")    (SAVE.CURSOR)    (ADJUSTLINE JUSTIFYING)    (COND      ((IGREATERP \HOMECOL (fetch LASTCOL of \ARROW))                                                       (* Oops, cursor must have moved)	(MOVE.TO.WHEREVER \CURSOR))      (T (RESTORE.CURSOR])(AT.END.OF.SCREEN  [LAMBDA NIL                                                (* bvm: " 1-JUN-82 18:09")    (OR (AT.END.OF.LINE)	(IGREATERP (IPLUS \CURSORCOL (TTBITWIDTH (REALBITS (CAR \CURSOR)))			  \CHARWIDTH)		   \RMARG])(AT.END.OF.TEXT  [LAMBDA (BUF)                                        (* bvm: "19-MAR-81 11:55")          (* Checks that this is the last printing char in buffer. Fancier than just checking that BUF = ENDBUFFER, since that	  would mess up if user deletes a line and decides to terminate on previous line)    (for X_BUF by (CDR X) until (EQ X \ENDBUFFER) always (SPACEP (CAR X])(AUTOCR?  [LAMBDA NIL                                                (* bvm: " 4-JUN-82 13:59")                                                             (* Terminates line if near edge of screen and in 							     autofill mode)    (COND      ((AND \AUTOFILL (IGREATERP (IPLUS \CURSORCOL TTYINAUTOFILLMARGIN)				 \RMARG))	[COND	  ((AT.END.OF.LINE)	    (START.NEW.LINE (CONSTANT PSEUDOCRCODE)))	  (T (BREAKLINE (CONSTANT PSEUDOCRCODE]	T])(BACKSKREAD  [LAMBDA (BUF NOTIFQUOTED)                                  (* bvm: "20-FEB-82 22:36")          (* Returns buffer position of start of list containing cursor position BUF, or start of buffer.	  If NOTIFQUOTED is true, then returns NIL if the paren/bracket at BUF is quoted with the escape char or is inside a	  string. Strategy: start at beginning of buffer and TTSKREAD forward (much easier); if read ends at BUF, we win;	  if ends before BUF, then resume reading there (we skipped an internal list); otherwise if read did not end, BUF 	  must be inside a list, so scan ahead for start of an inner list, and repeat)    (PROG ((B \BUFFER)	   (INNERMOSTLIST \BUFFER)	   BRACKETFLG X)      LP  (COND	    ((EQ B BUF)                                      (* No list in buffer at all)	      (RETURN INNERMOSTLIST)))          (SELCHARQ (CAR B)		    [(%( %[)                                 (* open paren or bracket. Try scanning this new internal							     list)		      (COND			((EQ (SETQ X (TTSKREAD (CDR B)					       BUF))			     BUF)			  (RETURN (OR BRACKETFLG B)))			(X                                   (* Skip over internal list just scanned)			   (SETQ B X))			(T           (* The TTSKREAD failed, so BUF must be at least this deeply nested. Save pointer here in case we abort inside a 	  string or such)			   (SETQ INNERMOSTLIST B)			   (COND			     ((AND (EQ (CAR B)				       (CHARCODE %[))				   (EQ (CAR BUF)				       (CHARCODE %])))       (* Brackets may match; save position of this open 							     bracket. Otherwise we'll return the innermost list, 							     rather than the start of the bracket expression)			       (SETQ BRACKETFLG B]		    [%%                                      (* %  to quote the next char)			(COND			  ((EQ (CDR B)			       BUF)                          (* The char at BUF is quoted.							     This is why TTSKREAD failed here.							     Just return the list we're now inside)			    (RETURN (AND (NOT NOTIFQUOTED)					 INNERMOSTLIST)))			  (T                                 (* skip over escape char)			     (SETQ B (CDR B]		    [%"                                      (* double-quote)			(COND			  ((NOT (SETQ B (FIND.MATCHING.QUOTE (CDR B)							     BUF)))                                                             (* Termination analogous to previous case)			    (RETURN (AND (NOT NOTIFQUOTED)					 INNERMOSTLIST]		    NIL)          (SETQ B (CDR B))          (GO LP])(BACKWARD.DELETE.TO  [LAMBDA (BUF)                                        (* bvm: "19-MAR-81 11:55")    (FORWARD.DELETE.TO (PROG1 \CURSOR (MOVE.BACK.TO BUF])(BREAKLINE  [LAMBDA (USECR STAY)    (DECLARE (USEDFREE \CURSOR \ARROW \CURSORCOL \CURSOR))   (* bvm: "16-SEP-82 11:52")          (* * Break current line at \CURSOR position, inserting a suitable <cr> if USECR is given. If STAY is true, \CURSOR	  does not move; otherwise cursor moves to first position of new line.)    (PROG ((OLDLINE \ARROW)	   (OLDEND (fetch END of \ARROW)))          (replace END of \ARROW with \CURSOR)               (* terminate current line at \CURSOR position)          (replace LASTCOL of \ARROW with \CURSORCOL)          (ERASE.TO.END.OF.LINE)          (COND	    (STAY (SAVE.CURSOR)))          (SETQ \ARROW (INSERTLINE \ARROW USECR))          (COND	    ((NOT STAY)	      (SAVE.CURSOR)))          (replace END of \ARROW with OLDEND)          [COND	    [(EQ \CURSOR OLDEND)                             (* cr was inserted at end of line.							     Maybe this never happens)	      (replace END of \ARROW with (SETQ \CURSOR (CDR OLDEND]	    (T (TYPE.BUFFER (SETQ \CURSOR (fetch START of \ARROW))			    OLDEND)                          (* Restore to screen what we erased above)	       (replace LASTCOL of \ARROW with \CURSORCOL)	       (COND		 ((OVERFLOWLINE? \ARROW)                     (* the previous line overflowed, but when we inserted a 							     cr we added more space on the line, so go fix it up)		   (ADJUSTLINE]          [COND	    (STAY                                            (* Oh well, undo what we did to poor \CURSOR)		  (SETQ \CURSOR (fetch END of (SETQ \ARROW OLDLINE]          (RESTORE.CURSOR])(BUFCHARCOUNT  [LAMBDA (BUF TAIL PRIN2CNT)                                (* bvm: "20-FEB-82 22:34")          (* returns the number of real chars from BUF to TAIL. If PRIN2CNT is true, pays attention to 	  (i.e. does not count) the escape char (%%))    (for X_BUF by (TTNEXTCHAR X) until (EQ X TAIL) sum [COND							 ((AND PRIN2CNT (EQ (CAR X)									    (CHARCODE %%)))                                                             (* %  to quote next char)							   (SETQ X (CDR X]						       1])(BUFTAILP  [LAMBDA (TAIL START END)                             (* bvm: "23-JUN-81 15:48")    (do (COND	  ((EQ TAIL START)	    (RETURN TAIL))	  ((OR (NOT START)	       (EQ START END))	    (RETURN)))	(SETQ START (CDR START])(CHECK.MARGIN  [LAMBDA (BUF LINE)                                         (* bvm: " 1-JUN-82 17:09")          (* * If BUF is the pseudo-cr at the end of this LINE, then back it up one, since you can't let the cursor sit on 	  it)    (COND      ((AND (EQ (fetch END of LINE)		BUF)	    (OR (EQ (fetch LASTCOL of LINE)		    \RMARG)		(EQ (fetch START of (fetch NEXTLINE of LINE))		    BUF)))	(TTNLEFT BUF 1 (fetch START of LINE)))      (T BUF])(CLEAR.LINE?  [LAMBDA (FLG)                                              (* bvm: "15-JUN-82 17:49")                                                             (* If FLG true, erase lots)    (COND      ((CAPABILITY? ERASE.TO.END)	(COND	  (FLG (ERASE.TO.END.OF.PAGE))	  (T (ERASE.TO.END.OF.LINE])(CREATE.LINE  [LAMBDA (START END COL1 LASTCOL ROW NEXT)                  (* bvm: " 1-JUN-82 18:45")    (FRPLNODE (SCRATCHCONS)	      START	      (FRPLNODE (SCRATCHCONS)			END			(FRPLNODE (SCRATCHCONS)				  COL1				  (FRPLNODE (SCRATCHCONS)					    LASTCOL					    (FRPLNODE (SCRATCHCONS)						      ROW NEXT])(CURRENT.WORD  [LAMBDA NIL                                                (* bvm: "24-AUG-81 18:15")          (* Used by word-completion routines. Returns position in buffer of the start of the current word, or NIL if no 	  word is in progress, or \COMMAND is true and this is not the first word, or the line is a comment)    (COND      ((AND (NOT (AT.START.OF.LINE))	    (NEQ (CAR (fetch START of \ARROW))		 (CHARCODE ;)))	(for (X _(fetch START of \ARROW)) by (CDR X) until (EQ X \CURSOR) bind NEW_T comment                                                              (* NEW is true after we scan a break character)	   do [SELECTC (REALBITS (CAR X))		       (SEPRCODES                            (* mark that we've seen this space)				  (SETQ NEW T))		       (BREAKCODES (SETQ NEW T)				   (SETQ $$VAL X))		       (COND			 (NEW                                (* This is the start of a new word;							     note it)			      (COND				((AND $$VAL \COMMAND)        (* Means this is second word)				  (RETURN)))			      (SETQ $$VAL X)			      (SETQ NEW NIL]	   finally (RETURN (COND			     ((AND (NOT NEW)				   (OR (NOT \READING)				       [NOT (FMEMB (CAR $$VAL)						   (CHARCODE (%" ' ^Y]				       (NEQ (SETQ $$VAL (CDR $$VAL))					    \CURSOR)))          (* Start of word seen, and not yet ended. Check for starting ' or %" in a list input, since those probably don't 	  start this word, i.e. atom)			       $$VAL])(DELETE.TO.END  [LAMBDA NIL                                          (* bvm: "19-MAR-81 11:56")          (* * Kills buffer from \CURSOR onward)    (SETTAIL? T)    (COND      (DISPLAYTERMFLG (ERASE.TO.END.OF.PAGE)))    (COND      ((fetch NEXTLINE of \ARROW)                      (* There are lines after this, so return them to garbage 						       heap)	(KILL.LINES (fetch NEXTLINE of \ARROW))	(replace NEXTLINE of \ARROW with NIL)))    (replace END of \ARROW with (SETQ \ENDBUFFER \CURSOR))    (replace LASTCOL of \ARROW with \CURSORCOL])(DELETELINE  [LAMBDA (LINE EMPTYLINE?)                                  (* bvm: "20-FEB-82 22:20")          (* Deletes this LINE from buffer and screen; assumes cursor is currently positioned somewhere on the line.	  EMPTYLINE? is true on calls from ADJUSTLINE where the line is naked and hence no text in the buffer needs to be 	  killed.)    (PROG ((NEXTLINE (fetch NEXTLINE of LINE))	   OLDSTART NEWSTART PREVLINE)          [COND	    ((AND (EQ LINE \ARROW)		  (ON.FIRST.LINE))	      (COND		((NOT NEXTLINE)                              (* Can't delete the only line)		  (RETURN (BEEP)))		((NEQ \PROMPT1 \PROMPT2)                     (* tricky to delete first line, since the correct prompt							     should be displayed)		  (MOVE.BACK.TO \BUFFER)		  (RETURN (FORWARD.DELETE.TO (fetch END of \ARROW]          (COND	    (DISPLAYTERMFLG (DO.DELETE.LINES 1)))          (RENUMBER.LINES NEXTLINE (fetch ROW of LINE))          (replace NEXTLINE of (SETQ PREVLINE (PREVLINE LINE 1)) with NEXTLINE)          [COND	    ((NOT NEXTLINE)                                  (* deleting last line: need to worry about \ENDBUFFER 							     and such)	      (SETQ \ENDBUFFER (fetch END of PREVLINE)))	    (T (replace NEXTLINE of LINE with NIL)           (* in preparation for KILL.LINES below)	       (COND		 ((NOT EMPTYLINE?)		   (KILLSEGMENT (SETQ OLDSTART (fetch START of LINE))				(SETQ NEWSTART (fetch START of NEXTLINE)))                                                             (* flush anything on the line.							     PREVLINE pointers remain valid)		   (COND		     ((EQ (fetch END of NEXTLINE)			  NEWSTART)		       (replace END of NEXTLINE with OLDSTART)))		   (replace START of NEXTLINE with OLDSTART]          (KILL.LINES LINE)                                  (* return to heap)          (COND	    ((EQ \ARROW LINE)                                (* if this is our home position, adjust appropriately)	      (SETQ \ARROW (SETQ LINE (OR NEXTLINE PREVLINE)))	      (SETQ \CURSOR (fetch START of LINE))	      (GO.TO.RELATIVE (QUOTE LINE)			      LINE])(DELETETO  [LAMBDA (TAIL)                                             (* bvm: " 1-JUN-82 18:24")    (SETTAIL?)    (COND      ((NEQ \CURSOR \ENDBUFFER)                              (* On other terminals also when Cursor capable)	(BACKWARD.DELETE.TO TAIL))      (T [COND	   [(NOT DISPLAYTERMFLG)	     (COND	       ((NOT \DELETING)                              (* prefix deletions with backslash)		 (COND		   ((NOT TTYINBSFLG)                         (* unless we are going to physically backspace)		     (TTBOUT \)))		 (SETQ \DELETING 0)))	     (DELETETO1 TAIL)	     (COND	       ((EQ TAIL \BUFFER)		 (END.DELETE.MODE]	   (T (PROG ((N (SEGMENT.BIT.LENGTH TAIL \ENDBUFFER)))                                                             (* need to kill the previous N chars)          (* (COND ((CAPABILITY? ERASE.TO.END T) (* Ah, all we need do is go back N and erase to end) 	  (DO.BACK N) (ERASE.TO.END.OF.LINE)) (T (* laborious technique for glass ttys: go back and wipe out each char one 	  at a time) (FRPTQ N (PROGN (DO.BACK 1) (* back up) (TTBOUT SPACE) (* overwrite with space) 	  (DO.BACK 1) (* and back up again))))))		    (DSPBACKUP N)		    (SETQ \CURSORCOL (IDIFFERENCE \CURSORCOL N]	 (replace END of \ARROW with (SETQ \CURSOR (SETQ \ENDBUFFER TAIL)))	 (replace LASTCOL of \ARROW with \CURSORCOL])(DELETETO1  [LAMBDA (TAIL)                                             (* bvm: " 1-JUN-82 18:27")          (* * Not used in Interlisp-D)          (* * on non-DMs: delete chars until we reach TAIL; since we echo deleted chars in reverse order, this is most 	  easily done recursively)    [COND      ((NEQ (CDR TAIL)	    \ENDBUFFER)	(DELETETO1 (CDR TAIL]    [COND      ((NOT (PREFIXCHAR (CAR TAIL)))	(SELECTQ TTYINBSFLG		 (NIL (TTBOUT (CAR TAIL)))		 (LF           (* physically backspace, crossing out character. LF means we will do a LF when ENDELETE happens.	  If we don't LF, then best not to cross out chars)		     (TTBOUT BS \ BS)		     (ADD1VAR \DELETING))		 (TTBOUT BS]                                 (* echo deleted char)    (SETQ \CURSORCOL (SUB1 \CURSORCOL])(DO.EDIT.COMMAND  [LAMBDA (CHAR EDITARG)                                     (* bvm: "15-JUN-82 16:51")          (* * Handles the various edit commands, which mostly move the cursor around in the buffer, or kill pieces of it.	  CHAR is the character stripped of its editbit. EDITARG is the argument, if any (not set by type-in, but by program	  asking for a particular edit function). If this routine returns something, it means process it like ordinary 	  character (this is how we can invoke non-editbit routines))    (PROG (EDITMINUS L X LASTSKIP)          [COND	    ((NOT EDITARG)	      (SETQ EDITARG 1))	    ((MINUSP EDITARG)	      (SETQ EDITMINUS T)	      (SETQ EDITARG (IABS EDITARG]      LP  [SELCHARQ (SETQ CHAR (U-CASECODE CHAR))		    [CR           (* <edit>CR on empty buffer means get back last buffer; in the middle of a buffer it is the same as normal CR, but	  also ends insert mode)			(COND			  ((EMPTY.BUFFER)			    (RESTOREBUF))			  ((ON.LAST.LINE)			    (RETURN CHAR))			  (T (MOVE.TO.LINE (TTNEXTLINE \ARROW EDITARG]		    [(SPACE >)                               (* move right)		      (COND			(EDITMINUS (SETQ CHAR (CHARCODE DEL))                                                             (* backward space is delete)				   (GO NOMINUS))			((AT.END.OF.BUF)			  (BEEP))			((AT.END.OF.SCREEN)			  (MOVE.TO.NEXT.LINE))			(T (MOVE.FORWARD.TO (TTNTH \CURSOR EDITARG]		    [(DEL ^A BS <)                           (* back up)		      (COND			(EDITMINUS (SETQ CHAR (CHARCODE SPACE))                                                             (* backward delete is space)				   (GO NOMINUS))			((AT.START.OF.BUF)			  (BEEP))			((AT.START.OF.LINE)			  (MOVE.TO.LINE (SETQ X (PREVLINE \ARROW 1))					(fetch END of X)))			(T (MOVE.BACK.TO (TTNLEFT \CURSOR EDITARG]		    [%(                                      (* backs up one word)			(COND			  (EDITMINUS (SETQ CHAR (CHARCODE %)))				     (GO NOMINUS))			  (T (MOVE.BACK.TO (PREVWORD \CURSOR EDITARG]		    [%)                                      (* moves ahead one word)			(COND			  (EDITMINUS (SETQ CHAR (CHARCODE %())				     (GO NOMINUS))			  ((AT.END.OF.SCREEN)			    (BEEP))			  (T (MOVE.FORWARD.TO (FIND.NEXT.WORD \CURSOR EDITARG]		    (TAB                                     (* go to end of line)			 (MOVE.TO.LINE (SETQ X (TTNEXTLINE \ARROW (SUB1VAR EDITARG)))				       (fetch END of X)))		    [^L                                      (* go to start of line)			(MOVE.TO.LINE (PREVLINE \ARROW (SUB1VAR EDITARG]		    ({                                       (* { goes to start of buffer, like infinite FF)		       (MOVE.TO.LINE \FIRSTLINE))		    (}                                       (* } goes to end of buffer, like infinite TAB)		       (MOVE.TO.LINE (SETQ X (TTLASTLINE))				     (fetch END of X)))		    [LF                                      (* moves down)			(COND			  (EDITMINUS (SETQ CHAR (CHARCODE ^))				     (GO NOMINUS))			  [(ON.LAST.LINE)			    (COND			      ((EMPTY.BUFFER)                (* Treat this the same as regular linefeed, i.e. restore							     buffer)				(RETURN (CHARCODE LF)))			      (T (BEEP]			  (T (MOVE.TO.LINE (SETQ X (TTNEXTLINE \ARROW EDITARG))					   (NTH.COLUMN.OF X (EDITCOLUMN]		    [^                                       (* moves up)		       (COND			 (EDITMINUS (SETQ CHAR (CHARCODE LF))				    (GO NOMINUS))			 ((ON.FIRST.LINE)			   (BEEP))			 (T (MOVE.TO.LINE (SETQ X (PREVLINE \ARROW (IMIN (IPLUS \LOC.ROW.0 \CURSORROW)									 EDITARG)))					  (NTH.COLUMN.OF X (EDITCOLUMN]		    [K                                       (* kills one char)		       (COND			 ((AT.END.OF.LINE)			   (BEEP))			 (T (FORWARD.DELETE.TO (TTNTH \CURSOR EDITARG]		    [I                                       (* insert)		       [COND			 ((NEQ EDITARG 1750Q)          (* $$I inserts line on any terminal; on EDIT-key terminals, we also allow TV's silly method of saying $I<cr>, so 	  have to peek at the next char)			   (COND			     ((OR (NOT (CAPABILITY? EDIT))				  (NOT (PROGN (SETQ CHAR (TTBIN))					      \EDITBIT)))			       (OR (AT.END.OF.LINE)				   (SETQ \INSERTING T))			       (RETURN CHAR))			     ((NEQ CHAR (CHARCODE CR))       (* editbit shuts off insert mode)			       (SETQ EDITARG 1)			       (GO NOMINUS]                  (* I<cr> means insert blank line IN FRONT OF this line 							     and stay on it)		       (COND			 ((ON.FIRST.LINE)                    (* Difficult to insert line in front of first, so use 							     plan b)			   (MOVE.BACK.TO \BUFFER)			   (BREAKLINE EOLCHARCODE)			   (MOVE.TO.LINE \FIRSTLINE))			 (T (GO.TO.RELATIVE NIL (SUB1 \CURSORROW))                                                             (* Since INSERTLINE thinks you're on the previous line)			    (INSERTLINE (PREVLINE \ARROW 1)					EOLCHARCODE)			    (SETQ \CURSOR (fetch START of (SETQ \ARROW (PREVLINE \ARROW 1]		    ((S Z B)                                 (* various skip or zap commands)		      (SKIP/ZAP CHAR (TTBIN)				EDITARG EDITMINUS))		    [A                                       (* repeat last S or Z)		       (COND			 ((SETQ LASTSKIP (fetch LASTSKIP of \TTYINSTATE))			   (SKIP/ZAP LASTSKIP (fetch LASTSKIPCHAR of \TTYINSTATE)				     EDITARG EDITMINUS))			 (T (BEEP]		    (L                                       (* lowercase word)		       (U/L-CASE EDITARG))		    (U                                       (* uppercase word)		       (U/L-CASE EDITARG T))		    (C                                       (* capitalize word)		       (U/L-CASE EDITARG 1))		    [G                                       (* grab a copy of Nth previous line)		       (COND			 ((OR (ON.FIRST.LINE)			      (NOT (AT.END.OF.LINE))			      (EQ (SETQ X (NTH.COLUMN.OF (SETQ L (PREVLINE \ARROW EDITARG))							 \CURSORCOL))				  (fetch END of L)))         (* nothing to copy)			   (BEEP))			 (T (READFROMBUF X (fetch END of L)					 T]		    [%]                                      (* Move to end of current expression)			(COND			  ((AT.END.OF.BUF)			    (BEEP))			  (T (MOVE.TO.WHEREVER (OR (TTSKREAD (TTNEXTCHAR \CURSOR))						   \ENDBUFFER]		    [%[                                      (* Move to start of current list expression)			(COND			  ((AT.START.OF.BUF)			    (BEEP))			  (T (MOVE.TO.WHEREVER (BACKSKREAD \CURSOR]		    [^W                                      (* delete current word)			(COND			  ((EMPTY.LINE)                      (* empty buffer)			    (BEEP))			  ((INSERTING)                       (* Don't want to delete whole word, just what's before 							     the cursor)			    (BACKWARD.DELETE.TO (PREVWORD \CURSOR EDITARG)))			  (T (SETQ X (OR (AT.END.OF.LINE)					 (SELCHARQ (CAR \CURSOR)						   ((%( %) %[ %])						     NIL)						   T)))          (* X is true if not sitting on a paren, in which case we want to treat parens as spaces; if on a paren, then allow	  below to delete parens as well)			     (MOVE.TO.START.OF.WORD)			     (FORWARD.DELETE.TO (FIND.NEXT.WORD \CURSOR EDITARG X]		    (^Y                                      (* gets userexec)			(COND			  ((AND (EQ EDITARG 1750Q)				(NEQ \CURSOR \ENDBUFFER))			    (TTUNREADBUF)                    (* Stuff what's ahead of cursor into input buffer)			    ))			(SETQ \EDITBIT T)			(RETURN CHAR))		    [(^Q ^U)                                 (* Delete line; ^U for tops20 folk)		      (COND			((EQ EDITARG 1750Q)			  (DELETE.TO.END))			(T (DELETELINE \ARROW]		    [D (COND			 [EMACSFLG                           (* EMACS interpretation is delete to end of word)				   (COND				     ((AT.END.OF.LINE)				       (BEEP))				     (T (COND					  ((AND (NEQ (SETQ X (FIND.NEXT.WORD \CURSOR EDITARG T))						     (fetch END of \ARROW))						(NOT (AT.START.OF.LINE))						[NOT (WORDSEPRP (CAR (TTNLEFT \CURSOR 1]						[SPACEP (CAR (SETQ L (TTNLEFT X 1 \CURSOR]						(NEQ L \CURSOR))          (* Don't want to delete all the way to start of new word, since we'd like a little space in between.	  Simulating EMACS would probably be easier if we just made FIND.NEXT.WORD stop at the intervening spaces rather 	  than at the end)					    (SETQ X L)))					(FORWARD.DELETE.TO X]			 (T                                  (* D is TVEDIT's delete command -- convert it to 							     appropriate cmd)			    (SELCHARQ (TTBIN)				      (CR (SETQ CHAR (CHARCODE ^Q))					  (GO LP))				      (DEL (SETQ CHAR (CHARCODE ^W))					   (GO LP))				      (BEEP]		    [F                                       (* accept tvedit's $$F to finish)		       (COND			 [(EQ EDITARG 1750Q)			   (MOVE.TO.WHEREVER \ENDBUFFER)			   (COND			     ((NEQ \CURSOR \ENDBUFFER)       (* This is because the cursor mover refuses to put me in							     column 120Q of a line, due to certain anomalies)			       (add \CURSORCOL (SEGMENT.BIT.LENGTH \CURSOR \ENDBUFFER))			       (SETQ \CURSOR \ENDBUFFER)			       (OVERFLOW? 0)))			   (RETURN (COND				     (\REPEAT                (* End with ^Z)					      (CHARCODE ^Z))				     (\READING               (* End read with "]"; of course, this doesn't always 							     "finish", but it's simple enough to remember what this 							     is)					       (CHARCODE %]))				     (T (CHARCODE CR]			 (T (BEEP]		    (J                                       (* Justify/fill line)		       (ADJUSTLINE.AND.RESTORE EDITARG))		    (-                                       (* minus sign negates arg)		       (SETQ EDITARG 0)		       (SETQ EDITMINUS T)		       (GO DONUMBERS))		    (ESCAPE                                  (* ESCAPE may modify next command)			    [COND			      ((AND (EQ EDITARG 1750Q)				    (EQ EDITPREFIXCHAR (CHARCODE ESCAPE)))          (* 3 escapes in a row is the way to type a regular Escape when Escape is the edit prefix. Better ways might be 	  forthcoming)				(RETURN (CHARCODE ESCAPE]			    (SETQ EDITARG 1750Q)             (* 1750Q is an adequate infinity for these purposes)			    (SETQ EDITMINUS)			    (SETQ CHAR (TTBIN))			    (GO LP))		    [(N ^R)                                  (* refresh n lines, or whole buffer for $$N)		      (COND			((EQ EDITARG 1750Q)			  (RETYPE.BUFFER \FIRSTLINE T))			(EDITMINUS (RETYPE.BUFFER (PREVLINE \ARROW EDITARG)						  \ARROW))			(T (RETYPE.BUFFER \ARROW (TTNEXTLINE \ARROW EDITARG]		    [T                                       (* transpose chars. If at end of line, do preceding two,							     else do the ones before and after the cursor.)		       [SETQ L (TTNLEFT \CURSOR (SETQ X (COND					    ((AT.END.OF.LINE)					      2)					    (T 1]            (* start of swap)		       (COND			 ((OR (EQ L \CURSOR)			      (PREFIXCHAR (CAR L))			      (AND (EQ X 2)				   (EQ (CDR L)				       \CURSOR))			      (PREFIXCHAR (CADR L)))         (* Complain if not enough chars to swap, or one of them 							     is a funny multiple char (I'm lazy))			   (BEEP))			 (T [GO.TO.RELATIVE (IDIFFERENCE \CURSORCOL (SEGMENT.BIT.LENGTH							   L							   (NTH L (ADD1 X]                                                             (* Back up to start of segment)			    [FRPLACA L (PROG1 (CADR L)					      (FRPLACA (CDR L)						       (CAR L]                                                             (* Do the swap in the buffer)			    (TYPE.BUFFER L (CDDR L))         (* Fix the display)			    (COND			      ((EQ X 1)                      (* Were between two chars, so get back there)				(GO.TO.RELATIVE (IDIFFERENCE \CURSORCOL (TTBITWIDTH							       (REALBITS (CADR L]		    (O                                       (* Open line, i.e. insert <cr> but stay here)		       (BREAKLINE EOLCHARCODE T))		    [_                                       (* Special hack: says to add the word before the cursor 							     to USERWORDS, so I can use altmode completion on it)		       (COND			 [(AND TTYINCOMPLETEFLG (SETQ X (CURRENT.WORD))			       [SETQ X (PROG ((\BUFFER X))					     (RETURN (TTRATOM]			       (LITATOM X))			   (COND			     ((ZEROP EDITARG)                (* Means to remove! I don't know if there's an "official" way to do this)			       (DREMOVE X USERWORDS))			     (T (ADDSPELL X 0]			 (T (BEEP]		    (P (DO.EDIT.PP))		    (COND		      ((SETQ CHAR (EDITNUMBERP CHAR))			(SETQ EDITARG CHAR)			(GO DONUMBERS))		      (T (BEEP]          (SETQ \LASTCHAR CHAR)          (RETURN)      NOMINUS          (SETQ EDITMINUS)          (GO LP)      DONUMBERS          (* * scanning a numeric arg. EDITARG is its magnitude; EDITMINUS set if negative. <edit>escape is treated as 1000,	  which is probably big enough. Doesn't matter if any of the next chars has edit bit on, since once we start a 	  number, any other digits must be part of it, since numbers aren't themselves commands)          (COND	    ([SETQ X (EDITNUMBERP (SETQ CHAR (TTBIN]	      [SETQ EDITARG (COND		  ((IGREATERP EDITARG 144Q)                  (* Limit numeric args to 1750Q so small number stuff 							     works)		    1750Q)		  (T (IPLUS (ITIMES EDITARG 12Q)			    X]	      (GO DONUMBERS)))          (COND	    ((AND EDITMINUS (ZEROP EDITARG))                 (* Happens if we get a "-" followed by no number)	      (SETQ EDITARG 1)))          (GO LP])(DO.EDIT.PP  [LAMBDA NIL                                                (* bvm: "18-OCT-82 12:38")    (COND      [\READING (PROG (LEFTOVER EXPRS (\BUFFER \BUFFER))		      [COND			((NOT (TTYIN.BALANCE))			  (COND			    ((NEQ \CURSOR \ENDBUFFER)			      (SETQ LEFTOVER (COPY.SEGMENT \CURSOR \ENDBUFFER))			      (SETQ \ENDBUFFER \CURSOR]		      (SETQ \CURSOR \BUFFER)		      [COND			((NEQ (TTSKIPSEPR)			      \ENDBUFFER)			  (SETQ EXPRS (CAR (OR (NLSETQ (TTYIN.READ 0 NIL (TTYIN.SCRATCHFILE)))					       (PROGN        (* Read failed, punt)						      (TTYIN.BALANCE)						      (RETURN (BEEP]		      (MOVE.TO.LINE \FIRSTLINE)		      (ERASE.TO.END.OF.PAGE)		      (TTYIN1RESTART)		      (replace FIRSTCOL of \ARROW with (replace LASTCOL of \ARROW with \CURSORCOL))		      [COND			(EXPRS (TTLOADBUF (LIST HISTSTR1 (TTYIN.PPTOFILE EXPRS]		      (COND			(LEFTOVER (BREAKLINE (CHARCODE EOL))				  (READFROMBUF LEFTOVER]      (T (RETYPE.BUFFER \FIRSTLINE T])(DO?CMD  [LAMBDA (CMD \?TAIL)    (DECLARE (SPECVARS \?TAIL \?PARAMS \BUFFER))             (* bvm: "15-NOV-82 17:41")          (* * Handles "read macros" ? and ?=. CMD is one of those. Returns NIL if thinks it isn't. Saves current cursor 	  location for later restoration)    (PROG ((\BUFFER \BUFFER)	   (START (BACKSKREAD \CURSOR))	   FN)          (SELCHARQ (CAR START)		    [(%( %[)		      (COND			((AND (EQ (SCANFORWARD (CAR START)					       \BUFFER)				  START)			      (PROGN                         (* START is the first paren in buffer, so check and see 							     if there's an atom before it)				     (SETQ FN (TTRATOM))				     [COND				       ((OR (EQ FN (QUOTE E))					    (AND (EQ \PROMPT1 (QUOTE *))						 (FMEMB FN EDITCOMSL)))                                                             (* What looks like a fn in apply format is really a 							     command, either E or an editor command)					 (SETQ FN (TTRATOM]				     (EQ (TTSKIPSEPR)					 START)))            (* This is first list on line, preceded by FN in evalqt 							     format)			  )			(T (SETQ \BUFFER (CDR START))        (* EVAL form: read fn)			   (COND			     ((EQ (SETQ FN (TTRATOM))				  CMD)                       (* Hasn't typed the fn name yet!)			       (RETURN]		    (PROGN                                   (* Not inside a list now, so no macro)			   (RETURN)))          (SAVE.CURSOR)          (COND	    [(NLSETQ (PROG ((\?PARAMS null)			    ARGS FILE STUFF)		           (COND			     ((EQ CMD (QUOTE ?))			       (TERPRI T)			       (XHELPSYS FN)			       (TAB 0 0 T))			     (T (GO.TO.FREELINE)				[COND				  ((EQ \BUFFER START)        (* Apply format, skip over paren)				    (SETQ \BUFFER (CDR START]				(COND				  ([OR (NOT TTYIN?=FN)				       (NOT (SETQ STUFF (APPLY* TTYIN?=FN FN]				    (TTYIN.PRINTARGS FN (SMARTARGLIST FN)						     T))				  ((EQ (CAR (LISTP STUFF))				       (QUOTE ARGS))				    (TTYIN.PRINTARGS FN (CDR STUFF)						     T))				  ((LISTP STUFF)				    (TTPRIN2 STUFF))				  ((NEQ STUFF T)				    (TTPRIN1 STUFF]	    ((EQ CMD (QUOTE ?=))          (* error occurred, probably undefined fn. This used to cause the cursor to be down further, in which case we did 	  TTCRLF.ACCOUNT, but now it is quiet)	      (BEEP)))          (RETURN T])(TTYIN.PRINTARGS  [LAMBDA (FN ARGS ACTUALS ARGTYPE)                          (* bvm: "27-JUL-83 23:30")    (PROG (TYPE)          (* Prints args to fn, mastching up with ACTUALS, if supplied. Do this in a way that lets us keep track of where we	  are)          (TTPRIN1 (SELECTQ (SYSTEMTYPE)			    (D (QUOTE %())			    (QUOTE %[)))          (DSPFONT (PROG1 (DSPFONT [CDR (COND					  ((EQ (CAR TTYINBOLDFONT)					       \FONT)					    TTYINBOLDFONT)					  (T (\SET.TTYINBOLDFONT \FONT]				   \DSP)                     (* Make fn name boldface)			  (TTPRIN1 FN))		   \DSP)          [COND	    ((NOT ARGS))	    ((NLISTP ARGS)	      (TTPRIN1 (QUOTE % ))	      (TTPRIN1 ARGS)	      (TTPRIN1 (QUOTE ...)))	    (T [COND		 ((COND		     ((EQ ACTUALS T)		       (SETQ ACTUALS (TTYIN.READ?=ARGS)))		     (T ACTUALS))		   [COND		     ((CDR ACTUALS)		       (TTCRLF))		     (T (TTPRIN1 (QUOTE % ]		   (while ACTUALS		      do [TTPRIN1 (COND				    (ARGS (OR (CAR (LISTP ARGS))					      ARGS))				    (T (QUOTE extra]			 (TTPRIN1 " = ")			 (COND			   ((LISTP ARGS)			     (TTPRIN2 (CAR ACTUALS)				      2 4)			     (SETQ ARGS (CDR ARGS))			     (SETQ ACTUALS (CDR ACTUALS)))			   (T (TTPRIN2 ACTUALS 2 4)			      (SETQ ACTUALS)))			 (TTCRLF]	       (for X in ARGS		  do (TTPRIN1 (QUOTE % ))		     (TTPRIN1 X]          (TTPRIN1 (SELECTQ (SYSTEMTYPE)			    (D (QUOTE %)))			    (QUOTE %])))          (COND	    ((SETQ TYPE (SELECTQ (OR ARGTYPE (ARGTYPE FN))				 (1 (QUOTE NL))				 (3 (QUOTE NL*))				 (2 (QUOTE L*))				 NIL))                       (* indicate arg type)	      (TTPRIN1 " {")	      (TTPRIN1 TYPE)	      (TTPRIN1 (QUOTE }])(TTYIN.READ?=ARGS  [LAMBDA NIL                                                (* bvm: "22-SEP-82 15:18")    (COND      [(EQ \?PARAMS null)	(SETQ \?PARAMS (COND	    ((NEQ (TTSKIPSEPR \?TAIL)		  \?TAIL)	      (PROG [(FILE (\GETOFD (TTYIN.SCRATCHFILE)				    (QUOTE INPUT]		    (\BOUT FILE (CHARCODE %())		    [for (BUF _ \BUFFER) by (TTNEXTCHAR BUF) until (EQ BUF \?TAIL)		       do (\BOUT FILE (REALBITS (CAR BUF]		    (\BOUT FILE (CHARCODE %)))		    (SETFILEPTR FILE 0)		    (RETURN (READ FILE RDTBL]      (T (LISTP \?PARAMS])(DOTABS  [LAMBDA (TABS)                                             (* bvm: " 1-JUN-82 18:06")                                                             (* Tab to next tabstop in TABS, if any.							     Represent pseudotabs as prefix chars 240Q.							     Return T if anything done)    (AND TABS (AT.END.OF.BUF)	 (for TB in TABS bind SPACES when (AND (SMALLP TB)					       (IGREATERP (SETQ SPACES (IDIFFERENCE (ITIMES TB 										       \CHARWIDTH)										    \CURSORCOL))							  \CHARWIDTH))	    do (OVERFLOW? (SETQ SPACES (IQUOTIENT SPACES \CHARWIDTH)))	       (INSERT.CHAR.IN.BUF (PREFIXCHARCODE SPACE))                                                              (* Stick in a pseudo-tab)	       (FRPTQ SPACES (ADDCHAR (PADCHARCODE SPACE)))                                                              (* Echo as spaces)	       (RETURN T])(EDITCOLUMN  [LAMBDA NIL                                                (* bvm: "24-AUG-81 23:17")          (* If last edit command moved up/down, then return the same column we were using then; else use current cursor 	  column, and record it as the "goal" column for any future such commands)    (OR (SELCHARQ \LASTCHAR		  ((LF ^)		    \HOMECOL)		  NIL)	(SETQ \HOMECOL \CURSORCOL])(EDITNUMBERP  [LAMBDA (CHAR)                                       (* bvm: "11-MAR-81 22:05")    (AND [NOT (MINUSP (SETQ CHAR (IDIFFERENCE CHAR (CONSTANT (CHCON1 0]	 (NOT (IGREATERP CHAR 11Q))	 CHAR])(END.DELETE.MODE  [LAMBDA NIL                                                (* bvm: "19-MAR-81 11:59")    (COND      (\DELETING (SELECTQ TTYINBSFLG			  (NIL (TTBOUT \))			  [LF (COND				((IGREATERP \DELETING 1)     (* if more than one char x'd out, lf to new line)				  (DO.LF]			  NIL)		 (SETQ \DELETING NIL])(ENDREAD?  [LAMBDA NIL                                                (* bvm: " 2-MAR-82 12:36")          (* Return true if the paren/bracket just typed terminates the input. It does if the right paren 	  (or even one earlier in buffer) is in excess, i.e unbalanced, or just balances and this is the only list on the 	  line, or we are doing a LISPX input and the input is in EVALQT form, with no space after the first atom)    (PROG (X)          (RETURN	    (AND	      (AT.END.OF.TEXT \CURSOR)	      (SETQ X (TTSKREAD \BUFFER))	      (OR		(NEQ X \ENDBUFFER)		(AND		  [SELCHARQ		    (CAR (SETQ X (FIND.NON.SPACE \BUFFER)))		    ((%( %[)                                 (* OK, line started with paren/bracket)		      T)		    (AND		      (EQ \READING (QUOTE EVALQT))		      (NEQ \PROMPT1 (QUOTE *))		      (while (NEQ X \ENDBUFFER)			 do           (* Skip over this first atom, to see if input is in EVALQT form. Prompt check is so we don't do this in the 	  editor)			    (SELCHARQ			      (REALBITS (CAR X))			      ((SPACE TAB ^Z %")             (* Space, etc: probably wants more on line)				(RETURN NIL))			      [(%( %[)                       (* Open paren/bracket: looks good)				(RETURN (PROGN (PROGN (PROGN (PROGN (PROGN (PROGN (PROGN                                                              (* Prettyprint sucks again!)											 T]			      (%%                            (* Skip over % )				  (SETQ X (CDR X)))			      NIL)			    (SETQ X (CDR X]		  (EQ (CDR (TTSKREAD (CDR X)))		      \CURSOR])(FIND.LINE  [LAMBDA (BUF)    (DECLARE (USEDFREE \FIRSTLINE))                    (* bvm: "23-JUN-81 16:12")          (* * Returns the buffer LINE on which BUF, a cursor position, occurs)    (for LINE_\FIRSTLINE do (COND			      [(EQ BUF (fetch END of LINE))                                                       (* Check this separately so next BUFTAILP doesn't catch it)				(RETURN (COND					  ((OVERFLOWLINE? LINE)					    (fetch NEXTLINE of LINE))					  (T LINE]			      ((BUFTAILP BUF (fetch START of LINE)					 (fetch END of LINE))				(RETURN LINE)))			    (OR (SETQ LINE (fetch NEXTLINE of LINE))				(SHOULDNT])(FIND.LINE.BREAK  [LAMBDA (START END USELAST)                                (* bvm: "20-FEB-82 22:35")          (* * Locates a place between START and END where line can be broken. If USELAST is true, returns last such place, 	  else first)    (while (NEQ START END) do [COND				((EQ (CAR START)				     (CHARCODE SPACE))				  (COND				    (USELAST (SETQ $$VAL START))				    (T (RETURN START]			      (SETQ START (TTNEXTCHAR START])(FIND.MATCHING.QUOTE  [LAMBDA (BUF END)                                          (* bvm: "24-AUG-81 23:57")          (* * Searches BUF until END for a closing double-quote)    (while (NEQ BUF END) do (SELCHARQ (CAR BUF)				      (%" (RETURN BUF))				      [%%                    (* "%%" quotes next char)					  (COND					    ((EQ (SETQ BUF (CDR BUF))						 END)					      (RETURN]				      NIL)			    (SETQ BUF (CDR BUF])(FIND.MATCHING.WORD  [LAMBDA (WORDS START BUFTAIL)                              (* bvm: "20-FEB-82 22:34")          (* Find the first word in spelling list WORDS which matches the characters in the buffer from START to BUFTAIL 	  (or current cursor position), and return the corresponding tail of WORDS)    (OR BUFTAIL (SETQ BUFTAIL \CURSOR))    (find TAIL on WORDS suchthat (WORD.MATCHES.BUFFER (INPART (CAR TAIL))						      START BUFTAIL])(FIND.NEXT.WORD  [LAMBDA (BUFTAIL N BACKUPFLG)                              (* bvm: "25-FEB-82 22:39")          (* * Return start of Nth word after BUFTAIL, or end of line if none. BACKUPFLG means if you cross a paren getting 	  to the Nth word, return the paren rather than the word (used for smart word-delete))    (PROG ((END (fetch END of \ARROW)))          (COND	    ((EQ BUFTAIL END)	      (RETURN END)))          (SETQ BUFTAIL (CDR BUFTAIL))      LP  [COND	    ((EQ BUFTAIL END)	      (RETURN END))	    ((WORDSEPRP (CAR BUFTAIL))                       (* Found a space. Now scan for first non-space, and 							     return there)	      [COND		(BACKUPFLG (SETQ BUFTAIL (SETQ BACKUPFLG (FIND.START.OF.WORD BUFTAIL END]	      (while (AND (NEQ BUFTAIL END)			  (WORDSEPRP (CAR BUFTAIL)))		 do (SETQ BUFTAIL (CDR BUFTAIL)))	      (COND		((OR (NOT N)		     (ZEROP (SUB1VAR N))		     (EQ BUFTAIL END))		  (RETURN (OR BACKUPFLG BUFTAIL]          (SETQ BUFTAIL (CDR BUFTAIL))          (GO LP])(FIND.NON.SPACE  [LAMBDA (BUF END)                                          (* bvm: " 2-MAR-82 12:35")    (OR END (SETQ END \ENDBUFFER))    (while (AND (NEQ BUF END)		(SPACEP (CAR BUF)))       do (SETQ BUF (CDR BUF)))    BUF])(FIND.START.OF.WORD  [LAMBDA (BUF END)                                          (* bvm: "25-FEB-82 22:46")          (* * Returns position of first word, i.e. non-space, in BUF before END)    (OR END (SETQ END \ENDBUFFER))    (while (AND (NEQ BUF END)		(WORDSEPRP (CAR BUF)))       do (SETQ BUF (CDR BUF)))    BUF])(FORWARD.DELETE.TO  [LAMBDA (BUFTAIL)                                          (* bvm: " 1-JUN-82 17:16")          (* * Delete from \CURSOR to BUFTAIL. Cursor does not move)    [COND      ((EQ BUFTAIL \CURSOR)                                  (* Nothing to do)	)      ((EQ BUFTAIL \ENDBUFFER)                               (* deleting to end is simple)	(ERASE.TO.END.OF.LINE)	(replace END of \ARROW with (SETQ \ENDBUFFER \CURSOR))	(replace LASTCOL of \ARROW with \CURSORCOL))      (T (PROG ((DELETEDWIDTH (SEGMENT.BIT.LENGTH \CURSOR BUFTAIL))		L)	       (COND		 ((EQ BUFTAIL (fetch END of \ARROW))         (* End pointer is about to disappear into free list, so 							     move it back here)		   (replace END of \ARROW with \CURSOR)		   [COND		     ((EQ (fetch START of (SETQ L (fetch NEXTLINE of \ARROW)))			  BUFTAIL)		       (replace START of L with \CURSOR)		       (COND			 ((EQ (fetch END of L)			      BUFTAIL)			   (replace END of L with \CURSOR]		   (ERASE.TO.END.OF.LINE))		 (T (TTDELSECTION DELETEDWIDTH)))	       (KILLSEGMENT \CURSOR BUFTAIL)	       (replace LASTCOL of \ARROW with (IDIFFERENCE (fetch LASTCOL of \ARROW)							    DELETEDWIDTH))	       (COND		 ((OVERFLOWLINE? \ARROW)		   (ADJUSTLINE.AND.RESTORE]    \CURSOR])(GO.TO.ADDRESSING  [LAMBDA (COL ROW)                                          (* bvm: "20-FEB-82 22:36")                                                             (* Regardless of where we are now, go to logical 							     position COL,ROW using cursor addressing)    (PROG ((ABSROW (IPLUS \LOC.ROW.0 ROW)))          (TTSETCURSOR COL (COND			 ((ILESSP ABSROW 0)                  (* trying to go beyond top of screen;							     ideally we should scroll, but for now just forbid it)			   (SETQ ROW (IDIFFERENCE ROW ABSROW))			   0)			 ((NOT (ILESSP ABSROW \TTPAGELENGTH))                                                             (* This shouldn't happen at all until we can scroll!)			   (SETQ ROW (IPLUS (IDIFFERENCE ROW ABSROW)					    \TTPAGELENGTH -1))			   (SUB1 \TTPAGELENGTH))			 (T ABSROW)))          (SETQ \CURSORROW ROW)          (SETQ \CURSORCOL COL])(GO.TO.FREELINE  [LAMBDA NIL                                                (* bvm: "30-MAR-82 14:54")          (* * Moves cursor to the first free line after the buffer, and clears it)    (GO.TO.RELATIVE NIL (fetch ROW of (TTLASTLINE)))         (* Put the cursor on the last row of buffer)    (TTCRLF)                                                 (* And down one more)    (COND      ((CAPABILITY? ERASE.TO.END)	(ERASE.TO.END.OF.PAGE])(GO.TO.RELATIVE  [LAMBDA (COL ROW)                                          (* bvm: "21-APR-83 11:42")          (* * Moves cursor to indicated row/col. ROW arg may be omitted if the movement is on the same row.	  If COL=LINE then ROW is interpreted as a LINE record, and destination is the start of that line)    [PROG ((FROMROW \CURSORROW)	   (FROMCOL \CURSORCOL))          (COND	    ((EQ COL (QUOTE LINE))	      (SETQ COL (fetch FIRSTCOL of ROW))	      (SETQ ROW (fetch ROW of ROW)))	    ((NOT COL)	      (SETQ COL FROMCOL))	    ((NOT ROW)	      (SETQ ROW FROMROW)))          (* (COND ((EQ FROMCOL \TTLINELENGTH) (SETQ FROMCOL 0) (* Cursor is logically at the end of the line, but on a dm, 	  an auto crlf has occurred, so cursor is really at start of next line) (DO.CRLF) (* This is supposed to work 	  (i.e. autocr means a crlf now is ignored), but what if something was sent between then and now?) 	  (ADD1VAR FROMROW))) (COND ((EQ COL \TTLINELENGTH) (* This shouldn't happen, but it can if there is a line that 	  fills the screen line but ends in a cr) (SETQ COL 0) (ADD1VAR ROW))))          (RETURN (MOVETO (IPLUS COL \LMARG)			  (IPLUS (ITIMES (SUB1 (IDIFFERENCE \TTPAGELENGTH (IPLUS \LOC.ROW.0 ROW)))					 \CHARHEIGHT)				 \BMARG)			  \DSP))          (* (COND ((NOT DISPLAYTERMFLG) (* Can't actually move cursor) (RETURN)) ((AND (CAPABILITY? \CURSOR T) 	  (COND ((EQ ROW FROMROW) (IGREATERP (IABS (IDIFFERENCE COL FROMCOL)) 1)) ((EQ COL FROMCOL) 	  (IGREATERP (IABS (IDIFFERENCE ROW FROMROW)) 1)) (T T))) (* If moving very far, use cursor addressing) 	  (RETURN (GO.TO.ADDRESSING COL ROW))) ((ILESSP FROMCOL COL) (* Only way to move forward is one position at a time) 	  (DO.FORWARD (IDIFFERENCE COL FROMCOL))) ((ILESSP (IPLUS COL 2) (IDIFFERENCE FROMCOL COL)) 	  (* Moving backward to a position which is closer to left margin than to the current position, so do it by a CR 	  first. Note: this assumes that moving backward and moving forward are equally expensive; probably 	  terminal-dependent) (COND ((ILESSP FROMROW ROW) (* Already above where we are going, so CR will take us down 1 row	  as well as putting us in col 0) (ADD1VAR FROMROW)) (T (DO.UP 1))) (DO.CRLF) (* actually, CR alone suffices, except	  that if the next char we output is a LF, it will be ignored, so do the LF anyway to avoid confusion.	  Besides, some clowns tried to simulate a datamedia and forgot this not very desirable feature, and thus we will be	  able to work on those terminals, too) (DO.FORWARD COL)) (T (DO.BACK (IDIFFERENCE FROMCOL COL)))) 	  (COND ((EQ FROMROW ROW) (* No row adjustment)) ((IGREATERP FROMROW ROW) (DO.UP (IDIFFERENCE FROMROW ROW))) 	  (T (DO.DOWN (IDIFFERENCE ROW FROMROW)))))      ]    (SETQ \CURSORROW ROW)    (SETQ \CURSORCOL COL])(INIT.CURSOR  [LAMBDA (COL)                                              (* bvm: "23-MAR-83 15:31")          (* * Initializes cursor accounting; in Interlisp-10, this assumed/forced the cursor to be in column COL of the 	  bottom row of the screen)    (PROG ((YBOT (fetch (REGION BOTTOM) of (DSPCLIPPINGREGION NIL \DSP)))	   INITY)          (SETQ INITY (IDIFFERENCE (DSPYPOSITION NIL \DSP)				   YBOT))          [SETQ \LOC.ROW.0 (SUB1 (IDIFFERENCE \TTPAGELENGTH (IQUOTIENT INITY \CHARHEIGHT]          (* \LOC.ROW.0 is the number of the "line" of the first line of text, counting from the top of the window.	  Instead, we really should count from the bottom and fix everyone who cares)          (SETQ \BMARG (IPLUS YBOT (IREMAINDER INITY \CHARHEIGHT)))          (SETQ \CURSORROW 0)          (SETQ \CURSORCOL COL])(INSERT.CHAR.IN.BUF  [LAMBDA (CHAR)                                             (* bvm: "20-FEB-82 22:22")          (* * Inserts CHAR in buffer at \CURSOR and advances \CURSOR appropriately)    (INSERT.NODE \CURSOR)    (FRPLACA \CURSOR CHAR)    [COND      ((AT.END.OF.LINE)	(replace END of \ARROW with (CDR \CURSOR]    (SETQ \CURSOR (CDR \CURSOR])(INSERT.NODE  [LAMBDA (BUF)                                              (* bvm: "20-FEB-82 22:34")          (* * Effectively does (ATTACH garbage BUF), but reuses from the garbage heap)    (COND      ((EQ BUF \ENDBUFFER)                                   (* Already at end, just push pointer)	(SETQ \ENDBUFFER (TTNEXTNODE \ENDBUFFER)))      (T (FRPLACD BUF (FRPLNODE2 (SCRATCHCONS)				 BUF])(INSERTLINE  [LAMBDA (OLDLINE USECR)                                    (* bvm: " 1-JUN-82 18:45")          (* Inserts a new line between OLDLINE and the next line, whose START is the END of LINE; caller must fill in END 	  if line is non-empty (defaults to start); USECR, if supplied, is the <cr> char to end the previous line with)    (PROG ((OLDEND (fetch END of OLDLINE))	   (ROW (ADD1 (fetch ROW of OLDLINE)))	   X NEWLINE)          [COND	    (USECR (INSERT.NODE OLDEND)		   (FRPLACA OLDEND USECR)		   (SETQ OLDEND (CDR OLDEND]          (TTCRLF)          (COND	    ((NEQ OLDEND \ENDBUFFER)                         (* Not last line, so insert a line on screen.)	      (DO.INSERT.LINE 1)))          (TTPROMPTCHAR)          [replace NEXTLINE of OLDLINE with (SETQ NEWLINE (CREATE.LINE OLDEND OLDEND (SETQ X 									 \CURSORCOL)								       X ROW (fetch NEXTLINE										of OLDLINE]          (RENUMBER.LINES NEWLINE ROW)          (RETURN NEWLINE])(KILL.LINES  [LAMBDA (FIRSTLINE)                                        (* bvm: " 2-JUN-82 15:46")          (* * Returns line records from FIRSTLINE onward to the heap)    [PROG NIL      LP  (COND	    (FIRSTLINE (SETQ FIRSTLINE (CDR (FRPLACA FIRSTLINE 0)))                                                             (* Remove some of the circularity in the buffer)		       (GO LP]    (FRPLACD (FLAST \ENDBUFFER)	     FIRSTLINE])(KILLSEGMENT  [LAMBDA (START END)                                        (* bvm: "25-AUG-81 17:25")          (* * Removes segment from START up to, but not including END. When done, START contains the contents of former 	  cell END. I.e. any pointer to START is still valid; any pointer to END should be reset to START.)    (COND      ((EQ END \ENDBUFFER)	(SETQ \ENDBUFFER START))      (T (replace OLDTAIL of \TTYINSTATE with (SETQ \LASTAIL))                                                             (* kill last buffer markers, as they may be trashed)	 (FRPLNODE START (CAR END)		   (PROG1 (CDR END)			  (FRPLACD END (CDR \ENDBUFFER))     (* Cell at END will point to free list)			  (FRPLACD \ENDBUFFER (CDR START))   (* And this segment now is start of free list)			  ])(L-CASECODE  [LAMBDA (CHAR)                                       (* bvm: "11-MAR-81 22:06")    (COND      ([AND [NOT (ILESSP CHAR (CONSTANT (CHCON1 (QUOTE A]	    (NOT (IGREATERP CHAR (CONSTANT (CHCON1 (QUOTE Z]	(LOGOR CHAR 40Q))      (T CHAR])(MOVE.BACK.TO  [LAMBDA (BUFTAIL)                                          (* bvm: " 1-JUN-82 18:10")    (GO.TO.RELATIVE (IDIFFERENCE \CURSORCOL (SEGMENT.BIT.LENGTH BUFTAIL \CURSOR)))    (SETQ \CURSOR BUFTAIL])(MOVE.FORWARD.TO  [LAMBDA (BUFTAIL)                                          (* bvm: " 1-JUN-82 18:03")    [GO.TO.RELATIVE (IPLUS \CURSORCOL (SEGMENT.BIT.LENGTH \CURSOR (SETQ BUFTAIL (CHECK.MARGIN BUFTAIL 											   \ARROW]    (SETQ \CURSOR BUFTAIL])(MOVE.TO.LINE  [LAMBDA (NEWLINE BUFTAIL)                                  (* bvm: " 1-JUN-82 17:56")          (* * Moves to indicated line at indicate buffer position (default is START), resetting \ARROW etc appropriately.)    (PROG ((RELATIVE.POSITION 0))          [COND	    [BUFTAIL (SETQ RELATIVE.POSITION (SEGMENT.BIT.LENGTH (fetch START of NEWLINE)								 (SETQ BUFTAIL (CHECK.MARGIN BUFTAIL 											  NEWLINE]	    (T (SETQ BUFTAIL (fetch START of NEWLINE]          (GO.TO.RELATIVE (IPLUS (fetch FIRSTCOL of NEWLINE)				 RELATIVE.POSITION)			  (fetch ROW of NEWLINE))          (SETQ \CURSOR BUFTAIL)          (RETURN (SETQ \ARROW NEWLINE])(MOVE.TO.NEXT.LINE  [LAMBDA NIL                                                (* bvm: "20-FEB-82 22:20")    (GO.TO.RELATIVE (QUOTE LINE)		    (SETQ \ARROW (fetch NEXTLINE of \ARROW)))    (SETQ \CURSOR (fetch START of \ARROW])(MOVE.TO.START.OF.WORD  [LAMBDA NIL                                                (* bvm: "20-FEB-82 22:34")    [COND      ((AT.END.OF.LINE)	(MOVE.BACK.TO (PREVWORD \CURSOR)))      ((SELCHARQ (CAR \CURSOR)		 ((%( %[)		   NIL)		 T)          (* Do nothing if sitting under an open paren/bracket, since otherwise the PREVWORD below will go to the previous 	  word, rather than selecting the "word" which begins with the paren; in all other cases the PREVWORD will do the 	  right thing: if under the word, goes to its start (ignoring parens), or if under a space goes to the start of the 	  word before the space)	(MOVE.BACK.TO (PREVWORD (TTNEXTCHAR \CURSOR]    NIL])(MOVE.TO.WHEREVER  [LAMBDA (BUF)                                        (* bvm: "24-Feb-80 00:28")          (* * Moves to BUF, wherever it may be.)    (MOVE.TO.LINE (FIND.LINE BUF)		  BUF])(NTH.COLUMN.OF  [LAMBDA (LINE N)                                     (* bvm: "11-MAR-81 22:00")          (* * Returns buffer tail of LINE record which best approximates the Nth printing column of that line)    (NTH.RELATIVE.COLUMN.OF LINE (IDIFFERENCE N (fetch FIRSTCOL of LINE])(NTH.RELATIVE.COLUMN.OF  [LAMBDA (LINE N)                                           (* bvm: " 1-JUN-82 22:23")          (* Returns buffer tail in LINE which represents the Nth printing character on the line. Returns start or end of 	  buffer if out of range. If the nth char is a pad char, returns the start of the pad char sequence)    (COND      ((NOT (IGREATERP N 0))	(fetch START of LINE))      (T (for WIDTH (BUF _(fetch START of LINE))	      (END _(fetch END of LINE)) do [COND					      ((EQ BUF END)                                                             (* Ran off the end, so quit)						(RETURN END))					      ((PREFIXCHAR (CAR BUF))                                                             (* Does not print, but this is a safe place to return)						(SETQ $$VAL BUF))					      (T [COND						   ([ILESSP N (SETQ WIDTH (TTBITWIDTH								(REALBITS (CAR BUF]						     (RETURN (COND							       ((AND (NEQ BUF END)								     (PADCHAR (CAR BUF)))                                                             (* Can't return in the middle of a multichar, so go back							     to its prefixchar)								 $$VAL)							       (T BUF]						 (SETQ N (IDIFFERENCE N WIDTH]					    (SETQ BUF (CDR BUF])(OVERFLOW?  [LAMBDA (WIDTH)                                            (* bvm: " 1-JUN-82 18:01")                                                             (* If typing WIDTH more chars would cause this line to 							     overflow, starts new line (or simply goes to next line 							     when N=0))    (COND      ((NOT (ILESSP (IPLUS \CURSORCOL WIDTH)		    \RMARG))	(COND	  [(AT.END.OF.LINE)	    (PROG ((OLDLINE \ARROW))	          (START.NEW.LINE)	          (COND		    ((AND \AUTOFILL DISPLAYTERMFLG)          (* Hit the margin in the middle of a word.							     Try to move that word intact to the new line)		      (ADJUSTLINE 1 OLDLINE)		      (GO.TO.RELATIVE (fetch LASTCOL of \ARROW)				      (fetch ROW of \ARROW]	  ((ZEROP WIDTH)	    (MOVE.TO.NEXT.LINE))	  (T (BREAKLINE])(OVERFLOWLINE?  [LAMBDA (LINE)                                       (* bvm: " 4-Aug-78 18:18")          (* * True if LINE overflows into next line, rather than ending in a cr)    (EQ (fetch END of LINE)	(fetch START of (fetch NEXTLINE of LINE])(PREVLINE  [LAMBDA (LINE N)                                     (* bvm: "11-MAR-81 21:39")          (* * Backs up N lines in buffer before LINE, as far as start of buffer. i.e. an NLEFT on line records.)    (PROG ((X \FIRSTLINE)	   (L \FIRSTLINE))      LP                                               (* Advance X by N chars)          (COND	    ((ZEROP N)	      (GO LP1))	    ((OR (EQ X LINE)		 (NULL X))                             (* The NULL case should never happen, but better be safe)	      (RETURN L)))          (SETQ X (fetch NEXTLINE of X))          (SUB1VAR N)          (GO LP)      LP1                                              (* Now advance X and L in parallel until X reaches LINE, at 						       which point L is N before it)          (COND	    ((OR (EQ X LINE)		 (NULL X))	      (RETURN L)))          (SETQ X (fetch NEXTLINE of X))          (SETQ L (fetch NEXTLINE of L))          (GO LP1])(PREVWORD  [LAMBDA (BUF N START)                                      (* bvm: "25-FEB-82 22:38")    (OR START (SETQ START (fetch START of \ARROW)))    (for X_START	 NEW_T	 #HITS_0 by (TTNEXTCHAR X) until (EQ X BUF) comment           (* * Return start of the Nth word in line before BUF, or beginning of line if no such word)       do (COND	    ((WORDSEPRP (CAR X))                             (* Space between words)	      (SETQ NEW T))	    (NEW (SETQ $$VAL X)                              (* Start of new word)		 (SETQ NEW NIL)		 (ADD1VAR #HITS)))       finally (RETURN (COND			 ((OR (NOT N)			      (EQ N 1)			      (ZEROP #HITS))			   (OR $$VAL START))			 ((ILESSP (SETQ N (IDIFFERENCE #HITS N))				  0)                         (* N was greater than #words in buffer)			   START)			 ((ZEROP N)			   (FIND.START.OF.WORD START))			 (T (FIND.NEXT.WORD (FIND.START.OF.WORD START)					    N])(PROPERTAILP  [LAMBDA (X Y)                                        (* bvm: " 4-Aug-78 12:03")          (* * true if X is a PROPER tail of Y)    (AND X (NEQ X Y)	 (BUFTAILP X Y])(READFROMBUF  [LAMBDA (START END COPYFLG)                                (* bvm: "15-JUN-82 18:02")          (* Unreads the chars in the buffer from START to END. The cells are returned to the free pool as they are used to 	  reduce the storage demands on large unreads. Multichar sequences in buffer are unread as just their "real" 	  characters)    (PROG (FIXUP)          [COND	    ([AND (NOT (AT.END.OF.LINE))		  (for (BUF _ START) by (CDR BUF) until (EQ BUF END) thereis (EQ (CAR BUF)										 (CHARCODE EOL]          (* An insertion that contains a cr. This will look awful if we have to keep shoving text in front of us, so break 	  the line first, then unbreak it at end)	      (BREAKLINE PSEUDOCRCODE (SETQ FIXUP T]          [until (EQ START END) do [COND				     ((NOT (PADCHAR (CAR START)))                                                             (* Don't include pad chars)				       (COND					 ((NEQ (CAR START)					       EOLCHARCODE)					   (ADDNAKEDCHAR (REALBITS (CAR START))							 T))					 ((NOT (AT.END.OF.LINE))                                                             (* Insert EOL in middle of line)					   (BREAKLINE EOLCHARCODE))					 ((OR (NEQ (CDR START)						   END)					      (NOT (AT.END.OF.TEXT \CURSOR)))                                                             (* EOL. Start new line. Ignore it if this is a 							     terminating eol)					   (START.NEW.LINE EOLCHARCODE]				   (SETQ START (PROG1 (CDR START)						      (SELECTQ (SYSTEMTYPE)							       (D                                                              (* Don't bother reclaiming)								  NIL)							       (OR COPYFLG								   (FRPLACD \ENDBUFFER									    (FRPLACD START										     (CDR \ENDBUFFER]          (COND	    (FIXUP                                           (* Kill the cr we inserted)		   (MOVE.TO.WHEREVER (PROG1 \CURSOR (DELETE.LONG.SEGMENT1 \ARROW \CURSOR									  (fetch NEXTLINE									     of \ARROW)									  (TTNEXTCHAR \CURSOR])(RENUMBER.LINES  [LAMBDA (LINE ROW)                                   (* bvm: " 4-Aug-78 18:18")          (* * Renumbers lines from LINE onward, giving LINE the value ROW)    (while LINE do (replace ROW of LINE with ROW)		   (ADD1VAR ROW)		   (SETQ LINE (fetch NEXTLINE of LINE])(RESTORE.CURSOR  [LAMBDA NIL                                                (* bvm: "20-FEB-82 22:21")    (COND      ((CAPABILITY? MOVEMENT)	(GO.TO.RELATIVE \HOMECOL \HOMEROW])(RESTOREBUF  [LAMBDA NIL                                                (* bvm: "27-JUL-82 14:50")          (* recover previous buffer, which extends to either our current LASTAIL, if user has done deletions on this line, 	  or previous LASTAIL, stored in the front of the buffer. If neither, then recover last thing zapped with the mouse)    (PROG (TAIL)          (COND	    ([AND (AT.END.OF.BUF)		  (SETQ TAIL (OR (AND \LASTAIL (IGEQ \LASTAILROW (fetch ROW of \ARROW))				      (OR (IGREATERP \LASTAILCOL \CURSORCOL)					  (IGREATERP \LASTAILROW (fetch ROW of \ARROW)))				      (PROPERTAILP \LASTAIL \ENDBUFFER))				 (PROPERTAILP (fetch OLDTAIL of \TTYINSTATE)					      \ENDBUFFER]	      (END.DELETE.MODE)	      (READFROMBUF [CONS (CAR \ENDBUFFER)				 (PROG1 (CDR \ENDBUFFER)     (* now detach buffer from here to TAIL to avoid 							     conflict)					(FRPLNODE \ENDBUFFER 0 (CDR TAIL]			   TAIL)	      (SETQ \LASTAIL \ENDBUFFER)	      (SETQ \LASTAILCOL \CURSORCOL)	      (SETQ \LASTAILROW (fetch ROW of \ARROW))	      (replace OLDTAIL of \TTYINSTATE with NIL))	    (\LAST.DELETION (READFROMBUF \LAST.DELETION NIL T)			    (ADJUSTLINE.AND.RESTORE T))	    (T                                               (* Can't find where buffer ended;							     perhaps we have written past it)	       (BEEP])(RETYPE.BUFFER  [LAMBDA (LINE LASTLINE FROM.HERE)                          (* bvm: " 9-NOV-82 14:51")          (* Refreshes buffer starting with LINE for one line, or going to LASTLINE, where LASTLINE=T means end of buffer.	  Moves cursor to start of LINE (based on where we think we might be now) unless FROM.HERE is set.	  FROM.HERE is set when retyping whole buffer with the current cursor position defined as 0,0;	  in this case, the cursor is restored on completion to wherever it was last saved, rather than its current 	  position)    (PROG (L (ROW (fetch ROW of LINE)))          (SETQ \DELETING)          (BINARY.MODE)          [COND	    (FROM.HERE (INIT.CURSOR 0))	    (T (SAVE.CURSOR)	       (COND		 [(CAPABILITY? MOVEMENT)                     (* position cursor at start of line)		   (CANCEL.MODES)                            (* in case an funny terminal setting occurred, say 							     because of noise)		   (COND		     ((CAPABILITY? \CURSOR T)		       (GO.TO.ADDRESSING 0 ROW))		     (T (DO.UP 1)                            (* Goto start of line by going up a line and doing a 							     crlf)			(DO.CRLF)			(SETQ \CURSORCOL 0]		 (T (TTCRLF]          [COND	    ((ZEROP ROW)                                     (* First line might be indented)	      (SELECTQ (SYSTEMTYPE)		       (D (RELMOVETO \INITPOS 0 \DSP))		       (TTBOUTN (SETQ \CURSORCOL \INITPOS)				SPACE]      LP  (TTPROMPTCHAR LINE)          (TYPE.BUFFER (fetch START of LINE)		       (fetch END of LINE))          (COND	    ((AND LASTLINE (SETQ L (fetch NEXTLINE of LINE))		  (NEQ L LASTLINE))	      (SETQ LINE L)	      (TTCRLF)	      (ADD1VAR ROW)	      (GO LP)))          (COND	    ((EQ LASTLINE T)                                 (* kill any text that might be below bottom line)	      (ERASE.TO.END.OF.PAGE)))          (RESTORE.CURSOR])(SAVE.CURSOR  [LAMBDA NIL                                          (* bvm: "11-MAR-81 21:40")    (SETQ \HOMEROW \CURSORROW)    (SETQ \HOMECOL \CURSORCOL])(SCANBACK  [LAMBDA (CHAR BUF N START)                                 (* bvm: "20-FEB-82 22:34")          (* * Searches back for Nth previous occurrence of CHAR in buffer before BUF, returning NIL if there are no 	  occurrences. Scan terminates at START, default is start of line; default N is 1; if there are fewer than N 	  occurrences, returns the earliest one it can)    (for [X _(OR START (SETQ START (fetch START of \ARROW]	 #HITS_0 by (TTNEXTCHAR X) until (EQ X BUF) do (COND							 ((EQ (U-CASECODE (REALBITS (CAR X)))							      CHAR)							   (SETQ $$VAL X)							   (ADD1VAR #HITS)))       finally (RETURN (COND			 ((OR (NOT N)			      (EQ N 1)			      (ZEROP #HITS)			      (EQ #HITS 1))			   $$VAL)			 (T                                  (* There are #HITS occurrences of CHAR, and we want the 							     Nth from the end)			    (SCANFORWARD CHAR START (ADD1 (IMAX (IDIFFERENCE #HITS N)								0))					 BUF])(SCANFORWARD  [LAMBDA (CHAR BUF N END)                                   (* bvm: "20-FEB-82 22:34")          (* * Finds Nth occurrence of CHAR in BUF before END. Default END is end of current line; default N is 1;	  CHAR should be uppercase if a letter)    (OR N (SETQ N 1))    (OR END (SETQ END (fetch END of \ARROW)))    (while (NEQ BUF END) do [COND			      ((EQ (U-CASECODE (REALBITS (CAR BUF)))				   CHAR)				(COND				  ((ZEROP (SUB1VAR N))				    (RETURN BUF))				  (T (SETQ $$VAL BUF]			    (SETQ BUF (TTNEXTCHAR BUF])(SCRATCHCONS  [LAMBDA NIL                                                (* bvm: "25-AUG-81 17:27")          (* * Returns a garbage cons from the heap at the end of the buffer, or a fresh cons if none available)    (replace OLDTAIL of \TTYINSTATE with (SETQ \LASTAIL))    (* Wipe out last buffer ptrs, as this may trash them)    (PROG1 (OR (CDR \ENDBUFFER)	       (CONS))	   (FRPLACD \ENDBUFFER (CDDR \ENDBUFFER])(SEGMENT.LENGTH  [LAMBDA (START END)                                        (* bvm: "25-Jul-78 23:07")          (* * Returns number of print positions in buffer from START to END)    (PROG ((N 0))      LP  (COND	    ((EQ START END)	      (RETURN N)))          (COND	    ((NOT (PREFIXCHAR (CAR START)))	      (ADD1VAR N)))          (SETQ START (CDR START))          (GO LP])(SEGMENT.BIT.LENGTH  [LAMBDA (START END)                                        (* bvm: " 6-JUN-82 18:06")          (* * Returns number of print positions in bits in buffer from START to END)    (COND      (\VARIABLEFONT (PROG ((N 0))		       LP  (COND			     ((EQ START END)			       (RETURN N)))		           [COND			     ((NOT (PREFIXCHAR (CAR START)))			       (add N (FCHARWIDTH (REALBITS (CAR START))						  \FONT]		           (SETQ START (CDR START))		           (GO LP)))      (T (PROG ((N 0))	   LP  (COND		 ((EQ START END)		   (RETURN N)))	       (COND		 ((NOT (PREFIXCHAR (CAR START)))		   (add N \CHARWIDTH)))	       (SETQ START (CDR START))	       (GO LP])(SETLASTC  [LAMBDA (CHAR)                                       (* bvm: "10-APR-81 23:28")                                                       (* Makes CHAR be LASTC for T. This is a kludge;						       I should be interfacing better with \LINEBUF.OFD at a more 						       fundamental level.)    (\BOUT \LINEBUF.OFD CHAR])(SETTAIL?  [LAMBDA (EVEN.IF.NOT.THERE)                                (* bvm: "27-JUL-82 14:52")          (* If \ENDBUFFER is farther than we've been before, save this position on LASTAIL. If EVEN.IF.NOT.THERE is set, do	  this even if cursor is not currently at the end)    (COND      ([AND (NOT \DELETING)	    (NOT (EMPTY.BUFFER))	    (OR EVEN.IF.NOT.THERE (EQ \CURSOR \ENDBUFFER))	    (OR (NOT \LASTAIL)		(OR (ILESSP \LASTAILROW (fetch ROW of \ARROW))		    (AND (ILESSP \LASTAILCOL \CURSORCOL)			 (ILEQ \LASTAILROW (fetch ROW of \ARROW]	(SETQ \LASTAIL \ENDBUFFER)	(SETQ \LASTAILCOL \CURSORCOL)	(SETQ \LASTAILROW (fetch ROW of \ARROW])(SHOW.MATCHING.PAREN  [LAMBDA (BUF)                                              (* bvm: " 1-JUN-82 17:57")          (* * Indicates parenthesis nesting by briefly moving the cursor to the paren that matches the paren at BUF, if 	  that position is still on the screen. The cursor stays there for SHOWPARENFLG seconds, or until there is input 	  from the user. Assumes terminal has cursor addressability)    (PROG ((MATCHING (BACKSKREAD BUF T))	   LINE ROW COL)                                     (* MATCHING is the buffer position that matches BUF, or 							     NIL if this paren was quoted somehow.)          (OR MATCHING (RETURN))          (SETQ LINE (FIND.LINE MATCHING))                   (* The buffer LINE on which it appears)          (COND	    ((ILESSP (IPLUS (SETQ ROW (fetch ROW of LINE))			    \LOC.ROW.0)		     0)                                      (* Not on screen, so forget it)	      (RETURN)))          (SETQ COL (IPLUS (SEGMENT.BIT.LENGTH (fetch START of LINE)					       MATCHING)			   (fetch FIRSTCOL of LINE)))        (* The absolute column position)          (COND	    ((TYPEAHEAD?)          (* After all this computation, there is now input waiting, so don't do anything. Didn't do this earlier, since the	  SIBE itself takes time, and is likely to fail when done immediately after reading the closing paren)	      (RETURN)))          (SAVE.CURSOR)          (GO.TO.ADDRESSING COL ROW)                         (* Go to absolute coordinates of matching paren)          (TTWAITFORINPUT (COND			    ((FIXP SHOWPARENFLG)			      (ITIMES SHOWPARENFLG 1750Q))			    (T 1750Q)))                      (* Wait a while to let user see it)          (\CHECKCARET \DSP)                                 (* Tell background we moved the cursor)          (RESTORE.CURSOR)                                   (* Put cursor back where it belongs)      ])(SKIP/ZAP  [LAMBDA (CMD CHAR N MINUS)                                 (* bvm: "20-FEB-82 22:34")          (* Performs <edit>S or <edit>Z, i.e. skip or zap to character. CMD is S, Z, B, or -Z (latter two are backward 	  versions of the first two); CHAR is the target character, N is a repeat arg and MINUS is its sign.	  Last such operation is saved on LASTSKIP so that <edit>A can repeat it)    (SETQ CHAR (U-CASECODE CHAR))                            (* Ignore case differences)    [COND      (MINUS                                                 (* invert command)	     (SETQ CMD (SELECTC CMD				((CHARCODE S)				  (CHARCODE B))				((CHARCODE B)				  (CHARCODE S))				((CHARCODE Z)				  (IMINUS (CHARCODE Z)))				((IMINUS (CHARCODE Z))				  (CHARCODE Z))				(SHOULDNT]    (COND      ([SETQ N (SELECTC CMD			((CHARCODE B)			  (SCANBACK CHAR \CURSOR N))			((IMINUS (CHARCODE Z))			  (SCANBACK CHAR (TTNLEFT \CURSOR 1)				    N))			(AND (NOT (AT.END.OF.LINE))			     (SCANFORWARD CHAR (TTNEXTCHAR \CURSOR)					  N]	(SELECTC CMD		 ((CHARCODE S)                               (* S)		   (MOVE.FORWARD.TO N))		 ((CHARCODE Z)                               (* Z)		   (FORWARD.DELETE.TO N))		 ((CHARCODE B)                               (* B)		   (MOVE.BACK.TO N))		 [(IMINUS (CHARCODE Z))                      (* -Z)		   (FORWARD.DELETE.TO (PROG1 (COND					       ((AT.END.OF.LINE)						 \CURSOR)					       (T (TTNEXTCHAR \CURSOR)))					     (MOVE.BACK.TO (TTNEXTCHAR N]		 (SHOULDNT)))      (T (BEEP)))    (replace LASTSKIP of \TTYINSTATE with CMD)    (replace LASTSKIPCHAR of \TTYINSTATE with CHAR])(START.NEW.LINE  [LAMBDA (USECR)                                            (* bvm: "16-SEP-82 11:53")          (* * Handles moving to new line. USECR, if set, is the <cr> character that should terminate current line)    (SETQ \CURSOR (fetch START of (SETQ \ARROW (INSERTLINE \ARROW USECR])(START.OF.PARAGRAPH?  [LAMBDA (LINE)                                             (* bvm: "25-AUG-81 00:06")    (OR (EQ (fetch END of LINE)	    (SETQ LINE (fetch START of LINE)))	(EQ (CAR LINE)	    (PREFIXCHARCODE TAB])(TTADJUSTWORD  [LAMBDA (WORD)                                             (* bvm: "16-SEP-82 12:14")          (* * Returns WORD, possibly corrected, according to the spelling list, if any. Returns NIL if FIX was specified 	  and the word fails.)    (PROG (X)          (RETURN (COND		    ((OR (NULL SPLST)			 (FMEMB WORD (QUOTE (%( %) %[ %] %" ,)))			 (FMEMB WORD SPLST))		      WORD)		    ((AND WORD (SETQ X (FASSOC WORD SPLST)))                                                             (* Is synonym. FASSOC assumes car of atom is NIL)		      (CDR X))		    ([AND SPLST (LITATOM WORD)			  (NEQ \NOFIXSPELL (QUOTE NOFIXSPELL))			  (SETQ X (FIXSPELL WORD 106Q SPLST (AND \NOFIXSPELL T)					    NIL NIL NIL (NOT \SPLSTFLG]                                                             (* respelled okay)		      X)		    (\FIX (TTPRIN1 WORD)			  (TTPRIN1 (QUOTE ?))			  (COND			    (HELP (TTGIVEHELP HELP))			    (T (TTPRIN1 "  please try again.")))			  (TTCRLF)			  NIL)		    (T WORD])(TTBIN  [LAMBDA NIL                                                (* bvm: "19-MAY-82 15:16")          (* * Read the next char from terminal, return its character code. Sets \EDITBIT true or false according to state 	  of the edit bit (200Q).)    (PROG ((CHAR (TTWAITFORINPUT NIL T)))          (COND	    [(EQ CHAR EDITPREFIXCHAR)                        (* edit prefix)	      (SETQ \EDITBIT T)	      (SETQ CHAR (\GETKEY))	      (COND		((EQ CHAR EDITPREFIXCHAR)                    (* Two edits in a row = Edit-Escape)		  (SETQ CHAR 33Q]	    ((AND (IGREATERP CHAR 177Q)		  (NEQ CHAR MOUSECODE)		  (NEQ CHAR \TTYIN.RESTOREBUFCODE)		  \TTYIN.METASTATE)                          (* Had meta key down, probably)	      (SETQ \EDITBIT T)	      (SETQ CHAR (LOGAND CHAR 177Q)))	    (T (SETQ \EDITBIT NIL)))          (\CHECKCARET \DSP)                                 (* Turn off the caret, since we will probably move)          (RETURN CHAR])(TTBITWIDTH  [LAMBDA (CHAR)                                             (* bvm: " 6-JUN-82 18:06")    (COND      (\VARIABLEFONT (FCHARWIDTH CHAR \FONT))      (T \CHARWIDTH])(TTCOMPLETEWORD  [LAMBDA (CAUTIOUS MUST.BE.UNIQUE FIRSTMATCH FIRSTCHAR)     (* bvm: " 4-JUN-82 18:23")          (* Tries to complete the current word from members of SPLST. Does nothing if no word in progress, or this is a 	  comment line. Returns true if some completion done. If CAUTIOUS, only complete if can do so uniquely and caller 	  permits fixspell; if MUST.BE.UNIQUE set, only do unique completion. FIRSTMATCH, if supplied, is the first match in	  SPLST, and FIRSTCHAR the start of the current word being worked on)    (PROG (TAIL FIRSTMATCHCHARS SUFFIXCHARS LASTCHAR NEXTCHAR I WORD (UNIQUE T))          (RETURN (COND		    ([AND [OR FIRSTCHAR (SETQ FIRSTCHAR (COND				  ((AT.START.OF.BUF)         (* Empty buffer. Allow altmode completion on one-word 							     splst here)				    (AND (NOT CAUTIOUS)					 \BUFFER))				  (T (CURRENT.WORD]			  (OR FIRSTMATCH (SETQ FIRSTMATCH (FIND.MATCHING.WORD SPLST FIRSTCHAR]          (* Completion may be possible. (CAR MATCH) is the first match in SPLST; FIRSTCHAR is buffer tail where current 	  word starts; NEXTCHAR is the relative position of cursor in current word, i.e. #chars in word + 1;	  LASTCHAR is the last char position in common among all words which match. Now run through all other possible 	  matches with the current word, reducing LASTCHAR to indicate the largest segment in common.)		      (SETQ NEXTCHAR (ADD1 (SEGMENT.LENGTH FIRSTCHAR \CURSOR)))		      [SETQ LASTCHAR (NCHARS (SETQ FIRSTMATCH (INPART (CAR (SETQ TAIL FIRSTMATCH]		      (COND			((OR CAUTIOUS (EQ (SUB1 NEXTCHAR)					  LASTCHAR))          (* The latter case happens if the current word is exactly MATCH. In this case, if there are any other matches they	  are with words containing MATCH as initial substring, and thus no further completion is possible)			  (SETQ MUST.BE.UNIQUE T)))		      (SETQ SUFFIXCHARS (FNTH (SETQ FIRSTMATCHCHARS (DCHCON FIRSTMATCH CHCONLST1))					      NEXTCHAR))          (* unpack FIRSTMATCH for faster tests below. CHCONLST1 is Dwim's scratch list. If user often uses very long words,	  may want to lengthen this list to reduce cons usage.)		      (while (SETQ TAIL (FIND.MATCHING.WORD (CDR TAIL)							    FIRSTCHAR \CURSOR))			 do (COND			      (MUST.BE.UNIQUE (RETURN)))			    (SETQ UNIQUE)			    (SETQ WORD (INPART (CAR TAIL)))			    [COND			      ((find old I from NEXTCHAR to LASTCHAR as REFERENCE in SUFFIXCHARS				  suchthat (NEQ (NTHCHARCODE WORD I)						REFERENCE))				(COND				  ((EQ I NEXTCHAR)           (* No characters in common, so give up)				    (RETURN))				  (T                         (* reset LASTCHAR to last common character)				     (SETQ LASTCHAR (SUB1 I]			 finally           (* * chars from NEXTCHAR to LASTCHAR are uniquely determined by prefix so far)				 (END.DELETE.MODE)				 [PROG ((BUF FIRSTCHAR)					RETYPEIT OLDLENGTH NEEDADJUST)				       (SETQ I 1)				   LP1           (* * Scan old part of string (part user has typed already) to make sure case is correct)				       (COND					 [(EQ I NEXTCHAR)    (* Done with first part now. Before we go on, retype 							     anything that needed it)					   [COND					     ((AND RETYPEIT DISPLAYTERMFLG)                                                             (* If we're capable of backspacing, go back and write 							     over input with correct case)					       (GO.TO.RELATIVE (IDIFFERENCE \CURSORCOL OLDLENGTH))					       [COND						 (\VARIABLEFONT (SETQ NEEDADJUST								  (TTADJUSTWIDTH (IDIFFERENCE										   (SEGMENT.BIT.LENGTH										     RETYPEIT \CURSOR)										   OLDLENGTH)										 \CURSOR]					       (TYPE.BUFFER RETYPEIT \CURSOR)					       (COND						 (NEEDADJUST (ADJUSTLINE.AND.RESTORE]					   (COND					     ((IGREATERP I LASTCHAR)                                                             (* Happens when entire word is complete as stands)					       (RETURN]					 (T [COND					      ((NEQ (CAR FIRSTMATCHCHARS)						    (CAR BUF))                                                             (* Case mismatch, want to fix)						(FRPLACA BUF (CAR FIRSTMATCHCHARS))						(COND						  ((NOT RETYPEIT)						    (SETQ RETYPEIT BUF)						    (SETQ OLDLENGTH (SEGMENT.BIT.LENGTH RETYPEIT 											\CURSOR]					    (SETQ FIRSTMATCHCHARS (CDR FIRSTMATCHCHARS))					    (SETQ BUF (CDR BUF))					    (ADD1VAR I)					    (GO LP1)))				   LP2                       (* Now do second half, the completion part: add new 							     chars from NEXTCHAR thru LASTCHAR)				       (ADDCHAR (CAR FIRSTMATCHCHARS))				       (COND					 ((NEQ I LASTCHAR)					   (SETQ FIRSTMATCHCHARS (CDR FIRSTMATCHCHARS))					   (ADD1VAR I)					   (GO LP2]				 [COND				   ((AND UNIQUE (NOT CAUTIOUS))                                                             (* word is unique, so delimit as well)				     (ADDCHAR (CHARCODE SPACE))				     (COND				       ((AND \SPLSTFLG (NEQ NEXTCHAR 1))          (* Spelling list maintenance: user completed on this word, so move to front of spelling list.	  Don't do it in the trivial case of filling in the entire word uniquely (as when doing LASTWORD))					 (MOVETOP FIRSTMATCH (OR SPLST USERWORDS]				 (RETURN (OR (AND UNIQUE FIRSTMATCH)					     T])(TTCRLF  [LAMBDA NIL                                          (* bvm: "12-MAR-81 16:35")          (* * Prints a crlf, updating cursor appropriately)    (DO.CRLF)    (TTCRLF.ACCOUNT])(TTCRLF.ACCOUNT  [LAMBDA NIL                                                (* bvm: "28-JUL-83 00:58")    (SETQ \CURSORROW (ADD1 \CURSORROW))    [COND      ((EQ (IPLUS \LOC.ROW.0 \CURSORROW)	   \TTPAGELENGTH)                                    (* This crlf glitched the screen, so row 0 has moved up 							     one)	(COND	  ((ILESSP (SETQ \LOC.ROW.0 (SUB1 \LOC.ROW.0))		   0)          (* tty scrolling is such that if the window had been a non-integral height, the scroll was less than one full 	  line. Adjust \BMARG appropriately)	    (SETQ \BMARG (DSPYPOSITION NIL \DSP]    (SETQ \CURSORCOL 0])(TTDELETECHAR  [LAMBDA NIL                                                (* bvm: "20-FEB-82 22:36")    (COND      ((AT.START.OF.BUF)	(BEEP))      [(AT.END.OF.LINE)	(COND	  [(AT.START.OF.LINE)                                (* empty line: need to delete to previous line)	    (PROG ((PREV (PREVLINE \ARROW 1))		   DODELETE)	          (SETQ DODELETE (OVERFLOWLINE? PREV))	          (DELETELINE \ARROW)                        (* get rid of this line)	          (MOVE.TO.LINE PREV (fetch END of PREV))    (* go to end of previous line)	          (COND		    (DODELETE                                (* We were on overflow line, so have to delete the last 							     char, too)			      (DELETETO (TTNLEFT \CURSOR 1)))		    ((NOT (CAPABILITY? MOVEMENT))		      (RETYPE.BUFFER \ARROW]	  (T (DELETETO (TTNLEFT \CURSOR 1]      ((INSERTING)	(TTRUBOUT))      (T                                                     (* DELETE inside line is like <edit>DELETE.)	 (DO.EDIT.COMMAND 177Q])(TTDELETELINE  [LAMBDA NIL                                                (* bvm: "20-FEB-82 22:36")    (COND      ((EMPTY.BUFFER)	(BEEP))      [(EMPTY.LINE)                                          (* Empty line: delete previous line if at end)	(COND	  ((AT.END.OF.BUF)	    (MOVE.TO.LINE (PREVLINE \ARROW 1))	    (COND	      ((NOT DISPLAYTERMFLG)		(TTBOUT _)		(DO.CRLF)))	    (DELETE.TO.END))	  (T (BEEP]      (T (SETQ \INSERTING)	 (SETTAIL? T)	 (COND	   ((NOT DISPLAYTERMFLG)	     (TTBOUT # #)                                    (* On non-display just print ## and return to initial 							     position)	     [replace END of \ARROW with (SETQ \CURSOR (SETQ \ENDBUFFER (fetch START of \ARROW]	     (replace LASTCOL of \ARROW with (fetch FIRSTCOL of \ARROW))	     (RETYPE.BUFFER \ARROW))	   ((AT.END.OF.LINE)                                 (* kill back to start of line.							     This can work on glass tty, too, whereas next clause 							     doesn't)	     (DELETETO (fetch START of \ARROW)))	   (T                                                (* We're inside line, so go back to start and then zap 							     whole line)	      (MOVE.BACK.TO (fetch START of \ARROW))	      (FORWARD.DELETE.TO (fetch END of \ARROW])(TTDELETEWORD  [LAMBDA NIL                                                (* bvm: "20-FEB-82 22:21")    (COND      ((NOT (AT.END.OF.LINE))                                (* Somewhere inside line, so do this as fancy edit 							     command)	(DO.EDIT.COMMAND (CHARCODE ^W)))      ((EMPTY.LINE)	(BEEP))      (T (DELETETO (PREVWORD \CURSOR])(TTECHO.TO.FILE  [LAMBDA (FILE DRIBBLING)    (DECLARE (USEDFREE \FIRSTLINE \PROMPT1 \PROMPT2 \ENDBUFFER))                                                             (* bvm: "18-JUN-82 14:26")          (* * Echos input to FILE. If DRIBBLING is true, the prompts are also echoed)    (for (OFD _(GETOFD FILE))	 (LINE _ \FIRSTLINE)	 (FIRSTIME _ T)	 X END do (COND		    ([AND DRIBBLING (SETQ X (COND			      (FIRSTIME (SETQ FIRSTIME NIL)					(AND (NOT \NOPROMPT)					     \PROMPT1))			      (T \PROMPT2]		      (PRIN1 X FILE)))		  (SETQ END (fetch END of LINE))		  (SETQ X (fetch START of LINE))		  (until (EQ X END) do [COND					 ((EQ (CAR X)					      (PREFIXCHARCODE SPACE))                                                             (* pseudo-tab kludge: instead of printing the "real" 							     character, ignore it and print only its padding spaces)					   (SETQ X (CDR X]				       (BOUT OFD (LOGAND (CAR X)							 177Q))				       (SETQ X (TTNEXTCHAR X)))		  (SETQ LINE (fetch NEXTLINE of LINE))		  (COND		    ((OR DRIBBLING (NEQ (fetch START of LINE)					END))                (* Don't terpri on overflow line, since user didn't;							     except always do it to dribblefile, since that's what's 							     on the screen)		      (TERPRI FILE)))       repeatwhile (AND LINE (OR (EQ END \ENDBUFFER)				 (NEQ (fetch START of LINE)				      \ENDBUFFER)))       comment                                               (* Second clause avoids echoing the terminating empty 							     line, except when it is an empty overflow line)	 ])(TTGIVEHELP  [LAMBDA (HELPKEY)                                          (* bvm: "20-FEB-82 22:22")    (RESETLST (PROG ((CTRLO! CTRLO!))		    (RESETSAVE (OUTPUT T))		    (COND		      ((AND (NOT CTRLO!)			    (FGETD (QUOTE CTRLO!)))          (* Enable ^O interrupt unless already done)			(RESETSAVE (INTERRUPTCHAR 17Q (QUOTE (CTRLO!))						  T))			(SETQ CTRLO! T)))		    (TERPRI)		    (COND		      ((EQ HELPKEY T)			(TTGIVEHELP1))		      [(LISTP HELPKEY)			(COND			  ((EQ (CAR HELPKEY)			       T)                            (* List SPLST first, then subsequent blurb)			    (TTGIVEHELP1 T)			    (PRIN1 (QUOTE % ))			    (TTGIVEHELP2 (CDR HELPKEY)					 T))			  ((EQ (CDR HELPKEY)			       T)                            (* Similar, but blurb first)			    (TTGIVEHELP2 (CAR HELPKEY)					 T)			    [COND			      ((NOT (ZEROP (POSITION)))				(PRIN1 (QUOTE % ]			    (TTGIVEHELP1 T T))			  (T (TTGIVEHELP2 HELPKEY]		      (T (TTGIVEHELP2 HELPKEY)))		    (COND		      ((NOT (ZEROP (POSITION)))			(TERPRI)))		    (TERPRI)		    (RETURN T])(TTGIVEHELP1  [LAMBDA (NO.OTHER NO.INTRO)                                (* bvm: "11-MAR-81 21:36")    (COND      (SPLST (OR NO.INTRO (PRIN1 "Please select from among "))	     (for X on SPLST unless (OR (EQ X SPELLSTR1)					(EQ X SPELLSTR2))		do (PRIN1 (INPART (CAR X)))		   (AND (CDR X)			(PRIN1 ", ")))	     (COND	       ((NOT NO.OTHER)		 (OR \FIX (PRIN1 ", or other"))		 (TERPRI])(TTGIVEHELP2  [LAMBDA (HELPKEY MIXED)                                    (* bvm: " 8-Aug-80 00:14")    (COND      [[OR (LITATOM HELPKEY)	   (AND (STRINGP HELPKEY)		(NOT (STRPOS (QUOTE % )			     HELPKEY]                        (* Atom or spaceless string is a hashfile key)	(COND	  ((NOT (DISPLAYHELP HELPKEY))	    (OR MIXED (PRIN1 "Sorry, no help available."]      (T (SPRINTT HELPKEY (COND		    (MIXED                                   (* no extra space)			   0)		    (T 4))		  4 0])(TTLASTLINE  [LAMBDA NIL                                                (* bvm: "11-MAR-81 21:37")          (* * Returns last LINE record in buffer)    (PROG ((LINE \FIRSTLINE)	   L)      LP  (COND	    ((SETQ L (fetch NEXTLINE of LINE))	      (SETQ LINE L)	      (GO LP)))          (RETURN LINE])(TTLOADBUF  [LAMBDA (BUF)                                              (* bvm: "14-AUG-81 12:41")          (* BUF is a list, a la READBUF, which is loaded into our character buffer, using DCHCON to convert the 	  s-expressions therein to char codes. If we are READING, then uses PRIN2 pnames, i.e. includes escape chars and 	  such stuff. Alternatively, BUF may be a string, in which case its contents are also loaded into the buffer, a la 	  BKSYSBUF, and the setting of \READING is irrelevant)    (COND      [(EQ (CAR (LISTP BUF))	   HISTSTR1)                                         (* read from file. BUF is (<histstr1> 							     (file start . end)))	(SETQ BUF (CADR BUF))	(SETFILEPTR (CAR BUF)		    (CADR BUF))	(bind CHAR NEXTCH LASTCHAR (OFD _(GETOFD (CAR BUF)))	      (#CHARS _(IDIFFERENCE (CDDR BUF)				    (CADR BUF)))	   while (IGREATERP #CHARS 0)	   do (add #CHARS -1)	      (COND		((NEQ (SETQ CHAR (BIN OFD))		      (CHARCODE CR))		  (ADDNAKEDCHAR CHAR T))		(T                                           (* eat up the lf after the cr)		   (COND		     ([OR (ZEROP #CHARS)			  (PROGN (SETQ NEXTCH (BIN OFD))				 (AND (ILEQ (add #CHARS -1)					    0)				      (EQ NEXTCH (CHARCODE LF]                                                             (* Ignore final CR)		       (RETURN)))		   (ADDNAKEDCHAR CHAR)		   (COND		     ((NEQ NEXTCH (CHARCODE LF))		       (ADDNAKEDCHAR NEXTCH]      (T (PROG (START END)	       [COND		 ((AND (LISTP BUF)		       (SETQ START (FMEMB HISTSTR0 BUF)))    (* HISTSTR0 is a marker used by lispx to denote end of 							     line)		   (FRPLACD (NLEFT BUF 1 START]	       (SETQ START (DCHCON BUF (CDR \ENDBUFFER)				   (AND (LISTP BUF)					\READING)				   T))                       (* Use our own buffer as a scratchlist for DCHCON as 							     long as it's lying around anyway.)	       [COND		 ((LISTP BUF)                                (* Remove the surrounding parens from the outer list)		   (SETQ END (NLEFT (SETQ START (CDR START))				    1]          (* now detach the result from our buffer to avoid conflict of interest. If DCHCON found our scratchlist 	  inadequate, START will not be a tail of \ENDBUFFER so the NLEFT below comes out NIL, which is also fine)	       (FRPLACD (NLEFT \ENDBUFFER 1 START))          (* Now unread the CHCON list.)	       (READFROMBUF START END])(TTNEXTCHAR  [LAMBDA (BUF)                                              (* bvm: " 2-MAY-81 16:14")          (* Returns next true tail of BUF. Chars that take up more than one element of buf are represented as <real char 	  with 200Q bit on> followed by the chars in the print representation, each with the 400Q bit on.	  Since TTNEXTCHAR is called from lots of places and wants to look like CDR, it is hand-coded here.)    (COND      ((ZEROP (LOGAND (CAR BUF)		      200Q))                                 (* normal situation, take cdr)	(CDR BUF))      (T           (* Was a prefix char (200Q bit on). Skip now over pad chars (400Q bit on). Need to also test for ENDBUFFER, since 	  buffer could coincidentally contain random garbage with the pad bit on)	 [do (SETQ BUF (CDR BUF)) repeatuntil (OR (EQ BUF \ENDBUFFER)						  (ZEROP (LOGAND (CAR BUF)								 400Q]	 BUF])(TTNEXTLINE  [LAMBDA (LINE N)                                           (* bvm: "20-FEB-82 23:25")    (bind L while (AND (NOT (ZEROP N))		       (SETQ L (fetch NEXTLINE of LINE)))       do (SETQ LINE L)	  (SUB1VAR N)       finally (RETURN LINE])(TTNEXTNODE  [LAMBDA (BUF)                                              (* bvm: " 2-JUN-82 15:44")          (* * Returns cdr of BUF, tacking on a new cons if the cdr was NIL)    (OR (CDR BUF)	(CDR (FRPLACD BUF (CONS 0])(TTNLEFT  [LAMBDA (BUF N START)                                      (* bvm: "20-FEB-82 22:34")          (* * Backs up N real characters in this line before BUF as far as START, default being the current start of the 	  line. Assumes BUF is a tail of line and N is small)    (OR START (SETQ START (fetch START of \ARROW)))    (PROG ((X START)	   (B START))      LP                                                     (* Advance X by N chars)          (COND	    ((ZEROP N)	      (GO LP1))	    ((OR (EQ X BUF)		 (NULL X))                                   (* The NULL case should never happen, but better be 							     safe)	      (RETURN B)))          (SETQ X (TTNEXTCHAR X))          (SUB1VAR N)          (GO LP)      LP1                                                    (* Now advance X and B in parallel until X reaches BUF, 							     at which point B is N before it)          (COND	    ((OR (EQ X BUF)		 (NULL X))	      (RETURN B)))          (SETQ X (TTNEXTCHAR X))          (SETQ B (TTNEXTCHAR B))          (GO LP1])(TTNTH  [LAMBDA (BUF N)                                            (* bvm: "20-FEB-82 22:34")          (* * Advances N real characters in BUF as far as the end of the line)    (bind (END _(fetch END of \ARROW)) while (AND (NOT (ZEROP N))						  (NEQ BUF END))       do (SETQ BUF (TTNEXTCHAR BUF))	  (SUB1VAR N)       finally (RETURN BUF])(TTNTHLINE  [LAMBDA (N)    (DECLARE (USEDFREE \FIRSTLINE))                          (* bvm: " 1-JUN-82 14:29")    (for (LINE _ \FIRSTLINE) do (COND				  ((ILEQ N 0)				    (RETURN LINE))				  (T (SETQ N (SUB1 N))				     (SETQ LINE (OR (fetch NEXTLINE of LINE)						    (RETURN LINE])(TTPRIN1  [LAMBDA (STR)                                              (* bvm: " 2-JUN-82 00:41")          (* * PRIN1 of STR, atom or string, directly to the terminal, bypassing any dribble file)    (PROG [(N (COND		(\VARIABLEFONT (STRINGWIDTH STR \FONT))		(T (ITIMES (NCHARS STR)			   \CHARWIDTH]          (COND	    ((IGEQ (IPLUS \CURSORCOL N)		   \RMARG)	      (TTCRLF)))          [for I from 1 do (TTBOUT (OR (NTHCHARCODE STR I)				       (RETURN]          (add \CURSORCOL N])(TTPRIN2  [LAMBDA (EXPR CARLVL CDRLVL)                               (* bvm: "16-SEP-82 16:01")    (SELECTQ (TYPENAME EXPR)	     (STRINGP (TTPRIN1 (QUOTE %"))		      (TTPRIN1 EXPR)		      (TTPRIN1 (QUOTE %")))	     [LISTP (OR CARLVL (SETQ CARLVL 12Q))		    (OR CDRLVL (SETQ CDRLVL 12Q))		    (COND		      ((ILEQ CARLVL 0)			(TTPRIN1 (QUOTE &)))		      (T (TTPRIN1 (QUOTE %())			 [do (TTPRIN2 (CAR EXPR)				      (SUB1 CARLVL)				      (SUB1 CDRLVL))			     (COND			       ((NLISTP (SETQ EXPR (CDR EXPR)))				 (COND				   (EXPR (TTPRIN1 " . ")					 (TTPRIN2 EXPR)))				 (RETURN))			       (T (TTPRIN1 (QUOTE % ))				  (COND				    ((ILEQ (SETQ CDRLVL (SUB1 CDRLVL))					   0)				      (TTPRIN1 "--")				      (RETURN]			 (TTPRIN1 (QUOTE %)]	     (MAPC (UNPACK EXPR T RDTBL)		   (QUOTE TTPRIN1])(TTPROMPTCHAR  [LAMBDA (LINE)                                       (* bvm: "11-MAR-81 21:43")          (* * Prints the prompt for indicated LINE)    (CLEAR.LINE?)    (COND      ((SETQ LINE (COND	    ((EQ LINE \FIRSTLINE)	      \PROMPT1)	    (T \PROMPT2)))	(TTPRIN1 LINE])(TTRATOM  [LAMBDA NIL                                                (* bvm: "20-FEB-82 22:34")          (* * Reads next atom from BUFFER, advancing it suitably)    (COND      ((EQ (TTSKIPSEPR)	   \ENDBUFFER)	null)      (T (PROG ((PACKBUF \ENDBUFFER)		PREVBUF CH)                                  (* PACKBUF is where we will build up the chars of the 							     atom)	   LP  (COND		 ((EQ \BUFFER \ENDBUFFER)		   (GO DONE)))	       (SELECTC (SETQ CH (REALBITS (CAR \BUFFER)))			[BREAKCODES                          (* Break chars: parens, brackets, quote)				    (COND				      ((AND (EQ CH (CHARCODE ,))					    \READING)        (* Comma does not break a read)					)				      [(EQ PACKBUF \ENDBUFFER)                                                             (* No atom read yet, so the break char is it)					(RETURN (PROG1 (FCHARACTER CH)						       (SETQ \BUFFER (CDR \BUFFER]				      (T (GO DONE]			(SEPRCODES                           (* separators terminate scan)				   (GO DONE))			[(CHARCODE %%)                       (* escape to quote next char)			  (COND			    ([OR \READING (AND (NEQ (CDR \BUFFER)						    \ENDBUFFER)					       (EQ (CADR \BUFFER)						   (CHARCODE ?]			      (SETQ \BUFFER (CDR \BUFFER]			NIL)	       (FRPLACA PACKBUF (REALBITS (CAR \BUFFER)))	       (SETQ PACKBUF (TTNEXTNODE (SETQ PREVBUF PACKBUF)))	       (SETQ \BUFFER (TTNEXTCHAR \BUFFER))	       (GO LP)	   DONE(RETURN (COND			 ((EQ PACKBUF (CDR \ENDBUFFER))			   (FCHARACTER (CAR \ENDBUFFER)))			 (T (FRPLACD PREVBUF)			    (PROG1 (PACKC \ENDBUFFER)				   (FRPLACD PREVBUF PACKBUF])(TTREAD  [LAMBDA NIL                                                (* bvm: "20-FEB-82 22:36")          (* Reads starting at BUFFER, advancing \BUFFER past what is read. If unmatched paren/bracket encountered, leaves 	  it. Returns the distinguished value null, a null string, if there is nothing to read)    (PROG (X)          (TTSKIPSEPR)          (RETURN (COND		    ((NEQ \BUFFER \ENDBUFFER)		      (SELCHARQ (REALBITS (CAR \BUFFER))				[(%( %[)				  (TTREADLIST (PROG1 (CAR \BUFFER)						     (SETQ \BUFFER (CDR \BUFFER]				((%) %])				  null)				[%" (SETQ X (OR (FIND.MATCHING.QUOTE (SETQ \BUFFER (CDR \BUFFER))								     \ENDBUFFER)						\ENDBUFFER))				    (PROG1 (TTYINSTRING \BUFFER X)					   (SETQ \BUFFER (CDR X]				['                           (* Do QUOTE readmacro)				   (SETQ \BUFFER (CDR \BUFFER))				   (COND				     ((AND (NOT (SPACEP (CAR \BUFFER)))					   (NEQ (SETQ X (TTREAD))						null))				       (LIST (QUOTE QUOTE)					     X))				     (T                      (* The quote was followed by "space", right 							     paren/bracket, or end of line)					(QUOTE ']				[^Y                          (* ^Y evaluates next thing in input)				    (SETQ \BUFFER (TTNEXTCHAR \BUFFER))				    (COND				      ((NEQ (SETQ X (TTREAD))					    null)					(STKEVAL (QUOTE TTYIN)						 X))				      (T (FCHARACTER (CHARCODE ^Y]				(TTRATOM)))		    (T null])(TTREADLIST  [LAMBDA (OPENCHAR)                                         (* bvm: "25-AUG-81 00:15")          (* * Read a list of elements. OPENCHAR is the character that started the list (paren or bracket) or NIL if none.)    (PROG (RESULT TAIL X)      LP  (COND	    ((EQ (TTSKIPSEPR)		 \ENDBUFFER)	      (RETURN RESULT)))      LP2 (SELCHARQ (CAR \BUFFER)		    (%)                                      (* right paren terminates list;							     eat it up to match open paren)			[COND			  (OPENCHAR (SETQ \BUFFER (CDR \BUFFER]			(RETURN RESULT))		    (%]                                      (* right bracket. Only eat it if started with bracket)			[COND			  ((EQ OPENCHAR (CHARCODE %[))			    (SETQ \BUFFER (CDR \BUFFER]			(RETURN RESULT))		    [%.                                      (* dot. if isolated and followed by one element, denotes							     dotted cdr)			(COND			  ((AND RESULT OPENCHAR (NEQ (CDR \BUFFER)						     \ENDBUFFER)				(SPACEP (CADR \BUFFER)))			    (SETQ \BUFFER (CDDR \BUFFER))    (* Looks good so far; skip over dot)			    (COND			      ((EQ (SETQ X (TTREAD))				   null)                     (* nothing there)				(SETQ X (QUOTE %.))				(GO ADDELT))			      ((AND (NEQ (TTSKIPSEPR)					 \ENDBUFFER)				    (SELCHARQ (CAR \BUFFER)					      ((%) %])						T)					      NIL))          (* terminated correctly on closing paren.							     do it)				(FRPLACD TAIL X)				(GO LP2))			      (T                             (* There's more there, so treat the dot as ordinary 							     atom)				 [FRPLACD TAIL (SETQ TAIL (CONS (QUOTE %.]				 (GO ADDELT]		    NIL)          (SETQ X (TTREAD))                                  (* scan next element)      ADDELT          (SETQ X (CONS X))                                  (* Now tack onto end of RESULT, doing open NCONC1 here)          (COND	    (RESULT (FRPLACD TAIL X))	    (T (SETQ RESULT X)))          (SETQ TAIL X)          (GO LP])(TTRUBOUT  [LAMBDA NIL                                                (* bvm: "19-MAR-81 12:02")          (* * Delete the previous character -- this is the interpretation of DELETE while inserting)    (COND      ((AT.START.OF.LINE)	(BEEP))      (T (BACKWARD.DELETE.TO (TTNLEFT \CURSOR 1])(TTSKIPSEPR  [LAMBDA (END)                                              (* bvm: "16-SEP-82 15:38")          (* * Skip \BUFFER over any separator chars, returning new value)    (while (AND (NEQ \BUFFER \ENDBUFFER)		(NEQ \BUFFER END)		(SPACEP (CAR \BUFFER)))       do (SETQ \BUFFER (CDR \BUFFER)))    \BUFFER])(TTSKREAD  [LAMBDA (BUF END)                                          (* bvm: "20-FEB-82 22:36")    (OR END (SETQ END \ENDBUFFER))    (bind X while (NEQ BUF END) comment           (* * Simulates READLINE starting at BUF, returning tail of BUF where the read would terminate, or NIL if the read 	  does not terminate before END (default \ENDBUFFER))       do (SELCHARQ (CAR BUF)		    [(%( %[)                                 (* open paren/bracket)		      (SETQ X (CAR BUF))		      (COND			((OR (NOT (SETQ BUF (TTSKREAD (CDR BUF)						      END)))			     (EQ BUF END))                   (* paren/bracket not closed)			  (RETURN))			((AND (EQ (CAR BUF)				  135Q)			      (NEQ X (CHARCODE %[)))         (* left paren terminated by right bracket)			  (RETURN BUF]		    ((%) %])                                 (* closing paren/bracket)		      (RETURN BUF))		    [%" (COND			  ((NOT (SETQ BUF (FIND.MATCHING.QUOTE (CDR BUF)							       END)))			    (RETURN]		    [%%                                      (* %  skip over without looking)			(COND			  ((EQ (SETQ BUF (CDR BUF))			       END)			    (RETURN]		    NIL)	  (SETQ BUF (CDR BUF))       finally (RETURN BUF])(TTUNREADBUF  [LAMBDA NIL    (DECLARE (USEDFREE \CURSOR \ENDBUFFER))                  (* bvm: "20-FEB-82 22:34")          (* * Takes contents of buffer from \CURSOR onward and "unreads" it, i.e. erases it and simulates terminal input, a	  la BKSYSBUF)    [for X_\CURSOR by (TTNEXTCHAR X) until (EQ X \ENDBUFFER) do (BKSYSCHAR0 (REALBITS (CAR X]    (DELETE.TO.END])(TTWAITFORINPUT  [LAMBDA (MSECS RETKEYFLG)                                  (* bvm: " 1-AUG-83 17:16")          (* Waits for mouse or keystroke. If MSECS is non-NIL, waits a maximum of that many milliseconds.	  If RETKEYFLG is true, returns the input (if there is some), otherwise just T without reading input.	  Mouse buttons are returned as funny codes)    (GLOBALRESOURCE (\TTWAITBOX)		    (PROG ((NOW (\CLOCK0 \TTWAITBOX))			   (REG (DSPCLIPPINGREGION NIL \DSP))			   X Y FN ABSY)		      LP  [COND			    ((\SYSBUFP)			      (\BOXIPLUS (LOCF (fetch KEYBOARDWAITTIME of \MISCSTATS))					 (CLOCKDIFFERENCE NOW))			      (RETURN (COND					(RETKEYFLG (\GETKEY))					(T T]		          (GETMOUSESTATE)		          [COND			    ((AND (LASTMOUSESTATE (OR RED YELLOW BLUE))				  (IGEQ (SETQ X (LASTMOUSEX \DSP))					0)				  (ILESSP X (fetch WIDTH of REG))				  (IGEQ (SETQ Y (IDIFFERENCE (SETQ ABSY (LASTMOUSEY \DSP))							     (fetch BOTTOM of REG)))					0)				  (ILESSP Y (IPLUS (fetch HEIGHT of REG)						   \CHARHEIGHT)))          (* The IPLUS is a grotesque kludge to include the title bar. Problem is that REG needs to be the clipping region, 	  not the window region, because we get mouse coordinates in DSP terms, not window terms. Damn Dedit typein buffer)                                                             (* Bugged inside this window)			      (COND				[(AND (ILESSP ABSY (IPLUS \BMARG (ITIMES (IDIFFERENCE \TTPAGELENGTH 										      \LOC.ROW.0)									 \CHARHEIGHT)))				      (IGEQ Y (IDIFFERENCE (ITIMES (IDIFFERENCE								     \TTPAGELENGTH								     (IPLUS \LOC.ROW.0									    (fetch ROW									       of (TTLASTLINE))									    1))								   \CHARHEIGHT)							   4)))                                                             (* Pointing inside text region)				  (\BOXIPLUS (LOCF (fetch KEYBOARDWAITTIME of \MISCSTATS))					     (CLOCKDIFFERENCE NOW))				  (RETURN (COND					    ((NOT RETKEYFLG)					      T)					    (T MOUSECODE]				([AND (WINDOWWORLD)				      (SETQ FN (COND					  ((LASTMOUSESTATE (ONLY BLUE))					    (OR (fetch TTOLDRIGHTFN of \TTYINSTATE)						(FUNCTION DOWINDOWCOM)))					  (T (fetch TTOLDBUTTONFN of \TTYINSTATE]                                                             (* Pointing in our window, but outside text--do regular 							     button stuff)				  (ERSETQ (APPLY* FN (WHICHW)))				  (COND				    ((NEQ \RMARG (SETQ \RMARG (DSPRIGHTMARGIN NIL \DSP)))                                                             (* Window was reshaped)				      (DO.EDIT.PP]		          (COND			    ((AND (FIXP MSECS)				  (IGREATERP (CLOCKDIFFERENCE NOW)					     MSECS))			      (\BOXIPLUS (LOCF (fetch KEYBOARDWAITTIME of \MISCSTATS))					 (CLOCKDIFFERENCE NOW))			      (RETURN NIL)))		          (\TTYBACKGROUND)		          (GO LP])(TTYINSTRING  [LAMBDA (BUF TAIL)                                         (* bvm: "20-FEB-82 22:34")          (* * Returns a string consisting of the "real" chars in buffer from BUF to TAIL or end of buffer.	  If BUF = TAIL returns a null string)    (OR TAIL (SETQ TAIL \ENDBUFFER))    (bind ($$VAL _(ALLOCSTRING (BUFCHARCOUNT BUF TAIL \READING))) for X_BUF by (TTNEXTCHAR X)       as I from 1 until (EQ X TAIL) do [COND					  ((AND \READING (EQ (CAR X)							     (CHARCODE %%)))                                                             (* %  to quote next char)					    (SETQ X (CDR X]					(RPLCHARCODE $$VAL I (REALBITS (CAR X])(TYPE.BUFFER  [LAMBDA (START END)                                        (* bvm: " 1-JUN-82 18:23")          (* * Types buffer from START to END, returning number of chars typed. Assumes no CR's)    (bind ($$VAL _ 0)	  WIDTH while (NEQ START END) do (COND					   ((NOT (PREFIXCHAR (CAR START)))					     (TTBOUT (CAR START))					     [add \CURSORCOL (SETQ WIDTH (TTBITWIDTH						      (REALBITS (CAR START]					     (add $$VAL WIDTH)))					 (SETQ START (CDR START])(U-CASECODE  [LAMBDA (CHAR)                                       (* bvm: "11-MAR-81 22:06")    (COND      ([AND [NOT (ILESSP CHAR (CONSTANT (CHCON1 (QUOTE a]	    (NOT (IGREATERP CHAR (CONSTANT (CHCON1 (QUOTE z]	(LOGAND CHAR 137Q))      (T CHAR])(U/L-CASE  [LAMBDA (N CAPFLG)    (DECLARE (USEDFREE \CURSOR \ARROW))                      (* bvm: " 4-JUN-82 18:16")          (* * UPPER or lower-case N words. CAPFLG=T for uppercase; CAPFLG=1 for just capitalization)    (COND      ((AND (EQ N 1750Q)	    (AT.END.OF.LINE))          (* $U or $L at end of line means do it to the whole line. This handles the common situation where you have typed 	  several words in the wrong case and want to fix them without backing up to the beginning)	(MOVE.BACK.TO (fetch START of \ARROW)))      (T (MOVE.TO.START.OF.WORD)))                           (* Go to start of current word)    (PROG ((NEXTWD (CHECK.MARGIN (FIND.NEXT.WORD \CURSOR N)))	   NEEDADJUST OLDLENGTH)          [COND	    (\VARIABLEFONT                                   (* Notice how long it is now)			   (SETQ OLDLENGTH (SEGMENT.BIT.LENGTH \CURSOR NEXTWD]          (for (BUF _ \CURSOR)	       CHAR until (EQ BUF NEXTWD) do [COND					       ((AND [NOT (PREFIXCHAR (SETQ CHAR (CAR BUF]						     (IGREATERP CHAR 100Q))						 (FRPLACA BUF (COND							    (CAPFLG (COND								      ((EQ CAPFLG 1)                                                             (* only raise first char of word)									(SETQ CAPFLG NIL)))								    (U-CASECODE CHAR))							    (T (L-CASECODE CHAR]					     (SETQ BUF (TTNEXTCHAR BUF)))          [COND	    (\VARIABLEFONT (SETQ NEEDADJUST (TTADJUSTWIDTH (IDIFFERENCE (SEGMENT.BIT.LENGTH \CURSOR 											   NEXTWD)									OLDLENGTH)							   NEXTWD]          (TYPE.BUFFER \CURSOR (SETQ \CURSOR NEXTWD))          (COND	    (NEEDADJUST (ADJUSTLINE.AND.RESTORE])(WORD.MATCHES.BUFFER  [LAMBDA (WORD START BUFTAIL)                               (* bvm: "20-FEB-82 22:35")          (* * True if WORD matches chars in buffer from START to BUFTAIL)    (for I from 1 as BTAIL_START by (TTNEXTCHAR BTAIL) bind CHAR until (EQ BTAIL BUFTAIL)       always (OR (EQ (SETQ CHAR (NTHCHARCODE WORD I))		      (CAR BTAIL))		  (AND CHAR (EQ (LOGXOR CHAR 40Q)				(CAR BTAIL))		       (IGEQ CHAR (CHARCODE A))		       (ILEQ CHAR (CHARCODE z]))(RPAQQ TTDISPLAYFNS (&DISPLAYCOMMENT CAPABILITY? BEEP BITBLT.DELETE BITBLT.ERASE BITBLT.INSERT 				     DO.CRLF DO.DELETE.LINES DO.DOWN DO.INSERT.LINE DO.LF DO.UP 				     ERASE.SCREEN ERASE.TO.END.OF.LINE ERASE.TO.END.OF.PAGE 				     INSERT.TEXT INSERTNCHARS TTDELSECTION TTADJUSTWIDTH 				     TTINSERTSECTION TTSETCURSOR))(DEFINEQ(&DISPLAYCOMMENT  [LAMBDA NIL                                          (* bvm: " 8-Mar-80 16:37")          (* The display-dependent functions follow. These are the functions to change to add new terminal types.	  You'll probably also want to change DISPLAYTERMP to include the new type, or at least set DISPLAYTYPES correctly.	  The types that TTYIN currently knows about, together with their internal codes (the value of DISPLAYTERMFLG) are -	  1: Datamedia -- can do anything asked in this package -	  2: Heath -- can display anything, but has no edit key -	  0: glass tty -- any terminal capable of at least backspacing and overprinting, so that the sequence BS, SPACE, BS 	  will delete a character.)          (* * The main body of TTYIN relies only on certain primitive operations, encoded according to terminal type in the 	  functions that follow. It uses the function CAPABILITY? to decide whether the terminal can perform a function it is 	  considering)          (* * The functions included herein assume you are running no faster than 2400-baud. Some functions need considerably	  more padding at 9600-baud, although if you're on tops20 in page mode the Heath will send ^S and ^Q to survive 	  anyway. The main thing that taxes the Heath is ADJUSTLINE trying to justify several lines at once.	  DM has biggest problem with Insert Line)    ])(CAPABILITY?  [NLAMBDA (TYPE ON.DISPLAY.FLG)                       (* bvm: "19-MAR-81 12:06")          (* * true if terminal has the indicated capability. This is a compiler macro that tests for appropriate values of 	  DISPLAYTERMFLG; if ON.DISPLAY.FLG is true, the macro may assume that DISPLAYTERMFLG is already non-NIL.	  TYPE may be -	  ERASE.TO.END -- terminal can erase to end of line -	  \CURSOR -- terminal has addressable cursor -	  MOVEMENT -- terminal permits cursor to move freely about page (up, down, left, right); \CURSOR is assumed to imply 	  MOVEMENT -	  EDIT -- terminal can send EDIT bit (200Q) -	  I/D.CHAR -- terminal has insert/delete character ability -	  -	  This package currently assumes that if the terminal can "edit", i.e. get into the edit-character routines, then it 	  has ERASE.TO.END, as well as insert/delete line, and preferably \CURSOR as well. For just "glass tty" operation, 	  existence of ERASE.TO.END and \CURSOR are the only relevant things; they may optimize large deletes 	  (^Q and ^W). Minimal display requirement is physical backspace; otherwise DISPLAYTERMFLG must be NIL.)    (SELECTQ TYPE	     (MOVEMENT T)	     (ERASE.TO.END T)	     (I/D.CHAR T)	     (\CURSOR T)	     NIL])(BEEP  [LAMBDA (DS)                                               (* bvm: "27-JUL-83 23:20")    (RESETFORM (VIDEOCOLOR (NOT (VIDEOCOLOR)))	       (DISMISS 310Q])(BITBLT.DELETE  [LAMBDA (X Y WIDTH)                                        (* bvm: " 1-JUN-82 16:34")    (PROG ((MOVEDWIDTH (IDIFFERENCE (IDIFFERENCE \RMARG X)				    WIDTH)))                 (* First move everything from the right over to cursor 							     pos)          (BITBLT \DSP (IPLUS X WIDTH)		  Y \DSP X Y MOVEDWIDTH \CHARHEIGHT (QUOTE INPUT)		  (QUOTE REPLACE))                           (* then delete the last WIDTH positions on the line.							     May be unnecessary if they were already blank, might 							     want to check LASTCOL)          (BITBLT.ERASE (IPLUS X MOVEDWIDTH)			Y WIDTH \CHARHEIGHT])(BITBLT.ERASE  [LAMBDA (LEFT BOTTOM WIDTH HEIGHT)                         (* bvm: " 1-JUN-82 15:10")    (BITBLT NIL NIL NIL \DSP LEFT BOTTOM WIDTH HEIGHT (QUOTE TEXTURE)	    (QUOTE REPLACE)	    \TEXTURE])(BITBLT.INSERT  [LAMBDA (X Y WIDTH)                                        (* bvm: " 1-JUN-82 14:12")    (BITBLT \DSP X Y \DSP (IPLUS X WIDTH)	    Y	    (IDIFFERENCE (IDIFFERENCE \RMARG X)			 WIDTH)	    \CHARHEIGHT	    (QUOTE INPUT)	    (QUOTE REPLACE])(DO.CRLF  [LAMBDA NIL                                                (* bvm: " 2-MAR-82 22:38")    (SETQ \CURRENTDISPLAYLINE 0)                             (* Avoid stop scroll nonsense)    (\DSPPRINTCR/LF (CHARCODE CR)		    \DSP])(DO.DELETE.LINES  [LAMBDA (#LINES)                                           (* bvm: "25-AUG-81 00:21")    (PROG ((DY (IPLUS (IDIFFERENCE (DSPYPOSITION NIL \DSP)				   \DESCENT)		      \CHARHEIGHT))	   (DELHEIGHT (ITIMES #LINES \CHARHEIGHT)))          (COND	    ((IGREATERP DELHEIGHT DY)	      (SETQ DELHEIGHT DY)))          (BITBLT \DSP 0 0 \DSP 0 DELHEIGHT \RMARG (IDIFFERENCE DY DELHEIGHT)		  (QUOTE INPUT)		  (QUOTE REPLACE))          (BITBLT.ERASE 0 0 \RMARG DELHEIGHT])(DO.DOWN  [LAMBDA (#LINES)                                           (* bvm: "25-AUG-81 00:24")                                                             (* LF works on all terminals I know about)    (RELMOVETO 0 (IMINUS (ITIMES #LINES \CHARHEIGHT))	       \DSP])(DO.INSERT.LINE  [LAMBDA NIL                                                (* bvm: "20-FEB-82 22:33")          (* * Inserts a new line on screen in front of current cursor row. The trickiness here is that unless there are 	  some blank lines at the bottom of the screen, we actually have to scroll upwards before we can insert downwards, 	  lest we lose the bottom line. Leaves cursor at start of new blank line.)    (PROG ((DY (IDIFFERENCE (DSPYPOSITION NIL \DSP)			    \DESCENT)))          [COND	    ((EQ (IPLUS \LOC.ROW.0 (fetch ROW of (TTLASTLINE))			1)		 \TTPAGELENGTH)                              (* Bottom line is occupied, so scroll stuff above us 							     upward)	      (add DY \CHARHEIGHT)	      (MOVETO (DSPXPOSITION NIL \DSP)		      (IPLUS DY \DESCENT)		      \DSP)	      (BITBLT \DSP 0 DY \DSP 0 (IPLUS DY \CHARHEIGHT)		      \RMARG		      (IDIFFERENCE (IDIFFERENCE (ITIMES \TTPAGELENGTH \CHARHEIGHT)						DY)				   \CHARHEIGHT)		      (QUOTE INPUT)		      (QUOTE REPLACE))	      (SETQ \LOC.ROW.0 (SUB1 \LOC.ROW.0))            (* Top line of buffer has moved up one)	      )	    (T                                               (* Shove everything below us down one)	       (BITBLT \DSP 0 \CHARHEIGHT \DSP 0 0 \RMARG DY (QUOTE INPUT)		       (QUOTE REPLACE]                       (* and clear this line)          (BITBLT.ERASE 0 DY \RMARG \CHARHEIGHT])(DO.LF  [LAMBDA NIL                                                (* bvm: "25-AUG-81 00:25")    (\DSPPRINTCR/LF (CHARCODE LF)		    \DSP])(DO.UP  [LAMBDA (#LINES)                                           (* bvm: "25-AUG-81 00:25")    (RELMOVETO 0 (ITIMES #LINES \CHARHEIGHT)	       \DSP])(ERASE.SCREEN  [LAMBDA NIL                                                (* bvm: "30-JUN-81 16:08")    (DSPRESET \DSP])(ERASE.TO.END.OF.LINE  [LAMBDA NIL                                                (* bvm: "25-AUG-81 00:27")    (PROG ((X (DSPXPOSITION NIL \DSP)))          (BITBLT.ERASE X (IDIFFERENCE (DSPYPOSITION NIL \DSP)				       \DESCENT)			(IDIFFERENCE \RMARG X)			\CHARHEIGHT])(ERASE.TO.END.OF.PAGE  [LAMBDA NIL                                                (* bvm: "25-AUG-81 00:28")          (* * Erases from current cursor position to end of page.)    (ERASE.TO.END.OF.LINE)    (PROG ((BELOW (IDIFFERENCE (DSPYPOSITION NIL \DSP)			       \DESCENT)))          (COND	    ((IGREATERP BELOW 0)	      (BITBLT.ERASE 0 0 \RMARG BELOW])(INSERT.TEXT  [LAMBDA (START END ENDOFLINE)                              (* bvm: " 4-JUN-82 13:43")          (* * Inserts on screen the contents of buffer from START to END. Text from END to ENDOFLINE is the remainder of 	  the line, in case it's more economical to just retype the line than do the insertion)    (COND      ((EQ END ENDOFLINE)	(TYPE.BUFFER START ENDOFLINE))      (T (TTINSERTSECTION (SEGMENT.BIT.LENGTH START END))	 (TYPE.BUFFER START END])(INSERTNCHARS  [LAMBDA (N CHAR)                                           (* bvm: " 4-JUN-82 13:43")          (* * Inserts N copies of CHAR in front of existing text)    (TTINSERTSECTION (ITIMES N (TTBITWIDTH CHAR)))    (TTBOUTN N CHAR])(TTDELSECTION  [LAMBDA (WIDTH)                                            (* bvm: " 1-JUN-82 16:43")          (* * Deletes WIDTH bits at current pos)    (BITBLT.DELETE (DSPXPOSITION NIL \DSP)		   (IDIFFERENCE (DSPYPOSITION NIL \DSP)				\DESCENT)		   WIDTH])(TTADJUSTWIDTH  [LAMBDA (DELTA END)                                        (* bvm: " 4-JUN-82 18:15")          (* Expand or shrink line at current cursorpos by DELTA. END, if supplied, is the end of the section being 	  adjusted; if it is the end of the current line, then it is assumed that expansion is cheap.	  Returns true if anything was done)    (COND      ((NOT (ZEROP DELTA))	(COND	  ((ILESSP DELTA 0)                                  (* Line has shrunk)	    (TTDELSECTION (IMINUS DELTA)))	  ((NEQ END (fetch END of \ARROW))                   (* Line has expanded, so need to spread it if not at the							     end)	    (TTINSERTSECTION DELTA)))	(add (fetch LASTCOL of \ARROW)	     DELTA)	T])(TTINSERTSECTION  [LAMBDA (WIDTH)                                            (* bvm: " 1-JUN-82 14:15")          (* * Inserts WIDTH character positions, leaving cursor at start of insertion)    (BITBLT.INSERT (DSPXPOSITION NIL \DSP)		   (IDIFFERENCE (DSPYPOSITION NIL \DSP)				\DESCENT)		   WIDTH])(TTSETCURSOR  [LAMBDA (COL ROW)                                          (* bvm: " 1-JUN-82 22:56")          (* * Sets cursor to absolute screen position COL,ROW)    (MOVETO (IPLUS COL \LMARG)	    (IPLUS (ITIMES (SUB1 (IDIFFERENCE \TTPAGELENGTH ROW))			   \CHARHEIGHT)		   \BMARG)	    \DSP]))(* Mouse handling)(DEFINEQ(DO.MOUSE  [LAMBDA NIL                                                (* bvm: " 1-JUN-82 18:36")          (* Called when mouse is clicked down inside of our region; performs it as an edit command, returning T, or returns	  NIL if it is not a legal mouse call. The commands that actually change something display their intent while the 	  button is down and are not actually executed until button is released.)    (COND      ([NOT (ZEROP (LOGAND LASTKEYBOARD (LOGOR \SHIFTKEYS \CTRLKEY]	(DO.SHIFTED.SELECTION))      [(LASTMOUSESTATE (ONLY RED))                           (* Position cursor)	(bind ROW/COL while (SETQ ROW/COL (TTRACKMOUSE ROW/COL)) when (LISTP ROW/COL)	   do (\CHECKCARET \DSP)	      (MOVE.TO.LINE (CAR ROW/COL)			    (CDR ROW/COL]      [(LASTMOUSESTATE (ONLY YELLOW))                        (* Position cursor by word)	(bind NEWPOS BUF COL LINE while (SETQ NEWPOS (TTRACKMOUSE NEWPOS)) when (LISTP NEWPOS)	   do (\CHECKCARET \DSP)	      [SETQ BUF (BRACKET.CURRENT.WORD (SETQ LINE (fetch ROWPOS of NEWPOS))					      (SETQ COL (fetch COLPOS of NEWPOS]	      (MOVE.TO.LINE LINE (COND			      ((IGREATERP (SEGMENT.BIT.LENGTH (CAR BUF)							      COL)					  (SEGMENT.BIT.LENGTH COL (CDR BUF)))				(CDR BUF))			      (T (CAR BUF]      ((LASTMOUSESTATE (ONLY BLUE))                          (* zap from cursor to mouse location.)	(DO.SHIFTED.SELECTION (QUOTE DELETE])(DO.SHIFTED.SELECTION  [LAMBDA (INITMODE)                                         (* bvm: " 2-MAR-82 22:29")    (bind START END SAVE EXTENDING MODE NEWSTART NEWEND COL NEWROW NEWMODE BUF NEWPOS WORDLEVEL 	  ENDLINE       while (OR (NEQ (LOGAND LASTKEYBOARD (LOGOR \SHIFTKEYS \CTRLKEY))		      0)		 (LASTMOUSESTATE (NOT UP)))       do (SETQ NEWPOS (TTRACKMOUSE NEWPOS))	  (\TTYBACKGROUND)                                   (* Flash caret)	  (COND	    [(LASTMOUSESTATE (OR RED YELLOW))                (* Start new selection)	      (COND		[(AND (LISTP NEWPOS)		      (NEQ (SETQ COL (fetch COLPOS of NEWPOS))			   \ENDBUFFER))                      (* There is a selection)		  (SETQ NEWSTART (create MOUSEPOS using NEWPOS))		  (SETQ NEWROW (fetch ROWPOS of NEWPOS))		  (COND		    ((OR (LASTMOUSESTATE (ONLY RED))			 (EQ COL (fetch END of NEWROW)))     (* Selection extends to next char)		      (SETQ NEWEND (TTNEXTPOS NEWROW COL))		      (SETQ WORDLEVEL NIL))		    (T                                       (* Selection is current "word")		       (SETQ BUF (BRACKET.CURRENT.WORD NEWROW (fetch COLPOS of NEWSTART)))		       (replace COLPOS of NEWSTART with (CAR BUF))                                                             (* Start of previous word)		       (SETQ NEWEND (create MOUSEPOS					    ROWPOS _ NEWROW					    COLPOS _(CDR BUF)))		       (SETQ WORDLEVEL T)))		  (SETQ NEWMODE (COND		      ((ZEROP (LOGAND LASTKEYBOARD \CTRLKEY))			(QUOTE SELECT))		      ((ZEROP (LOGAND LASTKEYBOARD \SHIFTKEYS))			(QUOTE DELETE))		      (T (QUOTE MOVE]		(T (SETQ NEWSTART NIL)))	      (COND		((OR (NEQPOS START NEWSTART)		     (NEQPOS END NEWEND)		     (NEQ MODE NEWMODE))		  (COND		    (START                                   (* turn off old selection)			   (INVERT.LONG.SEGMENT START END MODE)))		  (COND		    ((SETQ START NEWSTART)		      (INVERT.LONG.SEGMENT START (SETQ END NEWEND)					   (SETQ MODE NEWMODE]	    [(LASTMOUSESTATE (ONLY BLUE))                    (* Extend selection)	      [COND		((NOT START)                                 (* No selection, extend from cursor)		  [SETQ NEWSTART (SETQ NEWEND (SETQ START			(SETQ END (create MOUSEPOS					  ROWPOS _ \ARROW					  COLPOS _ \CURSOR]		  (SETQ WORDLEVEL (SETQ EXTENDING NIL))		  (COND		    (INITMODE (SETQ MODE INITMODE)           (* E.g. in DO.MOUSE on BLUE)			      (SETQ INITMODE))		    (T (SETQ MODE (COND			   ((ZEROP (LOGAND LASTKEYBOARD \CTRLKEY))			     (QUOTE SELECT))			   ((ZEROP (LOGAND LASTKEYBOARD \SHIFTKEYS))			     (QUOTE DELETE))			   (T (QUOTE MOVE]	      (SETQ NEWROW (fetch ROWPOS of NEWPOS))	      (COND		[(NLISTP NEWPOS)                             (* No selection; cancel any existing extension)		  (COND		    (EXTENDING (COND				 ((NEQPOS START NEWSTART)				   (INVERT.LONG.SEGMENT NEWSTART START MODE)				   (SETQ NEWSTART START))				 ((NEQPOS END NEWEND)				   (INVERT.LONG.SEGMENT END NEWEND MODE)				   (SETQ NEWEND END)))			       (SETQ EXTENDING NIL]		(T (COND		     ((TTBEFOREPOS NEWPOS START)             (* Extending to left of original selection)		       (COND			 ((AND EXTENDING (NEQPOS END NEWEND))                                                             (* We were extending to right, so switch)			   (INVERT.LONG.SEGMENT END NEWEND MODE)			   (SETQ NEWEND END)))		       (INVERT.LONG.SEGMENT NEWSTART (SETQ NEWSTART (create MOUSEPOS using NEWPOS))					    MODE))		     (T                                      (* Extending to right)			(COND			  ((AND EXTENDING (NEQPOS START NEWSTART))                                                             (* We were extending to left, so switch)			    (INVERT.LONG.SEGMENT START NEWSTART MODE)			    (SETQ NEWSTART START)))			(INVERT.LONG.SEGMENT NEWEND (SETQ NEWEND (TTNEXTPOS NEWROW									    (fetch COLPOS									       of NEWPOS)))					     MODE)))		   (SETQ EXTENDING T]	    (EXTENDING                                       (* End of extension, make NEWSTART/END permanent)		       (SETQ START NEWSTART)		       (SETQ END NEWEND)		       (SETQ EXTENDING NIL)))       finally (COND		 (START                                      (* There is a selection, so do it)			(\CHECKCARET \DSP)			(PROG ((STARTBUF (fetch COLPOS of START))			       (ENDBUF (fetch COLPOS of END)))			      (COND				[(EQ MODE (QUOTE SELECT))				  (INVERT.LONG.SEGMENT START END MODE)                                                             (* Take it as typein)				  (COND				    ((BEFOREBUF STARTBUF \CURSOR ENDBUF)                                                             (* Can't just unread, because structure will change as 							     we do so)				      (READFROMBUF (COPY.SEGMENT STARTBUF ENDBUF)))				    (T (READFROMBUF STARTBUF ENDBUF T]				((AND (EQ MODE (QUOTE MOVE))				      (BEFOREBUF STARTBUF \CURSOR ENDBUF))                                                             (* Action overlaps cursor, so effect is just to move 							     cursor)				  (INVERT.LONG.SEGMENT START END MODE)				  (MOVE.TO.LINE (fetch ROWPOS of END)						ENDBUF))				(T           (* Delete or move selection, insert it as typein at cursor for the latter. We save away the selection in 	  \LAST.DELETION to be restored later if desired)				   (SETQ SAVE (COND				       ((BEFOREBUF STARTBUF \CURSOR ENDBUF)                                                             (* The delete will move \CURSOR into trash heap)					 STARTBUF)				       (T \CURSOR)))				   (SETQ \LAST.DELETION (SETQ BUF (COPY.SEGMENT STARTBUF ENDBUF)))                                                             (* Save selection)				   (DELETE.LONG.SEGMENT START END)				   (MOVE.TO.WHEREVER SAVE)   (* Come back to where cursor is 							     (may have moved))				   (AND (EQ MODE (QUOTE MOVE))					(READFROMBUF BUF NIL T])(COPY.SEGMENT  [LAMBDA (START END)                                        (* bvm: " 4-DEC-81 17:04")    (for TAIL_START by (CDR TAIL) until (EQ TAIL END) collect (CAR TAIL])(DELETE.LONG.SEGMENT  [LAMBDA (START END)                                        (* bvm: "15-JUN-82 17:59")    (DELETE.LONG.SEGMENT1 (fetch ROWPOS of START)			  (fetch COLPOS of START)			  (fetch ROWPOS of END)			  (fetch COLPOS of END])(DELETE.LONG.SEGMENT1  [LAMBDA (STARTLINE STARTCOL ENDLINE ENDCOL)                (* bvm: "15-JUN-82 17:58")    (PROG (FIRSTLINE NEXTLINE NROWS)          (COND	    ([ZEROP (SETQ NROWS (IDIFFERENCE (fetch ROW of ENDLINE)					     (fetch ROW of STARTLINE]                                                             (* All on one line)	      (MOVE.TO.LINE STARTLINE STARTCOL)	      (FORWARD.DELETE.TO ENDCOL))	    (T (MOVE.TO.LINE (SETQ FIRSTLINE (fetch NEXTLINE of STARTLINE)))	       (DO.DELETE.LINES NROWS)                       (* Delete excess lines)	       (SETQ NEXTLINE (fetch NEXTLINE of ENDLINE))	       (replace NEXTLINE of STARTLINE with NEXTLINE)	       (RENUMBER.LINES NEXTLINE (ADD1 (fetch ROW of STARTLINE)))	       [add (fetch LASTCOL of STARTLINE)		    (IDIFFERENCE (SEGMENT.BIT.LENGTH ENDCOL (fetch END of ENDLINE))				 (SEGMENT.BIT.LENGTH STARTCOL (fetch END of STARTLINE]	       (replace END of STARTLINE with (fetch END of ENDLINE))	       (COND		 ((EQ ENDCOL (fetch END of STARTLINE))		   (replace END of STARTLINE with STARTCOL)))	       (KILLSEGMENT STARTCOL ENDCOL)	       (replace NEXTLINE of ENDLINE with NIL)	       (KILL.LINES FIRSTLINE)	       (MOVE.TO.LINE STARTLINE STARTCOL)	       (ERASE.TO.END.OF.LINE)	       (COND		 ((ILESSP (fetch LASTCOL of STARTLINE)			  \RMARG)		   (TYPE.BUFFER STARTCOL (fetch END of STARTLINE)))		 (T (TYPE.BUFFER STARTCOL (NTH.COLUMN.OF STARTLINE \RMARG))		    (ADJUSTLINE NIL STARTLINE])(INVERT.LONG.SEGMENT  [LAMBDA (START END MODE)                                   (* bvm: "25-FEB-82 15:57")    (COND      ((NOT (EQPOS START END))	(OR (TTBEFOREPOS START END)	    (swap START END))	(PROG ((COL (fetch COLPOS of START))	       (ROW (fetch ROWPOS of START)))	      (while (NEQ ROW (fetch ROWPOS of END)) do (INVERT.SEGMENT COL									(fetch START									   of (fetch NEXTLINE										 of ROW))									ROW MODE T)							(SETQ ROW (fetch NEXTLINE of ROW))							(SETQ COL (fetch START of ROW)))	      (INVERT.SEGMENT COL (fetch COLPOS of END)			      ROW MODE T])(INVERT.SEGMENT  [LAMBDA (START END LINE MODE NOSWAP)    (DECLARE (USEDFREE \ARROW \CHARWIDTH \LOC.ROW.0 \CHARHEIGHT \BMARG \LMARG))                                                             (* bvm: " 1-JUN-82 18:36")    (COND      ((NEQ START END)	(OR LINE (SETQ LINE \ARROW))	(OR MODE (SETQ MODE (QUOTE DELETE)))	(OR NOSWAP (BEFOREBUF START END (fetch END of LINE))	    (swap START END))	(PROG ((LEFT (IPLUS (fetch FIRSTCOL of LINE)			    (SEGMENT.BIT.LENGTH (fetch START of LINE)						START)			    \LMARG))	       (BOTTOM (IPLUS (ITIMES (SUB1 (IDIFFERENCE (IDIFFERENCE \TTPAGELENGTH \LOC.ROW.0)							 (fetch ROW of LINE)))				      \CHARHEIGHT)			      \BMARG			      (IMINUS \DESCENT)))	       (WIDTH (SEGMENT.BIT.LENGTH START END)))	      (BITBLT NIL NIL NIL \DSP LEFT BOTTOM WIDTH (COND			((NEQ MODE (QUOTE SELECT))			  \CHARHEIGHT)			(T 2))		      (QUOTE TEXTURE)		      (QUOTE INVERT)		      (COND			((NEQ MODE (QUOTE SELECT))			  BLACKSHADE)			(T DOTSHADE)))	      (COND		((EQ MODE (QUOTE MOVE))		  (BITBLT NIL NIL NIL \DSP LEFT BOTTOM WIDTH 2 (QUOTE TEXTURE)			  (QUOTE INVERT)			  DOTSHADE])(BRACKET.CURRENT.WORD  [LAMBDA (LINE COL)                                         (* bvm: "26-FEB-82 17:03")          (* * Return dotted pair of columns indicating start and end of "word" containing buffer position COL of LINE)    (PROG ((INSPACES T)	   (ENDLINE (fetch END of LINE))	   (WSTART (fetch START of LINE))	   FIRSTCOL LASTCOL)          (for BUF_WSTART by (TTNEXTCHAR BUF) until (EQ BUF ENDLINE)	     do [COND		  ([NEQ INSPACES (SETQ INSPACES (WORDSEPRP (CAR BUF]                                                             (* Change of state)		    (COND		      (FIRSTCOL                              (* Done)				(RETURN (SETQ LASTCOL BUF)))		      (T                                     (* Still looking for COL, note start of word)			 (SETQ WSTART BUF]		(COND		  ((EQ BUF COL)		    (SETQ FIRSTCOL WSTART)))	     finally                                         (* Got to end before word ended)		     (SETQ LASTCOL ENDLINE)		     (OR FIRSTCOL (SETQ FIRSTCOL LASTCOL)))          (OR (BEFOREBUF FIRSTCOL COL LASTCOL)	      (HELP))          (RETURN (CONS FIRSTCOL LASTCOL])(TTBEFOREPOS  [LAMBDA (X Y)                                              (* bvm: " 2-MAR-82 13:18")    (COND      [(EQ (fetch ROWPOS of X)	   (fetch ROWPOS of Y))	(AND (NEQ (fetch COLPOS of X)		  (fetch COLPOS of Y))	     (BEFOREBUF (fetch COLPOS of X)			(fetch COLPOS of Y)			(fetch END of (fetch ROWPOS of X]      (T (ILESSP (fetch ROW of (fetch ROWPOS of X))		 (fetch ROW of (fetch ROWPOS of Y])(TTNEXTPOS  [LAMBDA (LINE COL)                                         (* bvm: "25-FEB-82 16:04")          (* * Makes a MOUSEPOS out of the position, if any, immediately after COL of LINE)    (COND      ((AND (EQ COL (fetch END of LINE))	    (NEQ COL \ENDBUFFER))	(create MOUSEPOS		ROWPOS _(SETQ LINE (fetch NEXTLINE of LINE))		COLPOS _(fetch START of LINE)))      (T (create MOUSEPOS		 ROWPOS _ LINE		 COLPOS _(COND		   ((EQ COL \ENDBUFFER)		     COL)		   (T (TTNEXTCHAR COL])(TTRACKMOUSE  [LAMBDA (OLDROW/COL)                                       (* bvm: "23-MAR-83 15:37")    (DECLARE (USEDFREE \VARIABLEFONT \DSP \TTPAGELENGTH \LOC.ROW.0 \BMARG \CHARHEIGHT \LMARG \RMARG 		       \FONT))          (* Follows the mouse, returning whenever its row/col changes or the user lets up the mouse buttons.	  Converts mouse coordinates into a dotted pair (LINE . BUFPOS) indicating what char is being pointed at, or T if 	  outside range of text. Returns NIL when user lets go. OLDROW/COL is the previous value of this routine, which we 	  may smash.)    (PROG (OLDX OLDY ROW COL OLDROW OLDCOL CURSORPOS)          [COND	    ((LISTP OLDROW/COL)	      (SETQ OLDROW (CAR OLDROW/COL))	      (SETQ OLDCOL (CDR OLDROW/COL]      LP  (COND	    ((MOUSESTATE UP)                                 (* everything up)	      (RETURN)))          (SETQ CURSORPOS (CURSORPOSITION NIL \DSP CURSORPOS))          [COND	    ((OR (NEQ (CAR CURSORPOS)		      OLDX)		 (NEQ (CDR CURSORPOS)		      OLDY))                                 (* Cursor moved)	      [SETQ ROW (SUB1 (IDIFFERENCE (IDIFFERENCE \TTPAGELENGTH \LOC.ROW.0)					   (IQUOTIENT (IDIFFERENCE (SETQ OLDY (CDR CURSORPOS))								   \BMARG)						      \CHARHEIGHT]	      (SETQ OLDX (CAR CURSORPOS))	      (COND		[(AND (IGEQ OLDX \LMARG)		      (ILESSP OLDX \RMARG)		      (IGEQ ROW 0))		  (SETQ ROW (TTNTHLINE ROW))		  [SETQ COL (COND		      (\VARIABLEFONT (SETQ COL (IDIFFERENCE (IDIFFERENCE OLDX \LMARG)							    (fetch FIRSTCOL of ROW)))				     (bind WIDTH (BUF _(fetch START of ROW))					   (END _(fetch END of ROW)) while (NEQ BUF END)					do [SETQ WIDTH (COND					       ((NOT (PREFIXCHAR (CAR BUF)))						 (FCHARWIDTH (CAR BUF)							     \FONT))					       (T (SEGMENT.BIT.LENGTH BUF (TTNEXTCHAR BUF]					   (COND					     ((ILESSP COL (LRSH WIDTH 1))					       (RETURN BUF)))					   (SETQ COL (IDIFFERENCE COL WIDTH))					   (SETQ BUF (TTNEXTCHAR BUF))					finally (RETURN BUF)))		      (T (NTH.COLUMN.OF ROW (IDIFFERENCE OLDX \LMARG]		  (COND		    ((OR (NEQ ROW OLDROW)			 (NEQ COL OLDCOL))		      (RETURN (COND				((LISTP OLDROW/COL)				  (FRPLNODE OLDROW/COL ROW COL))				(T (CONS ROW COL]		(T (COND		     ((NEQ OLDROW/COL T)		       (RETURN T]          (\TTYBACKGROUND)          (GO LP])(TTYINBUTTONFN  [LAMBDA NIL                                                (* bvm: "23-MAR-82 22:59")                                                             (* a NILL we can distinguish)    NIL]))(* Support functions. These are all macros or for debugging)(RPAQQ TTSUPPORTFNS (ADD1POS INPART INSERTING TTBOUT TTBOUTN PR! PRALL PRBUF PRLINE))(DEFINEQ(ADD1POS  [LAMBDA (CHAR)                                             (* bvm: " 1-JUN-82 17:12")    (add \CURSORCOL (TTBITWIDTH CHAR])(INPART  [LAMBDA (X)                                          (* bvm: " 3-Jul-78 12:27")          (* Given a "word" from the spelling list, returns that which would be input to TTYIN, i.e. if a dotted synonym pair,	  its CAR, else the word itself)    (COND      ((LISTP X)	(CAR X))      (T X])(INSERTING  [LAMBDA NIL                                          (* bvm: "19-MAR-81 12:09")          (* * True if explicitly in INSERT mode, or if we are in EMACS mode, where most characters self-insert)    (OR \INSERTING EMACSFLG])(TTBOUT  [NLAMBDA CHARS                                             (* bvm: "25-AUG-81 00:31")          (* Prints one or more characters to the terminal. Arguments may be: a number, an atom on DMCHARCODES, or a single 	  character; any other arg is simply evaluated)    (for $CH in CHARS do (BLTCHAR (LOGAND (COND					    ((FIXP $CH)					      $CH)					    ((CDR (FASSOC $CH DMCHARCODES)))					    ((EQ (NCHARS $CH)						 1)					      (CHCON1 $CH))					    (T (EVAL $CH)))					  177Q)				  \DSP)			 (COND			   ((FIXP TTCLOCK)                   (* Slows down transmission rate for debugging)			     (DISMISS TTCLOCK])(TTBOUTN  [NLAMBDA $NCHARS                                     (* bvm: " 4-Mar-80 01:35")    (FRPTQ (EVAL (CAR $NCHARS))	   (APPLY (QUOTE TTBOUT)		  (CDR $NCHARS])(PR!  [LAMBDA NIL                                          (* bvm: "17-Aug-78 01:23")    (for X in BUFFIELDS do (SPACES 2)			   (PRIN1 (SETQ X (CAR X)))			   (PRIN1 ": ")			   (COND			     ((NLISTP (SETQ X (APPLY* (QUOTE !)						      X)))			       (PRINT X))			     ((SMALLP (CAR X))			       (PRBUF X))			     ((LISTP (CAR X))			       (PRLINE X))			     (T (PRINT X)))       when (IGREATERP (CADR X)		       2])(PRALL  [LAMBDA NIL    (DECLARE (USEDFREE \FIRSTLINE))                          (* bvm: "19-MAR-81 12:45")    (for (LINE _ \FIRSTLINE) by (fetch NEXTLINE of LINE) while LINE do (PRLINE LINE)								       (TERPRI])(PRBUF  [LAMBDA (BUF END N)                                  (* bvm: "11-MAR-81 22:06")    [OR N (SETQ N (COND	    (END 122Q)	    (T 17Q]    (PRIN1 (QUOTE {))    (for I from 1 to N while (AND BUF (NEQ BUF END)) bind X do [COND								 ((NOT (SMALLP (CAR BUF)))								   (RETURN (PRINT (QUOTE garbage]							       [COND								 ((PREFIXCHAR (CAR BUF))								   (PRIN1 (QUOTE ')))								 ((PADCHAR (CAR BUF))								   (PRIN1 (QUOTE %"]							       [COND								 ((ILESSP (SETQ X									    (REALBITS (CAR BUF)))									  40Q)								   (PRIN1 (QUOTE ^))								   (SETQ X (LOGOR X 100Q]							       (PRIN1 (FCHARACTER X))							       (SETQ BUF (CDR BUF))       finally [COND		 ((AND BUF (NEQ BUF END))		   (PRIN1 (QUOTE --]	       (PRIN1 (QUOTE }))	       (TERPRI])(PRLINE  [LAMBDA (LINE)                                             (* bvm: "25-AUG-81 17:29")    (PROG ((POS (POSITION T)))          (COND	    ((NOT LINE)	      (SETQ LINE \ARROW)	      (PRIN1 "(defaulting)")))          (TAB POS T)          [PRIN1 (COND		   ((EQ LINE (EVALV (QUOTE \ARROW)))		     (QUOTE _))		   (T (QUOTE % ]          (PRIN1 "Start: ")          (PRBUF (fetch START of LINE)		 (fetch END of LINE))          (TAB POS T)          (PRIN1 " End: ")          (PRBUF (fetch END of LINE))          (TAB POS T)          (PRIN1 " First, last: ")          (PRIN2 (fetch FIRSTCOL of LINE))          (PRIN1 ", ")          (PRINT (fetch LASTCOL of LINE))          (TAB POS T)          (PRIN1 " Row: ")          (PRINT (fetch ROW of LINE))          (COND	    ((NEQ (fetch END of LINE)		  (OR (LISTP (EVALV (QUOTE \ENDBUFFER)))		      (fetch OLDTAIL of TTYINBUFFER)))	      (TAB POS T)	      (PRIN1 " Nextline: ")	      (PRBUF (fetch START of (fetch NEXTLINE of LINE))		     NIL 10Q]))(* Auxiliary fns. These are outside the TTYIN block, and are provided to aid the outside world in special interfaces to TTYIN)(DEFINEQ(SETREADFN  [LAMBDA (FLG)                                              (* bvm: "10-MAR-83 21:46")    (/SETATOMVAL (QUOTE LISPXREADFN)		 (COND		   ((AND (NEQ FLG (QUOTE READ))			 (OR FLG TTYINBSFLG (DISPLAYTERMP))			 (FGETD (QUOTE TTYINREAD))			 (DISPLAYSTARTEDP))		     (QUOTE TTYINREAD))		   (T (QUOTE READ])(TTYINREADP  [LAMBDA (FLG)                                              (* bvm: "12-JUL-82 12:34")          (* * Intended to replace LISPXREADP. Does the right thing when READBUF has just a <cr> in it)    (COND      (READBUF (OR (NEQ (CAR READBUF)			HISTSTR0)		   FLG))      ((NOT (EOFP \LINEBUF.OFD))	(OR FLG (NEQ (\PEEKBIN \LINEBUF.OFD)		     (CHARCODE EOL])(TTYINREAD  [LAMBDA (FILE RDTBL)                                       (* bvm: "12-JUL-82 12:35")    (COND      (\INSIDE.TTYIN (READ FILE RDTBL))      (T (PROG (X)	       (RETURN (COND			 ((OR [do (COND				    ((EOFP \LINEBUF.OFD)     (* Nothing in buffer)				      (RETURN))				    ((NEQ (\PEEKBIN \LINEBUF.OFD)					  (CHARCODE EOL))    (* significant stuff)				      (RETURN T))				    (T (\BIN \LINEBUF.OFD]			      (EQ (SETQ X (TTYIN LISPXID NIL NIL (QUOTE (EVALQT FILLBUFFER NOPROMPT))						 NIL NIL NIL RDTBL))				  T))			   (READ \LINEBUF.OFD RDTBL))			 (T                                  (* indicate null input)			    (SETQ READBUF (NCONC1 (CDR X)						  HISTSTR0))			    (CAR X])(TTYINFIX  [LAMBDA (INPUT COMS)                                       (* bvm: "16-NOV-82 12:01")    (COND      ([AND (EQ LISPXREADFN (QUOTE TTYINREAD))	    (NOT COMS)	    (ILESSP (COUNT INPUT)		    TTYINFIXLIMIT)	    (NOT (CDR (MEMB HISTSTR0 INPUT]	(TTYIN LISPXID NIL NIL (QUOTE EVALQT)	       NIL NIL INPUT T))      (T (NONTTYINLISPXFIX INPUT COMS])(CHARMACRO?  [NLAMBDA (MACRO)    (DECLARE (USEDFREE \READING LISPXID))              (* bvm: "19-MAR-81 12:15")          (* * For use in a TTYINREADMACRO. If we are reading inside the editor, clear the output buffer and return MACRO)    (COND      ((AND (EQ \READING (QUOTE EVALQT))	    (EQ LISPXID (QUOTE *)))	(COND	  ((LISTP MACRO)                               (* a list of edit commands; we'd better copy)	    (APPEND MACRO))	  (T MACRO])(TTYINMETA  [LAMBDA (FLG)                                              (* bvm: "19-MAY-82 15:21")    (PROG1 \TTYIN.METASTATE (COND	     ((AND FLG (DEFINEDP (QUOTE PEEKKEYS)))          (* Non-wind, can't do)	       (\ILLEGAL.ARG FLG)))	   (METASHIFT FLG)	   [COND	     [FLG (SETQ \TTYIN.RESTOREBUFCODE 200Q)		  [KEYACTION (QUOTE BLANK-MIDDLE)			     (QUOTE ((200Q 200Q]		  (SETQ EDITPREFIXCHAR 0)		  (KEYACTION (QUOTE BLANK-TOP)			     (QUOTE ((0 0]	     (T (SETQ \TTYIN.RESTOREBUFCODE 302Q)		[KEYACTION (QUOTE BLANK-MIDDLE)			   (QUOTE ((302Q 302Q]		(SETQ EDITPREFIXCHAR 301Q)		(KEYACTION (QUOTE BLANK-TOP)			   (QUOTE ((301Q 301Q]	   (SETQ \TTYIN.METASTATE FLG])(\SET.TTYINBOLDFONT  [LAMBDA (PLAINFONT)                                        (* bvm: "17-AUG-83 12:31")    (SETQ TTYINBOLDFONT (CONS PLAINFONT (OR [CAR (NLSETQ (COND							   ((EQ (FONTPROP PLAINFONT (QUOTE WEIGHT))								(QUOTE BOLD))							     (FONTCOPY PLAINFONT (QUOTE WEIGHT)								       (QUOTE NORMAL)))							   (T (FONTCOPY PLAINFONT (QUOTE WEIGHT)									(QUOTE BOLD]					    PLAINFONT])(TTYIN.LASTINPUT  [LAMBDA NIL                                                (* bvm: " 9-NOV-82 14:56")    (PROG [(BUF (AND (LISTP TTYINBUFFER)		     (fetch OLDTAIL of TTYINBUFFER]          (RETURN (AND BUF (TTYINSTRING (fetch START of (fetch FIRSTLINE of TTYINBUFFER))					BUF]))(DEFINEQ(TTED  [NLAMBDA (FN C)    (DECLARE (USEDFREE COM))                                 (* bvm: "30-MAR-82 14:32")          (* Does the ED macro, returning a com to execute if there is any change to be made. Can also be used for other 	  types of editor escapes if FN is supplied. FN{exprlist,com} is called to edit a list of expressions.	  C is com)    (PROG ((EXPR (##))	   (TOP (## ^))	   UP NEW N)          (SETQ COM (OR C (QUOTE ED)))          [COND	    ((NEQ TOP EXPR)                                  (* would generate error if at top)	      (SETQ UP (## UP]                               (* in case of error, will print ED ?, instead of some 							     long edit macro body)          [COND	    ((NEQ UP EXPR)                                   (* If current expression is not a tail, pretend it is a 							     list of one expression)	      (SETQ EXPR (LIST (COND				 ((AND (EQ (CAR (LISTP EXPR))					   COMMENTFLG)				       (LISTP (CADR EXPR))				       (FIXP (CADDR EXPR)))                                                             (* EXPR is a comment pointer, so get the real comment to							     edit)				   (GETCOMMENT EXPR))				 (T EXPR]          (RETURN (COND		    ([NOT (SETQ NEW (COND			      (FN (APPLY* FN EXPR C))			      (T (TTYIN "** " NIL NIL (QUOTE LISPXREAD)					NIL NIL EXPR]        (* Replace with nothing?)		      (ERROR!))		    ((EQUAL NEW EXPR)		      (PRIN1 "(not changed)" T)		      NIL)		    [(OR (EQ EXPR UP)			 (AND (EQ (CAR EXPR)				  TOP)			      (PROGN [COND				       ((CDR NEW)            (* Replacing the top-level expression with more than one							     expression. That is really an error, but this way we at 							     least avoid losing data)					 (PRIN1 					"(Note: replaced one expression with a list of several)"						T))				       (T (SETQ NEW (CAR NEW]				     T)))                    (* Current expression is the top or a tail;							     can't use simple : command.)		      (CONS (QUOTE REPLACE)			    (CONS (QUOTE (1 TO))				  (CONS (QUOTE WITH)					NEW]		    ([AND (LISTP (CAR NEW))			  (NOT (CDR NEW))			  (SETQ N (MEMB (CAR EXPR)					(SETQ UP (## 0]          (* replacing an element with a list: if we did a : command, the editor would then be positioned at a tail, and 	  even if we did a (1 --) there would still be a tail in the edit chain. Better way to do this is thus to go up a 	  level and do the appropriate (n --) command and come back down. I wish the editor had a command to do this.)		      (LIST (QUOTE COMSQ)			    0			    (CONS [SETQ N (for $$VAL_1 while (NEQ N UP) do (ADD1VAR $$VAL)									   (SETQ UP (CDR UP]				  NEW)			    N))		    (T           (* Simple replacement of one element. Could be fancier and leave the current expression being the one just typed, 	  but that seems like a lot of bother)		       (COND			 ((AND (CDR NEW)			       (NOT (CDR EXPR)))             (* Warn that one expression became several)			   (PRIN1 "(new expressions spliced into parent)" T)))		       (CONS (QUOTE :)			     NEW])(DO.EE  [LAMBDA (EXPRS COM W)                                      (* bvm: " 2-APR-82 14:31")    (TTYINEDIT EXPRS W])(TTYINEDIT  [LAMBDA (EXPRS WINDOW PRINTFN)                             (* bvm: "16-NOV-82 12:44")    (OR PRINTFN (SETQ PRINTFN TTYINPRINTFN))    (RESETLST (SET.TTYINEDIT.WINDOW WINDOW)	      (RESETSAVE (CURSOR DEFAULTCURSOR))             (* Make sure we have something to point with)	      (PROG1 (TTYIN TTYINEDITPROMPT NIL NIL (QUOTE LISPXREAD)			    NIL NIL [COND			      ([OR (EQ PRINTFN T)				   (AND (NULL PRINTFN)					(NULL (CDR EXPRS))					(STRINGP (CAR EXPRS]                                                             (* Don't prettyprint it)				EXPRS)			      (T (LIST HISTSTR1 (TTYIN.PPTOFILE EXPRS PRINTFN]			    EDITRDTBL)		     (COND		       ((AND TTYINAUTOCLOSEFLG WINDOW)			 (CLOSEW WINDOW])(SIMPLETEXTEDIT  [LAMBDA (FILE WINDOW)                                      (* bvm: "18-JUN-82 14:29")    (RESETLST (PROG ([INPUTFILE (AND FILE (OPENFILE FILE (QUOTE INPUT]		     SCRATCHOUT MAINOUTPUT)		    (AND INPUTFILE (RESETSAVE NIL (LIST (QUOTE CLOSEF)							INPUTFILE)))		    (SETQ SCRATCHOUT (TTYIN.SCRATCHFILE))		    (SET.TTYINEDIT.WINDOW WINDOW)		    (RETURN (COND			      ([TTYIN TTYINEDITPROMPT NIL NIL (QUOTE (TEXT NOVALUE))				      SCRATCHOUT NIL (AND INPUTFILE							  (LIST HISTSTR1 (CONS INPUTFILE									       (CONS 0 (GETEOFPTR										       INPUTFILE]				[repeatuntil (PROGN [SETQ MAINOUTPUT						      (COND							(INPUTFILE (PROG1 (PACKFILENAME (QUOTE 											  VERSION)											NIL											(QUOTE BODY)											INPUTFILE)									  (SETQ INPUTFILE)))							(T (CAR (TTYIN "Output file: " NIL 								 "Name of file for edited output"								       (QUOTE (NORAISE READ]						    (NLSETQ (SETQ MAINOUTPUT (OPENFILE MAINOUTPUT										       (QUOTE OUTPUT]				(COPYBYTES SCRATCHOUT MAINOUTPUT 0 (GETFILEPTR SCRATCHOUT))				(CLOSEF MAINOUTPUT])(SET.TTYINEDIT.WINDOW  [LAMBDA (WINDOW)                                           (* bvm: " 2-JUN-82 16:11")          (* Changes output to WINDOW, or the TTYIN edit window, returning the resulting WINDOW, or NIL if there is no 	  window change. Caller must have RESETLST)    (COND      ((EQ WINDOW T)                                         (* Use current window)	NIL)      (T (SELECTQ (SYSTEMTYPE)		  ((ALTO D)		    [OR WINDOW (SETQ WINDOW (OR TTYINEDITWINDOW (SETQ TTYINEDITWINDOW						  (CREATEW NIL "Edit Work Area"]		    (CLEARW WINDOW)		    [PROG [(OFFSET (IREMAINDER (WINDOWPROP WINDOW (QUOTE HEIGHT))					       (IMINUS (DSPLINEFEED NIL WINDOW]		          (COND			    ((NEQ OFFSET 0)          (* Window is not an integral number of lines, so start down a little, so that bottom line will be correctly 	  aligned (we count from bottom of screen))			      (RELMOVETO 0 (IMINUS OFFSET)					 WINDOW]		    (RESETSAVE (TTYDISPLAYSTREAM WINDOW))		    WINDOW)		  NIL])(TTYIN.PPTOFILE  [LAMBDA (EXPRS PRINTFN)                                    (* bvm: "16-SEP-82 14:42")    (DECLARE (GLOBALVARS TTYINEDIT.SCRATCH))          (* * Prettyprint each of EXPRS to a scratch file, returning (scratchfile start . end), as TTYIN would like)    (TTYIN.SCRATCHFILE)    [RESETLST (RESETSAVE (OUTPUT TTYINEDIT.SCRATCH))	      (PROG [(LL (IDIFFERENCE (LINELENGTH NIL T)				      (ADD1 (NCHARS TTYINEDITPROMPT]		    (LINELENGTH LL TTYINEDIT.SCRATCH)        (* Try to make comments print in middle when linelength 							     short)		    (RESETSAVE PRETTYLCOM (IQUOTIENT LL 5)))	      (RESETSAVE FONTCHANGEFLG NIL)	      (COND		((AND PRINTFN (NEQ PRINTFN (QUOTE PRETTY)))		  (APPLY* (COND			    ((EQ PRINTFN T)			      (QUOTE PRINT))			    (T PRINTFN))			  EXPRS			  (OUTPUT)))		(T (AND CHANGESARRAY (RESETSAVE CHANGESARRAY))		   [COND		     ((NEQ NORMALCOMMENTSFLG T)              (* If there are comments, force them to be prettyprinted							     afresh at the new linelength;							     ordinarily this won't happen with file output)		       (RESETSAVE PRETTYPRINTMACROS (CONS (QUOTE (* . GETCOMMENT))							  PRETTYPRINTMACROS]		   (PRINTDEF EXPRS NIL T T]    (CONS TTYINEDIT.SCRATCH (CONS 0 (GETFILEPTR TTYINEDIT.SCRATCH])(TTYIN.SCRATCHFILE  [LAMBDA NIL    (DECLARE (GLOBALVARS TTYINEDIT.SCRATCH))                 (* bvm: "30-MAR-82 16:01")    [COND      ([OR (NOT TTYINEDIT.SCRATCH)	   (NOT (OPENP TTYINEDIT.SCRATCH (QUOTE BOTH]	(SETQ TTYINEDIT.SCRATCH (OPENFILE (SELECTQ (SYSTEMTYPE)						   ((D ALTO)						     (QUOTE {CORE}TTYINEDIT.SCRATCH))						   (QUOTE TTYINEDIT.SCRATCH;S))					  (QUOTE BOTH)					  (QUOTE OLD/NEW)))	(WHENCLOSE TTYINEDIT.SCRATCH (QUOTE CLOSEALL)		   (QUOTE NO)		   (QUOTE BEFORE)		   (FUNCTION [LAMBDA (F)		       (SETQ TTYINEDIT.SCRATCH NIL])		   (QUOTE AFTER)		   (QUOTE DELFILE))	(SETQ TTYINEDIT.SCRATCH (\GETOFD TTYINEDIT.SCRATCH]    (SETFILEPTR TTYINEDIT.SCRATCH 0)    TTYINEDIT.SCRATCH]))(ADDTOVAR USERMACROS (EE (DUMMY)			 (COMS (TTED DO.EE EE)))		     (EE NIL (COMS (TTED DO.EE EE)))		     (ED NIL (COMS (TTED)))		     (BUF NIL (E [LISPXUNREAD (TTYIN (QUOTE *)						     NIL NIL (QUOTE LISPXREAD)						     NIL NIL (LIST (QUOTE E)								   (##]				 T)))(ADDTOVAR EDITCOMSA EE ED BUF)(ADDTOVAR EDITCOMSL EE)(ADDTOVAR LISPXHISTORYMACROS [BUF NIL (TTYIN LISPXID NIL NIL (QUOTE EVALQT)					     NIL NIL (LIST (COND (LISPXLINE (VALUOF LISPXLINE))								 (T (CADDR (CAAR LISPXHISTORY])(ADDTOVAR LISPXMACROS (TV (APPLY* (QUOTE EDITV)				  (CAR LISPXLINE)				  (QUOTE ED))))(RPAQ? TTYINEDITWINDOW )(RPAQ? TTYINEDIT.SCRATCH )(RPAQ? TTYINEDITPROMPT T)(RPAQ? TTYINAUTOCLOSEFLG )(RPAQ? TTYINPRINTFN )(RPAQ? TTYIN?=FN )(ADDTOVAR AFTERSYSOUTFORMS (SETQ TTYINEDIT.SCRATCH NIL))(DECLARE: DOEVAL@COMPILE DONTCOPY (RPAQQ TTCOMPILETIME ((VARS TTYINBLOCKS)	(BLOCKS (NIL (LOCALVARS . T)		     (SPECVARS CTRLO! HELP SPLST \ARROW \AUTOFILL \BMARG \BUFFER \CHARHEIGHT 			       \CHARWIDTH \COMMAND \CURSOR \CURSORCOL \CURSORROW \DELETING \DESCENT 			       \DSP \EDITBIT \ENDBUFFER \FIRSTLINE \FIX \HOMECOL \HOMEROW \INITPOS 			       \INSERTING \LASTAIL \LASTCHAR \LMARG \LOC.ROW.0 \NOFIXSPELL \PROMPT1 			       \PROMPT2 \READING \REPEAT \RMARG \SPLSTFLG \INSIDE.TTYIN \TTYINSTATE 			       \TTPAGELENGTH \RAISEINPUT \FIRSTTIME \DONTCOMPLETE \NOVALUE 			       \STRINGVALUE \LISPXREADING \FILLINGBUFFER \RDTBLSA DIRECTORY/FILE 			       \LAST.DELETION \NOPROMPT \FONT \VARIABLEFONT \TEXTURE \LASTAILROW 			       \LASTAILCOL)		     TTYIN TTYIN1 TTYIN1RESTART TTYIN.FINISH TTYIN.READ TTYIN.BALANCE ADDCHAR 		     ADDCHARS.INSERTING TTBIN TTBITWIDTH TTCRLF TTCRLF.ACCOUNT TTDELETECHAR 		     TTDELETEWORD TTLASTLINE TTNEXTCHAR TTNEXTLINE TTNEXTNODE TTNLEFT TTNTH TTNTHLINE 		     TTPRIN1 TTPRIN2 TTPROMPTCHAR TTRUBOUT ADJUSTLINE ADJUSTLINE.AND.RESTORE 		     AT.END.OF.SCREEN AT.END.OF.TEXT AUTOCR? BACKSKREAD BACKWARD.DELETE.TO BREAKLINE 		     BUFCHARCOUNT BUFTAILP CLEAR.LINE? CURRENT.WORD DELETE.TO.END DELETETO 		     DO.EDIT.COMMAND ENDREAD? FIND.LINE FIND.LINE.BREAK FIND.MATCHING.QUOTE 		     FIND.NON.SPACE GO.TO.ADDRESSING GO.TO.FREELINE GO.TO.RELATIVE INIT.CURSOR 		     INSERT.CHAR.IN.BUF INSERT.NODE INSERTLINE KILLSEGMENT MOVE.TO.WHEREVER 		     NTH.COLUMN.OF NTH.RELATIVE.COLUMN.OF OVERFLOW? OVERFLOWLINE? PREVLINE PREVWORD 		     PROPERTAILP RESTORE.CURSOR SAVE.CURSOR SCANBACK SCANFORWARD SCRATCHCONS 		     SEGMENT.LENGTH SEGMENT.BIT.LENGTH SETLASTC SETTAIL? SHOW.MATCHING.PAREN 		     START.NEW.LINE TTSKIPSEPR TTSKREAD TTWAITFORINPUT TTYINSTRING TYPE.BUFFER BEEP 		     BITBLT.DELETE BITBLT.ERASE BITBLT.INSERT DO.CRLF DO.DELETE.LINES DO.INSERT.LINE 		     DO.LF DO.UP ERASE.SCREEN ERASE.TO.END.OF.LINE ERASE.TO.END.OF.PAGE INSERT.TEXT 		     INSERTNCHARS TTDELSECTION TTADJUSTWIDTH TTINSERTSECTION TTSETCURSOR DO.MOUSE 		     DO.SHIFTED.SELECTION COPY.SEGMENT DELETE.LONG.SEGMENT DELETE.LONG.SEGMENT1 		     INVERT.LONG.SEGMENT INVERT.SEGMENT BRACKET.CURRENT.WORD TTBEFOREPOS TTNEXTPOS 		     TTRACKMOUSE TTYINBUTTONFN SETREADFN TTYINREADP TTYINREAD TTYINFIX CHARMACRO? 		     TTYINMETA \SET.TTYINBOLDFONT TTYIN.LASTINPUT TTED DO.EE TTYINEDIT SIMPLETEXTEDIT 		     SET.TTYINEDIT.WINDOW TTYIN.PPTOFILE TTYIN.SCRATCHFILE ADDNAKEDCHAR ADDTAB 		     CHECK.MARGIN CREATE.LINE DELETELINE DO.EDIT.PP DO?CMD TTYIN.PRINTARGS 		     TTYIN.READ?=ARGS DOTABS EDITCOLUMN EDITNUMBERP END.DELETE.MODE 		     FIND.MATCHING.WORD WORD.MATCHES.BUFFER FIND.NEXT.WORD FIND.START.OF.WORD 		     FORWARD.DELETE.TO KILL.LINES L-CASECODE MOVE.BACK.TO MOVE.FORWARD.TO 		     MOVE.TO.LINE MOVE.TO.NEXT.LINE MOVE.TO.START.OF.WORD READFROMBUF RENUMBER.LINES 		     RESTOREBUF RETYPE.BUFFER SKIP/ZAP START.OF.PARAGRAPH? TTADJUSTWORD 		     TTCOMPLETEWORD TTDELETELINE TTECHO.TO.FILE TTGIVEHELP TTGIVEHELP1 TTGIVEHELP2 		     TTLOADBUF TTRATOM TTREAD TTREADLIST TTUNREADBUF U-CASECODE U/L-CASE))	(GLOBALVARS ?ACTIVATEFLG AFTERPROMPTCHARFORMS BLACKSHADE BUFFIELDS CAR/CDRNIL CHANGESARRAY 		    CHCONLST1 COMMENTFLG CTRLUFLG CTRLVFLG DISPLAYTYPES DMCHARCODES EDITCOMSL 		    EDITPREFIXCHAR EDITRDTBL EMACSFLG EOLCHARCODE FONTCHANGEFLG HISTSTR0 HISTSTR1 		    LASTKEYBOARD LASTMOUSEBUTTONS LASTWORD LISPXREADFN PROMPTCHARFORMS SHOWPARENFLG 		    SPELLSTR1 SPELLSTR2 TTCLOCK TTYINAUTOCLOSEFLG TTYINBOLDFONT TTYINBSFLG 		    TTYINBUFFER TTYINCOMPLETEFLG TTYINEDIT.SCRATCH TTYINEDITPROMPT TTYINEDITWINDOW 		    TTYINERRORSETFLG TTYINRAISEFLG TTYINREADMACROS TTYINRESPONSES TTYINUSERFN 		    TTYJUSTLENGTH TYPEAHEADFLG USERWORDS WHITESHADE \FIXP \MISCSTATS \TTWAITBOX 		    \TTYIN.EDITPREFIXCODE \TTYIN.METASTATE \TTYIN.RESTOREBUFCODE null 		    TTYINAUTOFILLMARGIN TTYINPRINTFN TTYIN?=FN TTYINFIXLIMIT)	(MACROS * TTYINMACROS)	(RECORDS LINE TTYINBUFFER MOUSEPOS)	(VARS (TTCLOCK)	      (CHANGESARRAY)	      DMCHARCODES TTSUPPORTFNS)	(ADDVARS (DONTCOMPILEFNS &DISPLAYCOMMENT DELETETO1 DELNCHARS DO.BACK DO.DOWN DO.FORWARD 				 ADDSILENTCHAR INSERTSPACES))	(CONSTANTS (DISPLAYTERMFLG T)		   (MOUSECODE 501Q)		   (DIDESCAPECODE 433Q)		   (PREFIXCODE 200Q)		   (PADCODE 400Q)		   (PSEUDOCRCODE 1040Q)		   (CHECKNIL?)		   BREAKCODES SEPRCODES (TTYINMAILFLG)		   \CTRLKEY \SHIFTKEYS DOTSHADE)	(VARS TTNILFNS)	(P (FOR FN IN TTNILFNS DO (MOVD (QUOTE NILL)					FN)))	(MACROS * TTNILFNS)	(DECLARE: DONTEVAL@COMPILE		  (TEMPLATES AT.END.OF.BUF AT.END.OF.LINE AT.START.OF.BUF AT.START.OF.LINE 			     EMPTY.BUFFER EMPTY.LINE INSERTING ON.FIRST.LINE ON.LAST.LINE PADCHAR 			     PADCHARCODE PREFIXCHAR PREFIXCHARCODE REALBITS SPACEP TTBOUT TTBOUTN 			     MOUSESTATE LASTMOUSESTATE CAPABILITY?)		  (P (RADIX 10Q))		  (LISPXMACROS _ _B)		  DONTEVAL@LOAD EVAL@COMPILE (VARS (DONTCOMPILEFNS (UNION (UNION TTYINMACROS 										 TTSUPPORTFNS)									  DONTCOMPILEFNS)))		  (FILES (LOADCOMP)			 ATERM))))(RPAQQ TTYINBLOCKS ((TTYIN TTYIN TTBIN TTCRLF TTCRLF.ACCOUNT SCANFORWARD TTNLEFT TTNTH TTPRIN1 			   TTPROMPTCHAR TTRATOM TTREAD TTREADLIST TTSKIPSEPR TTSKREAD TTYINSTRING 			   ADDCHAR ADDNAKEDCHAR AUTOCR? BACKWARD.DELETE.TO BEEP BUFTAILP CLEAR.LINE? 			   CREATE.LINE DELETE.TO.END DELETETO DELETETO1 DELNCHARS TTECHO.TO.FILE 			   END.DELETE.MODE ENDREAD? AT.END.OF.TEXT FIND.START.OF.WORD TTADJUSTWORD 			   FORWARD.DELETE.TO GO.TO.RELATIVE GO.TO.ADDRESSING GO.TO.FREELINE 			   INIT.CURSOR INSERT.CHAR.IN.BUF ADDCHARS.INSERTING INSERT.NODE TTRUBOUT 			   KILL.LINES KILLSEGMENT MOVE.BACK.TO MOVE.FORWARD.TO MOVE.TO.NEXT.LINE 			   START.NEW.LINE TTNEXTCHAR TTNEXTNODE OVERFLOW? PROPERTAILP RESTORE.CURSOR 			   SAVE.CURSOR SCRATCHCONS SETLASTC SETTAIL? SPACE/PARENP DO.EDIT.COMMAND 			   ADDSILENTCHAR ADDTAB AT.END.OF.SCREEN SCANBACK BACKSKREAD BREAKLINE 			   SEGMENT.LENGTH CHECK.MARGIN TTCOMPLETEWORD FIND.MATCHING.WORD NTHCHARCODE 			   DELETELINE DO?CMD DOTABS EDITCOLUMN FIND.LINE FIND.LINE.BREAK ADJUSTLINE 			   START.OF.PARAGRAPH? ADJUSTLINE.AND.RESTORE TTGIVEHELP TTGIVEHELP1 			   TTGIVEHELP2 INSERTLINE TTLASTLINE TTLOADBUF MOVE.TO.LINE 			   MOVE.TO.START.OF.WORD MOVE.TO.WHEREVER TTNEXTLINE FIND.MATCHING.QUOTE 			   FIND.NEXT.WORD NTH.COLUMN.OF NTH.RELATIVE.COLUMN.OF OVERFLOWLINE? PREVLINE 			   PREVWORD READFROMBUF RENUMBER.LINES RESTOREBUF RETYPE.BUFFER 			   SHOW.MATCHING.PAREN SKIP/ZAP SLEEP CURRENT.WORD TYPE.BUFFER U/L-CASE 			   TTUNREADBUF DO.BACK DO.DELETE.LINES DO.DOWN DO.FORWARD DO.INSERT.LINE 			   DO.UP ERASE.SCREEN ERASE.TO.END.OF.LINE ERASE.TO.END.OF.PAGE INSERT.TEXT 			   INSERTNCHARS TTSETCURSOR			   (LOCALFREEVARS ARROW AUTOFILL BUFFER COMMAND CURSOR DELETING EDITBIT 					  ENDBUFFER INITPOS INSERTING NOFIXSPELL READING REPEAT)			   (SPECVARS CTRLO!)			   (LINKFNS . T)			   (NOLINKFNS DISPLAYHELP DISPLAYTERMP EDITE ERROR! FIXSPELL!! GRIPE 				      GUESTUSER? MAILWATCH MWNOTE SETBACKSPACE SHOULDNT SMARTARGLIST 				      SPRINTT STKEVAL STRPOS USEREXEC XHELPSYS)			   (BLKLIBRARY NLEFT))	(NIL TTYINREAD (LOCALVARS . T)	     (LINKFNS TTYIN))	(NIL DISPLAYTERMP SETREADFN TTECHOMODE TTED TTYINPEEKC TTYINREADP TTYINREADPREP CHARMACRO?	     (LOCALVARS . T))))[DECLARE: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY(BLOCK: NIL (LOCALVARS . T)	(SPECVARS CTRLO! HELP SPLST \ARROW \AUTOFILL \BMARG \BUFFER \CHARHEIGHT \CHARWIDTH \COMMAND 		  \CURSOR \CURSORCOL \CURSORROW \DELETING \DESCENT \DSP \EDITBIT \ENDBUFFER 		  \FIRSTLINE \FIX \HOMECOL \HOMEROW \INITPOS \INSERTING \LASTAIL \LASTCHAR \LMARG 		  \LOC.ROW.0 \NOFIXSPELL \PROMPT1 \PROMPT2 \READING \REPEAT \RMARG \SPLSTFLG 		  \INSIDE.TTYIN \TTYINSTATE \TTPAGELENGTH \RAISEINPUT \FIRSTTIME \DONTCOMPLETE 		  \NOVALUE \STRINGVALUE \LISPXREADING \FILLINGBUFFER \RDTBLSA DIRECTORY/FILE 		  \LAST.DELETION \NOPROMPT \FONT \VARIABLEFONT \TEXTURE \LASTAILROW \LASTAILCOL)	TTYIN TTYIN1 TTYIN1RESTART TTYIN.FINISH TTYIN.READ TTYIN.BALANCE ADDCHAR ADDCHARS.INSERTING 	TTBIN TTBITWIDTH TTCRLF TTCRLF.ACCOUNT TTDELETECHAR TTDELETEWORD TTLASTLINE TTNEXTCHAR 	TTNEXTLINE TTNEXTNODE TTNLEFT TTNTH TTNTHLINE TTPRIN1 TTPRIN2 TTPROMPTCHAR TTRUBOUT 	ADJUSTLINE ADJUSTLINE.AND.RESTORE AT.END.OF.SCREEN AT.END.OF.TEXT AUTOCR? BACKSKREAD 	BACKWARD.DELETE.TO BREAKLINE BUFCHARCOUNT BUFTAILP CLEAR.LINE? CURRENT.WORD DELETE.TO.END 	DELETETO DO.EDIT.COMMAND ENDREAD? FIND.LINE FIND.LINE.BREAK FIND.MATCHING.QUOTE 	FIND.NON.SPACE GO.TO.ADDRESSING GO.TO.FREELINE GO.TO.RELATIVE INIT.CURSOR INSERT.CHAR.IN.BUF 	INSERT.NODE INSERTLINE KILLSEGMENT MOVE.TO.WHEREVER NTH.COLUMN.OF NTH.RELATIVE.COLUMN.OF 	OVERFLOW? OVERFLOWLINE? PREVLINE PREVWORD PROPERTAILP RESTORE.CURSOR SAVE.CURSOR SCANBACK 	SCANFORWARD SCRATCHCONS SEGMENT.LENGTH SEGMENT.BIT.LENGTH SETLASTC SETTAIL? 	SHOW.MATCHING.PAREN START.NEW.LINE TTSKIPSEPR TTSKREAD TTWAITFORINPUT TTYINSTRING TYPE.BUFFER 	BEEP BITBLT.DELETE BITBLT.ERASE BITBLT.INSERT DO.CRLF DO.DELETE.LINES DO.INSERT.LINE DO.LF 	DO.UP ERASE.SCREEN ERASE.TO.END.OF.LINE ERASE.TO.END.OF.PAGE INSERT.TEXT INSERTNCHARS 	TTDELSECTION TTADJUSTWIDTH TTINSERTSECTION TTSETCURSOR DO.MOUSE DO.SHIFTED.SELECTION 	COPY.SEGMENT DELETE.LONG.SEGMENT DELETE.LONG.SEGMENT1 INVERT.LONG.SEGMENT INVERT.SEGMENT 	BRACKET.CURRENT.WORD TTBEFOREPOS TTNEXTPOS TTRACKMOUSE TTYINBUTTONFN SETREADFN TTYINREADP 	TTYINREAD TTYINFIX CHARMACRO? TTYINMETA \SET.TTYINBOLDFONT TTYIN.LASTINPUT TTED DO.EE 	TTYINEDIT SIMPLETEXTEDIT SET.TTYINEDIT.WINDOW TTYIN.PPTOFILE TTYIN.SCRATCHFILE ADDNAKEDCHAR 	ADDTAB CHECK.MARGIN CREATE.LINE DELETELINE DO.EDIT.PP DO?CMD TTYIN.PRINTARGS TTYIN.READ?=ARGS 	DOTABS EDITCOLUMN EDITNUMBERP END.DELETE.MODE FIND.MATCHING.WORD WORD.MATCHES.BUFFER 	FIND.NEXT.WORD FIND.START.OF.WORD FORWARD.DELETE.TO KILL.LINES L-CASECODE MOVE.BACK.TO 	MOVE.FORWARD.TO MOVE.TO.LINE MOVE.TO.NEXT.LINE MOVE.TO.START.OF.WORD READFROMBUF 	RENUMBER.LINES RESTOREBUF RETYPE.BUFFER SKIP/ZAP START.OF.PARAGRAPH? TTADJUSTWORD 	TTCOMPLETEWORD TTDELETELINE TTECHO.TO.FILE TTGIVEHELP TTGIVEHELP1 TTGIVEHELP2 TTLOADBUF 	TTRATOM TTREAD TTREADLIST TTUNREADBUF U-CASECODE U/L-CASE)](DECLARE: DOEVAL@COMPILE DONTCOPY(ADDTOVAR GLOBALVARS ?ACTIVATEFLG AFTERPROMPTCHARFORMS BLACKSHADE BUFFIELDS CAR/CDRNIL CHANGESARRAY 	  CHCONLST1 COMMENTFLG CTRLUFLG CTRLVFLG DISPLAYTYPES DMCHARCODES EDITCOMSL EDITPREFIXCHAR 	  EDITRDTBL EMACSFLG EOLCHARCODE FONTCHANGEFLG HISTSTR0 HISTSTR1 LASTKEYBOARD 	  LASTMOUSEBUTTONS LASTWORD LISPXREADFN PROMPTCHARFORMS SHOWPARENFLG SPELLSTR1 SPELLSTR2 	  TTCLOCK TTYINAUTOCLOSEFLG TTYINBOLDFONT TTYINBSFLG TTYINBUFFER TTYINCOMPLETEFLG 	  TTYINEDIT.SCRATCH TTYINEDITPROMPT TTYINEDITWINDOW TTYINERRORSETFLG TTYINRAISEFLG 	  TTYINREADMACROS TTYINRESPONSES TTYINUSERFN TTYJUSTLENGTH TYPEAHEADFLG USERWORDS WHITESHADE 	  \FIXP \MISCSTATS \TTWAITBOX \TTYIN.EDITPREFIXCODE \TTYIN.METASTATE \TTYIN.RESTOREBUFCODE 	  null TTYINAUTOFILLMARGIN TTYINPRINTFN TTYIN?=FN TTYINFIXLIMIT))(RPAQQ TTYINMACROS (TYPEAHEAD? ADD1POS AT.END.OF.BUF AT.END.OF.LINE AT.START.OF.BUF AT.START.OF.LINE 			       BEFOREBUF BREAK.OR.SEPRP CAPABILITY? DISPLAYTERMP EMPTY.BUFFER 			       EMPTY.LINE EQPOS NEQPOS IABS INPART INSERTING ON.FIRST.LINE 			       ON.LAST.LINE PADCHAR PADCHARCODE PREFIXCHAR PREFIXCHARCODE REALBITS 			       SPACEP TTBOUT TTBOUTN WORDSEPRP FCHARWIDTH))(DECLARE: EVAL@COMPILE (PUTPROPS TYPEAHEAD? MACRO (NIL (\SYSBUFP)))(PUTPROPS ADD1POS MACRO ((CHAR)			 (add \CURSORCOL (TTBITWIDTH CHAR))))(PUTPROPS AT.END.OF.BUF MACRO (NIL (EQ \CURSOR \ENDBUFFER)))(PUTPROPS AT.END.OF.LINE MACRO (NIL (EQ (fetch END of \ARROW)					\CURSOR)))(PUTPROPS AT.START.OF.BUF MACRO (NIL (EQ \CURSOR \BUFFER)))(PUTPROPS AT.START.OF.LINE MACRO (NIL (EQ (fetch START of \ARROW)					  \CURSOR)))(PUTPROPS BEFOREBUF MACRO ((THIS THAT END)			   (BUFTAILP THAT THIS END)))(PUTPROPS BREAK.OR.SEPRP MACRO ((C)				(SELECTC (REALBITS C)					 ((APPEND SEPRCODES BREAKCODES)					   T)					 NIL)))(PUTPROPS CAPABILITY? MACRO ((X Y)			     T))(PUTPROPS DISPLAYTERMP ALTOMACRO (NIL T))(PUTPROPS EMPTY.BUFFER MACRO (NIL (EQ \BUFFER \ENDBUFFER)))(PUTPROPS EMPTY.LINE MACRO [X (SUBST (OR (CAR X)					 (QUOTE \ARROW))				     (QUOTE \ARROW)				     (QUOTE (EQ (fetch START of \ARROW)						(fetch END of \ARROW])(PUTPROPS EQPOS MACRO [(X Y)		       (AND (EQ (fetch COLPOS of X)				(fetch COLPOS of Y))			    (EQ (fetch ROWPOS of X)				(fetch ROWPOS of Y])(PUTPROPS NEQPOS MACRO ((X Y)			(NOT (EQPOS X Y))))(PUTPROPS IABS MACRO [OPENLAMBDA (A)				 (COND				   ((IGEQ A 0)				     A)				   (T (IMINUS A])(PUTPROPS INPART MACRO (OPENLAMBDA (X)				   (COND				     ((LISTP X)				       (CAR X))				     (T X))))(PUTPROPS INSERTING MACRO (NIL (OR EMACSFLG \INSERTING)))(PUTPROPS ON.FIRST.LINE MACRO (NIL (EQ \FIRSTLINE \ARROW)))(PUTPROPS ON.LAST.LINE MACRO (NIL (EQ (fetch END of \ARROW)				      \ENDBUFFER)))(PUTPROPS PADCHAR MACRO [(CHAR)			 (NOT (ZEROP (LOGAND CHAR 400Q])(PUTPROPS PADCHARCODE MACRO [(CHAR)			     (CONSTANT (IPLUS PADCODE (CHARCODE CHAR])(PUTPROPS PREFIXCHAR MACRO [(CHAR)			    (NOT (ZEROP (LOGAND CHAR 200Q])(PUTPROPS PREFIXCHARCODE MACRO [(CHAR)				(CONSTANT (IPLUS PREFIXCODE (CHARCODE CHAR])(PUTPROPS REALBITS MACRO ((X)			  (LOGAND X 177Q)))(PUTPROPS SPACEP MACRO [(CHAR)			(FMEMB (REALBITS CHAR)			       (QUOTE (40Q 11Q 15Q])(PUTPROPS TTBOUT MACRO [X (CONS (QUOTE PROGN)				(for ARG in X collect (LIST (QUOTE BLTCHAR)							    (OR (FIXP ARG)								(CDR (ASSOC ARG DMCHARCODES))								(AND (EQ (NCHARS ARG)									 1)								     (CHCON1 ARG))								(LIST (QUOTE REALBITS)								      ARG))							    (QUOTE \DSP])(PUTPROPS TTBOUTN MACRO ((X . Y)			 (FRPTQ X (TTBOUT . Y))))(PUTPROPS WORDSEPRP DMACRO [(X)			    (OR (EQ (\SYNCODE \PRIMTERMSA (REALBITS X))				    WORDSEPR.TC)				(PROGN (* Temporary)				       (SELCHARQ (REALBITS X)						 ((TAB CR %( %) %[ %])						  T)						 NIL])(PUTPROPS FCHARWIDTH MACRO ((CHAR FONT)			    (\FGETWIDTH [ffetch (ARRAYP BASE) of (ffetch \SFWidths								    of (\DTEST FONT (QUOTE 										   FONTDESCRIPTOR]					(LOGAND CHAR \CHARMASK)))))[DECLARE: EVAL@COMPILE (RECORD LINE (START END FIRSTCOL LASTCOL ROW . NEXTLINE))(RECORD TTYINBUFFER (FIRSTLINE OLDTAIL LASTSKIP LASTSKIPCHAR STORAGECOUNTER TTYINDSP TTOLDBUTTONFN 			       TTOLDRIGHTFN)		    STORAGECOUNTER _ 0)(RECORD MOUSEPOS (ROWPOS . COLPOS))](RPAQQ TTCLOCK NIL)(RPAQQ CHANGESARRAY NIL)(RPAQQ DMCHARCODES ((HOME . 2)		    (BELL . 7)		    (DELCH . 10Q)		    (BS . 10Q)		    (DOWN . 12Q)		    (INSERT.LINE . 12Q)		    (LF . 12Q)		    (ADDR . 14Q)		    (CR . 15Q)		    (BLINKON . 16Q)		    (INSERT/DELETE . 20Q)		    (DLE . 20Q)		    (ERASE.TO.END . 27Q)		    (CANCEL . 30Q)		    (UP . 32Q)		    (DELETE.LINE . 32Q)		    (ESC . 33Q)		    (FORWARD . 34Q)		    (ROLL . 35Q)		    (ERASE . 36Q)		    (CLEAR . 36Q)		    (US . 37Q)		    (SPACE . 40Q)))(RPAQQ TTSUPPORTFNS (ADD1POS INPART INSERTING TTBOUT TTBOUTN PR! PRALL PRBUF PRLINE))(ADDTOVAR DONTCOMPILEFNS &DISPLAYCOMMENT DELETETO1 DELNCHARS DO.BACK DO.DOWN DO.FORWARD ADDSILENTCHAR 					 INSERTSPACES)(DECLARE: EVAL@COMPILE (RPAQQ DISPLAYTERMFLG T)(RPAQQ MOUSECODE 501Q)(RPAQQ DIDESCAPECODE 433Q)(RPAQQ PREFIXCODE 200Q)(RPAQQ PADCODE 400Q)(RPAQQ PSEUDOCRCODE 1040Q)(RPAQQ CHECKNIL? NIL)(RPAQQ BREAKCODES (50Q 51Q 54Q 133Q 135Q 42Q))(RPAQQ SEPRCODES (40Q 11Q 15Q 37Q))(RPAQQ TTYINMAILFLG NIL)(RPAQQ \CTRLKEY 40Q)(RPAQQ \SHIFTKEYS 110Q)(RPAQQ DOTSHADE 31714Q)(CONSTANTS (DISPLAYTERMFLG T)	   (MOUSECODE 501Q)	   (DIDESCAPECODE 433Q)	   (PREFIXCODE 200Q)	   (PADCODE 400Q)	   (PSEUDOCRCODE 1040Q)	   (CHECKNIL?)	   BREAKCODES SEPRCODES (TTYINMAILFLG)	   \CTRLKEY \SHIFTKEYS DOTSHADE))(RPAQQ TTNILFNS (BINARY.MODE RESTOREMOD CANCEL.MODES TENEXCOMPLETE GUESTUSER?))(FOR FN IN TTNILFNS DO (MOVD (QUOTE NILL)			     FN))(DECLARE: EVAL@COMPILE (PUTPROPS BINARY.MODE MACRO (NIL NIL))(PUTPROPS RESTOREMOD MACRO (NIL NIL))(PUTPROPS CANCEL.MODES MACRO (NIL NIL))(PUTPROPS TENEXCOMPLETE MACRO (X NIL))(PUTPROPS GUESTUSER? MACRO (NIL NIL)))(DECLARE: DONTEVAL@COMPILE (SETTEMPLATE (QUOTE AT.END.OF.BUF)	     (QUOTE MACRO))(SETTEMPLATE (QUOTE AT.END.OF.LINE)	     (QUOTE MACRO))(SETTEMPLATE (QUOTE AT.START.OF.BUF)	     (QUOTE MACRO))(SETTEMPLATE (QUOTE AT.START.OF.LINE)	     (QUOTE MACRO))(SETTEMPLATE (QUOTE EMPTY.BUFFER)	     (QUOTE MACRO))(SETTEMPLATE (QUOTE EMPTY.LINE)	     (QUOTE MACRO))(SETTEMPLATE (QUOTE INSERTING)	     (QUOTE MACRO))(SETTEMPLATE (QUOTE ON.FIRST.LINE)	     (QUOTE MACRO))(SETTEMPLATE (QUOTE ON.LAST.LINE)	     (QUOTE MACRO))(SETTEMPLATE (QUOTE PADCHAR)	     (QUOTE MACRO))(SETTEMPLATE (QUOTE PADCHARCODE)	     (QUOTE MACRO))(SETTEMPLATE (QUOTE PREFIXCHAR)	     (QUOTE MACRO))(SETTEMPLATE (QUOTE PREFIXCHARCODE)	     (QUOTE MACRO))(SETTEMPLATE (QUOTE REALBITS)	     (QUOTE MACRO))(SETTEMPLATE (QUOTE SPACEP)	     (QUOTE MACRO))[SETTEMPLATE (QUOTE TTBOUT)	     (QUOTE (CALL .. (IF [OR (LISTP EXPR)				     (AND (NTHCHAR EXPR 2)					  (NOT (ASSOC EXPR DMCHARCODES]				 EVAL NIL][SETTEMPLATE (QUOTE TTBOUTN)	     (QUOTE (MACRO (X . Y)			   (FRPTQ X (TTBOUT . Y](SETTEMPLATE (QUOTE MOUSESTATE)	     (QUOTE (CALL)))(SETTEMPLATE (QUOTE LASTMOUSESTATE)	     (QUOTE (CALL)))(SETTEMPLATE (QUOTE CAPABILITY?)	     (QUOTE (CALL)))(RADIX 10Q)DONTEVAL@LOAD EVAL@COMPILE (RPAQ DONTCOMPILEFNS (UNION (UNION TTYINMACROS TTSUPPORTFNS)			    DONTCOMPILEFNS))(FILESLOAD (LOADCOMP)	   ATERM)))(RPAQ? TTYINBUFFER )(RPAQ? ?ACTIVATEFLG T)(RPAQ? EDITPREFIXCHAR 301Q)(RPAQ? EMACSFLG T)(RPAQ? SHOWPARENFLG T)(RPAQ? TTYINBSFLG T)(RPAQ? TTYINCOMPLETEFLG T)(RPAQ? TTYINUSERFN )(RPAQ? TYPEAHEADFLG T)(RPAQ? null "")(RPAQ? DEFAULTPROMPT "** ")(RPAQ? TTYJUSTLENGTH -10Q)(RPAQ? \INSIDE.TTYIN )(RPAQ? TTYINERRORSETFLG )(RPAQ? TTYINRAISEFLG T)(RPAQ? \TTYIN.RESTOREBUFCODE 302Q)(RPAQ? \TTYIN.METASTATE )(RPAQ? TTYINAUTOFILLMARGIN 10Q)(RPAQ? TTYINFIXLIMIT 62Q)(MOVD? (QUOTE NILL)       (QUOTE GUESTUSER?))(MOVD? (QUOTE FIXSPELL)       (QUOTE FIXSPELL!!))(MOVD? (QUOTE HELPSYS)       (QUOTE XHELPSYS))(PUTDQ? SPRINTT [LAMBDA (X)			(PRIN1 X])(MOVD? (QUOTE NILL)       (QUOTE WINDOWWORLD))(MOVD? (QUOTE LISPXFIX)       (QUOTE NONTTYINLISPXFIX))(ADDTOVAR TTYINREADMACROS )(ADDTOVAR TTYINRESPONSES )(ADDTOVAR LISPXCOMS (STOP . OK))(PUTPROPS TTYINREADMACROS VARTYPE ALIST)(DECLARE: DONTEVAL@LOAD DOCOPY [COND ((CCODEP (QUOTE TTYIN))       (CHANGENAME (QUOTE PROMPTCHAR)		   (QUOTE LISPXREADP)		   (QUOTE TTYINREADP))       (SETREADFN)       (MOVD (QUOTE TTYINFIX)	     (QUOTE LISPXFIX](\SET.TTYINBOLDFONT (DEFAULTFONT (QUOTE DISPLAY))))(RPAQQ \TTWAITBOX NIL)(DECLARE: DOEVAL@COMPILE DONTCOPY(ADDTOVAR GLOBALVARS \TTWAITBOX))(DECLARE: DOEVAL@COMPILE DONTCOPY (PUTDEF (QUOTE \TTWAITBOX)	(QUOTE GLOBALRESOURCES)	(QUOTE (CREATECELL \FIXP))))(DECLARE: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY COMPILERVARS (ADDTOVAR NLAMA TTBOUTN TTBOUT)(ADDTOVAR NLAML TTED CHARMACRO? CAPABILITY?)(ADDTOVAR LAMA ))(PUTPROPS TTYIN COPYRIGHT ("Xerox Corporation" 3676Q 3677Q))(DECLARE: DONTCOPY  (FILEMAP (NIL (11236Q 515402Q (TTYIN 11250Q . 30441Q) (TTYIN.SETUP 30443Q . 34063Q) (TTYIN.CLEANUP 34065Q . 34732Q) (TTYIN1 34734Q . 74556Q) (TTYIN1RESTART 74560Q . 76343Q) (TTYIN.FINISH 76345Q . 116405Q) (TTYIN.READ 116407Q . 122666Q) (TTYIN.BALANCE 122670Q . 123375Q) (ADDCHAR 123377Q . 127473Q) (ADDCHARS.INSERTING 127475Q . 131176Q) (ADDNAKEDCHAR 131200Q . 133670Q) (ADDSILENTCHAR 133672Q . 136122Q) (ADDTAB 136124Q . 137773Q) (ADJUSTLINE 137775Q . 163060Q) (ADJUSTLINE.AND.RESTORE 163062Q . 163675Q) (AT.END.OF.SCREEN 163677Q . 164260Q) (AT.END.OF.TEXT 164262Q . 165122Q) (AUTOCR? 165124Q . 166057Q) (BACKSKREAD 166061Q . 173113Q) (BACKWARD.DELETE.TO 173115Q . 173374Q) (BREAKLINE 173376Q . 176711Q) (BUFCHARCOUNT 176713Q . 177761Q) (BUFTAILP 177763Q . 200346Q) (CHECK.MARGIN 200350Q . 201353Q) (CLEAR.LINE? 201355Q . 202063Q) (CREATE.LINE 202065Q . 202621Q) (CURRENT.WORD 202623Q . 205633Q) (DELETE.TO.END 205635Q . 207033Q) (DELETELINE 207035Q . 213436Q) (DELETETO 213440Q . 216256Q) (DELETETO1 216260Q . 217773Q) (DO.EDIT.COMMAND 217775Q . 253520Q) (DO.EDIT.PP 253522Q . 255605Q) (DO?CMD 255607Q . 262425Q) (TTYIN.PRINTARGS 262427Q . 266046Q) (TTYIN.READ?=ARGS 266050Q . 267151Q) (DOTABS 267153Q . 271014Q) (EDITCOLUMN 271016Q . 271650Q) (EDITNUMBERP 271652Q . 272176Q) (END.DELETE.MODE 272200Q . 272724Q) (ENDREAD? 272726Q . 276055Q) (FIND.LINE 276057Q . 277365Q) (FIND.LINE.BREAK 277367Q . 300322Q) (FIND.MATCHING.QUOTE 300324Q . 301237Q) (FIND.MATCHING.WORD 301241Q . 302210Q) (FIND.NEXT.WORD 302212Q . 304261Q) (FIND.NON.SPACE 304263Q . 304653Q) (FIND.START.OF.WORD 304655Q . 305405Q) (FORWARD.DELETE.TO 305407Q . 310251Q) (GO.TO.ADDRESSING 310253Q . 312077Q) (GO.TO.FREELINE 312101Q . 313061Q) (GO.TO.RELATIVE 313063Q . 320620Q) (INIT.CURSOR 320622Q . 322361Q) (INSERT.CHAR.IN.BUF 322363Q . 323165Q) (INSERT.NODE 323167Q . 324041Q) (INSERTLINE 324043Q . 326103Q) (KILL.LINES 326105Q . 327016Q) (KILLSEGMENT 327020Q . 330517Q) (L-CASECODE 330521Q . 331123Q) (MOVE.BACK.TO 331125Q . 331471Q) (MOVE.FORWARD.TO 331473Q . 332120Q) (MOVE.TO.LINE 332122Q . 333442Q) (MOVE.TO.NEXT.LINE 333444Q . 334046Q) (MOVE.TO.START.OF.WORD 334050Q . 335376Q) (MOVE.TO.WHEREVER 335400Q . 335730Q) (NTH.COLUMN.OF 335732Q . 336417Q) (NTH.RELATIVE.COLUMN.OF 336421Q . 341060Q) (OVERFLOW? 341062Q . 342625Q) (OVERFLOWLINE? 342627Q . 343267Q) (PREVLINE 343271Q . 345226Q) (PREVWORD 345230Q . 347165Q) (PROPERTAILP 347167Q . 347477Q) (READFROMBUF 347501Q . 353630Q) (RENUMBER.LINES 353632Q . 354341Q) (RESTORE.CURSOR 354343Q . 354647Q) (RESTOREBUF 354651Q . 357504Q) (RETYPE.BUFFER 357506Q . 363437Q) (SAVE.CURSOR 363441Q . 363706Q) (SCANBACK 363710Q . 365677Q) (SCANFORWARD 365701Q . 367007Q) (SCRATCHCONS 367011Q . 367713Q) (SEGMENT.LENGTH 367715Q . 370534Q) (SEGMENT.BIT.LENGTH 370536Q . 372047Q) (SETLASTC 372051Q . 372610Q) (SETTAIL? 372612Q . 374100Q) (SHOW.MATCHING.PAREN 374102Q . 400036Q) (SKIP/ZAP 400040Q . 403412Q) (START.NEW.LINE 403414Q . 404114Q) (START.OF.PARAGRAPH? 404116Q . 404505Q) (TTADJUSTWORD 404507Q . 406546Q) (TTBIN 406550Q . 410506Q) (TTBITWIDTH 410510Q . 411001Q) (TTCOMPLETEWORD 411003Q . 423567Q) (TTCRLF 423571Q . 424112Q) (TTCRLF.ACCOUNT 424114Q . 425312Q) (TTDELETECHAR 425314Q . 427420Q) (TTDELETELINE 427422Q . 432224Q) (TTDELETEWORD 432226Q . 433021Q) (TTECHO.TO.FILE 433023Q . 436255Q) (TTGIVEHELP 436257Q . 440411Q) (TTGIVEHELP1 440413Q . 441262Q) (TTGIVEHELP2 441264Q . 442267Q) (TTLASTLINE 442271Q . 443001Q) (TTLOADBUF 443003Q . 447677Q) (TTNEXTCHAR 447701Q . 451543Q) (TTNEXTLINE 451545Q . 452200Q) (TTNEXTNODE 452202Q . 452560Q) (TTNLEFT 452562Q . 454710Q) (TTNTH 454712Q . 455516Q) (TTNTHLINE 455520Q . 456220Q) (TTPRIN1 456222Q . 457243Q) (TTPRIN2 457245Q . 461023Q) (TTPROMPTCHAR 461025Q . 461505Q) (TTRATOM 461507Q . 464717Q) (TTREAD 464721Q . 467620Q) (TTREADLIST 467622Q . 473607Q) (TTRUBOUT 473611Q . 474312Q) (TTSKIPSEPR 474314Q . 475036Q) (TTSKREAD 475040Q . 477412Q) (TTUNREADBUF 477414Q . 500255Q) (TTWAITFORINPUT 500257Q . 506135Q) (TTYINSTRING 506137Q . 507436Q) (TYPE.BUFFER 507440Q . 510446Q) (U-CASECODE 510450Q . 511054Q) (U/L-CASE 511056Q . 514371Q) (WORD.MATCHES.BUFFER 514373Q . 515400Q)) (516123Q 542044Q (&DISPLAYCOMMENT 516135Q . 520776Q) (CAPABILITY? 521000Q . 523443Q) (BEEP 523445Q . 523721Q) (BITBLT.DELETE 523723Q . 525150Q) (BITBLT.ERASE 525152Q . 525502Q) (BITBLT.INSERT 525504Q . 526121Q) (DO.CRLF 526123Q . 526512Q) (DO.DELETE.LINES 526514Q . 527477Q) (DO.DOWN 527501Q . 530132Q) (DO.INSERT.LINE 530134Q . 533021Q) (DO.LF 533023Q . 533250Q) (DO.UP 533252Q . 533514Q) (ERASE.SCREEN 533516Q . 533720Q) (ERASE.TO.END.OF.LINE 533722Q . 534362Q) (ERASE.TO.END.OF.PAGE 534364Q . 535166Q) (INSERT.TEXT 535170Q . 536154Q) (INSERTNCHARS 536156Q . 536572Q) (TTDELSECTION 536574Q . 537226Q) (TTADJUSTWIDTH 537230Q . 540642Q) (TTINSERTSECTION 540644Q . 541347Q) (TTSETCURSOR 541351Q . 542042Q)) (542100Q 602552Q (DO.MOUSE 542112Q . 545074Q) (DO.SHIFTED.SELECTION 545076Q . 561155Q) (COPY.SEGMENT 561157Q . 561466Q) (DELETE.LONG.SEGMENT 561470Q . 562126Q) (DELETE.LONG.SEGMENT1 562130Q . 565377Q) (INVERT.LONG.SEGMENT 565401Q . 566663Q) (INVERT.SEGMENT 566665Q . 571140Q) (BRACKET.CURRENT.WORD 571142Q . 573372Q) (TTBEFOREPOS 573374Q . 574375Q) (TTNEXTPOS 574377Q . 575435Q) (TTRACKMOUSE 575437Q . 602217Q) (TTYINBUTTONFN 602221Q . 602550Q)) (603013Q 613264Q (ADD1POS 603025Q . 603254Q) (INPART 603256Q . 603755Q) (INSERTING 603757Q . 604351Q) (TTBOUT 604353Q . 605606Q) (TTBOUTN 605610Q . 606067Q) (PR! 606071Q . 607006Q) (PRALL 607010Q . 607412Q) (PRBUF 607414Q . 611117Q) (PRLINE 611121Q . 613262Q)) (613475Q 622753Q (SETREADFN 613507Q . 614215Q) (TTYINREADP 614217Q . 615017Q) (TTYINREAD 615021Q . 616362Q) (TTYINFIX 616364Q . 617154Q) (CHARMACRO? 617156Q . 620110Q) (TTYINMETA 620112Q . 621400Q) (\SET.TTYINBOLDFONT 621402Q . 622247Q) (TTYIN.LASTINPUT 622251Q . 622751Q)) (622754Q 643134Q (TTED 622766Q . 631156Q) (DO.EE 631160Q . 631363Q) (TTYINEDIT 631365Q . 632746Q) (SIMPLETEXTEDIT 632750Q . 635126Q) (SET.TTYINEDIT.WINDOW 635130Q . 637130Q) (TTYIN.PPTOFILE 637132Q . 641575Q) (TTYIN.SCRATCHFILE 641577Q . 643132Q)))))STOP