(FILECREATED "10-Feb-86 12:12:49" {ERIS}<TEDIT>TEDIT.;28 96219  

      changes to:  (FNS PLCHAIN PRINTLINE SEEFILE)

      previous date: " 9-Feb-86 15:50:48" {ERIS}<TEDIT>TEDIT.;27)


(* Copyright (c) 1983, 1984, 1985, 1986 by John Sybalsky & Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT TEDITCOMS)

(RPAQQ TEDITCOMS 
       [(FILES TEXTOFD TEDITCOMMAND TEDITSCREEN TEDITABBREV TEDITLOOKS)
        (CONSTANTS (\SCRATCHLEN 64))
        [VARS (TEDIT.TERMSA.FONTS NIL)
              (TEDIT.TENTATIVE NIL)
              (TEDIT.DEFAULT.PROPS NIL)
              (TEDIT.STARTUP.MONITORLOCK (CREATE.MONITORLOCK (QUOTE TEDIT.STARTUP)))
              (TEDIT.RESTART.MENU (CREATE MENU ITEMS ← (QUOTE (NewEditProcess]
        (GLOBALVARS TEDIT.TENTATIVE TEDIT.DEFAULT.PROPS)
        (FNS \TEDIT2 COERCETEXTOBJ TEDIT TEDIT.CHARWIDTH TEDIT.COPY TEDIT.DELETE 
             TEDIT.DO.BLUEPENDINGDELETE TEDIT.INSERT TEDIT.KILL TEDIT.MAPLINES TEDIT.MAPPIECES 
             TEDIT.MOVE TEDIT.QUIT TEDIT.STRINGWIDTH TEDIT.\INSERT TEXTOBJ TEXTSTREAM \TEDIT.INCLUDE 
             \TEDIT.INSERT.PIECES \TEDIT.MOVE.PIECEMAPFN \TEDIT.OBJECT.SHOWSEL \TEDIT.RESTARTFN 
             \TEDIT.CHARDELETE \TEDIT.COPY.PIECEMAPFN \TEDIT.DELETE \TEDIT.DIFFUSE.PARALOOKS 
             \TEDIT.FOREIGN.COPY? \TEDIT.QUIT \TEDIT.WORDDELETE \TEDIT1)
        (COMS (* Debugging functions)
              (FNS PLCHAIN PRINTLINE SEEFILE))
        (COMS (* Object-oriented editing)
              (FNS TEDIT.INSERT.OBJECT TEDIT.EDIT.OBJECT TEDIT.FIND.OBJECT TEDIT.PUT.OBJECT 
                   TEDIT.GET.OBJECT TEDIT.OBJECT.CHANGED))
        (FILES TEDITFIND TEDITHISTORY TEDITFILE TEDITWINDOW TEDITSELECTION IMAGEOBJ TFBRAVO TEDITHCPY 
               TEDITMENU TEDITFNKEYS)
        (COMS (* TEDIT Support information)
              (E (SETQ TEDITSYSTEMDATE (DATE)))
              (VARS TEDITSYSTEMDATE (TEDITSUPPORT "TEditSupport.PA"))
              (FNS MAKETEDITFORM)
              (P (ADDTOVAR LAFITESPECIALFORMS ("TEdit Report" (QUOTE MAKETEDITFORM)
                                                     "Report a problem with TEdit"))
                 (SETQ LAFITEFORMSMENU NIL)))
        (COMS (* LISTFILES Interface, so the system can decide if a file is a TEdit file.)
              (ADDVARS (PRINTFILETYPES (TEDIT (TEST \TEDIT.FORMATTEDP1)
                                              (EXTENSION (TEDIT])
(FILESLOAD TEXTOFD TEDITCOMMAND TEDITSCREEN TEDITABBREV TEDITLOOKS)
(DECLARE: EVAL@COMPILE 

(RPAQQ \SCRATCHLEN 64)

(CONSTANTS (\SCRATCHLEN 64))
)

(RPAQQ TEDIT.TERMSA.FONTS NIL)

(RPAQQ TEDIT.TENTATIVE NIL)

(RPAQQ TEDIT.DEFAULT.PROPS NIL)

(RPAQ TEDIT.STARTUP.MONITORLOCK (CREATE.MONITORLOCK (QUOTE TEDIT.STARTUP)))

(RPAQ TEDIT.RESTART.MENU (CREATE MENU ITEMS ← (QUOTE (NewEditProcess))))
(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS TEDIT.TENTATIVE TEDIT.DEFAULT.PROPS)
)
(DEFINEQ

(\TEDIT2
  [LAMBDA (TEXT WINDOW UNSPAWNED)                            (* jds "13-Jun-85 11:42")
                                                             (* Does the actual editing work, once TEDIT has 
							     OPENTEXTSTREAMed the thing to be edited.)
    (\TEDIT.COMMAND.LOOP (fetch (TEXTSTREAM TEXTOBJ) of TEXT))
                                                             (* Run the editing engine)
    (CLOSEW WINDOW)                                          (* Close the edit window)
    (\TEXTCLOSEF TEXT)                                       (* Close the underlying files)
    (replace ACCESSBITS of TEXT with BothBits)               (* But leave the stream itself accessible)
    (AND (TEXTPROP (fetch (TEXTSTREAM TEXTOBJ) of TEXT)
		   (QUOTE AFTERQUITFN))
	 (APPLY* (TEXTPROP (fetch (TEXTSTREAM TEXTOBJ) of TEXT)
			   (QUOTE AFTERQUITFN))
		 WINDOW TEXT))                               (* Apply any post-window-close 
							     (and post-QUIT) function)
    (COND
      (UNSPAWNED                                             (* We're not a distinct process: Send back the edited 
							     text in some suitable form)
		 (COND
		   ((NEQ (fetch EDITFINISHEDFLG of (fetch (TEXTSTREAM TEXTOBJ) of TEXT))
			 T)
		     (PROG1 (fetch EDITFINISHEDFLG of (fetch (TEXTSTREAM TEXTOBJ) of TEXT))
			    (replace EDITFINISHEDFLG of (fetch (TEXTSTREAM TEXTOBJ) of TEXT)
			       with NIL)))
		   ((STRINGP (fetch TXTFILE of (fetch (TEXTSTREAM TEXTOBJ) of TEXT)))
		     (COERCETEXTOBJ (fetch (TEXTSTREAM TEXTOBJ) of TEXT)
				    (QUOTE STRINGP)))
		   (T TEXT])

(COERCETEXTOBJ
  [LAMBDA (STREAM TYPE OUTPUTSTREAM)                         (* jds "12-Mar-85 03:37")
                                                             (* Coerce the contents of the TEXOTBJ to be of the 
							     given type. This is for making a string from a textobj,
							     e.g.)
    (PROG ((TEXTOBJ (COND
		      ((type? STREAM STREAM)
			(fetch (TEXTSTREAM TEXTOBJ) of STREAM))
		      (T STREAM)))
	   OFILE FMTFILE)
          (OR (type? TEXTOBJ TEXTOBJ)
	      (\ILLEGAL.ARG TEXTOBJ))                        (* If we haven't got a TEXTOBJ, something is wrong.)
          (RETURN (SELECTQ TYPE
			   [(STRINGP STRING)
			     (AND (ILEQ (fetch TEXTLEN of TEXTOBJ)
					65535)
				  (PROG ((STR (ALLOCSTRING (fetch TEXTLEN of TEXTOBJ)))
					 PC
					 (CH# 1)
					 (PCTB (fetch PCTB of TEXTOBJ))
					 (DELTA 0)
					 PFILE)
				        [for I from (ADD1 \FirstPieceOffset)
					   to (IDIFFERENCE (\EDITELT PCTB \PCTBLastPieceOffset)
							   2)
					   by \EltsPerPiece
					   do (SETQ PC (\EDITELT PCTB I))
					      (COND
						((ATOM PC)   (* It's the lastpiece atom -- do nothing.)
						  )
						((fetch CLINVISIBLE of (fetch PLOOKS of PC))
                                                             (* If the characters are invisible, do nothing.
							     HOWEVER, we have to shrink the final string to account 
							     for the characters we ignored.)
						  (add DELTA (fetch PLEN of PC)))
						((fetch PSTR of PC)
						  [OR (ZEROP (fetch PLEN of PC))
						      (RPLSTRING STR CH#
								 (SUBSTRING (fetch PSTR of PC)
									    1
									    (fetch PLEN of PC]
						  (add CH# (fetch PLEN of PC)))
						((SETQ PFILE (fetch PFILE of PC))
						  [COND
						    ((NOT (OPENP PFILE))
						      (SETQ PFILE (\TEDIT.REOPEN.STREAM STREAM PFILE]
						  (SETFILEPTR PFILE (fetch PFPOS of PC))
						  (for C from CH# as I from 1
						     to (fetch PLEN of PC)
						     do (RPLCHARCODE STR C (BIN PFILE)))
						  (add CH# (fetch PLEN of PC)))
						((fetch POBJ of PC)
                                                             (* DO NOTHING FOR OBJECTS)
						  (add CH# (fetch PLEN of PC))
						  (add DELTA (fetch PLEN of PC)))
						(T (ERROR "CANNOT GET TEXT FROM A 'PIECE.'" PC]
				        [COND
					  ((ZEROP DELTA)     (* No change in the length; do nothing.)
					    )
					  (T                 (* The string got shortened to account for invisible 
							     chars. Chop it off)
					     (SETQ STR (SUBSTRING STR 1 (IDIFFERENCE (fetch TEXTLEN
											of TEXTOBJ)
										     DELTA]
				        (RETURN STR]
			   (STREAM (COND
				     ((type? STREAM (fetch TXTFILE of TEXTOBJ))
				       (OPENFILE (fetch FULLNAME of (fetch TXTFILE of TEXTOBJ))
						 (QUOTE INPUT))
				       (replace ACCESSBITS of (fetch TXTFILE of TEXTOBJ)
					  with ReadBit)))
				   (\SETUPGETCH 1 TEXTOBJ)
				   STREAM)
			   (FILE [SETQ OFILE (OR (AND OUTPUTSTREAM (OPENP OUTPUTSTREAM (QUOTE OUTPUT))
						      )
						 (OPENSTREAM (QUOTE {NODIRCORE})
							     (QUOTE BOTH)
							     (QUOTE NEW]
				 (TEDIT.PUT.PCTB TEXTOBJ OFILE)
				 (OR OUTPUTSTREAM (CLOSEF OFILE))
				 OFILE)
			   (SPLIT                            (* I.e., Return 2 files, one with plain text, one with 
							     formatting info, such that concatenating them will do 
							     the right thing.)
				  (SETQ OFILE (OPENFILE (QUOTE {NODIRCORE})
							(QUOTE BOTH)
							(QUOTE NEW)))
				  (SETQ FMTFILE (CAR (TEDIT.PUT.PCTB TEXTOBJ (\GETSTREAM
								       OFILE
								       (QUOTE BOTH))
								     NIL T)))
				  (CLOSEF OFILE)
				  (CONS OFILE FMTFILE))
			   NIL])

(TEDIT
  [LAMBDA (TEXT WINDOW DONTSPAWN PROPS)                      (* jds "31-Jul-85 16:35")
                                                             (* User entry to the text editor.
							     Takes an optional window to be used for editing)
                                                             (* DONTSPAWN => Don't try to create a new process for 
							     this edit.)
    (PROG (PROC TEDITCREATEDWINDOW)                          (* Inlcude the default properties in the list.)
          [COND
	    ((AND TEXT (ATOM TEXT))                          (* Make sure the file exists before trying to open the 
							     window.)
	      (SETQ TEXT (OPENFILE TEXT (QUOTE INPUT)
				   (QUOTE OLD]
          (RESETLST [RESETSAVE NIL (BQUOTE (AND (\, WINDOW)
						(WINDOWPROP (\, WINDOW)
							    (QUOTE TEXTOBJ)
							    NIL]
		    (WITH.MONITOR TEDIT.STARTUP.MONITORLOCK
				  (COND
				    ((NOT WINDOW)
				      (SETQ TEDITCREATEDWINDOW T)
				      (SETQ WINDOW (COND
					  [(OR (NOT TEDIT.DEFAULT.WINDOW)
					       (\TEDIT.ACTIVE.WINDOWP TEDIT.DEFAULT.WINDOW))
					    (TEDIT.CREATEW (COND
							     ((AND TEXT (ATOM TEXT))
							       (CONCAT 
							  "Please specify an editing window for "
								       TEXT))
							     (T 
						"Please specify a region for the editing window."))
							   TEXT
							   (APPEND PROPS (COPY TEDIT.DEFAULT.PROPS]
					  (T (\TEDIT.CREATEW.FROM.REGION (WINDOWPROP 
									     TEDIT.DEFAULT.WINDOW
										     (QUOTE REGION))
									 TEXT
									 (APPEND PROPS (COPY 
									      TEDIT.DEFAULT.PROPS)))
                                                             (* Replace the old title)
					     TEDIT.DEFAULT.WINDOW)))
				      (WINDOWPROP WINDOW (QUOTE TEXTOBJ)
						  T)         (* Mark the newly-created window reserved until the 
							     OPENTEXTSTREAM has done its work.)
				      ))                     (* mark that we created the window so that we know we 
							     can update the title, etc.)
				  ))
          (SETQ TEXT (OPENTEXTSTREAM TEXT WINDOW NIL NIL PROPS))
                                                             (* Connect the editor to the window)
          [COND
	    (TEDITCREATEDWINDOW (TEXTPROP TEXT (QUOTE TEDITCREATEDWINDOW)
					  (QUOTE T]
          (COND
	    (DONTSPAWN                                       (* Either no processes running, or specifically not to 
							     spawn one.)
		       (RETURN (\TEDIT2 TEXT WINDOW T)))
	    (T                                               (* Spawn a process to do the edit.)
	       [SETQ PROC (ADD.PROCESS (LIST (QUOTE \TEDIT2)
					     (KWOTE TEXT)
					     WINDOW NIL)
				       (QUOTE NAME)
				       (QUOTE TEdit)
				       (QUOTE RESTARTABLE)
				       (QUOTE HARDRESET)
				       (QUOTE RESTARTFORM)
				       (LIST (QUOTE \TEDIT.RESTARTFN)
					     (KWOTE TEXT)
					     WINDOW
					     (KWOTE PROPS]
	       (PROCESSPROP PROC (QUOTE WINDOW)
			    WINDOW)
	       (COND
		 ((NOT (LISTGET (APPEND PROPS (COPY TEDIT.DEFAULT.PROPS))
				(QUOTE LEAVETTY)))           (* Unless he asked us to leave the tty where it is, 
							     TEdit should get it.)
		   (TTY.PROCESS PROC)))
	       (RETURN PROC])

(TEDIT.CHARWIDTH
  [LAMBDA (CH FONT TERMSA)                                   (* jds "22-OCT-83 19:32")
                                                             (* Returns the width of CH in FONT printed according to
							     any special printing instructions in CHARTABLE TERMSA)
    (COND
      (TERMSA                                                (* There IS a TERMTABLE to account for)
	      (SELECTC (fetch CCECHO of (\SYNCODE TERMSA CH))
		       (INDICATE.CCE (IPLUS (COND
					      ((IGREATERP CH 127)
                                                             (* META character)
						(SETQ CH (LOGAND CH 127))
						(CHARWIDTH (CHARCODE #)
							   FONT))
					      (T 0))
					    (COND
					      ((ILESSP CH 32)
                                                             (* CONTROL character)
						(SETQ CH (LOGOR CH 64))
						(CHARWIDTH (CHARCODE ↑)
							   FONT))
					      (T 0))
					    (CHARWIDTH CH FONT)))
		       (SIMULATE.CCE (SELCHARQ CH
					       ((EOL CR LF)
						 (IMAX 6 (CHARWIDTH CH FONT)))
					       (ESCAPE (CHARWIDTH (CHARCODE $)
								  FONT))
					       (BELL 0)
					       (TAB 36)
					       (CHARWIDTH CH FONT)))
		       (REAL.CCE (CHARWIDTH CH FONT))
		       (IGNORE.CCE 0)
		       (SHOULDNT)))
      (T                                                     (* The usual case is to treat every character as a 
							     graphic.)
	 (SELCHARQ CH
		   (CR (IMAX 6 (CHARWIDTH CH FONT)))
		   (TAB 36)
		   (CHARWIDTH CH FONT])

(TEDIT.COPY
  [LAMBDA (FROM TO)                                          (* jds "30-Aug-85 13:49")
    (SETQ TEDIT.COPY.PENDING NIL)                            (* First, Turn off the global flag that got us here.)
    (COND
      ((NOT (AND FROM (fetch SET of FROM)))                  (* There MUST be a source selected first.)
	(TEDIT.PROMPTPRINT (fetch \TEXTOBJ of TO)
			   "Copy source selection hasn't been set yet." T))
      ((ZEROP (fetch DCH of FROM))                           (* The source is empty. Just turn off the selection 
							     hilite and ignore the request.)
	(\SHOWSEL FROM NIL NIL))
      (T (\SHOWSEL FROM NIL NIL)                             (* Before all else, make sure the copy source selection
							     is turned off)
	 (replace SET of FROM with NIL)
	 (COND
	   ((AND TO (fetch SET of TO))                       (* Can only do copy if there's a target selection)
	     (PROG ((TOOBJ (fetch \TEXTOBJ of TO))
		    (FROMOBJ (fetch \TEXTOBJ of FROM))
		    (CROSSCOPY (NEQ (fetch \TEXTOBJ of FROM)
				    (fetch \TEXTOBJ of TO)))
		    TOLEN LEN INSPC INSPC# PC NPC PCCH NPCCH OPLEN EVENT REPLACING INSERTCH# PCLST 
		    OBJ COPYFN UNDOCHAIN)
	           (SETQ PCLST (TEDIT.SELECTED.PIECES FROMOBJ FROM CROSSCOPY (FUNCTION 
							\TEDIT.COPY.PIECEMAPFN)
						      FROMOBJ TOOBJ))
                                                             (* Get the list of pieces to be copied)
	           (SETQ REPLACING (TEDIT.DO.BLUEPENDINGDELETE TO TOOBJ))
                                                             (* Do any blue-pending-delete)
	           (SETQ TOLEN (fetch TEXTLEN of TOOBJ))
	           (\SHOWSEL TO NIL NIL)                     (* NOW turn off the target selection.)
	           [COND
		     ((EQ (fetch POINT of TO)
			  (QUOTE LEFT))
		       (SETQ INSERTCH# (fetch CH# of TO)))
		     (T (SETQ INSERTCH# (IMIN (fetch CHLIM of TO)
					      (ADD1 TOLEN]   (* Figure out where to do the insertion.)
	           (COND
		     ((AND (fetch FORMATTEDP of FROMOBJ)
			   (NOT (fetch FORMATTEDP of TOOBJ)))
                                                             (* The source is formatted and the target isn't.
							     Give the guy a choice.)
                                                             (* For now, convert the target file to formatted.)
		       (\TEDIT.CONVERT.TO.FORMATTED TOOBJ)))
	           (SETQ UNDOCHAIN (\TEDIT.INSERT.PIECES TOOBJ INSERTCH# PCLST
							 (SETQ LEN (IDIFFERENCE (fetch CHLIM
										   of FROM)
										(fetch CH#
										   of FROM)))
							 NIL NIL CROSSCOPY))
	           (SETQ EVENT (fetch TXTHISTORY of TOOBJ))
	           (\TEDIT.HISTORYADD TOOBJ (create TEDITHISTORYEVENT
						    THACTION ←(COND
						      (REPLACING (QUOTE Replace))
						      (T (QUOTE Copy)))
						    THLEN ← LEN
						    THCH# ← INSERTCH#
						    THFIRSTPIECE ← UNDOCHAIN
						    THOLDINFO ←(AND REPLACING EVENT)))
                                                             (* Make a history-list entry for the COPY.)
	           (replace \DIRTY of TOOBJ with T)          (* Mark the document changed)
	           (replace TEXTLEN of TOOBJ with (IPLUS LEN TOLEN))
                                                             (* Set the new length)
	           (\FIXILINES TOOBJ TO INSERTCH# LEN TOLEN)
                                                             (* Fix LINES and SELs)
	           [COND
		     ((EQ (fetch FORMATTEDP of TOOBJ)
			  (fetch FORMATTEDP of FROMOBJ))     (* Either both of the files are formatted or neither 
							     is. This case is OK)
		       )
		     ((fetch FORMATTEDP of TOOBJ)            (* The source wasn't formatted, but the target is.
							     Go convert the copied text.)
		       (\TEDIT.CONVERT.TO.FORMATTED TOOBJ INSERTCH# (IPLUS INSERTCH# LEN]
	           (TEDIT.UPDATE.SCREEN TOOBJ)               (* Refresh the display)
	           (replace CH# of TO with INSERTCH#)        (* Correct the target selection)
	           (replace CHLIM of TO with (IPLUS INSERTCH# LEN))
	           (replace DCH of TO with LEN)
	           (replace (SELECTION DX) of TO with 0)
	           (replace POINT of TO with (QUOTE RIGHT))
                                                             (* (replace CARETLOOKS of TOOBJ with 
							     (\TEDIT.GET.INSERT.CHARLOOKS TOOBJ TO)))
                                                             (* Make any later type-in look like what we just 
							     copied.)
	           (replace \INSERTPCVALID of TOOBJ with NIL)
                                                             (* And make sure that the pieces copied never have 
							     their strings smashed by back spacing.)
	           (replace \INSERTPCVALID of FROMOBJ with NIL)
	           (\FIXSEL TO TOOBJ)
	           (\SHOWSEL TO NIL T)))
	   (T                                                (* There is no target selection -- complain)
	      (TEDIT.PROMPTPRINT (fetch \TEXTOBJ of FROM)
				 "Please select a destination for the copy first." T])

(TEDIT.DELETE
  [LAMBDA (STREAM SEL LEN)                                   (* jds "15-Feb-84 16:16")
                                                             (* DELETE THE CHARACTERS SPECIFIED FROM THE MAIN TEXT.)
    (PROG ((TEXTOBJ (TEXTOBJ STREAM)))
          [COND
	    ((FIXP SEL)
	      (TEDIT.SETSEL STREAM SEL LEN)
	      (SETQ SEL (fetch SEL of TEXTOBJ]
          (OR SEL (SETQ SEL (fetch SEL of TEXTOBJ)))
          (\TEDIT.DELETE SEL TEXTOBJ])

(TEDIT.DO.BLUEPENDINGDELETE
  [LAMBDA (SEL TEXTOBJ)                                      (* jds "12-Mar-85 07:32")
                                                             (* Check for blue-pending-delete, and do it if it's 
							     there.)
                                                             (* Return T if the deletion was made.
							     For people who need to know)
    (COND
      ((fetch BLUEPENDINGDELETE of TEXTOBJ)                  (* If he's in a Blue-pending-delete state, delete the 
							     selection.)
	(PROG1 (fetch BLUEPENDINGDELETE of TEXTOBJ)
	       (COND
		 ((NOT (ZEROP (fetch DCH of SEL)))           (* There really IS something to delete.)
		   (\SHOWSEL SEL NIL NIL)                    (* Turn off the selection)
		   (\DELETECH (fetch CH# of SEL)
			      (fetch CHLIM of SEL)
			      (fetch DCH of SEL)
			      TEXTOBJ)                       (* Delete the characters.)
		   (\FIXDLINES (fetch LINES of TEXTOBJ)
			       SEL
			       (fetch CH# of SEL)
			       (fetch CHLIM of SEL)
			       TEXTOBJ)                      (* Fix up any line descriptors to reflect the 
							     deletion.)
		   (TEDIT.RESET.EXTEND.PENDING.DELETE SEL)   (* Make it a normal selection again.)
		   (replace CHLIM of SEL with (fetch CH# of SEL))
                                                             (* Fix up the selection, so that it is 0 wide, where 
							     the old text used to be.)
		   (replace DCH of SEL with 0)
		   (replace POINT of SEL with (QUOTE LEFT))
		   (\FIXSEL SEL TEXTOBJ)                     (* Make its line descriptors &c reflect the new 
							     reality)
		   (\SHOWSEL SEL NIL T)                      (* And turn it back on.)
		   )
		 (T                                          (* Don't do it, since it's zero-width.
							     However, DO turn off the blue-pendingness of it.)
		    (TEDIT.RESET.EXTEND.PENDING.DELETE SEL])

(TEDIT.INSERT
  [LAMBDA (STREAM TEXT CH#ORSEL LOOKS DONTSCROLL)            (* jds " 3-Oct-85 17:34")
                                                             (* Insert TEXT (character, litatom or string) at the 
							     appropriate spot in the text.)
    (SETQ STREAM (TEXTSTREAM STREAM))
    [COND
      ((FIXP CH#ORSEL)                                       (* He gave us a ch# to insert before)
	(TEDIT.SETSEL STREAM CH#ORSEL 1 (QUOTE LEFT]
    [COND
      ((LITATOM TEXT)
	(SETQ TEXT (MKSTRING TEXT]
    [OR (type? SELECTION CH#ORSEL)
	(SETQ CH#ORSEL (fetch SEL of (fetch (TEXTSTREAM TEXTOBJ) of STREAM]
    (COND
      ((AND (STRINGP TEXT)
	    (ZEROP (NCHARS TEXT)))                           (* Can't insert an empty string sensibly.
							     It confuses the screen update code.)
	NIL)
      ((AND CH#ORSEL (fetch SET of CH#ORSEL))
	(PROG ((TEXTOBJ (fetch (TEXTSTREAM TEXTOBJ) of STREAM))
	       CH# LINE XPOINT OTEXTLEN DS LINES CHARS BLANKSEEN CRSEEN)
	      (TEDIT.DO.BLUEPENDINGDELETE CH#ORSEL TEXTOBJ)
                                                             (* If the selected text was for pending delete, delete 
							     it before doing the insert.)
	      (COND
		(LOOKS                                       (* If looks for this insertion were specified, set them
							     up.)
		       (TEDIT.CARETLOOKS STREAM LOOKS)))
	      (SETQ OTEXTLEN (fetch TEXTLEN of TEXTOBJ))     (* The PRE-INSERT text length, for starting the screen 
							     update process)
	      (COND
		((fetch \WINDOW of TEXTOBJ)                  (* If this text is in a window, move it so the 
							     insertion point is on-screen, then turn off the 
							     selection highlight)
		  (COND
		    ((NOT DONTSCROLL)                        (* If DONTSCROLL is T, then don't bother scrolling the 
							     window to show the change.)
		      (TEDIT.NORMALIZECARET TEXTOBJ CH#ORSEL)))
		  (\SHOWSEL CH#ORSEL NIL NIL)))
	      (SETQ CH# (IMAX 1 (SELECTQ (fetch POINT of CH#ORSEL)
					 (LEFT (fetch CH# of CH#ORSEL))
					 [RIGHT (IMIN (fetch CHLIM of CH#ORSEL)
						      (ADD1 (fetch TEXTLEN of TEXTOBJ]
					 NIL)))
	      (SETQ XPOINT (SELECTQ (fetch POINT of CH#ORSEL)
				    (LEFT (fetch X0 of CH#ORSEL))
				    (RIGHT (fetch XLIM of CH#ORSEL))
				    NIL))
	      [COND
		[(type? STRINGP TEXT)                        (* It's a string: Count the characters and Insert them 
							     one by one into the text stream)
		  (SETQ CHARS (NCHARS TEXT))
		  (for ACHAR instring TEXT as NCH# from CH# by 1
		     do (SELCHARQ ACHAR
				  ((CR #↑M 1,CR)
				    (SETQ CRSEEN T)
				    (\INSERTCR ACHAR NCH# TEXTOBJ))
				  (SPACE (SETQ BLANKSEEN T)
					 (\INSERTCH ACHAR NCH# TEXTOBJ))
				  (\INSERTCH ACHAR NCH# TEXTOBJ]
		(T                                           (* It's a singe character. Just insert it.)
		   (SETQ CHARS 1)
		   (SELCHARQ TEXT
			     ((CR #↑M 1,CR)
			       (SETQ CRSEEN T)
			       (\INSERTCR TEXT CH# TEXTOBJ))
			     (SPACE (SETQ BLANKSEEN T)
				    (\INSERTCH TEXT CH# TEXTOBJ))
			     (\INSERTCH TEXT CH# TEXTOBJ]
	      (\FIXILINES TEXTOBJ CH#ORSEL CH# CHARS OTEXTLEN)
                                                             (* Fix up the line descriptors and the Selection.)
	      (TEDIT.INSERT.UPDATESCREEN TEXT CH# CHARS XPOINT TEXTOBJ CH#ORSEL OTEXTLEN BLANKSEEN 
					 CRSEEN DONTSCROLL)
                                                             (* Update the edit window.)
	  ))
      (T (TEDIT.PROMPTPRINT (TEXTOBJ STREAM)
			    "Please select a place for the insertion." T])

(TEDIT.KILL
  [LAMBDA (STREAM)                                           (* jds "11-Feb-85 00:59")
                                                             (* Force the edit session supported by STREAM to 
							     terminate, and to return VALUE)
    (COND
      ((type? STREAM STREAM)                                 (* If he gave us a textofd, get the textobj)
	(SETQ STREAM (fetch (TEXTSTREAM TEXTOBJ) of STREAM)))
      [(WINDOWP STREAM)                                      (* Take a window, and do the obvious with it.)
	(SETQ STREAM (WINDOWPROP STREAM (QUOTE TEXTOBJ]
      ((type? TEXTOBJ STREAM)                                (* A Textobj is just fine)
	)
      (T                                                     (* Anything else is ungood, double-plus)
	 (\ILLEGAL.ARG STREAM)))
    (replace EDITFINISHEDFLG of STREAM with T)
    (PROG (TEDW TEDPROC)
          (AND (SETQ TEDW (CAR (fetch \WINDOW of STREAM)))
	       [PROCESSP (SETQ TEDPROC (WINDOWPROP TEDW (QUOTE PROCESS]
	       (NEQ TEDPROC (THIS.PROCESS))
	       (DEL.PROCESS TEDPROC)
	       (TEDIT.DEACTIVATE.WINDOW TEDW])

(TEDIT.MAPLINES
  [LAMBDA (TEXTOBJ FN)                                       (* jds "21-Aug-84 12:07")
                                                             (* Go thru the visible lines in a textobj and call a 
							     mapping fn on them)
                                                             (* FN has 2 args: the LINEDESCRIPTOR, and a VISIBLEFLG 
							     to say if the line is visible on the screen.)
    (bind (LINE ←(fetch NEXTLINE of (fetch LINES of TEXTOBJ)))
	  (BOT ←(fetch WBOTTOM of TEXTOBJ))
	  [TOP ←(fetch HEIGHT of (DSPCLIPPINGREGION (\TEDIT.PRIMARYW TEXTOBJ] while LINE
       do (COND
	    ((EQ (APPLY* FN LINE (AND (ILESSP (fetch YBOT of LINE)
					      TOP)
				      (IGEQ (fetch YBOT of LINE)
					    BOT)))
		 (QUOTE STOP))
	      (RETURN)))
	  (SETQ LINE (fetch NEXTLINE of LINE])

(TEDIT.MAPPIECES
  [LAMBDA (TEXTOBJ FN FNARG)                                 (* jds "28-Mar-84 17:58")
                                                             (* Go thru all the pieces in a document, applying a 
							     function to them serially)
                                                             (* FN is a function of 3 args 
							     (PIECE CH#-of-1st-char-in-piece PIECE# in table FNARG))
    (PROG ((PCTB (fetch PCTB of TEXTOBJ)))
          (RETURN (bind (BASE ←(\ADDBASE2 (fetch (ARRAYP BASE) of PCTB)
					  \FirstPieceOffset))
		     for I from \FirstPieceOffset to (IDIFFERENCE (ELT PCTB \PCTBLastPieceOffset)
								  \EltsPerPiece)
		     by \EltsPerPiece
		     do [COND
			  ((EQ (APPLY* FN (\GETBASEPTR BASE 0)
				       (\GETBASEPTR BASE 2)
				       I FNARG)
			       (QUOTE STOP))
			    (RETURN (LIST (\GETBASEPTR BASE 0)
					  (\GETBASEPTR BASE 2)
					  I]
			(SETQ BASE (\ADDBASE BASE (CONSTANT (IPLUS \EltsPerPiece \EltsPerPiece])

(TEDIT.MOVE
  [LAMBDA (FROM TO)                                      (* AJB "11-Oct-85 11:33")
                                                             (* Move the text described by the selection FROM to 
							     the place described by the selection TO)
    (SETQ TEDIT.MOVE.PENDING NIL)                          (* First, Turn off the global flag that got us here.)
    (COND
      ((NOT (AND FROM (fetch SET of FROM)))          (* There MUST be a source selected first.)
	(TEDIT.PROMPTPRINT (fetch \TEXTOBJ of TO)
			     "Move source selection hasn't been set yet." T))
      ((ZEROP (fetch DCH of FROM))                     (* The source selection is empty.
							     Just turn it off.)
	(\SHOWSEL FROM NIL NIL))
      (T (\SHOWSEL FROM NIL NIL)                           (* Before all else, make sure the copy source 
							     selection is turned off)
	 (COND
	   ((AND TO (fetch SET of TO))                 (* Can only do copy if there's a target selection)
	     (PROG ((TOOBJ (fetch \TEXTOBJ of TO))
		      (FROMOBJ (fetch \TEXTOBJ of FROM))
		      (TOLEN (fetch TEXTLEN of (fetch \TEXTOBJ of TO)))
		      (TOPCTB (fetch PCTB of (fetch \TEXTOBJ of TO)))
		      (FROMPCTB (fetch PCTB of (fetch \TEXTOBJ of FROM)))
		      (CROSSCOPY (NEQ (fetch \TEXTOBJ of FROM)
					(fetch \TEXTOBJ of TO)))
		      LEN INSPC INSPC# PC NPC PCCH NPCCH OPLEN EVENT REPLACING INSERTCH# PCLST OBJ 
		      COPYFN UNDOCHAIN)                      (* Find the insertion point)
		     (SETQ PCLST (TEDIT.SELECTED.PIECES FROMOBJ FROM CROSSCOPY
							    (FUNCTION \TEDIT.MOVE.PIECEMAPFN)
							    FROMOBJ TOOBJ))
                                                             (* Grab the pieces that reflect the source selection)
		     (SETQ REPLACING (TEDIT.DO.BLUEPENDINGDELETE TO TOOBJ))
                                                             (* Do any blue-pending-delete)
		     (SETQ TOPCTB (fetch PCTB of TOOBJ))
                                                             (* Get the new PCTB and text length)
		     (SETQ EVENT (fetch TXTHISTORY of TOOBJ))
		     (SETQ LEN (IDIFFERENCE (fetch CHLIM of FROM)
						(fetch CH# of FROM)))
                                                             (* Keep \DELETECH from playing clever games with the 
							     piece if it's new type-in: Don't let it be reclaimed 
							     by the deletion.)
		     (\DELETECH (fetch CH# of FROM)
				  (fetch CHLIM of FROM)
				  (fetch DCH of FROM)
				  FROMOBJ T)                 (* Now delete the text from its old place)
		     (\FIXDLINES (fetch LINES of FROMOBJ)
				   FROM
				   (fetch CH# of FROM)
				   (fetch CHLIM of FROM)
				   FROMOBJ)
		     (SETQ TOLEN (fetch TEXTLEN of TOOBJ))
		     (\SHOWSEL TO NIL NIL)                 (* NOW turn off the target selection.)
		     (replace SET of FROM with NIL)
		     [COND
		       ((EQ (fetch POINT of TO)
			      (QUOTE LEFT))
			 (SETQ INSERTCH# (fetch CH# of TO)))
		       (T (SETQ INSERTCH# (fetch CHLIM of TO]
                                                             (* Figure out where to do the insertion.)
		     (\TEDIT.INSERT.PIECES TOOBJ INSERTCH# PCLST LEN NIL NIL CROSSCOPY)
                                                             (* Get the pieces that actually got inserted, so we 
							     can UNDO the move)
		     (replace \INSERTPCVALID of TOOBJ with NIL)
                                                             (* Keep \DELETECH from playing clever games with the 
							     piece if it's new type-in: Don't let it be reclaimed 
							     by the deletion.)
		     (replace \INSERTPCVALID of FROMOBJ with NIL)
		     (\TEDIT.HISTORYADD TOOBJ (create TEDITHISTORYEVENT
							  THTEXTOBJ ← TOOBJ
							  THACTION ←(COND
							    (REPLACING (QUOTE ReplaceMove))
							    (T (QUOTE Move)))
							  THLEN ← LEN
							  THCH# ← INSERTCH#
							  THFIRSTPIECE ← PCLST
							  THAUXINFO ← FROMOBJ
							  THOLDINFO ←(fetch CH# of FROM)))
                                                             (* Make a history-list entry for the COPY.)
		     (replace \DIRTY of TOOBJ with T)
                                                             (* Mark the document changed)
		     (replace TEXTLEN of TOOBJ with (IPLUS LEN TOLEN))
                                                             (* Set the new length)
		     (\FIXILINES TOOBJ TO INSERTCH# LEN TOLEN)
                                                             (* Fix LINES and SELs)
		     (COND
		       ((EQ (fetch FORMATTEDP of TOOBJ)
			      (fetch FORMATTEDP of FROMOBJ))
                                                             (* Either both of the files are formatted or neither 
							     is. This case is OK)
			 )
		       ((fetch FORMATTEDP of TOOBJ)      (* The source wasn't formatted, but the target is.
							     Go convert the copied text.)
			 (\TEDIT.CONVERT.TO.FORMATTED TOOBJ INSERTCH# (IPLUS INSERTCH# LEN)))
		       (T                                    (* The source is formatted and the target isn't.
							     Give the guy a choice.)
                                                             (* For now, convert the target file to formatted.)
			  (\TEDIT.CONVERT.TO.FORMATTED TOOBJ)))
		     (TEDIT.UPDATE.SCREEN FROMOBJ)
		     (TEDIT.UPDATE.SCREEN TOOBJ)           (* Refresh the display)
		     (replace CH# of TO with INSERTCH#)
                                                             (* Correct the target selection)
		     (replace CHLIM of TO with (IPLUS INSERTCH# LEN))
		     (replace DCH of TO with LEN)
		     (replace (SELECTION DX) of TO with 0)
		     (replace POINT of TO with (QUOTE RIGHT))
		     (\FIXSEL TO TOOBJ)
		     (\SHOWSEL TO NIL T)))
	   (T                                                (* There is no target selection -- complain)
	      (TEDIT.PROMPTPRINT (fetch \TEXTOBJ of FROM)
				   "Please select a destination for the copy first." T])

(TEDIT.QUIT
  [LAMBDA (STREAM VALUE)                                     (* jds " 5-Jul-85 11:39")
                                                             (* Force the edit session supported by STREAM to 
							     terminate, and to return VALUE)
    (COND
      ((type? STREAM STREAM)                                 (* If he gave us a textofd, get the textobj)
	(SETQ STREAM (fetch (TEXTSTREAM TEXTOBJ) of STREAM)))
      ((type? TEXTOBJ STREAM)                                (* A Textobj is just fine)
	)
      (T                                                     (* Anything else is ungood, double-plus)
	 (\ILLEGAL.ARG STREAM)))
    (replace EDITFINISHEDFLG of STREAM with (OR VALUE T))    (* tell the command loop to stop next time through)
    (PROG (MAINW)
          (COND
	    ([AND (fetch \WINDOW of STREAM)
		  (NEQ (SETQ MAINW (\TEDIT.PRIMARYW STREAM))
		       (PROCESSPROP (TTY.PROCESS)
				    (QUOTE WINDOW]           (* there is a main window of the stream, and it is not 
							     the window of the tty process, so give it the tty)
	      (TTY.PROCESS (WINDOWPROP MAINW (QUOTE PROCESS)))
	      (AND (NEQ (TTY.PROCESS)
			(THIS.PROCESS))
		   (until [OR (NOT (WINDOWPROP MAINW (QUOTE PROCESS)))
			      (PROCESS.FINISHEDP (WINDOWPROP MAINW (QUOTE PROCESS]
		      do                                     (* Wait until the Edit process has had a chance to go 
							     away before continuing here.)
			 (DISMISS])

(TEDIT.STRINGWIDTH
  [LAMBDA (STR FONT TERMSA)                                  (* jds "19-AUG-83 14:40")
    (COND
      (TERMSA                                                (* We have a terminal table to take account of.
							     Do so.)
	      (for CH instring STR sum (TEDIT.CHARWIDTH CH FONT TERMSA)))
      (T                                                     (* Just use the native character widths)
	 (for CH instring STR sum (SELCHARQ CH
					    (TAB 36)
					    (CHARWIDTH CH FONT])

(TEDIT.\INSERT
  [LAMBDA (CH SEL STREAM)                                    (* jds " 3-Oct-85 17:35")
                                                             (* Insert the character CH at the appropriate spot in 
							     the text.)
    (DECLARE (LOCALVARS . T))
    (PROG [(TEXTOBJ (COND
		      ((type? STREAM STREAM)                 (* If we got a STREAM, change it into a textobj)
			(fetch (TEXTSTREAM TEXTOBJ) of STREAM))
		      (T STREAM]
          (COND
	    ((NOT (AND SEL (fetch SET of SEL)))
	      (TEDIT.PROMPTPRINT TEXTOBJ "Please select a place for the insertion." T)
	      (RETURN)))
          (COND
	    ((fetch \WINDOW of TEXTOBJ)                      (* There is a window; make sure the insert point is 
							     on-screen, and turn off any highlighted selection)
	      (TEDIT.NORMALIZECARET TEXTOBJ SEL)
	      (\SHOWSEL SEL NIL NIL)))
          (PROG ((CH# (TEDIT.GETPOINT STREAM SEL))
		 (XPOINT (SELECTQ (fetch POINT of SEL)
				  (LEFT (fetch X0 of SEL))
				  (RIGHT (fetch XLIM of SEL))
				  NIL))
		 (OTEXTLEN (fetch TEXTLEN of TEXTOBJ)))
	        (SELCHARQ CH
			  ((CR #↑M 1,CR)                     (* This was a CR. Go do the para breaking as needed)
			    (\INSERTCR CH CH# TEXTOBJ))
			  (\INSERTCH CH CH# TEXTOBJ))
	        (\FIXILINES TEXTOBJ SEL CH# 1 OTEXTLEN)
	        (TEDIT.INSERT.UPDATESCREEN CH CH# 1 XPOINT TEXTOBJ SEL OTEXTLEN NIL NIL NIL T])

(TEXTOBJ
  [LAMBDA (STREAM)                                           (* jds "11-Jul-85 12:06")
                                                             (* Convert from a text stream to the associated 
							     textobj)
    (COND
      ((type? TEXTOBJ STREAM)                                (* It's already a TEXTOBJ)
	STREAM)
      ((AND (type? STREAM STREAM)
	    (fetch (TEXTSTREAM TEXTOBJ) of STREAM)
	    (type? TEXTOBJ (fetch (TEXTSTREAM TEXTOBJ) of STREAM)))
                                                             (* It's a TEXTSTREAM)
	(fetch (TEXTSTREAM TEXTOBJ) of STREAM))
      ((AND (PROCESSP STREAM)
	    (PROCESS.WINDOW STREAM))                         (* It's an edit PROCESS)
	(WINDOWPROP (PROCESS.WINDOW STREAM)
		    (QUOTE TEXTOBJ)))
      [(AND (WINDOWP STREAM)
	    (WINDOWPROP STREAM (QUOTE TEXTOBJ]
      [(AND (DISPLAYSTREAMP STREAM)
	    (WINDOWPROP STREAM (QUOTE TEXTOBJ]
      ((\ILLEGAL.ARG STREAM])

(TEXTSTREAM
  [LAMBDA (STREAM)                                           (* jds "26-Dec-84 16:03")
                                                             (* Force a textobj or stream to be a stream)
    (COND
      ((AND (type? STREAM STREAM)
	    (fetch (TEXTSTREAM TEXTOBJ) of STREAM)
	    (type? TEXTOBJ (fetch (TEXTSTREAM TEXTOBJ) of STREAM)))
                                                             (* It's a stream, and is really a TEXT stream.
							     Just return it.)
	STREAM)
      ((type? TEXTOBJ STREAM)                                (* It's a TEXTOBJ, so grab the stream hint field and 
							     return that.)
	(fetch STREAMHINT of STREAM))
      ((AND (PROCESSP STREAM)
	    (PROCESS.WINDOW STREAM))                         (* It's an edit process, so grab the text stream from 
							     the edit window.)
	(WINDOWPROP (PROCESS.WINDOW STREAM)
		    (QUOTE TEXTSTREAM)))
      [(AND (WINDOWP STREAM)
	    (WINDOWPROP STREAM (QUOTE TEXTSTREAM]
      [(AND (DISPLAYSTREAMP STREAM)
	    (WINDOWPROP STREAM (QUOTE TEXTSTREAM]
      ((\ILLEGAL.ARG STREAM)                                 (* Not a reasonable coercion to the text stream.
							     Punt.)
	])

(\TEDIT.INCLUDE
  [LAMBDA (TEXTOBJ FILE START END)                                 (* jds 
                                                                           " 9-Feb-86 15:29")
                                                                           (* A NATIVE text 
                                                                           includer: Includes part 
                                                                           of a file, without 
                                                                           checking to see if it's 
                                                                           a bravo file, a TEdit 
                                                                           file or whatever.)
    (HELP)  
            (* (PROG ((LEN (IDIFFERENCE (OR END (GETEOFPTR FILE))
            (OR START 0))) (SEL (fetch SEL of TEXTOBJ)) NPC)
            (SETQ NPC (create PIECE PFILE ← (\GETOFD FILE
            (QUOTE INPUT)) PFPOS ← (OR START 0) PLEN ← LEN PLOOKS ←
            (\TEDIT.GET.INSERT.CHARLOOKS TEXTOBJ SEL) PPARALOOKS ← NIL))
            (* Create a PIECE to describe the text)
            (\TEDIT.INSERT.PIECES TEXTOBJ (fetch CH# of SEL) NPC LEN)
            (* Insert it in the document) (add (fetch TEXTLEN of TEXTOBJ) LEN)
            (* And update the document's length) (\TEDIT.MARK.LINES.DIRTY TEXTOBJ
            (fetch CH# of SEL) (IPLUS (fetch CH# of SEL) LEN))
            (* Mark the screen dirty, so updating it will find something to do)
            (replace CHLIM of SEL with (IPLUS (fetch CH# of SEL) LEN))
            (replace DCH of SEL with LEN) (replace
            (SELECTION DX) of SEL with 0) (replace POINT of SEL with
            (QUOTE RIGHT)) (replace SELKIND of SEL with
            (QUOTE CHAR)) (replace SELOBJ of SEL with NIL)
            (COND ((fetch \WINDOW of TEXTOBJ) (\SHOWSEL SEL NIL NIL)
            (TEDIT.UPDATE.SCREEN TEXTOBJ) (\FIXSEL SEL TEXTOBJ)
            (\SHOWSEL SEL NIL T))) (* Update the screen)
            (replace \DIRTY of TEXTOBJ with T) (\SETUPGETCH
            (fetch CH# of SEL) TEXTOBJ)))

    ])

(\TEDIT.INSERT.PIECES
  [LAMBDA (TEXTOBJ CH# FIRSTPIECE #CHARS INSPC INSPC# CROSSCOPY)
                                                             (* jds "30-Aug-85 14:11")

          (* Inserts a series of pieces into TEXTOBJ in front of character CH#. If FIRSTPIECE is a PIECE, this will follow the
	  next-piece pointer chain; if FIRSTPIECE is a list, it is a list of pieces to insert. If CROSSCOPY is non-NIL, the 
	  pieces' contents will be copied, to preserve text in case the original is deleted. INSPC and INSPC# are accelerators
	  for where in the PCTB the new pieces should go.)



          (* It is the CALLER'S RESPONSIBILITY to make sure the pieces to be inserted are "safe" --that they are, if 
	  necessary, copies of the originals, and can safely be modified.)

                                                             (* NB THAT THIS DOES NOT UPDATE TEXTLEN)
    (PROG ((TOLEN (fetch TEXTLEN of TEXTOBJ))
	   (TOPCTB (fetch PCTB of TEXTOBJ))
	   LEN PC PREVPC NPC UNDOCHAIN PSTR PFILE)
          [SETQ INSPC# (OR INSPC# (\CHTOPCNO CH# TOPCTB)
			   (SUB1 (\EDITELT TOPCTB \PCTBLastPieceOffset]
                                                             (* Get a handle on the piece we're to insert within or 
							     in front of)
          [SETQ INSPC (OR INSPC (\EDITELT TOPCTB (ADD1 INSPC#]
                                                             (* And the piece, itself.)
          (replace \INSERTPCVALID of TEXTOBJ with NIL)       (* Force later insertions to make new pieces.)
          (COND
	    ((IGREATERP CH# TOLEN)                           (* We're inserting at end of file;
							     leave the piece to insert before as LASTPIECE)
	      )
	    ((IEQP CH# (\EDITELT TOPCTB INSPC#))             (* The insertion is IN FRONT of this piece;
							     just continue on)
	      )
	    (T (SETQ INSPC (\SPLITPIECE INSPC CH# TEXTOBJ INSPC#))
	       (add INSPC# \EltsPerPiece)))                  (* Nope, we're inserting INSIDE this piece.
							     Split it in two.)
          (COND
	    ((NEQ INSPC (QUOTE LASTPIECE))                   (* Not the last piece, so back up using the pointer.)
	      (SETQ PREVPC (fetch PREVPIECE of INSPC)))
	    [(NOT (ZEROP (fetch TEXTLEN of TEXTOBJ)))        (* If we are at the end, AND there is text before us, 
							     find it thru the pctb.)
	      (SETQ PREVPC (\EDITELT TOPCTB (IDIFFERENCE (\EDITELT TOPCTB \PCTBLastPieceOffset)
							 \EltsPerPiece]
	    (T                                               (* Otherwise, there is no piece before where we're 
							     inserting.)
	       (SETQ PREVPC NIL)))                           (* For pushing para looks in)
          (bind [PC ←(create PIECE using (COND
					   ((LISTP FIRSTPIECE)
					     (pop FIRSTPIECE))
					   (T FIRSTPIECE]
		(LEN ← 0)
		(PCCOUNT ← 0) first (SETQ UNDOCHAIN PC) while (AND PC (OR (NOT #CHARS)
									  (ILESSP LEN #CHARS)))
	     do                                              (* Now insert the copied pieces into the new place)
		(COND
		  ((AND CROSSCOPY (SETQ PFILE (fetch PFILE of PC)))

          (* If this is a cross-document copy, and the text comes from a file, we must REALLY make a copy of the text, lest 
	  the source file be deleted.)


		    [replace PSTR of PC with (SETQ PSTR (ALLOCSTRING (fetch PLEN of PC)
								     NIL NIL (fetch PFATP
										of PC]
		    [COND
		      ((NOT (OPENP PFILE))                   (* The source file was CLOSED -- reopen it, for our us)
			(replace PFILE of PC with (SETQ PFILE (OPENSTREAM PFILE (QUOTE INPUT)
									  (QUOTE OLD]
		    (SETFILEPTR PFILE (fetch PFPOS of PC))
		    [bind (BASE ←(fetch (STRINGP BASE) of PSTR))
			  (OFFST ←(fetch (STRINGP OFFST) of PSTR)) for I from 0
		       to (SUB1 (fetch PLEN of PC))
		       do                                    (* Copy the characters to the string)
			  (COND
			    ((fetch PFATP of PC)
			      (\PUTBASEFAT BASE (IPLUS OFFST I)
					   (\WIN PFILE)))
			    (T (PUTBASEBYTE BASE (IPLUS OFFST I)
					    (\BIN PFILE]
		    (replace PFILE of PC with NIL)           (* And the piece no longer has a file attached.)
		    ))
		(replace PLOOKS of PC with (\TEDIT.UNIQUIFY.CHARLOOKS (fetch PLOOKS of PC)
								      TEXTOBJ))
		(replace PPARALOOKS of PC with (\TEDIT.UNIQUIFY.PARALOOKS (fetch PPARALOOKS
									     of PC)
									  TEXTOBJ))
                                                             (* Assure that the new document knows about this 
							     piece's looks)
		[COND
		  ((NULL FIRSTPIECE)
		    (SETQ NPC NIL))
		  [(LISTP FIRSTPIECE)                        (* If the piece list really IS a list, grab the next 
							     piece from the front)
		    (SETQ NPC (create PIECE using (pop FIRSTPIECE]
		  (T                                         (* Otherwise, follow the NEXTPIECE chain among pieces)
		     (SETQ NPC (create PIECE using (fetch NEXTPIECE of PC]
		(\INSERTPIECE PC INSPC TEXTOBJ NIL INSPC#) 
                                                             (* Insert the piece into the new document)
		(add INSPC# \EltsPerPiece)
		(add LEN (fetch PLEN of PC))
		(SETQ PC NPC))
          (\TEDIT.DIFFUSE.PARALOOKS PREVPC INSPC)
          (RETURN UNDOCHAIN])

(\TEDIT.MOVE.PIECEMAPFN
  [LAMBDA (PC TEXTOBJ FROMOBJ TOOBJ)                         (* jds " 8-Feb-85 18:14")
                                                             (* Called by TEDIT.MOVE via TEDIT.SELECTED.PIECES, to 
							     do the move-operation processing on the candidate 
							     pieces.)
    (PROG (OBJ MOVEFN)
          (SETQ PC (create PIECE using PC PNEW ← T))         (* No matter what, we need a fresh copy.)
          [COND
	    [(fetch POBJ of PC)                              (* This piece describes an object)
                                                             (* Call its WHENMOVEDFN.)
	      (SETQ OBJ (fetch POBJ of PC))
	      (COND
		((SETQ MOVEFN (IMAGEOBJPROP OBJ (QUOTE WHENMOVEDFN)))
                                                             (* If there's an eventfn for moving, use it.)
		  (APPLY* MOVEFN OBJ (CAR (fetch \WINDOW of TOOBJ))
			  (fetch STREAMHINT of FROMOBJ)
			  (fetch STREAMHINT of TOOBJ]
	    ((fetch PSTR of PC)                              (* If the piece is a string, make our own copy of the 
							     string header, even tho we share characters.)
	      (replace PSTR of PC with (SUBSTRING (fetch PSTR of PC)
						  1
						  (fetch PLEN of PC]
          (RETURN PC])

(\TEDIT.OBJECT.SHOWSEL
  [LAMBDA (TEXTOBJ SEL ON SELWINDOW)                       (* AJB "10-Oct-85 17:09")
                                                             (* We are hilighting (or dehilighting) a selected 
							     object. Let it know.)
    (PROG ((X (fetch X0 of SEL))
	     (Y (fetch Y0 of SEL))
	     (OBJ (fetch SELOBJ of SEL))
	     (WIDTH (fetch (SELECTION DX) of SEL))
	     (XOFFSET (DSPXOFFSET NIL SELWINDOW))
	     (YOFFSET (DSPYOFFSET NIL SELWINDOW))
	     (IMAGEFN (IMAGEOBJPROP (fetch SELOBJ of SEL)
				      (QUOTE WHENOPERATEDONFN)))
	     (WWIDTH (WINDOWPROP SELWINDOW (QUOTE WIDTH)))
	     (WHEIGHT (WINDOWPROP SELWINDOW (QUOTE HEIGHT)))
	     IMAGEBOX)
	    (COND
	      ((NOT (INSIDE? (CREATEREGION 0 0 WWIDTH WHEIGHT)
				 X Y))                       (* The selection is no longer on-screen.
							     Ignore the de-hilight command.)
		(RETURN)))
	    (SETQ IMAGEBOX (OR (IMAGEOBJPROP OBJ (QUOTE BOUNDBOX))
				   (APPLY* (IMAGEOBJPROP OBJ (QUOTE IMAGEBOXFN))
					     OBJ SELWINDOW)))
	    (RESETLST [RESETSAVE (DSPXOFFSET (IDIFFERENCE (IPLUS X XOFFSET)
								  (fetch XKERN of IMAGEBOX))
						   SELWINDOW)
				     (LIST (FUNCTION DSPXOFFSET)
					     XOFFSET
					     (WINDOWPROP SELWINDOW (QUOTE DSP]
			(RESETSAVE (DSPYOFFSET (IPLUS Y YOFFSET)
						   SELWINDOW)
				     (LIST (FUNCTION DSPYOFFSET)
					     YOFFSET SELWINDOW))
			(RESETSAVE (DSPCLIPPINGREGION (create REGION
								    LEFT ← 0
								    BOTTOM ← 0
								    WIDTH ←(IMIN
								      WIDTH
								      (IDIFFERENCE (fetch WRIGHT
											of TEXTOBJ)
										     X))
								    HEIGHT ←(fetch YSIZE
									       of IMAGEBOX))
							  SELWINDOW)
				     (LIST (FUNCTION DSPCLIPPINGREGION)
					     (DSPCLIPPINGREGION NIL SELWINDOW)
					     SELWINDOW))
			(AND IMAGEFN (ERSETQ (APPLY* IMAGEFN OBJ SELWINDOW
							   (COND
							     (ON (QUOTE HIGHLIGHTED))
							     (T (QUOTE UNHIGHLIGHTED)))
							   SEL
							   (fetch STREAMHINT of TEXTOBJ])

(\TEDIT.RESTARTFN
  [LAMBDA (TEXT WINDOW PROPS)                                (* jds "13-Jun-85 11:43")
                                                             (* Restarts a TEdit session.)
    (replace \WINDOW of (fetch (TEXTSTREAM TEXTOBJ) of TEXT) with NIL)
                                                             (* Unattach the window, so we do a redisplay.)
    (PROG [(ODIRTY (fetch \DIRTY of (fetch (TEXTSTREAM TEXTOBJ) of TEXT]
          (SETQ TEXT (OPENTEXTSTREAM TEXT WINDOW NIL NIL PROPS))
          (replace \DIRTY of (fetch (TEXTSTREAM TEXTOBJ) of TEXT) with ODIRTY))
                                                             (* Now reconnect the world together again)
    (\TEDIT.COMMAND.LOOP (fetch (TEXTSTREAM TEXTOBJ) of TEXT))
                                                             (* Run the editing engine)
    (CLOSEW WINDOW)                                          (* Close the edit window)
    (\TEXTCLOSEF TEXT)                                       (* Close the underlying files)
    (replace ACCESSBITS of TEXT with BothBits)               (* But leave the stream itself accessible)
    (AND (TEXTPROP (fetch (TEXTSTREAM TEXTOBJ) of TEXT)
		   (QUOTE AFTERQUITFN))
	 (APPLY* (TEXTPROP (fetch (TEXTSTREAM TEXTOBJ) of TEXT)
			   (QUOTE AFTERQUITFN))
		 WINDOW TEXT))                               (* Apply any post-window-close 
							     (and post-QUIT) function)
    ])

(\TEDIT.CHARDELETE
  [LAMBDA (TEXTOBJ SCRATCHSTRING SEL)                        (* jds " 7-Mar-85 03:49")
                                                             (* Do character-backspace deletion for TEDIT)
    (SETQ TEXTOBJ (TEXTOBJ TEXTOBJ))
    (PROG ((PCTB (fetch PCTB of TEXTOBJ))
	   TLEN INSCH# INSPC INSPC# TLOOKS)
          (COND
	    [NIL [NOT (ZEROP (SETQ TLEN (fetch (STRINGP OFFST) of SCRATCHSTRING]
                                                             (* If we didn't really insert the text yet, just remove
							     from the text to be inserted)
		 (replace (STRINGP OFFST) of SCRATCHSTRING with (SUB1 TLEN))
		 (replace (STRINGP LENGTH) of SCRATCHSTRING with (ADD1 (fetch (STRINGP LENGTH)
									  of SCRATCHSTRING]
	    (T                                               (* Delete the character just before the current 
							     insertpoint.)
	       (SELECTQ (fetch POINT of SEL)
			[LEFT (SETQ INSCH# (SUB1 (fetch CH# of SEL]
			[RIGHT (SETQ INSCH# (SUB1 (fetch CHLIM of SEL]
			NIL)
	       (COND
		 ((ILEQ INSCH# 0)                            (* Can't backspace past start of document)
		   (RETURN)))
	       [SETQ INSPC (\EDITELT PCTB (ADD1 (SETQ INSPC# (\CHTOPCNO INSCH# PCTB]
	       (SETQ TLOOKS (\TEDIT.APPLY.STYLES (fetch PLOOKS of INSPC)
						 INSPC TEXTOBJ))
	       [while (AND INSPC (fetch CLINVISIBLE of TLOOKS))
		  do                                         (* Back over any invisible text, which we're no allowed
							     to delete.)
		     (SETQ INSPC (fetch PREVPIECE of INSPC))
		     (SETQ INSCH# (SUB1 (\EDITELT PCTB INSPC#)))
		     (SETQ INSPC# (IDIFFERENCE INSPC# \EltsPerPiece))
		     (COND
		       (INSPC (SETQ TLOOKS (\TEDIT.APPLY.STYLES (fetch PLOOKS of INSPC)
								INSPC TEXTOBJ]
	       (COND
		 ((ILEQ INSCH# 0)                            (* We backed up to the start of the document.
							     Can't go no further.)
		   (RETURN))
		 ((NOT (fetch CLPROTECTED of TLOOKS))        (* Can only backspace if the char to go isn't 
							     protected.)
		   (replace CHLIM of SEL with (ADD1 (replace CH# of SEL with INSCH#)))
                                                             (* Set up the selection to point to the character which
							     is to be deleted.)
		   (replace DCH of SEL with 1)
		   (\SHOWSEL SEL NIL NIL)                    (* Turn off the underlining, if any, so there's no 
							     garbage.)
		   (\FIXSEL SEL TEXTOBJ)                     (* Fix the selection up so it points to the right line 
							     and all)
		   (\TEDIT.DELETE SEL TEXTOBJ T)             (* And delete it.)
		   ])

(\TEDIT.COPY.PIECEMAPFN
  [LAMBDA (PC TEXTOBJ FROMOBJ TOOBJ)                         (* jds "26-Feb-85 10:58")
                                                             (* Called by TEDIT.COPY via TEDIT.SELECTED.PIECES, to 
							     do the copy-operation processing on the candidate 
							     pieces.)
    (PROG (OBJ NEWOBJ COPYFN)
          (SETQ PC (create PIECE using PC PNEW ← T))         (* No matter what, we need a fresh copy.)
          [COND
	    ((fetch POBJ of PC)                              (* This piece describes an object)
	      (SETQ OBJ (fetch POBJ of PC))
	      [COND
		[(SETQ COPYFN (IMAGEOBJPROP OBJ (QUOTE COPYFN)))
		  (SETQ NEWOBJ (APPLY* COPYFN OBJ (fetch STREAMHINT of FROMOBJ)
				       (fetch STREAMHINT of TOOBJ)))
		  (COND
		    ((EQ NEWOBJ (QUOTE DON'T))               (* He said not to copy this piece -- abort the whole 
							     copy.)
		      (TEDIT.PROMPTPRINT TEXTOBJ "COPY of this object not allowed." T)
		      (RETFROM (QUOTE TEDIT.COPY)))
		    (NEWOBJ (replace POBJ of PC with NEWOBJ))
		    (T (replace POBJ of PC with (COPYALL OBJ]
		(OBJ                                         (* No copy fn; just strike off a copy of our own)
		     (replace POBJ of PC with (COPYALL OBJ]
	      (COND
		((SETQ COPYFN (IMAGEOBJPROP OBJ (QUOTE WHENCOPIEDFN)))
                                                             (* If there's an eventfn for copying, use it.)
		  (APPLY* COPYFN OBJ (WINDOWPROP (CAR (fetch \WINDOW of TOOBJ))
						 (QUOTE DSP))
			  (fetch STREAMHINT of FROMOBJ)
			  (fetch STREAMHINT of TOOBJ]
          [COND
	    ((fetch CLPROTECTED of (fetch PLOOKS of PC))     (* The source text was protected;
							     unprotect the copy.)
	      (replace PLOOKS of PC with (\TEDIT.UNIQUIFY.CHARLOOKS (create CHARLOOKS
								       using (fetch PLOOKS
										of PC)
									     CLPROTECTED ← NIL 
									     CLSELHERE ← NIL)
								    TOOBJ]
          (RETURN PC])

(\TEDIT.DELETE
  [LAMBDA (SEL STREAM SELOFF)                                (* jds "27-Aug-85 17:30")
                                                             (* DELETE THE CHARACTERS SPECIFIED FROM THE MAIN TEXT.)
                                                             (* SELOFF => The selection is already turned off.)
    (PROG [(TEXTOBJ (COND
		      ((type? STREAM STREAM)                 (* If we got a STREAM, change it into a textobj)
			(fetch (TEXTSTREAM TEXTOBJ) of STREAM))
		      (T STREAM]
          (PROG ((CH# (fetch CH# of SEL))
		 (CHLIM (fetch CHLIM of SEL))
		 (LINES (fetch LINES of TEXTOBJ))
		 (WINDOW (fetch \WINDOW of TEXTOBJ))
		 (HEIGHTCHANGED NIL)
		 (NLINE1 NIL)
		 (CRFLAG NIL)
		 (LINES\DELETED NIL)
		 OLINE1 OLINEN LEN NEXTLINE NL OLINE DX OCHLIM OXLIM OLHEIGHT OLASCENT OLDESCENT DY 
		 PREVLINE TEXTLEN OCR\END SAVEWIDTH IMAGECACHE)
	        [SETQ LEN (COND
		    ((IGREATERP CH# (fetch TEXTLEN of TEXTOBJ))
                                                             (* Past end of text, so don't delete any)
		      0)
		    ((IGEQ CH# CHLIM)                        (* Start is past end, so don't delete any.)
		      0)
		    ((ZEROP (fetch DCH of SEL))              (* Just a caret--no text really selected--so don't 
							     delete any)
		      0)
		    ((ZEROP CHLIM)                           (* CHLIM is before start of text, so don't delete any)
		      0)
		    (T                                       (* The normal case.)
		       (IDIFFERENCE CHLIM CH#]               (* # of characters to be deleted)
	        (COND
		  ((OR (NOT (fetch SET of SEL))
		       (ZEROP LEN))                          (* If the selection isn't set, don't do anything.)
		    (RETURN)))
	        (AND WINDOW (TEDIT.NORMALIZECARET TEXTOBJ SEL))
                                                             (* If the text appears in a window, move the deletion 
							     point on-screen)
	        (SETQ OLINE1 (fetch L1 of SEL))
	        (SETQ OLINEN (fetch LN of SEL))
	        (\TEDIT.SHOWSELS TEXTOBJ NIL NIL)            (* Turn off the selection's highlighting)
	        (AND LINES (\FIXDLINES LINES SEL CH# CHLIM TEXTOBJ))
                                                             (* Update the line descriptors to account for the 
							     deletion)
	        (\DELETECH CH# CHLIM LEN TEXTOBJ)            (* Do the actual deletion of characters)
	        (replace THPOINT of (fetch TXTHISTORY of TEXTOBJ) with (fetch POINT of SEL))
                                                             (* Remember which side of the selection we were on, in 
							     case it gets undone.)
	        (replace CH# of SEL with (IMAX 1 CH#))
	        (replace CHLIM of SEL with (fetch CH# of SEL))
	        (replace POINT of SEL with (QUOTE LEFT))
	        (replace DCH of SEL with 0)
	        (COND
		  ((NOT WINDOW)                              (* If there's no window to update, don't bother)
		    (RETURN)))
	        (SETQ TEXTLEN (fetch TEXTLEN of TEXTOBJ))    (* The new text length)
	        (for OLINE1 inside (fetch L1 of SEL) as OLINEN inside (fetch LN of SEL) as TOPLINE
		   inside (fetch LINES of TEXTOBJ) as THISW inside WINDOW
		   do (SETQ LINES\DELETED
			(\TEDIT.CLOSEUPLINES TEXTOBJ
					     (OR (AND OLINE1 (COND
							((fetch DELETED of OLINE1)
							  (fetch PREVLINE of OLINE1))
							(T OLINE1)))
						 (COND
						   ([AND (fetch NEXTLINE of TOPLINE)
							 (OR (IGEQ (fetch CHAR1
								      of (fetch NEXTLINE
									    of TOPLINE))
								   (fetch CHLIM of SEL))
							     (ILESSP (fetch CHARLIM
									of (fetch NEXTLINE
									      of TOPLINE))
								     (fetch CH# of SEL]
                                                             (* The first line on the screen is already past where 
							     we're to delete. DON'T delete any lines)
						     NIL)
						   (T TOPLINE)))
					     (AND OLINEN (COND
						    ((fetch DELETED of OLINEN)
						      (fetch NEXTLINE of OLINEN))
						    (T OLINEN)))
					     NIL THISW)))    (* Remove any lines which were completely deleted.)
	        (COND
		  ((OR T (LISTP WINDOW)
		       (TEXTPROP TEXTOBJ (QUOTE SLOWUPDATE))
		       (NOT OLINE1)
		       (NOT OLINEN)
		       (OR (NEQ (fetch QUAD of (fetch LFMTSPEC of OLINE1))
				(QUOTE LEFT))
			   (IGREATERP (fetch RIGHTMAR of (fetch LFMTSPEC of OLINE1))
				      (fetch WRIGHT of TEXTOBJ)))
		       (fetch LHASTABS of OLINE1)
		       (fetch LHASTABS of OLINEN))           (* This line must needs be reformatted the hard way--it
							     isn't a left ragged line or one of the lines is 
							     off-screen.)
		    (replace (SELECTION DX) of SEL with 0)
		    (TEDIT.UPDATE.SCREEN TEXTOBJ NIL T)      (* Correct the text that's displayed already)
		    (\FIXSEL (fetch SEL of TEXTOBJ)
			     TEXTOBJ)                        (* Then fix up the selection as needed.)
		    (\TEDIT.SHOWSELS TEXTOBJ NIL T)
		    (RETURN])

(\TEDIT.DIFFUSE.PARALOOKS
  [LAMBDA (PRIORPC SUCCEEDINGPC)                             (* jds " 6-Dec-84 13:34")

          (* Given a discontinuity in paragraph looks, caused by an insertion or by a deletion: Diffuse the existing paragraph
	  looks across the discontinuity, so that all the pieces in a single paragraph have consistent looks.
	  Give preference to diffusion toward the END of the document. This means that if you delete a CR between paragraphs, 
	  the second para is absorbed into the first.)

                                                             (* PRIORPC and SUCCEEDINGPC are the PIECEs that bound 
							     the area of potential discontinuity: the change will 
							     occur at one boundary or the other....)
    [COND
      ((AND PRIORPC (NOT (fetch PPARALAST of PRIORPC)))      (* The discontinuity is inside a paragraph.
							     Must copy para looks forward into the text.)
	(bind (PPLOOKS ←(fetch PPARALOOKS of PRIORPC))
	      (PC ←(fetch NEXTPIECE of PRIORPC)) while PC
	   do                                                (* Copy para looks info in from the left, up the the 
							     first para break.)
	      (replace PPARALOOKS of PC with PPLOOKS)
	      (COND
		((fetch PPARALAST of PC)                     (* If this piece ends a paragraph, we're done.)
		  (RETURN)))
	      (SETQ PC (fetch NEXTPIECE of PC]
    (COND
      ((AND SUCCEEDINGPC (NEQ SUCCEEDINGPC (QUOTE LASTPIECE)))
                                                             (* Only copy para looks in from the right if there is 
							     text to the right.)
	(bind (PPLOOKS ←(fetch PPARALOOKS of SUCCEEDINGPC))
	      (PC ←(fetch PREVPIECE of SUCCEEDINGPC)) while (NEQ PC PRIORPC)
	   do                                                (* Copy para looks in from the right, up to the first 
							     para break)
	      (COND
		((fetch PPARALAST of PC)                     (* If this piece ends a paragraph, we're done.)
		  (RETURN)))
	      (replace PPARALOOKS of PC with PPLOOKS)
	      (SETQ PC (fetch PREVPIECE of PC])

(\TEDIT.FOREIGN.COPY?
  [LAMBDA (SEL)                                              (* jds "19-Dec-85 16:56")

          (* IF the current process's window isn't a TEdit window, do a "Copy" by BKSYSBUFing the selected text.
	  Then turn off all the various indicators.)


    (PROG (PROCW (SOURCE.TEXTOBJ (fetch \TEXTOBJ of SEL))
		   CH STREAM DEST.TEDIT? DEST.TEXTOBJ)
	    [SETQ DEST.TEDIT? (AND (SETQ PROCW (PROCESSPROP (TTY.PROCESS)
								    (QUOTE WINDOW)))
				       (SETQ DEST.TEXTOBJ (WINDOWPROP PROCW (QUOTE TEXTOBJ)))
				       (NOT (TEXTPROP DEST.TEXTOBJ (QUOTE COPYBYBKSYSBUF]

          (* Treat the destination specially if (1) the recipient process has a window, and (2) it's a TEdit window, and 
	  (3) the TEdit isn't declining special treatment by having COPYBYBKSYSBUF set in its props.)


	    (COND
	      ((OR (NOT DEST.TEDIT?)
		     (AND PROCW DEST.TEXTOBJ (NEQ SOURCE.TEXTOBJ DEST.TEXTOBJ)
			    (fetch EDITOPACTIVE of DEST.TEXTOBJ)))
                                                             (* OK -- receiver isn't TEdit.
							     Do it the hard way.)
		(\SETUPGETCH (fetch CH# of SEL)
			       SOURCE.TEXTOBJ)               (* Go to the first character to be copied)
		(SETQ STREAM (fetch STREAMHINT of SOURCE.TEXTOBJ))
		[for I from 1 to (fetch DCH of SEL)
		   do                                      (* Run thru the selected text, copying only those 
							     items that really ARE characters--IMAGEOBJs don't get 
							     copied by this route.)
			(COND
			  ((FIXP (SETQ CH (\BIN STREAM)))
			    (BKSYSBUF (CHARACTER CH)))
			  (T (COPYINSERT CH]
		(\SHOWSEL SEL NIL NIL)                     (* Then reset the copy-pending flags.)
		(SETQ TEDIT.COPY.PENDING NIL])

(\TEDIT.QUIT
  [LAMBDA (W NOFORCE)                                        (* jds " 7-May-85 15:31")
                                                             (* Called by the default TEDIT.DEFAULT.MENUFN to 
							     perform the QUIT command.)
    (PROG* ((TEXTOBJ (WINDOWPROP W (QUOTE TEXTOBJ)))
	    (QUITFNS (TEXTPROP TEXTOBJ (QUOTE QUITFN)))
	    QUITFLG RESP)
           [for QUITFN inside QUITFNS while (AND (NEQ QUITFLG (QUOTE DON'T))
						 (NEQ QUITFLG T))
	      do (COND
		   ((EQ QUITFN T)
		     (SETQ QUITFLG T))
		   (T (AND QUITFN (NEQ QUITFN T)
			   (SETQ QUITFLG (APPLY* QUITFN W (fetch STREAMHINT of TEXTOBJ)
						 TEXTOBJ
						 (fetch EDITPROPS of TEXTOBJ]
           (COND
	     ((EQ QUITFLG (QUOTE DON'T))                     (* The user supplied a QUITFN, and it returned "DON'T",
							     so just ignore all this Fooferaw and keep editing.)
	       (RETURN))
	     [(AND (fetch \DIRTY of TEXTOBJ)
		   (NOT (fetch MENUFLG of TEXTOBJ))
		   (NEQ QUITFNS T)
		   (NEQ QUITFLG T))                          (* If this document has changed, check with the user to
							     make sure he really wants to do it.)
	       (replace EDITFINISHEDFLG of TEXTOBJ with (MOUSECONFIRM 
							    "Not saved yet; LEFT to Quit anyway."
								      T
								      (fetch PROMPTWINDOW
									 of TEXTOBJ]
	     (T                                              (* Go ahead and quit the next time we see the main 
							     command loop.)
		(replace EDITFINISHEDFLG of TEXTOBJ with T)))
           [AND (fetch \WINDOW of TEXTOBJ)
		(NOT NOFORCE)
		(NEQ (\TEDIT.PRIMARYW TEXTOBJ)
		     (PROCESSPROP (TTY.PROCESS)
				  (QUOTE WINDOW)))
		(TTY.PROCESS (WINDOWPROP (\TEDIT.PRIMARYW TEXTOBJ)
					 (QUOTE PROCESS]
           (RETURN (fetch EDITFINISHEDFLG of TEXTOBJ])

(\TEDIT.WORDDELETE
  [LAMBDA (TEXTOBJ)                                          (* jds " 7-Mar-85 03:50")
                                                             (* Delete the word to the left of the caret.)
    (PROG ((SEL (fetch SEL of TEXTOBJ))
	   (STREAM (fetch STREAMHINT of TEXTOBJ))
	   (READSA (fetch READSA of (OR (fetch TXTWTBL of TEXTOBJ)
					TEDIT.WORDBOUND.READTABLE)))
	   INSCH# CH CHNO)                                   (* Back word.)
          (SETQ INSCH# (SELECTQ (fetch POINT of SEL)
				(LEFT (SUB1 (fetch CH# of SEL)))
				(RIGHT (SUB1 (fetch CHLIM of SEL)))
				NIL))                        (* Find the place to delete backward from)
          (COND
	    ((IGREATERP INSCH# 0)                            (* Don't try to back up past start of file.)
	      (\SETUPGETCH INSCH# TEXTOBJ)
	      (SETQ CH (\BIN STREAM))
	      (for old CHNO from INSCH# to 1 by -1
		 while [AND (SELECTC (COND
				       ((FIXP CH)
					 (\SYNCODE READSA CH))
				       (T                    (* It's an object!)
					  TEXT.TTC))
				     (TEXT.TTC NIL)
				     T)
			    (NOT (fetch CLPROTECTED of (fetch PLOOKS of (fetch (TEXTSTREAM PIECE)
									   of STREAM]
		 do (SETQ CH (\GETCHB TEXTOBJ)))             (* Skip over any initial separator characters)
	      (for old CHNO from CHNO to 1 by -1
		 while [AND (SELECTC (COND
				       ((FIXP CH)
					 (\SYNCODE READSA CH))
				       (T                    (* It's an object!)
					  TEXT.TTC))
				     (TEXT.TTC T)
				     NIL)
			    (NOT (fetch CLPROTECTED of (fetch PLOOKS of (fetch (TEXTSTREAM PIECE)
									   of STREAM]
		 do (SETQ CH (\GETCHB TEXTOBJ)))             (* Skip over the next group of non-separators 
							     (= a "word"))
	      (\SHOWSEL SEL NIL NIL)
	      [replace CH# of SEL with (COND
					 ((ILEQ CHNO 1)
					   1)
					 (T (IPLUS 2 CHNO]   (* First character to delete)
	      (replace CHLIM of SEL with (ADD1 INSCH#))
	      (replace DCH of SEL with (IDIFFERENCE INSCH# CHNO))
	      (\FIXSEL SEL TEXTOBJ)
	      (\SHOWSEL SEL NIL T)
	      (\TEDIT.DELETE SEL TEXTOBJ])

(\TEDIT1
  [LAMBDA (TEXT WINDOW UNSPAWNED PROPS)                      (* jds " 7-May-85 15:32")
                                                             (* Does the actual editing work, and re-coercion or 
							     process kill when done. Called by TEDIT directly, or 
							     ADD.PROCESSed by it.)
    (SETQ TEXT (OPENTEXTSTREAM TEXT WINDOW NIL NIL PROPS))   (* Open the text for editing)
    (\TEDIT.COMMAND.LOOP (fetch (TEXTSTREAM TEXTOBJ) of TEXT))
                                                             (* Run the editing engine)
    (CLOSEW WINDOW)
    (replace \WINDOW of (fetch (TEXTSTREAM TEXTOBJ) of TEXT) with NIL)
    (AND (TEXTPROP (fetch (TEXTSTREAM TEXTOBJ) of TEXT)
		   (QUOTE AFTERQUITFN))
	 (APPLY* (TEXTPROP (fetch (TEXTSTREAM TEXTOBJ) of TEXT)
			   (QUOTE AFTERQUITFN))
		 WINDOW TEXT))                               (* Apply any post-window-close 
							     (and post-QUIT) function)
    (COND
      (UNSPAWNED                                             (* We're not a distinct process: Send back the edited 
							     text in some suitable form)
		 (COND
		   ((NEQ (fetch EDITFINISHEDFLG of (fetch (TEXTSTREAM TEXTOBJ) of TEXT))
			 T)
		     (PROG1 (fetch EDITFINISHEDFLG of (fetch (TEXTSTREAM TEXTOBJ) of TEXT))
			    (replace EDITFINISHEDFLG of (fetch (TEXTSTREAM TEXTOBJ) of TEXT)
			       with NIL)))
		   ((STRINGP (fetch TXTFILE of (fetch (TEXTSTREAM TEXTOBJ) of TEXT)))
		     (COERCETEXTOBJ (fetch (TEXTSTREAM TEXTOBJ) of TEXT)
				    (QUOTE STRINGP)))
		   (T TEXT])
)



(* Debugging functions)

(DEFINEQ

(PLCHAIN
  [LAMBDA (LN)                                                         (* jds 
                                                                           "21-JAN-82 09:57")
    (PRINTLINE LN)
    (COND
       ((fetch NEXTLINE of LN)
        (PLCHAIN (fetch NEXTLINE of LN])

(PRINTLINE
  [LAMBDA (LN)                                                         (* jds 
                                                                           "27-Aug-84 15:35")
                                                                           (* Print out a line 
                                                                           descriptor in a 
                                                                           reasonable form.)
    (printout T "-----" T LN "  Bot: " (fetch YBOT of LN)
           "  Base: "
           (fetch YBASE of LN)
           "  Height: "
           (fetch LHEIGHT of LN)
           "  Ascent: "
           (fetch ASCENT of LN)
           "  Descent: "
           (fetch DESCENT of LN)
           T "Char1: " (fetch CHAR1 of LN)
           "  Lim: "
           (fetch CHARLIM of LN)
           "  Top: "
           (fetch CHARTOP of LN))
    (COND
       ((fetch DIRTY of LN)
        (PRIN1 "  DIRTY")))
    (COND
       ((fetch CR\END of LN)
        (PRIN1 "  CR-at-end")))
    (COND
       ((fetch DELETED of LN)
        (PRIN1 "  DELETED")))
    (COND
       ((fetch LHASPROT of LN)
        (PRIN1 "  [Protected text]")))
    (COND
       ((fetch LHASTABS of LN)
        (PRIN1 "  Has Tabs")))
    (PRIN1 ".
")
    (printout T "RMar: " (fetch RIGHTMARGIN of LN)
           "  XLim: "
           (fetch LXLIM of LN)
           "  Left: "
           (fetch SPACELEFT of LN)
           T "Prev:  " (fetch PREVLINE of LN)
           T "Next:  " (fetch NEXTLINE of LN)
           T)
    (COND
       ((AND (IGEQ (fetch CHAR1 of LN)
                   1)
             (ILEQ (fetch CHAR1 of LN)
                   (fetch TEXTLEN of TEXTOBJ)))                    (* The line is real 
                                                                           -- print it.)
        (\SETUPGETCH (fetch CHAR1 of LN)
               TEXTOBJ)
        (PRIN1 "|")
        [bind CH for CHNO from (fetch CHAR1 of LN)
           to (IMIN (fetch TEXTLEN of TEXTOBJ)
                        (fetch CHARLIM of LN)) do (SETQ CH (\GETCH TEXTOBJ))
                                                             (COND
                                                                ((SMALLP CH)
                                                                 (PRIN1 (CHARACTER CH)))
                                                                (T (PRINT CH]
        (PRIN1 "|
"])

(SEEFILE
  [LAMBDA (FILE ST ND)                                                 (* jds 
                                                                           " 4-NOV-83 20:21")
    (PROG (CH)
          [SETQ FILE (OR (OPENP FILE)
                         (OPENSTREAM FILE (QUOTE INPUT]
          (SETFILEPTR FILE (OR ST 0))
          (for I from (OR ST 0) to (OR ND (SUB1 (GETEOFPTR FILE)))
             do (printout T I 5 (SETQ CH (BIN FILE))
                           9
                           (COND
                              [(ILEQ CH (CHARCODE ↑Z))
                               (CONCAT "↑" (CHARACTER (IPLUS CH (CHARCODE @]
                              (T (CHARACTER CH)))
                           T])
)



(* Object-oriented editing)

(DEFINEQ

(TEDIT.INSERT.OBJECT
  [LAMBDA (OBJECT STREAM CH#)                                (* jds " 6-Mar-85 21:44")
                                                             (* Inserts the annotation OBJECT into text STREAM in 
							     front of character CH.)
    (PROG ((TEXTOBJ (TEXTOBJ STREAM))
	   SEL SUBSTREAM)
          (SETQ SEL (fetch SEL of TEXTOBJ))
          (COND
	    ((NULL CH#)                                      (* Omitted CH# means put it at the current spot.)
	      (SETQ CH# SEL)))
          [COND
	    ((type? SELECTION CH#)                           (* If the CH# passed in was a selection 
							     (or we set it because he defaulted CH#), then compute 
							     the REAL CH#.)
	      (SETQ CH# (SELECTQ (fetch POINT of CH#)
				 (LEFT (fetch CH# of CH#))
				 (RIGHT (fetch CHLIM of CH#))
				 (SHOULDNT]
          (PROG ((PCTB (ffetch PCTB of TEXTOBJ))
		 TEXTLEN PC PCNO CHNO NEWPC PREVPC INSERTFN)
	        (TEDIT.DO.BLUEPENDINGDELETE SEL TEXTOBJ)     (* Do the pending delete, if there is one.)
	        (\SHOWSEL SEL NIL NIL)                       (* Turn off the selection for now)
	        (SETQ TEXTLEN (fetch TEXTLEN of TEXTOBJ))
	        (SETQ CH# (IMIN CH# (ADD1 TEXTLEN)))         (* CH# we're to insert these characters in front of)
	        (freplace \INSERTFIRSTCH of TEXTOBJ with -1)
	        [SETQ PC (COND
		    ((ILEQ CH# TEXTLEN)
		      (SETQ PCNO (\CHTOPCNO CH# PCTB))
		      (\EDITELT PCTB (ADD1 PCNO)))
		    (T (SETQ PCNO (SUB1 (\EDITELT PCTB \PCTBLastPieceOffset)))
		       (QUOTE LASTPIECE]                     (* Piece we're to insert in front of or inside)
	        (SETQ NEWPC (create PIECE
				    PSTR ← NIL
				    PFILE ← NIL
				    POBJ ← OBJECT
				    PLEN ← 1))               (* The new piece we're inserting)
	        [COND
		  ((SETQ SUBSTREAM (IMAGEOBJPROP OBJECT (QUOTE SUBSTREAM)))
                                                             (* If this is computed text in bulk, fix the length.)
		    (replace PLEN of NEWPC with (fetch TEXTLEN of (fetch (TEXTSTREAM TEXTOBJ)
								     of SUBSTREAM]
	        [COND
		  ((OR (IGREATERP CH# TEXTLEN)
		       (IEQP CH# (\EDITELT PCTB PCNO)))      (* We're inserting on a piece boundary;
							     do it, then remember the prior piece.)
		    (\INSERTPIECE NEWPC PC TEXTOBJ NIL PCNO))
		  (T                                         (* Not on a piece boundary; split the piece we're 
							     inside of, then insert.)
		     (\INSERTPIECE NEWPC (\SPLITPIECE PC CH# TEXTOBJ)
				   TEXTOBJ NIL (IPLUS PCNO \EltsPerPiece]
	        (COND
		  ((SETQ INSERTFN (IMAGEOBJPROP OBJECT (QUOTE WHENINSERTEDFN)))
                                                             (* If there is a WHENINSERTEDFN, apply it.)
		    (APPLY* INSERTFN OBJECT (WINDOWPROP (CAR (fetch \WINDOW of TEXTOBJ))
							(QUOTE DSP))
			    NIL STREAM)))
	        (SETQ PCTB (fetch PCTB of TEXTOBJ))
	        (SETQ PREVPC (fetch PREVPIECE of NEWPC))     (* Fill in the para looks)
	        [COND
		  [PREVPC (COND
			    [(AND (fetch PPARALAST of PREVPC)
				  (fetch NEXTPIECE of NEWPC))
			      (replace PPARALOOKS of NEWPC with (fetch PPARALOOKS
								   of (fetch NEXTPIECE of NEWPC]
			    (T (replace PPARALOOKS of NEWPC with (fetch PPARALOOKS of PREVPC]
		  (T (COND
		       ((SETQ PREVPC (fetch NEXTPIECE of NEWPC))
			 (replace PPARALOOKS of NEWPC with (fetch PPARALOOKS of PREVPC)))
		       (T (replace PPARALOOKS of NEWPC with (fetch FMTSPEC of TEXTOBJ]
	        (replace PLOOKS of NEWPC with (fetch CARETLOOKS of TEXTOBJ))
	        (\TEDIT.HISTORYADD TEXTOBJ (create TEDITHISTORYEVENT
						   THACTION ←(QUOTE Insert)
						   THCH# ← CH#
						   THLEN ← 1
						   THFIRSTPIECE ← NEWPC))
	        (SETQ TEXTLEN (freplace TEXTLEN of TEXTOBJ with (IPLUS (fetch PLEN of NEWPC)
								       TEXTLEN)))
	        (replace \INSERTPCVALID of TEXTOBJ with NIL)
                                                             (* Since adding an IMAGEOBJ creates a new piece, the 
							     old insertion cache piece is no longer valid.)
	        (replace \DIRTY of TEXTOBJ with T)
	        (replace DESC of (fetch THISLINE of TEXTOBJ) with NIL)
	        (replace SELKIND of SEL with (QUOTE CHAR))
	        (COND
		  ((fetch \WINDOW of TEXTOBJ)
		    (\FIXILINES TEXTOBJ SEL CH# (fetch PLEN of NEWPC)
				(SUB1 TEXTLEN))
		    (replace DCH of SEL with 0)
		    (replace (SELECTION DX) of SEL with 0)
		    (TEDIT.UPDATE.SCREEN TEXTOBJ)
		    (\FIXSEL SEL TEXTOBJ)
		    (\SHOWSEL SEL NIL T))
		  (T [replace CHLIM of SEL with (replace CH# of SEL
						   with (IPLUS CH# (fetch PLEN of NEWPC]
		     (replace DCH of SEL with 0)
		     (replace (SELECTION DX) of SEL with 0)
		     (replace POINT of SEL with (QUOTE LEFT))
		     (replace DESC of (fetch THISLINE of TEXTOBJ) with NIL)))
	        (\COPYSEL SEL TEDIT.SELECTION])

(TEDIT.EDIT.OBJECT
  [LAMBDA (STREAM OBJ)                                       (* jds " 6-Mar-85 21:07")
    (PROG ([TEXTOBJ (COND
		      ((type? TEXTOBJ STREAM)
			STREAM)
		      ((type? STREAM STREAM)
			(fetch (TEXTSTREAM TEXTOBJ) of STREAM))
		      ((SHOULDNT]
	   SEL LL CH# SELOBJ EDITFN)
          [COND
	    [(AND OBJ (IMAGEOBJP OBJ))
	      (SETQ CH# (TEDIT.FIND.OBJECT TEXTOBJ OBJ))
	      (COND
		(CH# (SETQ SEL (fetch SCRATCHSEL of TEXTOBJ))
		     (replace CH# of SEL with CH#)
		     (replace CHLIM of SEL with (ADD1 CH#))
		     (SETQ SELOBJ OBJ)
		     (replace DCH of SEL with 1)
		     (replace \TEXTOBJ of SEL with TEXTOBJ)
		     (\FIXSEL SEL TEXTOBJ))
		(T (TEDIT.PROMPTPRINT TEXTOBJ "Can't find specified object." T]
	    (T (SETQ SEL (fetch SEL of TEXTOBJ))
	       (SETQ OBJ (fetch SELOBJ of SEL]
          (COND
	    [OBJ                                             (* OK There's an object selected.
							     Edit it.)
		 (SETQ EDITFN (IMAGEOBJPROP OBJ (QUOTE EDITFN)))
		 (COND
		   ((AND EDITFN (APPLY* EDITFN OBJ))         (* If the editfn makes a change, update the screen.)
		     (for LINE inside (fetch L1 of SEL) do (replace DIRTY of LINE with T))
		     (replace TXTNEEDSUPDATE of TEXTOBJ with T)
		     (TEDIT.UPDATE.SCREEN TEXTOBJ]
	    (T                                               (* No object selected.)
	       (TEDIT.PROMPTPRINT TEXTOBJ "Please select an editable object first." T])

(TEDIT.FIND.OBJECT
  [LAMBDA (TEXTOBJ OBJ)                                      (* jds "22-OCT-83 17:36")
                                                             (* Find OBJ, if it's in TEXTOBJ, and return CH#.
							     Else return nil)
    (SETQ TEXTOBJ (TEXTOBJ TEXTOBJ))
    (PROG ((PCTB (fetch PCTB of TEXTOBJ))
	   PC)
          (RETURN (for PCNO from (ADD1 \FirstPieceOffset) to (\EDITELT PCTB \PCTBLastPieceOffset)
		     by \EltsPerPiece
		     do (SETQ PC (\EDITELT PCTB PCNO))
			(COND
			  ((EQ (fetch POBJ of PC)
			       OBJ)
			    (RETURN (\EDITELT PCTB (SUB1 PCNO])

(TEDIT.PUT.OBJECT
  [LAMBDA (PIECE OFILE FONTFILE CURCH#)                      (* jds "19-Feb-85 10:12")
                                                             (* Given a piece which describes an object, put the 
							     object out there.)
    (PROG ((OBJECT (fetch POBJ of PIECE))
	   (FONTCH# (GETFILEPTR FONTFILE))
	   TOFILE LEN)
          (\DWOUT FONTFILE 0)                                (* Placeholder for length of the object's description)
          (\SMALLPOUT FONTFILE \PieceDescriptorOBJECT)       (* Mark this as setting the piece's looks)
          (\ATMOUT FONTFILE (IMAGEOBJPROP OBJECT (QUOTE GETFN)))
                                                             (* The FN to apply to reconstruct the object)
          (APPLY* (IMAGEOBJPROP OBJECT (QUOTE PUTFN))
		  OBJECT OFILE)
          (SETFILEPTR FONTFILE FONTCH#)                      (* Now go back and fill in the length of the text 
							     description of the object.)
          [\DWOUT FONTFILE (SETQ LEN (ADD1 (IDIFFERENCE (GETEOFPTR OFILE)
							CURCH#]
          (SETFILEPTR FONTFILE -1)                           (* Make sure we're at the end of the font file)
          (AND (RANDACCESSP OFILE)
	       (SETFILEPTR OFILE -1))                        (* And the text part of the file)
          (RETURN LEN])

(TEDIT.GET.OBJECT
  [LAMBDA (STREAM PIECE FILE CURCH#)                                       (* rrb 
                                                                           " 3-Feb-86 19:13")
                                                                           (* Get an object from 
                                                                           the file)
                                                                           (* CURCH# = fileptr 
                                                                           within the text section 
                                                                           of the file where the 
                                                                           object's text starts.)
    (PROG ((TEXTOBJ (fetch (TEXTSTREAM TEXTOBJ) of STREAM))
           FILEPTRSAVE NAMELEN GETFN OBJ)
          (SETQ GETFN (\ATMIN FILE))                                       (* The GETFN for this 
                                                                           kind of IMAGEOBJ)
          (SETQ FILEPTRSAVE (GETFILEPTR FILE))                             (* Save our file 
                                                                           location thru the 
                                                                           building of the object)
          (SETFILEPTR FILE CURCH#)
          (SETQ OBJ (READIMAGEOBJ FILE GETFN NIL FILEPTRSAVE))
          (COND
             ((IMAGEOBJPROP OBJ (QUOTE UNKNOWNGETFN))                      (* If the object has an 
                                                                           unknown getfn property, 
                                                                           then it's an 
                                                                           encapsulated object.
                                                                           Warn the user)
              (TEDIT.PROMPTPRINT STREAM "WARNING: Document contains unknown image objects." T)))
          (SETFILEPTR FILE FILEPTRSAVE)
          (replace POBJ of PIECE with OBJ)
          (replace PFILE of PIECE with NIL)
          (replace PSTR of PIECE with NIL)
          [replace PLOOKS of PIECE with (COND
                                           ((fetch PREVPIECE of PIECE)
                                            (fetch PLOOKS of (fetch PREVPIECE of PIECE)))
                                           (T (OR (fetch DEFAULTCHARLOOKS of TEXTOBJ)
                                                  (\TEDIT.UNIQUIFY.CHARLOOKS (CHARLOOKS.FROM.FONT
                                                                              DEFAULTFONT)
                                                         TEXTOBJ]
          (RETURN (fetch POBJ of PIECE])

(TEDIT.OBJECT.CHANGED
  [LAMBDA (STREAM OBJECT)                                    (* jds " 7-Feb-85 13:44")
                                                             (* Notify TEdit that an object has changed, and the 
							     display may need to be updated.)
    (PROG ((TEXTOBJ (TEXTOBJ STREAM))
	   (LINES (fetch LINES of (TEXTOBJ STREAM)))
	   PCINFO CHANGED CHANGEDCH#)
          (SETQ PCINFO (TEDIT.MAPPIECES TEXTOBJ [FUNCTION (LAMBDA (CH# PC PCNO OBJ)
					    (AND (EQ OBJ (fetch POBJ of PC))
						 (QUOTE STOP]
					OBJECT))             (* Find the piece containing this object)
          (OR PCINFO (HELP "Changed OBJECT not found!?"))
          (SETQ CHANGEDCH# (CAR PCINFO))                     (* Get the CH# of the changed object)
          (\TEDIT.MARK.LINES.DIRTY TEXTOBJ CHANGEDCH# CHANGEDCH#)
                                                             (* Mark affected lines)
          (replace \DIRTY of TEXTOBJ with T)                 (* And mark the document dirty.)
          (\SHOWSEL (fetch SEL of TEXTOBJ)
		    NIL NIL)
          (TEDIT.UPDATE.SCREEN TEXTOBJ)
          (\FIXSEL (fetch SEL of TEXTOBJ)
		   TEXTOBJ)
          (\SHOWSEL (fetch SEL of TEXTOBJ)
		    NIL T])
)
(FILESLOAD TEDITFIND TEDITHISTORY TEDITFILE TEDITWINDOW TEDITSELECTION IMAGEOBJ TFBRAVO TEDITHCPY 
       TEDITMENU TEDITFNKEYS)



(* TEDIT Support information)


(RPAQQ TEDITSYSTEMDATE "10-Feb-86 12:14:25")

(RPAQ TEDITSUPPORT "TEditSupport.PA")
(DEFINEQ

(MAKETEDITFORM
  [LAMBDA NIL                                                (* jds "12-Mar-85 04:00")
                                                             (* Builds a trouble-report form for TEdit.)
    (MAKEXXXSUPPORTFORM "TEdit" TEDITSUPPORT TEDITSYSTEMDATE])
)
(ADDTOVAR LAFITESPECIALFORMS ("TEdit Report" (QUOTE MAKETEDITFORM)
                                    "Report a problem with TEdit"))
(SETQ LAFITEFORMSMENU NIL)



(* LISTFILES Interface, so the system can decide if a file is a TEdit file.)


(ADDTOVAR PRINTFILETYPES (TEDIT (TEST \TEDIT.FORMATTEDP1)
                                    (EXTENSION (TEDIT))))
(PUTPROPS TEDIT COPYRIGHT ("John Sybalsky & Xerox Corporation" 1983 1984 1985 1986))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (2895 77703 (\TEDIT2 2905 . 4738) (COERCETEXTOBJ 4740 . 8980) (TEDIT 8982 . 12539) (
TEDIT.CHARWIDTH 12541 . 14199) (TEDIT.COPY 14201 . 19845) (TEDIT.DELETE 19847 . 20373) (
TEDIT.DO.BLUEPENDINGDELETE 20375 . 22532) (TEDIT.INSERT 22534 . 26540) (TEDIT.KILL 26542 . 27793) (
TEDIT.MAPLINES 27795 . 28761) (TEDIT.MAPPIECES 28763 . 29888) (TEDIT.MOVE 29890 . 36540) (TEDIT.QUIT 
36542 . 38196) (TEDIT.STRINGWIDTH 38198 . 38747) (TEDIT.\INSERT 38749 . 40326) (TEXTOBJ 40328 . 41413)
 (TEXTSTREAM 41415 . 42759) (\TEDIT.INCLUDE 42761 . 44920) (\TEDIT.INSERT.PIECES 44922 . 50791) (
\TEDIT.MOVE.PIECEMAPFN 50793 . 52221) (\TEDIT.OBJECT.SHOWSEL 52223 . 54515) (\TEDIT.RESTARTFN 54517 . 
56145) (\TEDIT.CHARDELETE 56147 . 59171) (\TEDIT.COPY.PIECEMAPFN 59173 . 61427) (\TEDIT.DELETE 61429
 . 67119) (\TEDIT.DIFFUSE.PARALOOKS 67121 . 69427) (\TEDIT.FOREIGN.COPY? 69429 . 71370) (\TEDIT.QUIT 
71372 . 73444) (\TEDIT.WORDDELETE 73446 . 75905) (\TEDIT1 75907 . 77701)) (77736 81482 (PLCHAIN 77746
 . 78064) (PRINTLINE 78066 . 80727) (SEEFILE 80729 . 81480)) (81519 95186 (TEDIT.INSERT.OBJECT 81529
 . 87193) (TEDIT.EDIT.OBJECT 87195 . 88892) (TEDIT.FIND.OBJECT 88894 . 89580) (TEDIT.PUT.OBJECT 89582
 . 91018) (TEDIT.GET.OBJECT 91020 . 93813) (TEDIT.OBJECT.CHANGED 93815 . 95184)) (95447 95744 (
MAKETEDITFORM 95457 . 95742)))))
STOP