(FILECREATED " 1-Oct-85 16:08:30" {DSK}<LISPFILES>TEXEC.;31 58547  

      changes to:  (FNS \TEXEC.SELFN \TEXEC.TEXTBOUT2 \TEXEC.TEXTBOUT4 
			TEDIT.SCROLL? \TEXEC.TEXTBOUT3 
			TEXEC.OPENTEXTSTREAM TEXEC.DISPLAYTEXT TEXEC 
			\TEXEC.TEXTBOUT \TEXEC.TEXTBOUT1)

      previous date: "30-Sep-85 16:11:04" {DSK}<LISPFILES>TEXEC.;25)


(* Copyright (c) 1985, 1900 by Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT TEXECCOMS)

(RPAQQ TEXECCOMS ((COMS (* THE FILLBUFFER REPLACEMENT CODE)
			(FNS TEXEC.OPENTEXTSTREAM TEXEC.FILLBUFFER 
			     TEXEC.FILLBUFFER.TCLASS 
			     TEXEC.FILLBUFFER.CHSELPENDING 
			     TEXEC.FILLBUFFER.CHARDELETE 
			     TEXEC.FILLBUFFER.WORDDELETE 
			     TEXEC.PARENCOUNT TEXEC.PARENMATCH 
			     TEXEC.FLASHCARET 
			     TEXEC.TEXTSTREAM.TO.LINEBUF TEXEC.FIX? 
			     TEXEC.NTHBUFCHARBACK TEXEC.NTHBACKCHNUM 
			     TEXEC.EOTP TEXEC.GETKEY TEXEC.INSERTCHAR 
			     TEXEC.DELETE TEXEC.\CHDEL1 TEXEC.?EQUAL 
			     TEXEC.?CR TEDIT.SCROLL? TEXEC.DISPLAYTEXT 
			     \TEXEC.TEXTBOUT \TEXEC.TEXTBOUT1 
			     \TEXEC.TEXTBOUT2 \TEXEC.TEXTBOUT3 
			     \TEXEC.TEXTBOUT4 \TEXEC.SELFN))
	(COMS (* Code to support a TEXEC lisp "listener")
	      (FNS TEXEC TTEXEC)
	      (APPENDVARS (BackgroundMenuCommands
			    (TEXEC (QUOTE (TEXEC))
				   "Starts TEXEC in a new window.")))
	      (VARS (BackgroundMenu NIL)))
	(INITVARS (TEXEC.BUFFERLIMIT 10000))
	(FILES TEDITCHAT)))



(* THE FILLBUFFER REPLACEMENT CODE)

(DEFINEQ

(TEXEC.OPENTEXTSTREAM
  (LAMBDA (WINDOW MENUFN)                  (* AJB " 1-Oct-85 11:43")
                                           (* Initialize and return TEDIT TEXTSTREAM)
    (PROG* ((TEXSTREAM (OPENTEXTSTREAM NIL WINDOW NIL NIL))
	    (TEXOBJ (TEXTOBJ TEXSTREAM))
	    (TEXLEN (fetch TEXTLEN TEXOBJ)))
                                           (* force shift select typein to be put in keyboard buffer)
           (TEXTPROP TEXSTREAM (QUOTE STARTINGEOF)
		     TEXLEN)
           (TEXTPROP TEXSTREAM (QUOTE COPYBYBKSYSBUF)
		     T)                    (* forces COPY-SELECT to unread chars into TTY buffer)
           (TEXTPROP TEXSTREAM (QUOTE SELFN)
		     (FUNCTION \TEXEC.SELFN))
                                           (* Limits selection to current input)
           (replace STRMBOUTFN of TEXSTREAM with (QUOTE \TEXEC.TEXTBOUT)
		    )
           (replace SET of (fetch SEL of TEXOBJ) with T)
           (replace L1 of (fetch SEL of TEXOBJ)
	      with (LIST (fetch DESC of (fetch THISLINE of TEXOBJ))))
                                           (* hookup middle button menu instead of TEDIT menu)
           (WINDOWPROP WINDOW (QUOTE TEDIT.TITLEMENUFN)
		       MENUFN)
           (CHANGEFONT (fetch CLFONT of (fetch CARETLOOKS of TEXOBJ))
		       TEXSTREAM)
           (RETURN TEXSTREAM))))

(TEXEC.FILLBUFFER
  (LAMBDA (FILLTYPE)                       (* AJB "17-Sep-85 13:41")

          (* While filling the line, the current file pointer is the end of the line. When the line is closed, this is made 
	  the eof. -
	  #CURRENTRDTBL# is used for syntactic delimiters and paren counting on READ and RATOM calls but isn't referenced 
	  (or bound) for READC)


    (DECLARE (USEDFREE #CURRENTRDTBL# \PRIMTERMTABLE FLG \TERM.OFD)
	     (SPECVARS RSNX TCLASS RTBLSA RAISEDCHAR FILLTYPE 
		       RAISEDCHAR PEEKEDECHOED C))
    (\RESETLINE)

          (* * If ERROR or RESET, move STARTINGEOF to end of text (TEXTLEN))


    (RESETLST
      (RESETSAVE
	NIL
	(LIST (FUNCTION (LAMBDA NIL
		  (COND
		    (RESETSTATE            (* Point to end of text and clearout linebuffer on RESET or ERROR)
				(PROG* ((TEXOBJ (fetch (TEXTSTREAM
							 TEXTOBJ)
						   of \TERM.OFD))
					(SEL (fetch SEL of TEXOBJ)))
				       (TEXTPROP TEXOBJ (QUOTE 
							STARTINGEOF)
						 (fetch TEXTLEN
						    of TEXOBJ))
				       (replace (STREAM REVALIDATEFLG)
					  of \LINEBUF.OFD)
				       (\RESETTERMINAL)
				       (\SHOWSEL SEL)
				       (replace CH# of SEL
					  with (ADD1 (fetch TEXTLEN
							of TEXOBJ)))
				       (replace CHLIM of SEL
					  with (ADD1 (fetch TEXTLEN
							of TEXOBJ)))
				       (replace POINT of SEL
					  with (QUOTE LEFT))
				       (replace DCH of SEL
					  with 0)
				       (replace SET of SEL
					  with T)
				       (\FIXSEL SEL TEXOBJ))))))))
      (PROG* ((RTBLSA (AND (NEQ FILLTYPE READC.FT)
			   (fetch READSA of #CURRENTRDTBL#)))
	      (CONTROLTON (fetch CONTROLFLG of \PRIMTERMTABLE))
	      (TEXOBJ (fetch (TEXTSTREAM TEXTOBJ) of \TERM.OFD))
	      (SEL (fetch SEL of TEXOBJ))
	      (WINDOW (fetch \WINDOW of TEXOBJ))
	      (LINES (fetch LINES of TEXOBJ))
	      RSNX TCLASS C RAISEDCHAR PEEKEDECHOED TTYWINDOW FN TCH 
	      INSCH# CHNO ADDEDEOL)

          (* * STARTINGEOF is the beginning of the current text being entered which gets returned to READ so that 
	  \TEXEC.TEXTBOUT knows where to output any text including ↑T)



          (* * TCLASS is terminal syntax class, RSNX is read-table code)


	     (TEXTPROP TEXOBJ (QUOTE STARTINGEOF)
		       (fetch TEXTLEN of TEXOBJ))
                                           (* Keep STARTINGEOF in sync)
	     (COND
	       ((SETQ C (fetch (LINEBUFFER PEEKEDCHAR) of \LINEBUF.OFD))
                                           (* Account for peeked character)
		 (SETQ C (IABS C))

          (* The peeked char may be negative because it was BIN'ed earlier. Make sure it is positive.)


		 (replace (LINEBUFFER PEEKEDCHAR) of \LINEBUF.OFD
		    with NIL)
		 (SETQ PEEKEDECHOED T)
		 (SETQ RAISEDCHAR (\RAISECHAR C))
		 (COND
		   ((EQ FILLTYPE READ.FT)
		     (TEXTPROP TEXOBJ (QUOTE STARTINGEOF)
			       (SUB1 (TEXTPROP TEXOBJ (QUOTE 
							STARTINGEOF)))))
		   )

          (* Backup one in textstream to start the input before the peeked and echoed character if doing a READ)


		 ))
	     (COND
	       ((EQ FILLTYPE READC.FT)
		 (TEXEC.INSERTCHAR TEXOBJ C)
                                           (* Read single char and check for echoing)
		 (COND
		   (CONTROLTON (GO EXIT)))))
                                           (* If in CONTROL T mode and reading a single char)
	     (COND
	       (C (GO NEXTTCLASS)))
	 NEXT(SETQ C (TEXEC.GETKEY TEXOBJ))
                                           (* read next character from keyboard)
	 NEXTTCLASS
	     (SETQ TCLASS (fetch TERMCLASS
			     of (\SYNCODE \PRIMTERMSA (SETQ RAISEDCHAR
					    (\RAISECHAR C)))))
	 REDO

          (* (while (OR TEDIT.SELPENDING (fetch EDITOPACTIVE of TEXOBJ)) do (* Don't do anything while he's selecting or one 
	  of the lock-out ops is active.) (BLOCK)))

                                           (* (replace EDITOPACTIVE of TEXOBJ with T))
	     (TEXEC.FILLBUFFER.CHSELPENDING TEXOBJ)
                                           (* Check for SHIFT/COPY/MOVE active)

          (* * Handle Terminal Class characters)


	     (SELECTQ (TEXEC.FILLBUFFER.TCLASS TEXOBJ SEL)
		      (NEXT (GO NEXT))
		      (EXIT (GO EXIT))
		      NIL)

          (* * Here if it isn't a terminal class.)


	     (COND
	       (PEEKEDECHOED (SETQ PEEKEDECHOED NIL))
	       (T (TEXEC.INSERTCHAR TEXOBJ C)))
	     (AND (EQ FILLTYPE READC.FT)
		  (GO NEXT))
	     (COND
	       ((EQ ESCAPE.RC (SETQ RSNX (\SYNCODE RTBLSA RAISEDCHAR)))
		 (COND
		   ((EQ CTRLV.TC (SETQ TCLASS
			  (fetch TERMCLASS
			     of (\SYNCODE \PRIMTERMSA (SETQ RAISEDCHAR
					    (TEXEC.INSERTCHAR TEXOBJ))))
			  ))
		     (GO REDO)))
		 (GO NEXT)))
	     (SELECTC
	       FILLTYPE
	       (RATOM/RSTRING.FT (COND
				   ((AND CONTROLTON
					 (fetch STOPATOM of RSNX))
				     (GO EXIT))))
	       (READ.FT
		 (SELECTC RSNX
			  ((LIST RIGHTPAREN.RC RIGHTBRACKET.RC)
			    (TEXEC.FLASHCARET TEXOBJ (TEXEC.PARENMATCH
						TEXOBJ RSNX)))
			  NIL)
		 (COND
		   ((AND CONTROLTON (ZEROP (fetch (LINEBUFFER LBRKCOUNT)
					      of \LINEBUF.OFD))
			 (ZEROP (fetch (LINEBUFFER LPARCOUNT)
				   of \LINEBUF.OFD))
			 (fetch STOPATOM of RSNX)
			 (SELECTC RSNX
				  ((LIST LEFTPAREN.RC LEFTBRACKET.RC 
					 RIGHTBRACKET.RC RIGHTPAREN.RC)
				    NIL)
				  (STRINGDELIM.RC
				    (COND
				      ((fetch (LINEBUFFER INSTRINGP)
					  of \LINEBUF.OFD)
					(replace (LINEBUFFER INSTRINGP)
					   of \LINEBUF.OFD
					   with NIL)
					T)))
				  (NOT (fetch (LINEBUFFER INSTRINGP)
					  of \LINEBUF.OFD))))

          (* READ is reading an atom. Return when atom ends, but also obey bracket/paren exception noted on page 14.33 of 
	  manual.)


		     (GO EXIT)))
		 (COND
		   ((TEXEC.EOTP TEXOBJ)
		     (COND
		       ((fetch (STREAM REVALIDATEFLG) of \LINEBUF.OFD)
			 (TEXEC.PARENCOUNT TEXOBJ)
                                           (* text needs recount of parens/brackets)
			 ))
		     (COND
		       ((\INCPARENCOUNT RSNX)

          (* Parens balance--throw the carriage if the closing paren or bracket character was not a CR, and if FLG argument of
	  READ is NIL. (We know we are under a READ call because of FILLTYPE))

                                           (* copy the chars from the textstream into the linebuffer)
			 (TEXEC.TEXTSTREAM.TO.LINEBUF
			   TEXOBJ
			   (TEXTPROP TEXOBJ (QUOTE STARTINGEOF))
			   \LINEBUF.OFD FILLTYPE)
			 (AND (EQ FILLTYPE READ.FT)
			      (TEXEC.FIX? TEXOBJ \LINEBUF.OFD)
			      (GO NEXT))   (* If it was a PA FIX command handle it, and allow editing)

          (* now reset the new STARTINGEOF to start at the end of the text)


			 (TEXTPROP TEXOBJ (QUOTE STARTINGEOF)
				   (fetch TEXTLEN of TEXOBJ))
			 (\CLOSELINE)
			 (AND (NEQ RAISEDCHAR (CHARCODE EOL))
			      (NOT FLG)
			      (\OUTCHAR \TERM.OFD (CHARCODE EOL)))
                                           (* \CLOSELINE first so dribble happens before EOL)
			 (RETURN))
		       ((EQ IMMEDIATE.RMW (fetch WAKEUP of RSNX))
                                           (* Immediate read-macro)
			 (RETURN))))))
	       (SHOULDNT))
	     (GO NEXT)
	 EXIT(COND
	       ((AND (EQ FILLTYPE READ.FT)
		     (EQ RAISEDCHAR (CHARCODE EOL))
		     (EQ (SUB1 (fetch TEXTLEN of TEXOBJ))
			 (TEXTPROP TEXOBJ (QUOTE STARTINGEOF))))
		 (\LINEBUFBOUT \LINEBUF.OFD (CAR (GETSYNTAX
						   (QUOTE RIGHTBRACKET)
						   #CURRENTRDTBL#)))

          (* If doing a READ, force a lone CR to terminate the READ by handing back a RIGHTBRACKET into the LINEBUFFER)


		 )
	       (T (TEXEC.TEXTSTREAM.TO.LINEBUF TEXOBJ
					       (TEXTPROP TEXOBJ
							 (QUOTE 
							STARTINGEOF))
					       \LINEBUF.OFD FILLTYPE)))
	     (TEXTPROP TEXOBJ (QUOTE STARTINGEOF)
		       (fetch TEXTLEN of TEXOBJ))
	     (AND (EQ FILLTYPE READ.FT)
		  (TEXEC.FIX? TEXOBJ \LINEBUF.OFD)
		  (GO NEXT))               (* If it was a PA FIX command handle it, and allow editing)
	     (\CLOSELINE)
	     (AND (NEQ RAISEDCHAR (CHARCODE EOL))
		  (NOT CONTROLTON)
		  (NOT FLG)
		  (\OUTCHAR \TERM.OFD (CHARCODE EOL)))))))

(TEXEC.FILLBUFFER.TCLASS
  (LAMBDA (TEXOBJ SEL)                     (* AJB "27-Sep-85 14:39")

          (* * Handle special terminal class characters)


    (DECLARE (USEDFREE \LINEBUF.OFD PEEKEDECHOED C FILLTYPE TCLASS))
    (PROG NIL
          (SELECTC TCLASS
		   (RETYPE.TC (RETURN (QUOTE NEXT))
                                           (* Ignore ↑R since the user can rescroll the line)
			      )
		   (LINEDELETE.TC (COND
				    ((IGREATERP (fetch CH#
						   of SEL)
						(TEXTPROP TEXOBJ
							  (QUOTE 
							STARTINGEOF)))

          (* Only allow deletion of selection if left side of selection is after start of current input)


				      (TEDIT.DO.BLUEPENDINGDELETE
					SEL TEXOBJ)
				      (replace (STREAM REVALIDATEFLG)
					 of \LINEBUF.OFD with T)))
                                           (* invalidate paren/bracket count)
				  (\SHOWSEL SEL NIL NIL)
                                           (* Erase characters from the screen)
				  (TEDIT.UPDATE.SCREEN TEXOBJ)
				  (\FIXSEL SEL TEXOBJ)
				  (\SHOWSEL SEL NIL T)
				  (RETURN (QUOTE NEXT)))
		   (CHARDELETE.TC (TEXEC.FILLBUFFER.CHARDELETE TEXOBJ)
				  (RETURN (QUOTE NEXT)))
		   (WORDDELETE.TC (TEXEC.FILLBUFFER.WORDDELETE TEXOBJ)
				  (RETURN (QUOTE NEXT)))
		   (CTRLV.TC (COND
			       (PEEKEDECHOED (SETQ PEEKEDECHOED NIL)))
			     (TEXEC.INSERTCHAR TEXOBJ C)
			     (COND
			       ((NEQ FILLTYPE READC.FT)
				 (SETQ C (TEXEC.GETKEY TEXOBJ))))
			     (SETQQ TCLASS NONE.TC))
		   (EOL.TC (AND (EQ FILLTYPE READ.FT)
				(TEXEC.?EQUAL TEXOBJ)
				(RETURN (QUOTE NEXT))
                                           (* If ?= handle it and go for more input)
				)
			   (AND (EQ FILLTYPE READ.FT)
				(TEXEC.?CR TEXOBJ)
				(RETURN (QUOTE NEXT))
                                           (* Test for ? <cr>, and if so call HELPSYS)
				)
			   (TEXEC.INSERTCHAR TEXOBJ C)
			   (COND
			     ((EQ FILLTYPE READ.FT)
                                           (* If we are doing a "READ")

          (* If we are at the end of the input now, update parencount if invalid, and test for matching paren/bracket count)


			       (AND (TEXEC.EOTP TEXOBJ)
				    (COND
				      ((fetch (STREAM REVALIDATEFLG)
					  of \LINEBUF.OFD)
					(TEXEC.PARENCOUNT TEXOBJ))
				      (T T))
				    (ZEROP (fetch (LINEBUFFER LBRKCOUNT)
					      of \LINEBUF.OFD))
				    (ZEROP (fetch (LINEBUFFER LPARCOUNT)
					      of \LINEBUF.OFD))
				    (NOT (fetch (LINEBUFFER INSTRINGP)
					    of \LINEBUF.OFD))
				    (RETURN (QUOTE EXIT))
                                           (* Proper termination of READ)
				    )
			       (RETURN (QUOTE NEXT))
                                           (* Else go for more input)
			       )
			     (T (RETURN (QUOTE EXIT))
                                           (* Exit always if not in "READ" mode)
				)))
		   NIL)
          (COND
	    ((EQ C (CHARCODE ↑X))          (* ↑X positions to end of text)
	      (\SETUPGETCH (fetch TEXTLEN of TEXOBJ)
			   TEXOBJ)
	      (replace CH# of SEL with (ADD1 (fetch TEXTLEN
						of TEXOBJ)))
	      (replace CHLIM of SEL with (fetch CH# of SEL))
	      (replace POINT of SEL with (QUOTE LEFT))
	      (replace DCH of SEL with 0)
	      (replace SET of SEL with T)
	      (replace HASCARET of SEL with T)
	      (UNINTERRUPTABLY
                  (\CHECKCARET)
		  (for CARET inside (fetch CARET of TEXOBJ)
		     as WIN inside (fetch (TEXTOBJ \WINDOW)
				      of TEXOBJ)
		     do (\FIXSEL SEL TEXOBJ WIN)
			(MOVETO (fetch X0 of SEL)
				(fetch Y0 of SEL)
				WIN)
			(replace TCCARETX of CARET
			   with (fetch X0 of SEL))
			(replace TCCARETY of CARET
			   with (fetch Y0 of SEL))))
	      (RETURN (QUOTE NEXT)))))))

(TEXEC.FILLBUFFER.CHSELPENDING
  (LAMBDA (TEXOBJ)                         (* AJB "11-Sep-85 14:44")
                                           (* Before starting to work, note that we're doing something.)
    (ERSETQ (COND
	      (TEDIT.COPY.PENDING          (* Have to copy the shifted SEL to caret.)
				  (SETQ TEDIT.COPY.PENDING NIL)
				  (\COPYSEL TEDIT.SHIFTEDSELECTION
					    (fetch SHIFTEDSEL
					       of TEXOBJ))
				  (TEDIT.COPY (fetch SHIFTEDSEL
						 of TEXOBJ)
					      (fetch SEL of TEXOBJ))
				  (replace SET of 
					     TEDIT.SHIFTEDSELECTION
				     with NIL)
				  (replace L1 of TEDIT.SHIFTEDSELECTION
				     with NIL)
				  (replace LN of TEDIT.SHIFTEDSELECTION
				     with NIL)
				  (\COPYSEL TEDIT.SHIFTEDSELECTION
					    (fetch SHIFTEDSEL
					       of TEXOBJ)))
	      (TEDIT.COPYLOOKS.PENDING     (* Have to copy the shifted SEL to caret.)
				       (SETQ TEDIT.COPYLOOKS.PENDING 
					 NIL)
				       (\COPYSEL 
					   TEDIT.COPYLOOKSSELECTION
						 (fetch SHIFTEDSEL
						    of TEXOBJ))
				       (COND
					 ((EQ (QUOTE PARA)
					      (fetch SELKIND
						 of (fetch SHIFTEDSEL
						       of TEXOBJ)))
                                           (* copy the paragraph looks, since the source selection type was 
					   paragraph)
					   (TEDIT.COPY.PARALOOKS
					     TEXOBJ
					     (fetch SHIFTEDSEL
						of TEXOBJ)
					     (fetch SEL of TEXOBJ)))
					 (T 
                                           (* copy the character looks)
					    (TEDIT.COPY.LOOKS
					      TEXOBJ
					      (fetch SHIFTEDSEL
						 of TEXOBJ)
					      (fetch SEL of TEXOBJ))))
				       (\SHOWSEL (fetch SHIFTEDSEL
						    of TEXOBJ)
						 NIL NIL)
				       (replace SET of 
					   TEDIT.COPYLOOKSSELECTION
					  with NIL)
				       (replace L1 of 
					   TEDIT.COPYLOOKSSELECTION
					  with NIL)
				       (replace LN of 
					   TEDIT.COPYLOOKSSELECTION
					  with NIL)
				       (\COPYSEL 
					   TEDIT.COPYLOOKSSELECTION
						 (fetch SHIFTEDSEL
						    of TEXOBJ)))
	      (TEDIT.MOVE.PENDING          (* Have to move the ctrl-shift SEL to caret.)
				  (SETQ TEDIT.MOVE.PENDING NIL)
				  (\COPYSEL TEDIT.MOVESELECTION
					    (fetch MOVESEL
					       of TEXOBJ))
				  (TEDIT.DO.BLUEPENDINGDELETE SEL 
							     TEXOBJ)
				  (TEDIT.MOVE (fetch MOVESEL
						 of TEXOBJ)
					      (fetch SEL of TEXOBJ))
				  (replace SET of TEDIT.MOVESELECTION
				     with NIL)
				  (replace L1 of TEDIT.MOVESELECTION
				     with NIL)
				  (replace LN of TEDIT.MOVESELECTION
				     with NIL)
				  (\COPYSEL TEDIT.MOVESELECTION
					    (fetch MOVESEL
					       of TEXOBJ)))
	      (TEDIT.DEL.PENDING           (* Delete the current selection.)
				 (SETQ TEDIT.DEL.PENDING NIL)
                                           (* Above all, reset the demand flag first)
				 (COND
				   ((fetch SET of TEDIT.DELETESELECTION)
                                           (* Only try the deletion if he really set the selection.)
				     (\SHOWSEL (fetch DELETESEL
						  of TEXOBJ)
					       NIL NIL)
                                           (* Turn off the selection highlights)
				     (\SHOWSEL (fetch SEL of TEXOBJ)
					       NIL NIL)
				     (replace SET
					of (fetch DELETESEL
					      of TEXOBJ)
					with NIL)
				     (\COPYSEL TEDIT.DELETESELECTION
					       (fetch SEL of TEXOBJ))
				     (\TEDIT.SET.SEL.LOOKS
				       (fetch SEL of TEXOBJ)
				       (QUOTE NORMAL))
                                           (* Grab the selection we're to use)
				     (\TEDIT.DELETE
				       (fetch SEL of TEXOBJ)
				       (fetch \TEXTOBJ
					  of (fetch SEL of TEXOBJ))
				       NIL)
				     (replace L1 of 
					      TEDIT.DELETESELECTION
					with NIL)
				     (replace LN of 
					      TEDIT.DELETESELECTION
					with NIL))))))))

(TEXEC.FILLBUFFER.CHARDELETE
  (LAMBDA (TEXOBJ)                         (* AJB "11-Sep-85 15:26")
    (DECLARE (USEDFREE FILLTYPE RSNX TCLASS RTBLSA RAISEDCHAR 
		       #CURRENTRDTBL#))
    (PROG (C)
          (COND
	    ((NULL (SETQ C (TEXEC.\CHDEL1 TEXOBJ)))

          (* Try deleting a character (put the deleted char in C and RETURN C). If there was no character to delete 
	  (ie, we're at start of line), (RETURN NIL))


	      (FLASHWINDOW WINDOW)
	      (RETURN)))
          (PROG (C1 (ESCAPE? (AND (NEQ FILLTYPE READC.FT)
				  (fetch ESCAPEFLG of #CURRENTRDTBL#)
				  ESCAPE.RC)))
	        (COND
		  ((NEQ FILLTYPE READC.FT)
                                           (* Don't process escapes if READC)
		    (SETQ RSNX (\SYNCODE RTBLSA C))
		    (COND
		      ((SETQ C1 (TEXEC.NTHBUFCHARBACK TEXOBJ 0))
                                           (* Check preceding char C1 for escape)
			(COND
			  ((EQ ESCAPE? (\SYNCODE RTBLSA C1))
			    (SETQ RSNX OTHER.RC)
			    (SETQ C (TEXEC.\CHDEL1 TEXOBJ))
                                           (* Delete the ESCAPE char also)
			    ))))
		    (COND
		      ((NULL (fetch (STREAM REVALIDATEFLG)
				of \LINEBUF.OFD))
			(\DECPARENCOUNT RSNX)

          (* no need to update parencount if deleting chars in the middle of the text)


			)))))
          (RETURN C)                       (* Successful delete)
      )))

(TEXEC.FILLBUFFER.WORDDELETE
  (LAMBDA (TEXOBJ)                         (* AJB "11-Sep-85 15:09")

          (* Delete chars until first non-sepr/non-other, or first non-other after sepr string and other string.
	  Note that a terminal wordsepr is treated as if it were a read-sepr)


    (DECLARE (USEDFREE RSNX RTBLSA \PRIMTERMSA TCLASS FILLTYPE 
		       #CURRENTRDTBL#))
    (PROG (C)
          (COND
	    ((TEXEC.FILLBUFFER.CHARDELETE TEXOBJ)
                                           (* Delete first character always)
	      )
	    (T (RETURN)                    (* No chars in buffer, return)
	       ))
      AGAIN
          (COND
	    ((SETQ C (TEXEC.NTHBUFCHARBACK TEXOBJ 0))
	      (SELECTC RSNX
		       (SEPRCHAR.RC (COND
				      ((TEXEC.FILLBUFFER.CHARDELETE
					  TEXOBJ)
					(GO AGAIN)
                                           (* cont until first non-sepr)
					)
				      (T (RETURN)
                                           (* No more chars in buffer, return)
					 )))
		       (OTHER.RC
			 (COND
			   ((EQ WORDSEPR.TC (\SYNCODE \PRIMTERMSA C))
			     (COND
			       ((TEXEC.FILLBUFFER.CHARDELETE TEXOBJ)
				 (GO AGAIN)
                                           (* cont until first non-sepr)
				 )
			       (T (RETURN)
                                           (* No more chars in buffer, return)
				  ))))
			 (PROG (C1 (ESCAPE? (AND (NEQ FILLTYPE READC.FT)
						 (fetch ESCAPEFLG
						    of #CURRENTRDTBL#)
						 ESCAPE.RC)))
                                           (* The first OTHER)
			   TRY (COND
				 ((NULL (TEXEC.FILLBUFFER.CHARDELETE
					  TEXOBJ))
				   (RETURN)))
			       (COND
				 ((SETQ C (TEXEC.NTHBUFCHARBACK TEXOBJ 
								0))
                                           (* look at previous char)
				   (SETQ RSNX (\SYNCODE RTBLSA C))
				   (SETQ TCLASS (\SYNCODE \PRIMTERMSA C)
				     )
				   (COND
				     ((SETQ C1 (TEXEC.NTHBUFCHARBACK
					   TEXOBJ 1))
				       (COND
					 ((EQ ESCAPE? (\SYNCODE RTBLSA 
								C1))
					   (SETQ RSNX OTHER.RC)
					   (SETQ TCLASS NONE.TC)))))
				   (COND
				     ((AND (NEQ TCLASS WORDSEPR.TC)
					   (EQ OTHER.RC RSNX))
                                           (* Erase it)
				       (GO TRY)))))))
		       (RETURN)))))))

(TEXEC.PARENCOUNT
  (LAMBDA (TEXOBJ)                         (* AJB "11-Sep-85 14:47")
    (DECLARE (USEDFREE \LINEBUF.OFD))
    (PROG ((STREAM (fetch STREAMHINT of TEXOBJ)))
          (replace (LINEBUFFER LPARCOUNT) of \LINEBUF.OFD with 0)
          (replace (LINEBUFFER LBRKCOUNT) of \LINEBUF.OFD with 0)
          (replace (LINEBUFFER LPARCOUNT) of \LINEBUF.OFD with 0)
          (replace (LINEBUFFER INSTRINGP) of \LINEBUF.OFD with NIL)
          (\SETUPGETCH (TEXTPROP TEXOBJ (QUOTE STARTINGEOF))
		       TEXOBJ)
          (for I from (TEXTPROP TEXOBJ (QUOTE STARTINGEOF))
	     to (fetch TEXTLEN of TEXOBJ)
	     do (\INCPARENCOUNT (\SYNCODE RTBLSA (\BIN STREAM))))
          (replace (STREAM REVALIDATEFLG) of \LINEBUF.OFD with NIL)

          (* Last thing is to reset the validation flag, and always RETURN T for AND's to work)


          (RETURN T))))

(TEXEC.PARENMATCH
  (LAMBDA (TEXOBJ RSNX)                    (* AJB "11-Sep-85 15:13")

          (* * Returns CH# if matching left paren/bracket is found, else NIL)


    (DECLARE (USEDFREE #CURRENTRDTBL# \TERM.OFD))
    (PROG (MATCH? N CH CH1 CH2 (PCOUNT 1))
          (SELECTC RSNX
		   (RIGHTPAREN.RC (SETQ CH (CAR (GETSYNTAX
						  (QUOTE LEFTPAREN)
						  #CURRENTRDTBL#)))
				  (SETQ CH1 (CAR (GETSYNTAX
						   (QUOTE RIGHTPAREN)
						   #CURRENTRDTBL#))))
		   (RIGHTBRACKET.RC (SETQ CH
				      (CAR (GETSYNTAX (QUOTE 
							LEFTBRACKET)
						      #CURRENTRDTBL#)))
				    (SETQ CH1
				      (CAR (GETSYNTAX (QUOTE 
						       RIGHTBRACKET)
						      #CURRENTRDTBL#))))
		   0)
          (for I from 1 to (IDIFFERENCE (fetch TEXTLEN of TEXOBJ)
					(TEXTPROP TEXOBJ (QUOTE 
							STARTINGEOF)))
	     do (SETQ CH2 (TEXEC.NTHBUFCHARBACK TEXOBJ I))
		(COND
		  ((EQ CH2 CH1)
		    (SETQ PCOUNT (ADD1 PCOUNT)))
		  ((EQ CH2 CH)
		    (SETQ PCOUNT (SUB1 PCOUNT))))
	     until (SETQ MATCH? (EQ PCOUNT 0))
	     finally (COND
		       (MATCH?             (* \CARET.DOWN \TERM.OFD)
			       (SETQ N (TEXEC.NTHBACKCHNUM
				   TEXOBJ
				   (SUB1 I))))))
          (RETURN N))))

(TEXEC.FLASHCARET
  (LAMBDA (TEXOBJ N)                       (* AJB "11-Sep-85 14:56")

          (* * Flashes caret at char# N, used for flashing caret at matching paren/bracket If N is NIL, simply returns)


    (PROG (TSEL (WINDOW (fetch (TEXTOBJ \WINDOW) of TEXOBJ)))
          (COND
	    ((NOT N)
	      (RETURN)))
          (SETQ TSEL (create SELECTION
			using (fetch SEL of TEXOBJ)
			      CH# ← N CHLIM ← N DCH ← 0 POINT ←(QUOTE
				LEFT)
			      \TEXTOBJ ← TEXOBJ SET ← T))
          (UNINTERRUPTABLY
              (bind (FIRSTTIME ← T) for CARET
		 inside (fetch CARET of TEXOBJ) as WIN inside WINDOW
		 as L1 inside (fetch L1 of TSEL)
		 do (COND
		      (L1 (\EDIT.UPCARET CARET)
			  (\FIXSEL TSEL TEXOBJ WIN)
			  (COND
			    (FIRSTTIME (SETQ FIRSTTIME NIL)
				       (\CARET.FLASH? (fetch TCCARETDS
							 of CARET)
						      (fetch TCCARET
							 of CARET)
						      NIL NIL
						      (fetch X0
							 of TSEL)
						      (fetch Y0
							 of TSEL)))
			    (T (\CARET.FLASH.AGAIN (fetch TCCARET
						      of CARET)
						   (fetch TCCARETDS
						      of CARET)
						   (fetch X0
						      of TSEL)
						   (fetch Y0
						      of TSEL)))))))
	      (DISMISS 500)
	      (for WIN inside WINDOW as CARET
		 inside (fetch CARET of TEXOBJ)
		 do (\EDIT.DOWNCARET CARET) 
                                           (* Display the caret at the typein point)
		   )))))

(TEXEC.TEXTSTREAM.TO.LINEBUF
  (LAMBDA (TEXOBJ STARTINGEOF LINEBUF FILLTYPE)
                                           (* AJB "17-Sep-85 14:48")

          (* Copy the contents of the current edit line into the line buffer, for transmission to the system.)


    (\SETUPGETCH (IMIN (fetch TEXTLEN of TEXOBJ)
		       (ADD1 STARTINGEOF))
		 TEXOBJ)
    (SETFILEPTR LINEBUF 0)
    (\SETEOFPTR LINEBUF 0)
    (while (NOT (EOFP (fetch STREAMHINT of TEXOBJ)))
       do
	(\LINEBUFBOUT
	  LINEBUF
	  (PROG ((C (\BIN (fetch STREAMHINT of TEXOBJ))))
	        (COND
		  ((AND (NEQ FILLTYPE READC.FT)
			(EQ (CHARCODE ↑V)
			    C))            (* convert ↑Vx to real CONTROL char)
		    (SETQ C
		      (COND
			((OR (AND (IGEQ (SETQ C
					  (\BIN (fetch STREAMHINT
						   of TEXOBJ)))
					(CHARCODE A))
				  (ILEQ C (CHARCODE Z)))
			     (AND (IGEQ C (CHARCODE a))
				  (ILEQ C (CHARCODE z))))
                                           (* CONVERT TO CONTROL CHAR)
			  (LOGAND C 31))
			(T C)))))
	        (RETURN C))))

          (* \TEDIT.CHANGE.LOOKS (fetch STREAMHINT of TEXOBJ) (QUOTE (PROTECTED ON)) (IMIN (fetch TEXTLEN of TEXOBJ) 
	  (ADD1 STARTINGEOF)) (IDIFFERENCE (fetch TEXTLEN of TEXOBJ) STARTINGEOF))


    T))

(TEXEC.FIX?
  (LAMBDA (TEXOBJ LINEBUF)                 (* AJB "11-Sep-85 15:22")

          (* * Checks for a FIX command before it is handed back to LISP, and enters the returned history event into the 
	  TEXTSTREAM for editing. If so returns T, if not a FIX command, returns NIL)


    (DECLARE (USEDFREE #CURRENTRDTBL#))
    (PROG (FIXL)
          (SETFILEPTR LINEBUF 0)
          (SETQ FIXL (U-CASE (READ LINEBUF)))
          (COND
	    ((COND
		((EQ FIXL (QUOTE FIX))     (* Test if we have a FIX command)
		  (while (EQ (READC LINEBUF)
			     (CONSTANT (CHARACTER (CHARCODE SPACE)))))
                                           (* skip blanks)
		  (COND
		    ((EQ (LASTC LINEBUF)
			 (CONSTANT (CHARACTER (CHARCODE EOL))))
                                           (* if the last character was a carriage return, then get last event)
		      (SETQ FIXL (QUOTE (-1))))
		    (T 

          (* otherwise reset the file pointer to start and skipover FIX, and READ the rest of the line)


		       (SETFILEPTR LINEBUF 0)
		       (READ LINEBUF)
		       (SETQ FIXL (LIST (READ LINEBUF)))))
                                           (* value T for finding a FIX command)
		  T)
		((LISTP FIXL)
		  (COND
		    ((EQ (CAR FIXL)
			 (QUOTE FIX))
		      (SETQ FIXL (CDR FIXL))
		      (AND (NOT FIXL)
			   (SETQ FIXL (QUOTE (-1))))
		      (TEXEC.INSERTCHAR TEXOBJ (CHARCODE EOL))
                                           (* Throw the carriage)
		      T))))
	      (HISTORYSAVE LISPXHISTORY LISPXID NIL NIL
			   (LIST (MKSTRING (LIST (QUOTE FIX)
						 (CAR FIXL)))))
	      (SETQ FIXL (GETEXPRESSIONFROMEVENTSPEC FIXL))
                                           (* get historyevent based on eventspec in FIXL)
	      (\RESETTERMINAL)             (* Reset LINEBUFFER)
	      (COND
		(FIXL (TEXTPROP TEXOBJ (QUOTE STARTINGEOF)
				(fetch TEXTLEN of TEXOBJ))
                                           (* Set the new STARTINGEOF to the beginning of the text to insert)
		      (for C inside (CHCON FIXL)
			 do (TEXEC.INSERTCHAR TEXOBJ C))
                                           (* Add the history command found to the end of the TEXTSTREAM)
		      (TEXEC.PARENCOUNT TEXOBJ)
                                           (* Have to do a paren/bracket count again)
		      (RETURN T)           (* Return T to indicate valid FIX command)
		      )
		(T (\LINEBUFBOUT \LINEBUF.OFD
				 (CAR (GETSYNTAX (QUOTE RIGHTBRACKET)
						 #CURRENTRDTBL#)))

          (* force a lone CR to terminate the READ by handing back a RIGHTBRACKET into the LINEBUFFER)


		   (RETURN)                (* Return NIL to ignore the FIX)
		   )))
	    (T (SETFILEPTR LINEBUF (GETEOFPTR LINEBUF))
	       (RETURN)                    (* Not a fix command return NIL)
	       )))))

(TEXEC.NTHBUFCHARBACK
  (LAMBDA (TEXOBJ N)                       (* AJB "11-Sep-85 15:13")

          (* Return the Nth character back from the current end of text. Puts the pointer back at the end of the buffer)


    (PROG ((CHPOS (TEXEC.NTHBACKCHNUM TEXOBJ N)))
                                           (* CHPOS is the actual char position in the text.)
          (COND
	    ((OR (ILEQ CHPOS (TEXTPROP TEXOBJ (QUOTE STARTINGEOF)))
		 (ILEQ CHPOS 1))           (* returns NIL if there is no char at that position)
	      (RETURN)))
          (\SETUPGETCH CHPOS TEXOBJ)       (* Setup position to BIN character)
          (RETURN (\BIN (fetch STREAMHINT of TEXOBJ))))))

(TEXEC.NTHBACKCHNUM
  (LAMBDA (TEXOBJ N)                       (* AJB "11-Sep-85 15:12")

          (* Converts N chars back from the end of the selection to a CH#)


    (IDIFFERENCE (IMIN (fetch TEXTLEN of TEXOBJ)
		       (SELECTQ (fetch POINT
				   of (fetch SEL of TEXOBJ))
				(LEFT (fetch CH#
					 of (fetch SEL of TEXOBJ)))
				(RIGHT (fetch CHLIM
					  of (fetch SEL of TEXOBJ)))
				NIL))
		 N)))

(TEXEC.EOTP
  (LAMBDA (TEXOBJ)                         (* AJB "11-Sep-85 15:14")
                                           (* Test if the caret is at the end of the text)
    (PROG ((SEL (fetch SEL of TEXOBJ)))
          (RETURN (ILESSP (fetch TEXTLEN of TEXOBJ)
			  (SELECTQ (fetch POINT of SEL)
				   (LEFT (fetch CH# of SEL))
				   (RIGHT (fetch CHLIM of SEL))
				   NIL))))))

(TEXEC.GETKEY
  (LAMBDA (TEXOBJ)                         (* AJB "10-Sep-85 16:25")

          (* * Return a character from the keyboard without echoing. If no key has been typed, update the screen if prior 
	  input-output didn't want to do it, flash the caret in all of the attached windows if the keyboard is attached to 
	  this process, ie, is the TTYDISPLAYSTREAM. Blocks until a key is typed with the keyboard attached to this process)


    (PROG ((SEL (fetch SEL of TEXOBJ)))
          (until (\WAITFORSYSBUFP 100)
	     do (COND
		  ((fetch TXTNEEDSUPDATE of TEXOBJ)
                                           (* Screen needs updating)
		    (\SHOWSEL SEL NIL NIL)
		    (TEDIT.UPDATE.SCREEN TEXOBJ)
                                           (* Turn highlighting off of selection)
		    (\FIXSEL SEL TEXOBJ)   (* Fix up the selection fields)
		    (TEDIT.SCROLL? TEXOBJ)
                                           (* Scroll windows if necessary)
		    (\SHOWSEL SEL NIL T)   (* Turn any selection back on)
		    ))
		(TEDIT.FLASHCARET (fetch CARET of TEXOBJ))
		(BLOCK))                   (* Flash carets in all windows until a key is entered)
          (RETURN (\GETKEY)))))

(TEXEC.INSERTCHAR
  (LAMBDA (TEXOBJ C)                       (* AJB "17-Sep-85 13:51")

          (* * Inserts a character into the textstream. If the character is being inserted prior to the current input then the
	  start of the current input pointer, STARTINGEOF is incremented. If echoing is off, then the character is inserted as
	  "invisible")


    (DECLARE (USEDFREE \PRIMTERMTABLE \TERM.OFD))
    (PROG ((SEL (fetch SEL of TEXOBJ)))
          (COND
	    ((ILEQ (SELECTQ (fetch POINT of SEL)
			    (LEFT (fetch CH# of SEL))
			    (RIGHT (fetch CHLIM of SEL))
			    NIL)
		   (TEXTPROP TEXOBJ (QUOTE STARTINGEOF)))
	      (TEXTPROP TEXOBJ (QUOTE STARTINGEOF)
			(ADD1 (TEXTPROP TEXOBJ (QUOTE STARTINGEOF))))

          (* If inserting text prior to current input move the start of input down 1 to compensate)


	      )
	    (T (AND (IGREATERP (IMIN (fetch CH# of SEL)
				     (fetch CHLIM of SEL))
			       (TEXTPROP TEXOBJ (QUOTE STARTINGEOF)))
		    (TEDIT.DO.BLUEPENDINGDELETE SEL TEXOBJ))))
                                           (* Only allow deletion of seletected text if after start of current 
					   input)
          (COND
	    ((fetch ECHOFLG of \PRIMTERMTABLE)
	      (TEDIT.\INSERT (OR C (SETQ C (TEXEC.GETKEY TEXOBJ)))
			     SEL \TERM.OFD))
	    (T (TEDIT.CARETLOOKS TEXOBJ (QUOTE (INVISIBLE ON)))
	       (TEDIT.\INSERT (OR C (SETQ C (TEXEC.GETKEY TEXOBJ)))
			      SEL \TERM.OFD)
	       (TEDIT.CARETLOOKS TEXOBJ (QUOTE (INVISIBLE OFF)))))
          (RETURN C)                       (* Return character inserted)
      )))

(TEXEC.DELETE
  (LAMBDA (TEXOBJ START END)               (* AJB "11-Sep-85 15:22")
                                           (* Deletes the chars in the textstream from START to END)
    (DECLARE (USEDFREE \TERM.OFD))
    (LET ((TSEL (create SELECTION
		   using (fetch SEL of TEXOBJ)
			 CH# ← START CHLIM ←(ADD1 END)
			 POINT ←(QUOTE LEFT)
			 DCH ←(ADD1 (IDIFFERENCE END START))
			 L1 ←(LIST NIL)
			 LN ←(LIST NIL))))
         (TEXTPROP TEXOBJ (QUOTE STARTINGEOF)
		   (IDIFFERENCE (TEXTPROP TEXOBJ (QUOTE STARTINGEOF))
				(ADD1 (IDIFFERENCE END START))))
         (\TEDIT.DELETE TSEL \TERM.OFD T))))

(TEXEC.\CHDEL1
  (LAMBDA (TEXOBJ)                         (* AJB "11-Sep-85 15:25")

          (* Delete the last character in the text stream, and return it, so we can decide what to do with it.)


    (DECLARE (USEDFREE \LINEBUF.OFD))
    (LET* ((SEL (fetch SEL of TEXOBJ))
	   (TEXTLEN (fetch TEXTLEN of TEXOBJ))
	   (CH (COND
		 ((SELECTQ (fetch POINT of SEL)
			   (LEFT (IDIFFERENCE (fetch CH# of SEL)
					      1))
			   (RIGHT (fetch CH# of SEL))
			   NIL)))))        (* CH = character position at current location of caret)
          (COND
	    ((NEQ CH (TEXTPROP TEXOBJ (QUOTE STARTINGEOF)))
                                           (* don't allow deletion of text if at beginning of current input)
	      (COND
		((ILEQ (SELECTQ (fetch POINT
				   of (fetch SEL of TEXOBJ))
				(LEFT (fetch CH#
					 of (fetch SEL of TEXOBJ)))
				(RIGHT (SUB1 (fetch CHLIM
						of (fetch SEL
						      of TEXOBJ))))
				NIL)
		       (TEXTPROP TEXOBJ (QUOTE STARTINGEOF)))
		  (TEXTPROP TEXOBJ (QUOTE STARTINGEOF)
			    (SUB1 (TEXTPROP TEXOBJ (QUOTE STARTINGEOF)))
			    )

          (* If deleting text prior to current input move the start of input up 1 to compensate)


		  ))
	      (COND
		((TEXEC.EOTP TEXOBJ))
		(T (replace (STREAM REVALIDATEFLG) of \LINEBUF.OFD
		      with T)

          (* Invalidate paren/bracket count since we are no longer at the end of the text)


		   ))
	      (PROG1 (PROGN (\SETUPGETCH CH TEXOBJ)
			    (\BIN (fetch STREAMHINT of TEXOBJ)))
		     (\TEDIT.CHARDELETE TEXOBJ ""
					(fetch SEL of TEXOBJ))))))))

(TEXEC.?EQUAL
  (LAMBDA (TEXOBJ)                         (* AJB "27-Sep-85 14:55")

          (* * Test for ?= and if so handle it and RETURN T else RETURN NIL)


    (DECLARE (USEDFREE #CURRENTRDTBL#))
    (PROG ((CH# 0)
	   CH FLG (TS (fetch STREAMHINT of TEXOBJ))
	   LST PTR FNAME TAIL TEMPFILE (STARTINGEOF
	     (TEXTPROP TEXOBJ (QUOTE STARTINGEOF))))
          (COND
	    ((AND (EQ (TEXEC.NTHBUFCHARBACK TEXOBJ 0)
		      (CHARCODE =))
		  (EQ (TEXEC.NTHBUFCHARBACK TEXOBJ 1)
		      (CHARCODE ?))
		  (FMEMB (TEXEC.NTHBUFCHARBACK TEXOBJ 2)
			 (CHCON (QUOTE % '%()
				(QUOTE %[))))
	      (TEXEC.FILLBUFFER.CHARDELETE TEXOBJ)
                                           (* Delete ?= from input stream)
	      (TEXEC.FILLBUFFER.CHARDELETE TEXOBJ)
	      (SETQ CH# (IMAX (OR (TEXEC.PARENMATCH TEXOBJ 
						    RIGHTBRACKET.RC)
				  0)
			      (OR (TEXEC.PARENMATCH TEXOBJ 
						    RIGHTPAREN.RC)
				  0)))
	      (COND
		((OR (ZEROP CH#)
		     (PROGN (\SETUPGETCH (ADD1 STARTINGEOF)
					 TEXOBJ)
			    (SETQ CH (\BIN TS))
			    (SETQ FLG (AND (NEQ CH (CHARCODE %())
					   (NEQ CH (CHARCODE %[))))))
		  (SETQ CH# (ADD1 STARTINGEOF))
                                           (* No left paren/bracket, start at beginning of input)
		  ))
	      (\SETUPGETCH CH# TEXOBJ)
	      (RESETLST (RESETSAVE NIL (LIST (FUNCTION CLOSEF)
					     TEMPFILE))
			(SETQ TEMPFILE (OPENSTREAM (QUOTE {NODIRCORE})
						   (QUOTE BOTH)
						   (QUOTE OLD/NEW)
						   NIL))
			(for I from CH# to (fetch TEXTLEN of TEXOBJ)
			   do (\BOUT TEMPFILE (\BIN TS)))
			(SETFILEPTR TEMPFILE 0)
			(AND CH (NOT FLG)
			     (READC TEMPFILE))
                                           (* Skip first left paren/bracket)
			(SETQ FNAME (READ TEMPFILE T T))
			(AND FLG CH (READC TEMPFILE))
                                           (* Skip first left paren/bracket)
			(SETQ TAIL (TCONC NIL FNAME))
			(NLSETQ (repeatuntil (EOFP TEMPFILE)
				   do (TCONC TAIL
					     (READ TEMPFILE T T))))
			(DO?= (LIST FNAME)
			      (CAR TAIL)
			      \TERM.OFD)
			(\OUTCHAR \TERM.OFD (CHARCODE EOL))
			(\OUTCHAR \TERM.OFD (CHARCODE EOL))
			(\TEDIT.MARK.LINES.DIRTY TEXOBJ STARTINGEOF
						 (fetch TEXTLEN
						    of TEXOBJ)))
	      (RETURN T))
	    (T (RETURN))))))

(TEXEC.?CR
  (LAMBDA (TEXOBJ)                         (* AJB "20-Sep-85 15:53")

          (* * Test for ? and if so handle it and RETURN T else RETURN NIL)


    (DECLARE (USEDFREE #CURRENTRDTBL#))
    (PROG ((CH# 0)
	   (TS (fetch STREAMHINT of TEXOBJ))
	   TEMPFILE
	   (STARTINGEOF (TEXTPROP TEXOBJ (QUOTE STARTINGEOF))))
          (COND
	    ((AND (EQ (TEXEC.NTHBUFCHARBACK TEXOBJ 0)
		      (CHARCODE ?))
		  (EQ (TEXEC.NTHBUFCHARBACK TEXOBJ 1)
		      (CHARCODE % )))
	      (TEXEC.FILLBUFFER.CHARDELETE TEXOBJ)
                                           (* Delete ? from input stream)
	      (SETQ CH# (IMAX (OR (TEXEC.PARENMATCH TEXOBJ 
						    RIGHTBRACKET.RC)
				  0)
			      (OR (TEXEC.PARENMATCH TEXOBJ 
						    RIGHTPAREN.RC)
				  0)))
	      (COND
		((ZEROP CH#)
		  (RETURN)                 (* No left paren/bracket, return NIL)
		  ))
	      (\SETUPGETCH CH# TEXOBJ)
	      (RESETLST (RESETSAVE NIL (LIST (FUNCTION CLOSEF)
					     TEMPFILE))
			(SETQ TEMPFILE (OPENSTREAM (QUOTE {NODIRCORE})
						   (QUOTE BOTH)
						   (QUOTE OLD/NEW)
						   NIL))
			(for I from CH# to (fetch TEXTLEN of TEXOBJ)
			   do (\BOUT TEMPFILE (\BIN TS)))
			(SETFILEPTR TEMPFILE 0)
			(READC TEMPFILE)   (* Skip first left paren/bracket)
			(HELPSYS (READ TEMPFILE T T)))
	      (RETURN T))
	    (T (RETURN))))))

(TEDIT.SCROLL?
  (LAMBDA (TEXOBJ)                         (* AJB " 1-Oct-85 14:18")

          (* * This function scrolls all of the windows if the caret is off-window in the selection window)


    (PROG ((SEL (fetch SEL of TEXOBJ))
	   SELINE)
          (for WIN inside (fetch \WINDOW of TEXOBJ) as L1
	     on (fetch L1 of SEL) as LN on (fetch LN of SEL)
	     do
	      (COND
		((AND (EQ WIN (fetch SELWINDOW of TEXOBJ))
		      (OR (NOT (SELECTQ (fetch POINT of SEL)
					(LEFT (CAR L1))
					(RIGHT (CAR LN))
					NIL))
			  (ILEQ (SELECTQ (fetch POINT of SEL)
					 (LEFT (fetch YBOT
						  of (CAR L1)))
					 (RIGHT (fetch YBOT
						   of (CAR LN)))
					 0)
				(fetch BOTTOM of (DSPCLIPPINGREGION
						   NIL WIN)))))

          (* The caret is off-window in the selection window. Need to scroll it up so the caret is visible.)


		  (while (OR (COND
			       ((SETQ SELINE
				   (SELECTQ (fetch POINT of SEL)
					    (LEFT (CAR L1))
					    (RIGHT (CAR LN))
					    NIL))
				 (ILESSP (fetch YBOT of SELINE)
					 (fetch WBOTTOM of TEXOBJ)))
			       (T (ILESSP (fetch Y0 of SEL)
					  (fetch WBOTTOM of TEXOBJ))))
			     (AND (IGEQ (fetch Y0 of SEL)
					(fetch WTOP of TEXOBJ))
				  (NULL SELINE)))
		     do                    (* The caret just went off-screen. Move it up some.)
		      (replace EDITOPACTIVE of TEXOBJ with NIL)
		      (SCROLLW
			WIN 0
			(LLSH (COND
				((SELECTQ (fetch POINT of SEL)
					  (LEFT (CAR L1))
					  (RIGHT (CAR LN))
					  NIL)
				  (fetch LHEIGHT
				     of (SELECTQ (fetch POINT
						    of SEL)
						 (LEFT (CAR L1))
						 (RIGHT (CAR LN))
						 (SHOULDNT))))
				(T 12))
			      1)))))))))

(TEXEC.DISPLAYTEXT
  (LAMBDA (TEXTOBJ CH FONT LINE XPOINT DS SEL)
                                           (* AJB " 1-Oct-85 11:31")

          (* This function does the actual displaying of typed-in text on the edit window.)


    (PROG ((TERMSA (fetch TXTTERMSA of TEXTOBJ))
	   DY)
          (DSPXPOSITION XPOINT DS)         (* Set the display stream X position)
          (COND
	    (TERMSA                        (* Special terminal table for controlling character display.
					   Use it.)
	      (COND
		((STRINGP CH)
		  (for CHAR instring CH
		     do (SELCHARQ CHAR
				  (TAB     (* Put down white)
				       (BITBLT NIL 0 0 DS XPOINT
					       (fetch YBOT
						  of LINE)
					       36
					       (fetch LHEIGHT
						  of LINE)
					       (QUOTE TEXTURE)
					       (QUOTE REPLACE)
					       WHITESHADE)
				       (RELMOVETO 36 0 DS))
				  (CR (BITBLT NIL 0 0 DS XPOINT
					      (fetch YBOT of LINE)
					      (IMAX 6 (CHARWIDTH CHAR 
							       FONT))
					      (fetch LHEIGHT
						 of LINE)
					      (QUOTE TEXTURE)
					      (QUOTE REPLACE)
					      WHITESHADE))
				  (\DSPPRINTCHAR DS CHAR))))
		(T (SELCHARQ CH
			     (TAB          (* Put down white)
				  (BITBLT NIL 0 0 DS XPOINT
					  (fetch YBOT of LINE)
					  36
					  (fetch LHEIGHT of LINE)
					  (QUOTE TEXTURE)
					  (QUOTE REPLACE)
					  WHITESHADE)
				  (RELMOVETO 36 0 DS))
			     (CR (BITBLT NIL 0 0 DS XPOINT
					 (fetch YBOT of LINE)
					 (IMAX 6 (CHARWIDTH CH FONT))
					 (fetch LHEIGHT of LINE)
					 (QUOTE TEXTURE)
					 (QUOTE REPLACE)
					 WHITESHADE))
			     (\DSPPRINTCHAR DS CH)))))
	    (T                             (* No special handling; just use native character codes)
	       (COND
		 ((STRINGP CH)
		   (for CHAR instring CH
		      do (SELCHARQ CHAR
				   (TAB    (* Put down white)
					(BITBLT NIL 0 0 DS
						(DSPXPOSITION NIL DS)
						(fetch YBOT
						   of LINE)
						36
						(fetch LHEIGHT
						   of LINE)
						(QUOTE TEXTURE)
						(QUOTE REPLACE)
						WHITESHADE)
					(RELMOVETO 36 0 DS))
				   (CR (BITBLT NIL 0 0 DS
					       (DSPXPOSITION NIL DS)
					       (fetch YBOT
						  of LINE)
					       (IMAX 6
						     (CHARWIDTH CHAR 
							       FONT))
					       (fetch LHEIGHT
						  of LINE)
					       (QUOTE TEXTURE)
					       (QUOTE REPLACE)
					       WHITESHADE))
				   (BLTCHAR CHAR DS))))
		 (T (SELCHARQ CH
			      (TAB         (* Put down white)
				   (BITBLT NIL 0 0 DS (DSPXPOSITION
					     NIL DS)
					   (fetch YBOT of LINE)
					   36
					   (fetch LHEIGHT of LINE)
					   (QUOTE TEXTURE)
					   (QUOTE REPLACE)
					   WHITESHADE)
				   (RELMOVETO 36 0 DS))
			      (CR          (* Blank out the CR's width.)
				  (BITBLT NIL 0 0 DS (DSPXPOSITION
					    NIL DS)
					  (fetch YBOT of LINE)
					  (IMAX 6 (CHARWIDTH CH FONT))
					  (fetch LHEIGHT of LINE)
					  (QUOTE TEXTURE)
					  (QUOTE REPLACE)
					  WHITESHADE))
			      (BLTCHAR CH DS)))))))))

(\TEXEC.TEXTBOUT
  (LAMBDA (STREAM BYTE)                    (* AJB "25-Sep-85 09:18")

          (* * Do BOUT to a text stream, which is an insertion at the end of text pointer)


    (UNINTERRUPTABLY
        (PROG ((TEXOBJ (fetch (TEXTSTREAM TEXTOBJ) of STREAM))
	       CH# WINDOW TEXTLEN SEL STARTINGEOF)
	      (SETQ STARTINGEOF (ADD1 (TEXTPROP TEXOBJ (QUOTE 
							STARTINGEOF))))

          (* Insertion point for output -
	  is actually the beginning of the next/current text being entered to return to READ)


	      (TEXTPROP TEXOBJ (QUOTE STARTINGEOF)
			STARTINGEOF)       (* This adds 1 to the previous value on the property list)
	      (SETQ TEXTLEN (fetch TEXTLEN of TEXOBJ))
                                           (* The length of the total text in chars)
	      (SETQ WINDOW (fetch \WINDOW of TEXOBJ))
	      (SETQ SEL (fetch SEL of TEXOBJ))
                                           (* The current selection)

          (* COND ((NOT (LDIFFERENCE (fetch L1 of SEL) (QUOTE (NIL)))) (RETURN)))



          (* Return if caret out of bounds, ie, user scrolls past end of text)


	      (SETQ CH# (OR STARTINGEOF (fetch CH# of SEL)))
	      (AND WINDOW
		   (for L1 in (fetch L1 of SEL) as LN
		      in (fetch LN of SEL)
		      do                   (* Mark changed lines as DIRTY.)
			 (COND
			   (L1 (replace DIRTY of L1 with T))
			   (LN (replace DIRTY of LN with T)))))
	      (\INSERTCH BYTE CH# TEXOBJ)
	      (replace TXTNEEDSUPDATE of TEXOBJ with T)
	      (AND WINDOW (\TEXEC.TEXTBOUT1 TEXOBJ STREAM BYTE CH# SEL))
	  ))))

(\TEXEC.TEXTBOUT1
  (LAMBDA (TEXOBJ STREAM BYTE CH# SEL)     (* AJB "26-Sep-85 15:39")
    (PROG ((THISLINE (fetch THISLINE of TEXOBJ))
	   PS PC OFFST)

          (* * Update stream CHARPOSITION for calls to POSITION ie, GAINSPACE)


          (add (fetch CH# of SEL)
	       1)                          (* These must be here, since SELs are valid even without a window.)
          (replace CHLIM of SEL with (fetch CH# of SEL))
          (replace POINT of SEL with (QUOTE LEFT))
          (replace DCH of SEL with 0)
          (replace SELKIND of SEL with (QUOTE CHAR))
          (for CARET inside (fetch CARET of TEXOBJ)
	     do (\EDIT.UPCARET CARET))
          (\TEXEC.TEXTBOUT2 TEXOBJ STREAM BYTE CH# SEL)
          (replace ONFLG of SEL with T)
          (replace DESC of THISLINE with NIL)

          (* SO that this line of text is run thru the formatter again before anything interesting that depends on it being 
	  right (like scrolling the window))



          (* * Fix up the TEXTSTREAM so that the FILEPTR looks like it ought to after the BOUT, even though we've been 
	  updating the screen (which usually moves the fileptr....))


          (SETQ PS (ffetch PSTR of (SETQ PC (fetch \INSERTPC
					       of TEXOBJ))))
                                           (* This piece resides in a STRING. Because it's newly "typed" material.)
          (replace (TEXTSTREAM PIECE) of STREAM with PC)
                                           (* Remember the current piece for others.)
          (replace (TEXTSTREAM PCNO) of STREAM
	     with (fetch \INSERTPCNO of TEXOBJ))
                                           (* And which number piece this is.)
          (freplace CPPTR of STREAM
	     with (ADDBASE (ffetch (STRINGP BASE) of PS)
			   (LRSH (SETQ OFFST (ffetch (STRINGP OFFST)
						of PS))
				 1)))      (* Pointer to the actual characters in the string 
					   (allowing for substrings.))
          (freplace CPAGE of STREAM with 0)
          (freplace COFFSET of STREAM
	     with (IPLUS (freplace (TEXTSTREAM PCSTARTCH) of STREAM
			    with (LOGAND 1 OFFST))
			 (fetch \INSERTLEN of TEXOBJ)))
          (freplace (TEXTSTREAM PCSTARTPG) of STREAM with 0)
                                           (* Page # within the "file" where this piece starts)
          (freplace CBUFSIZE of STREAM with (fetch COFFSET
					       of STREAM))
          (freplace EPAGE of STREAM with 1)
          (freplace (TEXTSTREAM CHARSLEFT) of STREAM with 0)
                                           (* We're, perforce, at the end of the piece.)
          (freplace (TEXTSTREAM REALFILE) of STREAM with NIL)
                                           (* We're not on a file....)
      )))

(\TEXEC.TEXTBOUT2
  (LAMBDA (TEXOBJ STREAM BYTE CH# SEL)     (* AJB " 1-Oct-85 15:48")
    (PROG (YFLG)
          (for WIN in (fetch \WINDOW of TEXOBJ) as L1
	     on (fetch L1 of SEL) as LN on (fetch LN of SEL)
	     do (COND
		  ((CAR L1)
		    (add (fetch CHARLIM of (CAR L1))
			 1)
		    (add (fetch CHARTOP of (CAR L1))
			 1)
		    (COND
		      ((EQ WIN (fetch SELWINDOW of TEXOBJ))
			(SETQ YFLG (ILESSP (fetch YBASE
					      of (CAR L1))
					   0)))))))
          (COND
	    ((OR (IGREATERP (PLUS (fetch X0 of SEL)
				  (CHARWIDTH BYTE
					     (fetch CLFONT
						of (fetch CARETLOOKS
						      of TEXOBJ))))
			    (IDIFFERENCE (fetch WRIGHT of TEXOBJ)
					 16))
		 (IEQP BYTE (CHARCODE EOL))
		 (IEQP BYTE (CHARCODE CR))
		 (ILESSP CH# (fetch TEXTLEN of TEXOBJ))
		 YFLG)

          (* gone off the edge of the line, Or not at end of text reformat and add new line)


	      (\TEXEC.TEXTBOUT3 TEXOBJ STREAM BYTE CH# SEL))
	    (T                             (* Display text on same line without updating entire screen)
	       (\TEXEC.TEXTBOUT4 TEXOBJ STREAM BYTE CH# SEL))))))

(\TEXEC.TEXTBOUT3
  (LAMBDA (TEXOBJ STREAM BYTE CH# SEL)     (* AJB " 1-Oct-85 12:07")

          (* * Updates the screen if necessary and checks for exceeding bufferlimit size)


    (PROG (OCHLIM)
          (COND
	    ((IGEQ CH# (fetch TEXTLEN of TEXOBJ))
	      (\SHOWSEL SEL NIL NIL)
	      (TEDIT.UPDATE.SCREEN TEXOBJ)
                                           (* Only update screen if at end of text)
	      (\FIXSEL SEL TEXOBJ NIL)
	      (TEDIT.SCROLL? TEXOBJ)
	      (\SHOWSEL SEL NIL T)
	      (COND
		((IGREATERP (SETQ OCHLIM (IDIFFERENCE (GETEOFPTR 
							  \TERM.OFD)
						      TEXEC.BUFFERLIMIT)
			      )
			    0)
		  (replace \INSERTPCVALID of TEXOBJ with NIL)
		  (TEXEC.DELETE TEXOBJ 1 (IMAX OCHLIM (LRSH 
						  TEXEC.BUFFERLIMIT 3)))

          (* Remove the top 1/8 or at least the number of chars exceeding TEXEC.BUFFERLIMIT)


		  (\FIXSEL SEL TEXOBJ))))))))

(\TEXEC.TEXTBOUT4
  (LAMBDA (TEXOBJ STREAM BYTE CH# SEL)     (* AJB " 1-Oct-85 14:51")

          (* * Display character on same line with no reformatting screen)


    (COND
      ((IGEQ CH# (fetch TEXTLEN of TEXOBJ))

          (* Don't display character unless the output is at the end, \TEXEC.GETKEY will update the screen when the next input
	  is called for.)


	(for WIN in (fetch \WINDOW of TEXOBJ) as L1
	   on (fetch L1 of SEL) as LN on (fetch LN of SEL)
	   do (COND
		((AND (CAR L1)
		      (IGEQ (fetch YBASE of (CAR L1))
			    0))
		  (TEXEC.DISPLAYTEXT TEXOBJ BYTE
				     (fetch CLFONT
					of (fetch CARETLOOKS
					      of TEXOBJ))
				     (CAR L1)
				     (DSPXPOSITION NIL WIN)
				     (WINDOWPROP WIN (QUOTE DSP))
				     SEL)
                                           (* Print out the character on the screen)
		  (replace X0 of SEL with (DSPXPOSITION NIL WIN))
		  (replace XLIM of SEL with (DSPXPOSITION NIL WIN)))))))
    ))

(\TEXEC.SELFN
  (LAMBDA (TEXOBJ SEL SELMODE CONTROL)     (* AJB " 1-Oct-85 16:06")
    (PROG NIL
          (COND
	    ((AND (FMEMB SELMODE (QUOTE (NORMAL PENDINGDEL MOVE DELETE))
			 )
		  (ILESSP (SELECTQ (fetch POINT of SEL)
				   (LEFT (fetch CH# of SEL))
				   (RIGHT (fetch CHLIM of SEL))
				   NIL)
			  (ADD1 (TEXTPROP TEXOBJ (QUOTE STARTINGEOF)))))
	      (RETURN (QUOTE DON'T))       (* Don't allow selection if selecting text prior to current input)
	      )
	    (T (RETURN T)))                (* else return T)
      )))
)



(* Code to support a TEXEC lisp "listener")

(DEFINEQ

(TEXEC
  (LAMBDA (region Prompt)                  (* AJB "30-Sep-85 16:10")
                                           (* Create an Interlisp executive window with TEdit as the editor behind 
					   it.)
    (PROG (handle window teditstream)
          (SETQ window (CREATEW region "TEXEC (Version 13.2)"))
                                           (* Create a window for the TEdit-based listener)
          (SETQ teditstream (TEXEC.OPENTEXTSTREAM window (QUOTE NULL)))

          (* Create a TEdit stream for the TEXEC and fill in our non-standard fields)


          (SETQ handle
	    (ADD.PROCESS
	      (BQUOTE (PROGN (TTYDISPLAYSTREAM (QUOTE , teditstream))
			     (EVALQT (QUOTE , (OR Prompt (QUOTE #))))))
	      (QUOTE NAME)
	      (QUOTE TEXEC)
	      (QUOTE RESTARTABLE)
	      T))                          (* Create the listener process)
          (WINDOWPROP window (QUOTE TITLE)
		      (PROCESSPROP handle (QUOTE NAME)))
          (WINDOWADDPROP
	    window
	    (QUOTE CLOSEFN)
	    (FUNCTION (LAMBDA (window)
		(PROG ((proc (WINDOWPROP window (QUOTE PROCESS))))
		      (RETURN (COND
				((EQ (THIS.PROCESS)
				     proc)
				  (ADD.PROCESS (LIST (QUOTE CLOSEW)
						     (KWOTE window)))
				  (QUOTE DON'T))
				((PROCESSP proc)
				  (DEL.PROCESS proc)
				  NIL)))))))
          (TTY.PROCESS handle))))

(TTEXEC
  (LAMBDA NIL                              (* AJB "13-Sep-85 15:20")

          (* * This function replaces the Top Level Interlisp-D Executive with TEXEC, but only if this function is being run 
	  from the Top Level Exec window.)


    (COND
      ((EQ \TopLevelTtyWindow (fetch PROCWINDOW of (THIS.PROCESS)))
	(SETREADFN (QUOTE READ))
	(TTYDISPLAYSTREAM (TEXEC.OPENTEXTSTREAM \TopLevelTtyWindow
						(QUOTE NULL)))
	(WHENCLOSE \TERM.OFD (QUOTE BEFORE)
		   (QUOTE DON'T))
	(WINDOWPROP \TopLevelTtyWindow (QUOTE CLOSEFN)
		    NIL)
	(CLOSEATTACHEDWINDOWS \TopLevelTtyWindow)
	(SETREADFN (QUOTE TTYINREAD)))
      (T (PROMPTPRINT 
	"To switch EXEC to TEXEC, load TEXEC.DCOM from EXEC window")))))
)

(APPENDTOVAR BackgroundMenuCommands (TEXEC (QUOTE (TEXEC))
					   
				    "Starts TEXEC in a new window."))

(RPAQQ BackgroundMenu NIL)

(RPAQ? TEXEC.BUFFERLIMIT 10000)
(FILESLOAD TEDITCHAT)
(PUTPROPS TEXEC COPYRIGHT ("Xerox Corporation" 1985 1900))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (1470 55941 (TEXEC.OPENTEXTSTREAM 1480 . 2908) (
TEXEC.FILLBUFFER 2910 . 11389) (TEXEC.FILLBUFFER.TCLASS 11391 . 15436) (
TEXEC.FILLBUFFER.CHSELPENDING 15438 . 19677) (
TEXEC.FILLBUFFER.CHARDELETE 19679 . 21126) (TEXEC.FILLBUFFER.WORDDELETE 
21128 . 23470) (TEXEC.PARENCOUNT 23472 . 24443) (TEXEC.PARENMATCH 24445
 . 25703) (TEXEC.FLASHCARET 25705 . 27288) (TEXEC.TEXTSTREAM.TO.LINEBUF 
27290 . 28582) (TEXEC.FIX? 28584 . 31462) (TEXEC.NTHBUFCHARBACK 31464 . 
32172) (TEXEC.NTHBACKCHNUM 32174 . 32651) (TEXEC.EOTP 32653 . 33089) (
TEXEC.GETKEY 33091 . 34356) (TEXEC.INSERTCHAR 34358 . 36022) (
TEXEC.DELETE 36024 . 36664) (TEXEC.\CHDEL1 36666 . 38370) (TEXEC.?EQUAL 
38372 . 40739) (TEXEC.?CR 40741 . 42143) (TEDIT.SCROLL? 42145 . 44037) (
TEXEC.DISPLAYTEXT 44039 . 47214) (\TEXEC.TEXTBOUT 47216 . 48998) (
\TEXEC.TEXTBOUT1 49000 . 52073) (\TEXEC.TEXTBOUT2 52075 . 53329) (
\TEXEC.TEXTBOUT3 53331 . 54267) (\TEXEC.TEXTBOUT4 54269 . 55362) (
\TEXEC.SELFN 55364 . 55939)) (55994 58260 (TEXEC 56004 . 57522) (TTEXEC 
57524 . 58258)))))
STOP