(FILECREATED "24-May-84 15:41:29" {DSK}TEDITSELECTION.;8 80160  

      changes to:  (FNS \SHOWSEL)

      previous date: "24-May-84 11:00:40" {DSK}TEDITSELECTION.;7)


(PRETTYCOMPRINT TEDITSELECTIONCOMS)

(RPAQQ TEDITSELECTIONCOMS ((RECORDS SELECTION)
	(FNS TEDIT.SEL.AS.STRING TEDIT.SELECTED.PIECES \TEDIT.FIND.FIRST.LINE \TEDIT.FIND.LAST.LINE 
	     \TEDIT.FIND.OVERLAPPING.LINE \TEDIT.FIND.PROTECTED.END \TEDIT.FIND.PROTECTED.START 
	     \TEDIT.WORD.BOUND)
	(FILES TEXTOFD)
	(CONSTANTS (COPYSELSHADE 30583)
		   (EDITMOVESHADE -1)
		   (EDITGRAY 32800))
	(INITVARS (TEDIT.EXTEND.PENDING.DELETE T))
	(VARS (TEDIT.SELECTION (create SELECTION))
	      (TEDIT.SCRATCHSELECTION (create SELECTION))
	      (TEDIT.SHIFTEDSELECTION (create SELECTION HOW←COPYSELSHADE HASCARET←NIL))
	      (TEDIT.MOVESELECTION (CREATE SELECTION HOW←EDITMOVESHADE HASCARET←NIL HOWHEIGHT←32767))
	      (TEDIT.DELETESELECTION (CREATE SELECTION HOW←BLACKSHADE HASCARET←NIL HOWHEIGHT←32767))
	      SELECTION SELECTION (TEDIT.SELPENDING NIL))
	(GLOBALVARS TEDIT.SELECTION TEDIT.SCRATCHSELECTION TEDIT.MOVESELECTION TEDIT.SHIFTEDSELECTION 
		    TEDIT.DELETESELECTION TEDIT.SELPENDING TEDIT.EXTEND.PENDING.DELETE)
	(COMS (* Selection manipulating code)
	      (FNS \SHOWSEL TEDIT.EXTEND.SEL TEDIT.GETSEL TEDIT.MAKESEL 
		   TEDIT.RESET.EXTEND.PENDING.DELETE TEDIT.SCANSEL TEDIT.SELECT TEDIT.SCAN.LINE 
		   TEDIT.SELECT.LINE.SCANNER TEDIT.SET.SEL.LOOKS TEDIT.SETSEL TEDIT.SHOWSEL \COPYSEL 
		   \FIXSEL \TEDIT.FIXDELSEL \TEDIT.FIXSELS \TEDIT.SELECT.CHARACTER \TEDIT.SHOWSELS 
		   \TEDIT.UPDATE.SHOWSEL))))
[DECLARE: EVAL@COMPILE 

(DATATYPE SELECTION (Y0                                      (* Y value of topmost line of selection)
			X0                                   (* X value of left edge of selection)
			DX                                   (* Width of the selection, if it's on one line.)
			CH#                                  (* CH# of the first selected character)
			XLIM                                 (* X value of right edge of last selected character)
			CHLIM                                (* CH# of the last character in the selection)
			DCH                                  (* # of characters selected (can be zero, for point 
							     selection.))
			L1                                   (* -> line descriptor for the line where the first 
							     selected character is)
			LN                                   (* -> line descriptor for the line which contains the 
							     end of the selection)
			YLIM                                 (* Y value of the bottom of the line that ends the 
							     selection)
			POINT                                (* Which end should the caret appear at? 
							     (LEFT or RIGHT))
			SET                                  (* T if this selection is real;
							     NIL if not)
			(\TEXTOBJ FULLXPOINTER)              (* TEXTOBJ that describes the selected text)
			SELKIND                              (* What kind of selection? CHAR or WORD or LINE or PARA)
			HOW                                  (* SHADE used to highlight this selection)
			HOWHEIGHT                            (* Height of the highlight (1 usually, full line for 
							     delete selection...))
			HASCARET                             (* T if there should be a caret for this selection)
			SELOBJ                               (* If this selection is inside an object, which object?)
			ONFLG                                (* T if the selection is highlighted on the screen, else
							     NIL)
			SELOBJINFO                           (* A Place for the selected object to put info about 
							     selection inside itself.)
			)
	  SET ← NIL HOW ← BLACKSHADE HOWHEIGHT ← 1 HASCARET ← T Y0 ← 0 X0 ← 0 POINT ←(QUOTE LEFT))
]
(/DECLAREDATATYPE (QUOTE SELECTION)
		  (QUOTE (POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER 
				  POINTER POINTER POINTER FULLXPOINTER POINTER POINTER POINTER 
				  POINTER POINTER POINTER POINTER)))
(DEFINEQ

(TEDIT.SEL.AS.STRING
  [LAMBDA (STREAM SEL)                                       (* jds "14-Feb-84 16:29")
                                                             (* Given a text stream, go to the TEXTOBJ, get the 
							     current selection, and return it as a string.)
    (SETQ STREAM (TEXTSTREAM STREAM))
    (PROG ((TEXTOBJ (fetch (TEXTSTREAM TEXTOBJ) of STREAM))
	   LEN TSEL RESULT OFFST BASE)
          (SETQ TSEL (OR SEL (fetch SEL of TEXTOBJ)))
          (SETQ LEN (fetch DCH of TSEL))
          (COND
	    ((OR (ZEROP LEN)
		 (NOT (fetch SET of TSEL)))                  (* There is no selection, or it's zero-width.
							     Return "")
	      (RETURN ""))
	    (T (SETQ RESULT (ALLOCSTRING LEN (CHARCODE SPACE)))
                                                             (* The resulting string)
	       (SETQ OFFST (fetch (STRINGP OFFST) of RESULT))
	       (SETQ BASE (\ADDBASE (fetch (STRINGP BASE) of RESULT)
				    OFFST))
	       (\SETUPGETCH (fetch CH# of TSEL)
			    TEXTOBJ)                         (* Starting point for the string is start of selection.)
	       (for I from 0 to (SUB1 LEN)
		  do                                         (* Get chars from the stream, and put them in the 
							     string.)
		     (\PUTBASEBYTE BASE I (\GETCH TEXTOBJ)))
	       (RETURN RESULT])

(TEDIT.SELECTED.PIECES
  [LAMBDA (TEXTOBJ SEL CROSSCOPY PIECEMAPFN FNARG1 FNARG2)   (* jds "12-Apr-84 15:32")

          (* Create a list of pieces corresponding to the selection; if FNARG, apply it to each piece, and use the result as
	  the copy of the piece)


    (PROG ((CH1 (fetch CH# of SEL))
	   (CHLIM (fetch CHLIM of SEL))
	   (PCTB (fetch PCTB of TEXTOBJ))
	   LEN INSPC INSPC# PC NPC PCCH NPCCH OPLEN EVENT REPLACING INSERTCH# PCLST OBJ COPYFN 
	   UNDOCHAIN)                                        (* Find the insertion point)
          (SETQ PCLST (TCONC NIL))
          [for I from \FirstPieceOffset to (IDIFFERENCE (\EDITELT PCTB \PCTBLastPieceOffset)
							\EltsPerPiece)
	     by \EltsPerPiece
	     do                                              (* Gather a list of pieces to be copied)
		(SETQ PCCH (\EDITELT PCTB I))                (* CH# for this piece)
		(SETQ PC (\EDITELT PCTB (ADD1 I)))           (* The piece itself)
		(SETQ NPCCH (\EDITELT PCTB (IPLUS I \EltsPerPiece))) 
                                                             (* Next piece's CH#)
		(COND
		  ((ILEQ NPCCH CH1)                          (* The current piece isn't inside the region to be 
							     copied.)
		    )
		  ((IGREATERP PCCH CHLIM)                    (* We've passed beyond the copy region.
							     Bail out.)
		    (RETURN))
		  (T                                         (* This piece overlaps the copy-source region of the 
							     document)
                                                             (* Add it to the copy list.)
		     [COND
		       ((ILESSP PCCH CH1)                    (* The piece overlaps the bottom of the copy region: 
							     Chop off its front part.)
			 (SETQ PC (\SPLITPIECE PC CH1 TEXTOBJ I))
			 (add I \EltsPerPiece)
			 (SETQ PCTB (fetch PCTB of TEXTOBJ]
		     [COND
		       ((ILESSP CHLIM (SUB1 NPCCH))          (* This piece overlaps the end of the copy region.
							     Shorten it at the end.)
			 (\SPLITPIECE PC (ADD1 CHLIM)
				      TEXTOBJ I)
			 (SETQ PCTB (fetch PCTB of TEXTOBJ]
		     (TCONC PCLST (SETQ NPC (COND
				(PIECEMAPFN (APPLY* PIECEMAPFN PC TEXTOBJ FNARG1 FNARG2))
				(T PC]
          (RETURN (CDAR PCLST])

(\TEDIT.FIND.FIRST.LINE
  [LAMBDA (TEXTOBJ WHEIGHT CH# WINDOW)                       (* jds "29-Feb-84 17:09")
                                                             (* Find the first line to be displayed, given that it 
							     must include character CH#)
    (PROG ((LINES (OR (AND WINDOW (WINDOWPROP WINDOW (QUOTE LINES)))
		      (fetch LINES of TEXTOBJ)))
	   (WWIDTH (fetch WRIGHT of TEXTOBJ))
	   (TEXTSTREAM (fetch STREAMHINT of TEXTOBJ))
	   LINE CHNO CH)
          [COND
	    ((ZEROP (fetch TEXTLEN of TEXTOBJ))              (* If there's no text, force an empty line)
	      (SETQ CHNO 1)
	      (replace NEXTLINE of LINES with NIL)
	      (RETURN LINES))
	    ((IGREATERP CH# (fetch TEXTLEN of TEXTOBJ))      (* If there's no text on the screen, just return nil)
	      (RETURN NIL))
	    [(fetch FORMATTEDP of TEXTOBJ)                   (* For a para-formatted object, back up to the prior 
							     para bound.)
	      (SETQ CHNO (CAR (\TEDIT.PARABOUNDS TEXTOBJ CH#]
	    (T                                               (* Otherwise, move back thru the text until we find a 
							     for-sure line break)
	       (\SETUPGETCH CH# TEXTOBJ)
	       (SETQ CH 0)
	       (for old CHNO from (SUB1 CH#) to 2 by -1 repeatwhile (NOT (EQ CH (CHARCODE CR)))
		  do (SETQ CH (\BACKBIN TEXTSTREAM)))
	       (SETQ CHNO (COND
		   ((ILEQ CHNO 1)                            (* If we moved back to start-of-file, move forward from 
							     there;)
		     1)
		   ((IEQP CHNO CH#)                          (* If we landed on a CR first shot, let's try moving 
							     forward from there.)
		     CH#)
		   (T                                        (* Else, skip the CR we passed over)
		      (ADD1 CHNO]
          (SETQ CH# (IMIN CH# (fetch TEXTLEN of TEXTOBJ)))
          [repeatwhile (ILEQ CHNO CH#)
	     do                                              (* Starting from the known line break, move forward 
							     until we find the line which has the right CH# in it)
		(SETQ LINE (\FORMATLINE TEXTOBJ NIL CHNO))
		(replace YBOT of LINE with WHEIGHT)
		(replace NEXTLINE of LINES with LINE)
		(replace PREVLINE of LINE with LINES)
		(SETQ LINES LINE)
		(SETQ CHNO (ADD1 (fetch CHARLIM of LINE]
          (RETURN LINE])

(\TEDIT.FIND.LAST.LINE
  [LAMBDA (TEXTOBJ LINES)                                    (* jds "16-Jan-84 13:09")
                                                             (* Among the line descriptors in LINES, find the last 
							     one on the screen; then return it.)
    (OR LINES (SETQ LINES (fetch LINES of TEXTOBJ)))         (* Make sure a list of line descriptors is specified.)
    (COND
      ((fetch \WINDOW of TEXTOBJ)                            (* If there's no window, return NIL.)
	(bind (OLINE ← LINES)
	      (LINE ← LINES)
	      (CURY ←(fetch YBOT of LINES)) while (AND LINE (IGREATERP (fetch YBOT of LINE)
								       0))
	   do                                                (* Find the lowest line above screen bottom, and put it 
							     in OLINE.)
	      (SETQ OLINE LINE)
	      (SETQ LINE (fetch NEXTLINE of LINE))
	   finally (RETURN OLINE)))
      (T NIL])

(\TEDIT.FIND.OVERLAPPING.LINE
  [LAMBDA (LINES Y)                                          (* jds " 9-Dec-83 17:17")
    (while LINES do (COND
		      ((ILEQ (fetch YBOT of LINES)
			     Y)
			(RETURN LINES))
		      (T (SETQ LINES (fetch NEXTLINE of LINES])

(\TEDIT.FIND.PROTECTED.END
  [LAMBDA (TEXTOBJ CH# LIMITCH#)                             (* jds "21-May-84 16:11")
                                                             (* Starting from a CH# within a menu fill-in space, find
							     the CH# of the last character in that fill-in.)
                                                             (* If LIMITCH# is given, the search will stop there.)
    (bind (PCTB ←(fetch PCTB of TEXTOBJ)) for I from (ADD1 (\CHTOPCNO CH# (fetch PCTB of TEXTOBJ)))
       to (\EDITELT (fetch PCTB of TEXTOBJ)
		    \PCTBLastPieceOffset)
       by \EltsPerPiece do (COND
			     [(fetch CLPROTECTED of (fetch PLOOKS of (\EDITELT PCTB I)))
			       (RETURN (SUB1 (\EDITELT PCTB (SUB1 I]
			     ((AND LIMITCH# (IGREATERP (\EDITELT PCTB (SUB1 I))
						       LIMITCH#))
                                                             (* We've passed the limit, so it's time to give up.
							     Just return the LIMITCH#)
			       (RETURN LIMITCH#])

(\TEDIT.FIND.PROTECTED.START
  [LAMBDA (TEXTOBJ CH# LIMITCH#)                             (* jds "21-May-84 16:09")
                                                             (* Starting from a CH# within a menu fill-in, find the 
							     beginning CH# of that fill-in)
                                                             (* Will stop looking when it passes LIMITCH#, if it is 
							     specified.)
    (bind (PCTB ←(fetch PCTB of TEXTOBJ)) for I from (ADD1 (\CHTOPCNO CH# (fetch PCTB of TEXTOBJ)))
       to \FirstPieceOffset by (IMINUS \EltsPerPiece) do (COND
							   [(fetch CLPROTECTED
							       of (fetch PLOOKS
								     of (\EDITELT PCTB I)))
                                                             (* We hit a PROTECTED piece of text.
							     This is the place to stop. Return the CH# just AFTER the
							     protected text we found.)
							     (RETURN (\EDITELT PCTB (ADD1 I]
							   ((AND LIMITCH# (ILEQ (\EDITELT
										  PCTB
										  (SUB1 I))
										LIMITCH#))
                                                             (* If he specified a LIMITCH#, and we have passed it, 
							     stop bothering and return the LIMITCH#)
							     (RETURN LIMITCH#])

(\TEDIT.WORD.BOUND
  [LAMBDA (TEXTOBJ PREVCH CH)                                (* jds "24-Jan-84 14:11")
    (PROG ((READSA (fetch READSA of (OR (fetch TXTWTBL of TEXTOBJ)
					TEDIT.WORDBOUND.READTABLE)))
	   SYN1 SYN2)
          (COND
	    ((NOT (AND (FIXP PREVCH)
		       (FIXP CH)))
	      (RETURN T)))
          (SETQ SYN1 (\SYNCODE READSA PREVCH))
          (SETQ SYN2 (\SYNCODE READSA CH))
          (RETURN (NEQ SYN1 SYN2])
)
(FILESLOAD TEXTOFD)
(DECLARE: EVAL@COMPILE 

(RPAQQ COPYSELSHADE 30583)

(RPAQQ EDITMOVESHADE -1)

(RPAQQ EDITGRAY 32800)

(CONSTANTS (COPYSELSHADE 30583)
	   (EDITMOVESHADE -1)
	   (EDITGRAY 32800))
)

(RPAQ? TEDIT.EXTEND.PENDING.DELETE T)

(RPAQ TEDIT.SELECTION (create SELECTION))

(RPAQ TEDIT.SCRATCHSELECTION (create SELECTION))

(RPAQ TEDIT.SHIFTEDSELECTION (create SELECTION HOW←COPYSELSHADE HASCARET←NIL))

(RPAQ TEDIT.MOVESELECTION (CREATE SELECTION HOW←EDITMOVESHADE HASCARET←NIL HOWHEIGHT←32767))

(RPAQ TEDIT.DELETESELECTION (CREATE SELECTION HOW←BLACKSHADE HASCARET←NIL HOWHEIGHT←32767))

(RPAQQ SELECTION NOBIND)

(RPAQQ SELECTION NOBIND)

(RPAQQ TEDIT.SELPENDING NIL)
(DECLARE: DOEVAL@COMPILE DONTCOPY

(ADDTOVAR GLOBALVARS TEDIT.SELECTION TEDIT.SCRATCHSELECTION TEDIT.MOVESELECTION 
	  TEDIT.SHIFTEDSELECTION TEDIT.DELETESELECTION TEDIT.SELPENDING TEDIT.EXTEND.PENDING.DELETE)
)



(* Selection manipulating code)

(DEFINEQ

(\SHOWSEL
  [LAMBDA (SEL HOW ON)                                       (* jds "24-May-84 15:40")
                                                             (* Highlight the selection SEL, according to HOW, 
							     turning it on or off according to ON)
    (COND
      ((AND SEL (fetch SET of SEL)
	    (fetch \WINDOW of (fetch \TEXTOBJ of SEL)))      (* This operation only makes sense if there is a 
							     selection, it has been set, and there's a window to do 
							     the highlighting in.)
	(PROG ((TEXTOBJ (fetch \TEXTOBJ of SEL))
	       SHOWFN)
	      (PROG ((DS (\TEDIT.MAINW TEXTOBJ))
		     (LINES (WINDOWPROP (\TEDIT.MAINW TEXTOBJ)
					(QUOTE LINES)))
		     (SHADE (OR (fetch HOW of SEL)
				BLACKSHADE))
		     (SHADEHEIGHT (OR (fetch HOWHEIGHT of SEL)
				      1))
		     LL)
		    (COND
		      ((fetch SELOBJ of SEL)                 (* If it is an object and it has a non-nil showselfn 
							     then use it)
			(\TEDIT.OBJECT.SHOWSEL TEXTOBJ SEL ON DS)
			(RETURN)))
		    (COND
		      [(AND ON (NOT (fetch ONFLG of SEL)))   (* It's off and we want to turn it on)
			(replace ONFLG of SEL with T)        (* Mark the selection as highlighted)
			[COND
			  ((OR (fetch L1 of SEL)
			       (fetch LN of SEL))            (* One end or the other is on-screen, so it makes sense 
							     to try displaying something.)
			    (COND
			      ((EQ (fetch L1 of SEL)
				   (fetch LN of SEL))        (* It's all in a single line;
							     just underline the right section and beat it)
				(BITBLT NIL 0 0 DS (fetch X0 of SEL)
					(fetch Y0 of SEL)
					(fetch DX of SEL)
					(IMIN SHADEHEIGHT (fetch LHEIGHT
							     of (fetch L1 of SEL)))
					(QUOTE TEXTURE)
					(QUOTE INVERT)
					SHADE))
			      (T                             (* Different lines.)
				 (AND (fetch L1 of SEL)
				      (BITBLT NIL 0 0 DS (fetch X0 of SEL)
					      (fetch Y0 of SEL)
					      (IDIFFERENCE (fetch LXLIM of (fetch L1 of SEL))
							   (fetch X0 of SEL))
					      (IMIN SHADEHEIGHT (fetch LHEIGHT
								   of (fetch L1 of SEL)))
					      (QUOTE TEXTURE)
					      (QUOTE INVERT)
					      SHADE))        (* If the first line is known, underline the right 
							     section of it.)
				 (SETQ LL (OR (fetch L1 of SEL)
					      LINES))
				 (AND LL (SETQ LL (fetch NEXTLINE of LL)))
                                                             (* The line after the first, or the top line on the 
							     screen -- if we didn't have a first line)
				 (while LL until (OR (EQ LL (fetch LN of SEL))
						     (ILEQ (fetch YBOT of LL)
							   (fetch WBOTTOM of TEXTOBJ)))
				    do                       (* Highlight every line between first and last)
				       (BITBLT NIL 0 0 DS (fetch LEFTMARGIN of LL)
					       (fetch YBOT of LL)
					       (IDIFFERENCE (fetch LXLIM of LL)
							    (fetch LEFTMARGIN of LL))
					       (IMIN SHADEHEIGHT (fetch LHEIGHT of LL))
					       (QUOTE TEXTURE)
					       (QUOTE INVERT)
					       SHADE)
				       (SETQ LL (fetch NEXTLINE of LL)))
				 (AND LL (IGREATERP (fetch YBOT of LL)
						    (fetch WBOTTOM of TEXTOBJ))
				      (BITBLT NIL 0 0 DS (fetch LEFTMARGIN of LL)
					      (fetch YBOT of (fetch LN of SEL))
					      (IDIFFERENCE (fetch XLIM of SEL)
							   (fetch LEFTMARGIN of LL))
					      (IMIN SHADEHEIGHT (fetch LHEIGHT of LL))
					      (QUOTE TEXTURE)
					      (QUOTE INVERT)
					      SHADE))        (* Highlight the final line of the selection)
				 ]
			(COND
			  ((AND (fetch HASCARET of SEL)
				(NOT (fetch TXTREADONLY of TEXTOBJ)))
                                                             (* If the selection has a caret, turn one on.)
			    (COND
			      ((EQ (fetch POINT of SEL)
				   (QUOTE LEFT))             (* At the LEFT end of the selection)
				(\SETCARET (fetch X0 of SEL)
					   (fetch Y0 of SEL)
					   DS TEXTOBJ))
			      (T                             (* Or at the RIGHT end.)
				 (\SETCARET (fetch XLIM of SEL)
					    (fetch YLIM of SEL)
					    DS TEXTOBJ]
		      ((AND (NOT ON)
			    (fetch ONFLG of SEL))            (* The selection is highlighted and we want to turn it 
							     off.)
			(replace ONFLG of SEL with NIL)      (* Mark it as being turned off)
			[COND
			  ((AND (fetch HASCARET of SEL)
				(NOT (fetch TXTREADONLY of TEXTOBJ)))
                                                             (* IF the selection has a caret with it, make sure it's 
							     turned off.)
			    (COND
			      ((EQ (fetch POINT of SEL)
				   (QUOTE LEFT))
				(\EDIT.UPCARET (fetch CARET of TEXTOBJ)))
			      (T (\EDIT.UPCARET (fetch CARET of TEXTOBJ]
			(COND
			  ((OR (fetch L1 of SEL)
			       (fetch LN of SEL))            (* Now, some part of the selection is highlighted on 
							     screen, since one end or the other is associated with an
							     active line descriptor.)
			    (COND
			      ((EQ (fetch L1 of SEL)
				   (fetch LN of SEL))        (* It's a single line; just highlight the right section 
							     of it.)
				(BITBLT NIL 0 0 DS (fetch X0 of SEL)
					(fetch Y0 of SEL)
					(fetch DX of SEL)
					(IMIN SHADEHEIGHT (fetch LHEIGHT
							     of (fetch L1 of SEL)))
					(QUOTE TEXTURE)
					(QUOTE INVERT)
					SHADE))
			      (T                             (* The selection extends over 2 or more lines.)
				 (AND (fetch L1 of SEL)
				      (BITBLT NIL 0 0 DS (fetch X0 of SEL)
					      (fetch Y0 of SEL)
					      (IDIFFERENCE (fetch LXLIM of (fetch L1 of SEL))
							   (fetch X0 of SEL))
					      (IMIN SHADEHEIGHT (fetch LHEIGHT
								   of (fetch L1 of SEL)))
					      (QUOTE TEXTURE)
					      (QUOTE INVERT)
					      SHADE))        (* If we know the first line, de-highlight it.)
				 (SETQ LL (OR (fetch L1 of SEL)
					      LINES))
				 (AND LL (SETQ LL (fetch NEXTLINE of LL)))
                                                             (* Find the next line (either next after 1st in 
							     selection, or top one on screen))
				 (while LL until (OR (EQ LL (fetch LN of SEL))
						     (ILEQ (fetch YBOT of LL)
							   (fetch WBOTTOM of TEXTOBJ)))
				    do                       (* Loop thru subsequent lines unhilighting them.)
				       (BITBLT NIL 0 0 DS (fetch LEFTMARGIN of LL)
					       (fetch YBOT of LL)
					       (IDIFFERENCE (fetch LXLIM of LL)
							    (fetch LEFTMARGIN of LL))
					       (IMIN SHADEHEIGHT (fetch LHEIGHT of LL))
					       (QUOTE TEXTURE)
					       (QUOTE INVERT)
					       SHADE)
				       (SETQ LL (fetch NEXTLINE of LL)))
				 (AND LL (IGREATERP (fetch YBOT of LL)
						    (fetch WBOTTOM of TEXTOBJ))
				      (BITBLT NIL 0 0 DS (fetch LEFTMARGIN of LL)
					      (fetch YBOT of (fetch LN of SEL))
					      (IDIFFERENCE (fetch XLIM of SEL)
							   (fetch LEFTMARGIN of LL))
					      (IMIN SHADEHEIGHT (fetch LHEIGHT of LL))
					      (QUOTE TEXTURE)
					      (QUOTE INVERT)
					      SHADE))        (* And the final line.)
				 ])

(TEDIT.EXTEND.SEL
  [LAMBDA (X Y OSEL TEXTOBJ SELOPERATION SELWINDOW)          (* jds "16-May-84 11:12")
                                                             (* Gather a new selected character, and extend OSEL to 
							     include it. Return the extended selection.)
    (PROG ((NSEL (TEDIT.SELECT X Y TEXTOBJ (SELECTQ (fetch SELKIND of OSEL)
						    ((LINE PARA)
						      (QUOTE LINE))
						    ((WORD CHAR)
						      (QUOTE TEXT))
						    (QUOTE TEXT))
			       (OR (EQ (fetch SELKIND of OSEL)
				       (QUOTE WORD))
				   (EQ (fetch SELKIND of OSEL)
				       (QUOTE PARA)))
			       SELOPERATION SELWINDOW))
	   (TEXTLEN (fetch TEXTLEN of TEXTOBJ))
	   (NPOINT NIL)
	   (SETOSELFLG NIL))
          (COND
	    ((ZEROP TEXTLEN)                                 (* No sense in extending a selection if there's no 
							     text!)
	      (RETURN NSEL)))
          (COND
	    ((AND NSEL (fetch SET of NSEL))                  (* If there's no second selection, don't bother trying)
	      (TEDIT.SET.SEL.LOOKS NSEL SELOPERATION)        (* Make the new selection be the same kind as the 
							     original, as to what it's for -- regular, copy-source, 
							     etc.)
	      [SETQ NPOINT (COND
		  ((IGEQ (fetch CHLIM of NSEL)
			 (fetch CHLIM of OSEL))              (* The new selection ends to the right of the old one.
							     Move this edge.)
		    (QUOTE RIGHT))
		  ((ILEQ (fetch CH# of NSEL)
			 (fetch CH# of OSEL))                (* If the new selection starts to left of old one, caret
							     goes at the LEFT)
		    (QUOTE LEFT))
		  ([IGREATERP (IABS (IDIFFERENCE (fetch CHLIM of NSEL)
						 (fetch CHLIM of OSEL)))
			      (IABS (IDIFFERENCE (fetch CH# of NSEL)
						 (fetch CH# of OSEL]
		    (SETQ SETOSELFLG T)
		    (QUOTE LEFT))
		  (T (SETQ SETOSELFLG T)
		     (QUOTE RIGHT]
	      [SELECTQ NPOINT
		       [LEFT                                 (* Caret's to the left. Keep the same right end)
			     [replace CHLIM of NSEL
				with (IMAX (fetch CHLIM of NSEL)
					   (SELECTQ (fetch POINT of OSEL)
						    (LEFT (IPLUS (fetch CH# of OSEL)
								 -1
								 (fetch DCH of OSEL)))
						    (RIGHT (fetch CHLIM of OSEL))
						    (SHOULDNT]
			     (replace XLIM of NSEL with (fetch XLIM of OSEL))
			     (replace YLIM of NSEL with (fetch YLIM of OSEL))
			     (replace LN of NSEL with (fetch LN of OSEL))
			     (COND
			       ((AND (fetch MENUFLG of TEXTOBJ)
				     (NEQ SELOPERATION (QUOTE COPY)))
                                                             (* The old sel is in a protected area.
							     Only let him extend to the start of it.)
				 [replace CH# of NSEL with (IMAX (fetch CH# of NSEL)
								 (\TEDIT.FIND.PROTECTED.START
								   TEXTOBJ
								   (fetch CHLIM of NSEL]
				 (\FIXSEL NSEL TEXTOBJ]
		       [RIGHT                                (* Point's to the right; keep the same left end.)
			      [replace CH# of NSEL
				 with (IMIN (fetch CH# of NSEL)
					    (SELECTQ (fetch POINT of OSEL)
						     (LEFT (fetch CH# of OSEL))
						     [RIGHT (ADD1 (IDIFFERENCE (fetch CHLIM
										  of OSEL)
									       (fetch DCH
										  of OSEL]
						     (SHOULDNT]
			      (replace X0 of NSEL with (fetch X0 of OSEL))
			      (replace Y0 of NSEL with (fetch Y0 of OSEL))
			      (replace L1 of NSEL with (fetch L1 of OSEL))
			      (COND
				((AND (fetch MENUFLG of TEXTOBJ)
				      (NEQ SELOPERATION (QUOTE COPY)))
                                                             (* The old sel is in a protected area.
							     Only let him extend to the start of it.)
				  [replace CHLIM of NSEL with (IMIN (fetch CHLIM of NSEL)
								    (\TEDIT.FIND.PROTECTED.END
								      TEXTOBJ
								      (fetch CH# of NSEL]
				  (\FIXSEL NSEL TEXTOBJ]
		       (PROGN (replace CHLIM of NSEL with (fetch CHLIM of OSEL))
			      (replace XLIM of NSEL with (fetch XLIM of OSEL))
			      (replace YLIM of NSEL with (fetch YLIM of OSEL))
			      (replace LN of NSEL with (fetch LN of OSEL))
			      (replace CH# of NSEL with (fetch CH# of OSEL))
			      (replace X0 of NSEL with (fetch X0 of OSEL))
			      (replace Y0 of NSEL with (fetch Y0 of OSEL))
			      (replace L1 of NSEL with (fetch L1 of OSEL))
			      (SETQ NPOINT (fetch POINT of OSEL]
	      [replace DCH of NSEL with (ADD1 (IDIFFERENCE (IMIN TEXTLEN (fetch CHLIM of NSEL))
							   (fetch CH# of NSEL]
                                                             (* The selection's length cannot exceed that of the 
							     whole text.)
	      [replace CHLIM of NSEL with (IPLUS (fetch CH# of NSEL)
						 (SUB1 (fetch DCH of NSEL]
                                                             (* This assures that the CHLIM corresponds to the DCH.)
	      (replace POINT of NSEL with NPOINT)
	      (replace DX of NSEL with (IDIFFERENCE (fetch XLIM of NSEL)
						    (fetch X0 of NSEL)))
	      (COND
		((NEQ (fetch SELOBJ of OSEL)
		      (fetch SELOBJ of NSEL))
		  (replace SELOBJ of NSEL with NIL)))
	      (COND
		(SETOSELFLG                                  (* For whatever reason, it is wise to copy the new sel 
							     into the old one.)
			    (\COPYSEL NSEL OSEL))
		(T                                           (* Otherwise, set the POINT of the old sel to correspond
							     to the new sel's.)
                                                             (* (replace POINT of OSEL with NPOINT))
                                                             (* THIS WAS REMOVED, BECAUSE EXTENDING A POINT-SELECTION
							     WOULD DIE WHEN THIS WAS DONE)
		   ))
	      (RETURN NSEL))
	    (T                                               (* No new selection was made;
							     just return the old one.)
	       (RETURN OSEL])

(TEDIT.GETSEL
  [LAMBDA (STREAM)                                           (* jds "14-Feb-84 16:29")
    (create SELECTION using (fetch SEL of (fetch (TEXTSTREAM TEXTOBJ) of STREAM])

(TEDIT.MAKESEL
  [LAMBDA (STREAM CH# LEN POINT)                             (* jds "14-Feb-84 16:29")
    (PROG ((SEL (fetch SEL of (fetch (TEXTSTREAM TEXTOBJ) of STREAM)))
	   (TEXTOBJ (fetch (TEXTSTREAM TEXTOBJ) of STREAM)))
          (\SHOWSEL SEL NIL NIL)
          (replace CH# of SEL with CH#)
          (replace CHLIM of SEL with (IMAX CH# (IPLUS CH# LEN -1)))
          (replace DCH of SEL with LEN)
          (replace POINT of SEL with (OR POINT (QUOTE LEFT)))
          (replace \TEXTOBJ of SEL with TEXTOBJ)
          (replace SET of SEL with T)
          (AND (fetch \WINDOW of TEXTOBJ)
	       (\FIXSEL SEL TEXTOBJ))
          (\SHOWSEL SEL NIL T])

(TEDIT.RESET.EXTEND.PENDING.DELETE
  [LAMBDA (SEL)                                              (* jds " 6-Jan-84 16:02")
                                                             (* Reset the "Extend Pending Delete" status)
    (AND SEL (TEDIT.SET.SEL.LOOKS SEL (QUOTE NORMAL)))
    (SETQ TEDIT.PENDINGDEL NIL)
    (AND (fetch \TEXTOBJ of SEL)
	 (replace BLUEPENDINGDELETE of (fetch \TEXTOBJ of SEL) with NIL])

(TEDIT.SCANSEL
  [LAMBDA (STREAM)                                           (* jds "14-Feb-84 16:29")
                                                             (* Set up to read the selected text;
							     return the sel's length or NIL if nothing selected.)
    (PROG ((TEXTOBJ (fetch (TEXTSTREAM TEXTOBJ) of STREAM))
	   SEL)
          (SETQ SEL (fetch SEL of TEXTOBJ))
          (COND
	    ((fetch SET of SEL)
	      (\SETUPGETCH (fetch CH# of SEL)
			   TEXTOBJ)
	      (RETURN (fetch DCH of SEL)))
	    (T (RETURN NIL])

(TEDIT.SELECT
  [LAMBDA (X Y TEXTOBJ REGION WORDSELFLG SELOPERATION WINDOW)
                                                             (* jds "18-Jan-84 14:42")
                                                             (* Select the character word, line, or paragraph the 
							     mouse is pointing at.)
    (PROG ((L NIL)
	   (TEXTLEN (fetch TEXTLEN of TEXTOBJ))
	   PREVLINE)
          (SETQ L (TEDIT.SELECT.LINE.SCANNER X Y TEXTOBJ (WINDOWPROP WINDOW (QUOTE LINES))
					     REGION WORDSELFLG SELOPERATION WINDOW))
          (COND
	    ((type? SELECTION L)                             (* He pointed at something real;
							     return that.)
	      (TEDIT.SET.SEL.LOOKS L SELOPERATION)
	      (RETURN L))
	    ((type? LINEDESCRIPTOR L)                        (* He pointed below the bottom of the text.
							     Select to the right of the last character on the 
							     screen.)
	      (COND
		((OR (fetch LHASPROT of L)
		     (fetch MENUFLG of TEXTOBJ))             (* The last line is protected.
							     Don't select anything.)
		  (RETURN)))
	      (SETQ PREVLINE L)
	      (SETQ L (fetch SCRATCHSEL of TEXTOBJ))
	      (replace SET of L with T)
	      (replace \TEXTOBJ of L with TEXTOBJ)
	      [replace CH# of L with (IMAX 1 (IMIN TEXTLEN (fetch CHARLIM of PREVLINE]
	      (replace CHLIM of L with (fetch CH# of L))
	      (replace DCH of L with 0)
	      [replace POINT of L with (COND
					 ((IGREATERP (fetch CH# of L)
						     (fetch TEXTLEN of TEXTOBJ))
                                                             (* Can't select to the right of a character past EOF, 
							     only to the left -- which is the right edge of the 
							     text.)
					   (QUOTE LEFT))
					 (T (QUOTE RIGHT]
	      (TEDIT.SET.SEL.LOOKS L SELOPERATION)
	      (\FIXSEL L TEXTOBJ)
	      (RETURN L])

(TEDIT.SCAN.LINE
  [LAMBDA (TEXTOBJ LINE THISLINE X Y WORDSELFLG SELOPERATION WINDOW)
                                                             (* jds " 2-May-84 16:52")
                                                             (* Given a line, find the character which straddles the 
							     mouse.)
    (PROG ((L NIL)
	   (WLIST (fetch WIDTHS of THISLINE))
	   (CHLIST (fetch CHARS of THISLINE))
	   (LLIST (fetch LOOKS of THISLINE))
	   (LOOKNO 1)
	   (DX 0)
	   OTX YBOT YBASE TX (CH (CHARCODE SPACE))
	   PREVCH CHOBJB TXB CHB (TEXTLEN (fetch TEXTLEN of TEXTOBJ))
	   CLOOKS PCLOOKS)
          (COND
	    ((NEQ (fetch DESC of THISLINE)
		  LINE)                                      (* If the cache doesn't describe this line, call 
							     \FORMATLINE so it will.)
	      (\FORMATLINE TEXTOBJ NIL (fetch CHAR1 of LINE)
			   LINE)))
          [SETQ OTX (SETQ TXB (SETQ TX (fetch LEFTMARGIN of LINE]
          (SETQ X (IMAX X TX))                               (* The mouse MUST be inside the line being selected.)
          (SETQ CHB (SUB1 (fetch CHAR1 of LINE)))
          (SETQ CLOOKS (\EDITELT LLIST 0))
          (\TEDIT.CHECK (IGEQ X (fetch LEFTMARGIN of LINE)))
                                                             (* The mouse MUST be inside the line being selected.)
          (for I from 0 to (fetch LEN of THISLINE) as CHNO from (SUB1 (fetch CHAR1 of LINE))
	     do (SETQ PREVCH CH)
		(SETQ PCLOOKS CLOOKS)
		(SETQ CH (\EDITELT CHLIST I))
		[COND
		  ((EQ CH 401)                               (* An invisible run -- skip it)
		    (add CHNO (\EDITELT LLIST LOOKNO))       (* The length of the run)
		    (add LOOKNO 1)                           (* Move to next CLook for next transition)
		    (add I 1)                                (* Don't count this toward the CHNO counter.)
		    (SETQ CH (\EDITELT CHLIST I]
		(\TEDIT.CHECK (NEQ CH 401))                  (* Can't have 2 invisible runs in a row.)
		[COND
		  ((EQ CH 400)                               (* Change of CharLooks -- make the switch)
		    (SETQ CLOOKS (\EDITELT LLIST LOOKNO))    (* New looks)
		    (add LOOKNO 1)                           (* Move to next CLook for next transition)
		    (add I 1)                                (* Don't count this toward the CHNO counter.)
		    (SETQ CH (\EDITELT CHLIST I]
		[COND
		  ((AND (ILESSP X TX)
			(OR (EQ SELOPERATION (QUOTE COPY))
			    (fetch CLSELHERE of PCLOOKS)
			    (NOT (fetch CLPROTECTED of PCLOOKS)))
			(OR (NOT WORDSELFLG)
			    (NOT (SMALLP PREVCH))
			    (\TEDIT.WORD.BOUND TEXTOBJ PREVCH CH)))

          (* If we're beyond the mouse's X, and the character is selectable, and we're in char select or this is a word 
	  boundary then SELECT!!!)


		    (\TEDIT.CHECK (NOT (ZEROP I)))           (* We had best not have fouled out to the left of the 
							     left margin!)
		    (SETQ L (fetch SCRATCHSEL of TEXTOBJ))   (* Grab the scratch sel)
		    (replace SET of L with T)                (* Mark it valid)
		    [replace SELKIND of L with (COND
						 (WORDSELFLG (QUOTE WORD))
						 (T (QUOTE CHAR]
		    (\TEDIT.SELECT.CHARACTER TEXTOBJ L PREVCH LINE X Y TXB WINDOW)
		    (replace Y0 of L with (fetch YBOT of LINE))
		    (replace X0 of L with (COND
					    ((fetch CLSELHERE of PCLOOKS)
                                                             (* If CLSelHere, then select to RIGHT always.)
					      TX)
					    (WORDSELFLG TXB)
					    (T OTX)))
		    (replace DX of L with (COND
					    ((fetch CLSELHERE of PCLOOKS)
					      0)
					    (WORDSELFLG (IDIFFERENCE TX TXB))
					    (T DX)))
		    [replace CH# of L with (IMAX 1 (COND
						   ((fetch CLSELHERE of PCLOOKS)
						     CHNO)
						   (WORDSELFLG (ADD1 CHB))
						   (T CHNO]
		    (replace XLIM of L with (COND
					      ((fetch CLSELHERE of PCLOOKS)
						TX)
					      (WORDSELFLG TX)
					      (T TX)))
		    (replace CHLIM of L with (COND
					       ((fetch CLSELHERE of PCLOOKS)
						 CHNO)
					       (WORDSELFLG CHNO)
					       (T CHNO)))
		    (replace YLIM of L with (fetch YBOT of LINE))
		    (replace L1 of L with LINE)
		    (replace LN of L with LINE)
		    [replace POINT of L with (COND
					       ((fetch CLSELHERE of PCLOOKS)
                                                             (* Always to the right of an otherwise-protected 
							     insertion point marker)
						 (QUOTE RIGHT))
					       [WORDSELFLG (COND
							     ((AND (NEQ PREVCH (CHARCODE CR))
								   (IGEQ X (LRSH (IPLUS TX TXB)
										 1)))
                                                             (* To the right if it isn't a CR and we're right of 
							     center.)
							       (QUOTE RIGHT))
							     (T (QUOTE LEFT]
					       (T (COND
						    ((AND (IGEQ DX 3)
							  (NEQ PREVCH (CHARCODE CR))
							  (IGEQ X (LRSH (IPLUS TX OTX)
									1)))

          (* If it's wide enough to sensibly decide on an edge for, this isn't a CR, and we're right of center, then put the
	  caret to the RIGHT)


						      (QUOTE RIGHT))
						    (T (QUOTE LEFT]
		    (replace DCH of L with (COND
					     ((fetch CLSELHERE of PCLOOKS)
					       0)
					     (WORDSELFLG (IDIFFERENCE CHNO CHB))
					     (T 1)))
		    (RETURN))
		  (T                                         (* We're not past the mouse yet;
							     just track the last word boundary 
							     (or protected-text boundary) for word selection.)
		     (COND
		       ((OR (AND (NOT (fetch CLPROTECTED of CLOOKS))
				 (\TEDIT.WORD.BOUND TEXTOBJ PREVCH CH))
			    (NEQ (fetch CLPROTECTED of PCLOOKS)
				 (fetch CLPROTECTED of CLOOKS))
			    (fetch CLSELHERE of PCLOOKS))
			 (SETQ TXB TX)
			 (SETQ CHB CHNO)
			 (SETQ CHOBJB PREVCH]
		(SETQ OTX TX)
		(SETQ DX (\WORDELT WLIST I))
		(SETQ TX (IPLUS TX DX)))
          [COND
	    ((AND (NOT L)
		  (IGEQ (fetch LEN of THISLINE)
			0)
		  (fetch CLPROTECTED of CLOOKS))             (* He's pointing to the right of the line, but there's 
							     protected text at the end. Select a point at the last 
							     legal spot.)
	      (COND
		((SMALLP CHOBJB)                             (* And the last item wasn't a menu button)
		  (SETQ L (fetch SCRATCHSEL of TEXTOBJ))
		  (replace SET of L with T)
		  (replace Y0 of L with (fetch YBOT of LINE))
		  (replace X0 of L with TXB)
		  (replace DX of L with 0)
		  (replace CH# of L with (IMAX 1 (ADD1 CHB)))
		  (replace XLIM of L with TXB)
		  (replace CHLIM of L with (IMAX 1 (ADD1 CHB)))
		  (replace YLIM of L with (fetch YBOT of LINE))
		  (replace L1 of L with LINE)
		  (replace LN of L with LINE)
		  (replace POINT of L with (QUOTE LEFT))
		  (replace DCH of L with 0)
		  (replace SELOBJ of L with NIL))
		(T                                           (* Oops--the last item WAS a menu button.
							     Don't let it be selected.)
		   (RETURN (QUOTE DON'T]
          (COND
	    (L                                               (* If we found the place he's pointing, set up the 
							     inter-pointers so each can find the other)
	       (replace \TEXTOBJ of L with TEXTOBJ))
	    (T                                               (* We didn't find what he was pointing at.
							     Point to the end of the line.)
	       (SETQ L (fetch SCRATCHSEL of TEXTOBJ))
	       (replace SET of L with T)
	       [replace SELKIND of L with (COND
					    (WORDSELFLG (QUOTE WORD))
					    (T (QUOTE CHAR]
                                                             (* THIS MUST PRECEDE THE \TEDIT.SELECT.CHARACTER, SO 
							     OBJECTS CAN TURN THE SELECTION VOLATILE.)
	       (\TEDIT.SELECT.CHARACTER TEXTOBJ L CH LINE X Y TXB WINDOW)
	       (replace Y0 of L with (fetch YBOT of LINE))
	       [replace X0 of L with (COND
				       (WORDSELFLG TXB)
				       (T (IDIFFERENCE TX DX]
	       (replace XLIM of L with TX)
	       (replace DX of L with (COND
				       (WORDSELFLG (IDIFFERENCE TX TXB))
				       (T DX)))
	       [replace CH# of L with (COND
					(WORDSELFLG (ADD1 CHB))
					(T (IMIN (fetch CHARLIM of LINE)
						 TEXTLEN]
	       (replace YLIM of L with (fetch YBOT of LINE))
	       (replace CHLIM of L with (IMIN (fetch CHARLIM of LINE)
					      TEXTLEN))
	       [replace POINT of L with (COND
					  [(NEQ CH (CHARCODE CR))
                                                             (* You can select only to the left of a CR;
							     elsewhere, you can select to the right)
					    (COND
					      ((IGEQ X (LRSH (IPLUS TX TXB)
							     1))
						(QUOTE RIGHT))
					      (T (QUOTE LEFT]
					  (T (QUOTE LEFT]
	       (replace L1 of L with LINE)
	       (replace LN of L with LINE)
	       (replace DCH of L with (COND
					(WORDSELFLG (IDIFFERENCE (IMIN (fetch CHARLIM of LINE)
								       TEXTLEN)
								 CHB))
					(T 1)))
	       (replace \TEXTOBJ of L with TEXTOBJ)))
          (RETURN L])

(TEDIT.SELECT.LINE.SCANNER
  [LAMBDA (X Y TEXTOBJ LINE.LIST REGION WORDSELFLG SELOPERATION WINDOW)
                                                             (* jds "22-May-84 12:30")
                                                             (* Find the text line the mouse is pointing at.)
    (PROG ((L NIL)
	   (WWIDTH (fetch WRIGHT of TEXTOBJ))
	   (THISLINE (fetch THISLINE of TEXTOBJ))
	   (DS (fetch DS of TEXTOBJ))
	   (TEXTLEN (fetch TEXTLEN of TEXTOBJ))
	   PREVLINE PARABOUNDS PARASTART PARAEND)
          (bind (LINE ← LINE.LIST) while (AND LINE (IGREATERP (fetch YBOT of LINE)
							      (fetch WBOTTOM of TEXTOBJ)))
	     do 

          (* Search thru the list of displayed lines, looking for the first one whose bottom is below the mouse.
	  That's the line we're pointing at.)


		(COND
		  ((ILEQ (fetch YBOT of LINE)
			 Y)                                  (* Found it.)
		    (SELECTQ REGION
			     (TEXT                           (* We're in the regular text area, so scan accross 
							     looking for the character.)
				   (SETQ L (TEDIT.SCAN.LINE TEXTOBJ LINE THISLINE X Y WORDSELFLG 
							    SELOPERATION WINDOW)))
			     [LINE                           (* He is selecting an entire line, or a paragraph.)
				   (SETQ L (fetch SCRATCHSEL of TEXTOBJ))
				   (COND
				     ((AND (fetch LHASPROT of LINE)
					   (NEQ SELOPERATION (QUOTE COPY)))
                                                             (* In a TEDIT menu, you can't select a whole paragraph 
							     or line.)
				       (replace SET of L with NIL)
				       (RETURN L)))          (* The scratch selection)
				   (replace \TEXTOBJ of L with TEXTOBJ)
                                                             (* Make sure he knows what document the selection's in.)
				   (replace SET of L with T)
                                                             (* Mark it valid.)
				   (replace SELOBJ of L with NIL)
                                                             (* Not selecting an object just yet)
				   (COND
				     [WORDSELFLG             (* Select a paragraph.)
						 (replace SELKIND of L with (QUOTE PARA))
                                                             (* SEARCH FORWARD FROM THE CURRENT LINE TO A LINE WITH A
							     CR OR CHARLIM=EOTEXT)
						 [COND
						   ((fetch FORMATTEDP of TEXTOBJ)
                                                             (* If this is a para-formatted document, use the 
							     paragraph bounds. Otherwise, delimit a para by the 
							     surrounding CRs.)
						     (SETQ PARABOUNDS (\TEDIT.PARABOUNDS
							 TEXTOBJ
							 (fetch CHAR1 of LINE)))
						     (SETQ PARASTART (\TEDIT.FIND.PROTECTED.START
							 TEXTOBJ
							 (fetch CHAR1 of LINE)
							 (CAR PARABOUNDS)))
						     (SETQ PARAEND (\TEDIT.FIND.PROTECTED.END
							 TEXTOBJ
							 (fetch CHAR1 of LINE)
							 (CDR PARABOUNDS]
						 (bind (LL ← LINE)
						    while (AND [COND
								 ((fetch FORMATTEDP of TEXTOBJ)
								   (ILESSP (fetch CHARLIM
									      of LL)
									   PARAEND))
								 (T (NOT (fetch CR\END of LL]
							       (ILESSP (fetch CHARLIM of LL)
								       TEXTLEN))
						    do [COND
							 ((fetch NEXTLINE of LL)
							   (SETQ LL (fetch NEXTLINE of LL)))
							 (T [replace NEXTLINE of LL
							       with (\FORMATLINE TEXTOBJ NIL
										 (ADD1 (fetch CHARLIM
											  of LL]
							    (replace PREVLINE
							       of (fetch NEXTLINE of LL)
							       with LL)
							    (SETQ LL (fetch NEXTLINE of LL]
						    finally (replace LN of L with LL))
                                                             (* SEARCH BACK TO A LINE WITH A CR OR BOTEXT)
						 [bind (LL ←(fetch PREVLINE of LINE))
						    while [AND (IGEQ (fetch CHAR1 of LL)
								     1)
							       (COND
								 ((fetch FORMATTEDP of TEXTOBJ)
								   (IGEQ (fetch CHAR1 of LL)
									 PARASTART))
								 (T (NOT (fetch CR\END of LL]
						    do (SETQ LL (fetch PREVLINE of LL))
						    finally (replace L1 of L
							       with
								(COND
								  ((IGEQ (fetch CHAR1 of LL)
									 1)
								    (COND
								      ((OR (NOT (fetch FORMATTEDP
										   of TEXTOBJ))
									   (ILESSP (fetch CHARLIM
										      of LL)
										   PARASTART))
									(fetch NEXTLINE of LL))
								      (T LL)))
								  (T (\BACKFORMAT LINE.LIST TEXTOBJ)
								     (fetch NEXTLINE of LINE.LIST]
						 [replace CH# of L
						    with (OR PARASTART (fetch CHAR1
									  of (fetch L1 of L]
						 [replace CHLIM of L
						    with (OR PARAEND (fetch CHARLIM
									of (fetch LN of L]
						 (replace POINT of L with (QUOTE LEFT))
						 [replace DCH of L
						    with (ADD1 (IDIFFERENCE (fetch CHLIM
									       of L)
									    (fetch CH# of L]
						 (COND
						   ((OR (fetch MENUFLG of TEXTOBJ)
							(fetch LHASPROT of LINE))
                                                             (* We have cause to suspect there may be protected text 
							     around this para. Fix the sel the hard way.)
						     (\FIXSEL L TEXTOBJ))
						   (T        (* No protected text is evident.
							     DO it the easy way.)
						      (replace Y0 of L
							 with (fetch YBOT
								 of (fetch L1 of L)))
						      (replace YLIM of L
							 with (fetch YBOT
								 of (fetch LN of L)))
						      (replace X0 of L
							 with (fetch LEFTMARGIN
								 of (fetch L1 of L)))
						      (replace XLIM of L
							 with (fetch LXLIM
								 of (fetch LN of L)))
						      (replace DX of L
							 with (IPLUS 1 (IDIFFERENCE (fetch XLIM
										       of L)
										    (fetch X0
										       of L]
				     (T                      (* Select the line we're pointing at.)
					(replace SELKIND of L with (QUOTE LINE))
					(replace L1 of L with (replace LN of L with LINE))
					(replace CH# of L with (fetch CHAR1 of LINE))
					(replace CHLIM of L with (fetch CHARLIM of LINE))
					(replace DX of L with (IDIFFERENCE (fetch LXLIM of LINE)
									   (fetch LEFTMARGIN
									      of LINE)))
					(replace X0 of L with (fetch LEFTMARGIN of LINE))
					(replace XLIM of L with (fetch LXLIM of LINE))
					(replace Y0 of L with (replace YLIM of L
								 with (fetch YBOT of LINE)))
					[replace DCH of L with (ADD1 (IDIFFERENCE (fetch CHLIM
										     of L)
										  (fetch CH#
										     of L]
					(replace POINT of L with (QUOTE LEFT))
					(replace SET of L with T]
			     (SHOULDNT "Unknown text/line-bar region?"))
		    (RETURN)))
		(SETQ PREVLINE LINE)
		(SETQ LINE (fetch NEXTLINE of LINE)))
          (RETURN (OR L PREVLINE])

(TEDIT.SET.SEL.LOOKS
  [LAMBDA (SEL OPERATION)                                    (* edited: "14-MAR-83 18:39")
                                                             (* Set what the selection should be displayed like, 
							     given what it's for (NORMAL, COPY, MOVE, etc.))
    (SELECTQ OPERATION
	     (NORMAL                                         (* Regular selection)
		     (replace HOW of SEL with BLACKSHADE)
		     (replace HOWHEIGHT of SEL with 1)
		     (replace HASCARET of SEL with T))
	     (COPY                                           (* Copy source)
		   (replace HOW of SEL with COPYSELSHADE)
		   (replace HOWHEIGHT of SEL with 1)
		   (replace HASCARET of SEL with NIL))
	     (MOVE                                           (* Copy source)
		   (replace HOW of SEL with EDITMOVESHADE)
		   (replace HOWHEIGHT of SEL with 16384)
		   (replace HASCARET of SEL with NIL))
	     (DELETE                                         (* To be deleted instantly)
		     (replace HOW of SEL with BLACKSHADE)
		     (replace HOWHEIGHT of SEL with 16384)
		     (replace HASCARET of SEL with NIL)
		     NIL)
	     (PENDINGDEL                                     (* Delete at next type-in)
			 (replace HOW of SEL with BLACKSHADE)
			 (replace HOWHEIGHT of SEL with 16384)
			 (replace HASCARET of SEL with T)
			 NIL)
	     NIL])

(TEDIT.SETSEL
  [LAMBDA (STREAM CH# LEN POINT PENDINGDELFLG LEAVECARETLOOKS)
                                                             (* gbn " 9-Apr-84 16:29")
                                                             (* Given a text stream or textobj, and a piece of text 
							     to select, set the internal selection, and return it.)
                                                             (* Make sure we got a stream)
    (PROG ((TEXTOBJ (TEXTOBJ STREAM))
	   SEL TEXTLEN)
          (SETQ SEL (fetch SEL of TEXTOBJ))
          (SETQ TEXTLEN (fetch TEXTLEN of TEXTOBJ))
          (\SHOWSEL SEL NIL NIL)                             (* First turn the old sel off.)
          [COND
	    ((type? SELECTION CH#)                           (* He gave use a selection; just plug it in)
	      (\COPYSEL CH# SEL)
	      (replace ONFLG of SEL with NIL)                (* And make sure it can be turned on.)
	      )
	    (T                                               (* He fed us numbers; use them)
	       (replace CH# of SEL with (IMIN (IMAX 1 CH#)
					      (ADD1 TEXTLEN)))
                                                             (* Starting character)
	       (replace CHLIM of SEL with (IMIN (IMAX CH# (IPLUS CH# (IMIN LEN TEXTLEN)
								 -1)
						      1)
						(ADD1 TEXTLEN)))
                                                             (* Last selected character)
	       [replace DCH of SEL with (IMIN LEN (ADD1 (IDIFFERENCE (fetch CHLIM of SEL)
								     (fetch CH# of SEL]
	       (replace POINT of SEL with (OR (AND (IGREATERP CH# TEXTLEN)
						   (QUOTE LEFT))
					      POINT
					      (QUOTE LEFT)))
                                                             (* Which side the caret should go on)
	       (COND
		 ((OR (IGREATERP (fetch CH# of SEL)
				 TEXTLEN)
		      (NEQ 1 LEN))
		   (replace SELOBJ of SEL with NIL))
		 (T (replace SELOBJ of SEL with (fetch POBJ of (\CHTOPC (fetch CH# of SEL)
									(fetch PCTB of TEXTOBJ]
          (replace \TEXTOBJ of SEL with TEXTOBJ)             (* Link it back to the associated textobj)
          (COND
	    (PENDINGDELFLG                                   (* This selection is to be a pending-deletion sel.)
			   (replace BLUEPENDINGDELETE of TEXTOBJ with T)
                                                             (* Warn TEdit that there's a deletion pending)
			   (TEDIT.SET.SEL.LOOKS SEL (QUOTE PENDINGDEL))
                                                             (* And make the selection look right.)
			   )
	    (T                                               (* This selection is to be a pending-deletion sel.)
	       (TEDIT.RESET.EXTEND.PENDING.DELETE SEL)))
          (replace SET of SEL with T)                        (* Mark the selection as valid for others to use)
          [COND
	    ((NOT LEAVECARETLOOKS)                           (* And set the insertion looks to follow.)
	      (replace CARETLOOKS of TEXTOBJ with (\TEDIT.GET.INSERT.CHARLOOKS TEXTOBJ SEL]
          (AND (fetch \WINDOW of TEXTOBJ)
	       (\FIXSEL SEL TEXTOBJ))                        (* Update the selection's screen location)
          (\SHOWSEL SEL NIL T)                               (* Highlight it on the screen)
          (RETURN SEL])

(TEDIT.SHOWSEL
  [LAMBDA (STREAM ONFLG SEL)                                 (* jds "14-Feb-84 16:29")
    (PROG ((TEXTOBJ (fetch (TEXTSTREAM TEXTOBJ) of STREAM)))
          (COND
	    (SEL                                             (* He's giving us a selection to highlight.
							     Connect it to this textobj.)
		 (replace \TEXTOBJ of SEL with TEXTOBJ)
		 (\FIXSEL SEL TEXTOBJ)))
          (\SHOWSEL (OR SEL (fetch SEL of TEXTOBJ))
		    NIL ONFLG])

(\COPYSEL
  [LAMBDA (FROM TO)                                          (* jds " 7-FEB-83 13:37")
                                                             (* Copy a SELECTION record from FROM to TO, without 
							     creating any new ones)
    (replace Y0 of TO with (fetch Y0 of FROM))
    (replace X0 of TO with (fetch X0 of FROM))
    (replace DX of TO with (fetch DX of FROM))
    (replace CH# of TO with (fetch CH# of FROM))
    (replace XLIM of TO with (fetch XLIM of FROM))
    (replace CHLIM of TO with (fetch CHLIM of FROM))
    (replace DCH of TO with (fetch DCH of FROM))
    (replace L1 of TO with (fetch L1 of FROM))
    (replace LN of TO with (fetch LN of FROM))
    (replace YLIM of TO with (fetch YLIM of FROM))
    (replace POINT of TO with (fetch POINT of FROM))
    (replace SET of TO with (fetch SET of FROM))
    (replace \TEXTOBJ of TO with (fetch \TEXTOBJ of FROM))
    (replace SELKIND of TO with (fetch SELKIND of FROM))
    (replace HOW of TO with (fetch HOW of FROM))
    (replace HOWHEIGHT of TO with (fetch HOWHEIGHT of FROM))
    (replace HASCARET of TO with (fetch HASCARET of FROM))
    (replace SELOBJ of TO with (fetch SELOBJ of FROM))
    (replace ONFLG of TO with (fetch ONFLG of FROM])

(\FIXSEL
  [LAMBDA (SEL TEXTOBJ)                                      (* jds "22-May-84 12:36")
                                                             (* Given that the selection SEL contains the correct CH#
							     and CHLIM, reset the Y0 X0, DX, and XLIM values.)
    (PROG ((CH# (fetch CH# of SEL))
	   (CHLIM (fetch CHLIM of SEL))
	   (THISLINE (fetch THISLINE of TEXTOBJ))
	   (WINDOW (fetch SELWINDOW of TEXTOBJ))
	   (STARTFOUND NIL)
	   WLIST CHLIST LOOKS LINE PREVLINE)
          (COND
	    ((AND (fetch SET of SEL)
		  WINDOW)                                    (* Only if a "real" SELECTION proceed)
	      (replace X0 of SEL with -1)
	      (SETQ WLIST (fetch WIDTHS of THISLINE))
	      (SETQ CHLIST (fetch CHARS of THISLINE))
	      (SETQ LOOKS (fetch LOOKS of THISLINE))
	      (replace XLIM of SEL with -1)
	      (replace Y0 of SEL with (fetch HEIGHT of (DSPCLIPPINGREGION NIL WINDOW)))
	      (replace YLIM of SEL with -1)
	      (replace L1 of SEL with (replace LN of SEL with NIL))
	      (bind (LINE ←(fetch NEXTLINE of (fetch LINES of TEXTOBJ)))
		    TX DX while LINE
		 do (COND
		      [(AND (IGEQ CH# (fetch CHAR1 of LINE))
			    (ILEQ CH# (fetch CHARLIM of LINE)))
                                                             (* The selection starts in this line.
							     Fix L1, X0, and Y0.)
			(SETQ STARTFOUND T)
			(replace Y0 of SEL with (fetch YBOT of LINE))
			(replace L1 of SEL with LINE)
			(SETQ TX (fetch LEFTMARGIN of LINE))
                                                             (* Temp. X value for scanning the line from left margin 
							     to the right)
			(replace X0 of SEL with (fetch LEFTMARGIN of LINE))
			(COND
			  [(AND (IEQP CH# (fetch CHARLIM of LINE))
				(EQ (fetch POINT of SEL)
				    (QUOTE RIGHT))
				(IEQP (fetch DCH of SEL)
				      0)
				(fetch CR\END of LINE)
				(fetch NEXTLINE of LINE))    (* This selection starts AFTER the CR on a line, and 
							     doesn't include it.)
			    (replace L1 of SEL with (fetch NEXTLINE of LINE))
                                                             (* Change the selection to start on the next line, at 
							     the margin, instead.)
			    (replace X0 of SEL with (fetch LEFTMARGIN of (fetch L1 of SEL)))
			    (replace Y0 of SEL with (fetch YBOT of (fetch L1 of SEL]
			  ((IGREATERP CH# (fetch CHAR1 of LINE))
                                                             (* Only bother formatting the line if the selection 
							     doesn't include the first character.)
			    (COND
			      ((NEQ (fetch DESC of THISLINE)
				    LINE)                    (* If this line isn't cached in THISLINE, reformat it.)
				(\FORMATLINE TEXTOBJ NIL (fetch CHAR1 of LINE)
					     LINE)))
			    (COND
			      ((IGEQ (fetch LEN of THISLINE)
				     0)                      (* As long as there's something there on the line...)
				(bind (LOOKNO ← 0) for I from 0 to (fetch LEN of THISLINE)
				   as CHNO from (fetch CHAR1 of LINE)
				   do (SETQ DX (\WORDELT WLIST I))
				      (SETQ TX (IPLUS TX DX))
				      (COND
					((IGEQ CHNO CH#)
					  (RETURN))
					[(EQ 401 (\EDITELT CHLIST I))
                                                             (* This is INVISIBLE text. Count the characters as 
							     though they were there.)
					  (add LOOKNO 1)
					  (add CHNO (SUB1 (\EDITELT LOOKS LOOKNO]
					((EQ 400 (\EDITELT CHLIST I))
                                                             (* This is a format effector--reduce CHNO to ignore it)
					  (add LOOKNO 1)
					  (SETQ CHNO (SUB1 CHNO)))
					(T (replace X0 of SEL with TX]
		      ((IEQP CH# (ADD1 (fetch CHARLIM of LINE)))
                                                             (* The selection starts either here or at the start of 
							     the next line.)
			(replace Y0 of SEL with (fetch YBOT of LINE))
			(replace L1 of SEL with LINE)
			(replace X0 of SEL with (fetch LXLIM of LINE)))
		      ((AND (NOT STARTFOUND)
			    (IGREATERP (fetch CHAR1 of LINE)
				       CH#)
			    (ILEQ (fetch CHAR1 of LINE)
				  CHLIM))                    (* The selection starts before this line, so play 
							     catch-up)
			(replace Y0 of SEL with (fetch YBOT of LINE))
			(replace L1 of SEL with LINE)
			(replace X0 of SEL with (fetch LEFTMARGIN of LINE))
			(SETQ STARTFOUND T)))
		    [COND
		      [(AND (IGEQ CHLIM (fetch CHAR1 of LINE))
			    (ILEQ CHLIM (fetch CHARLIM of LINE)))
                                                             (* The selection ends in this line.
							     Fix LN, XLIM, and YLIM.)
			(replace YLIM of SEL with (fetch YBOT of LINE))
			(replace LN of SEL with LINE)
			(SETQ TX (fetch LEFTMARGIN of LINE))
                                                             (* Temp X position)
			(replace XLIM of SEL with (fetch LXLIM of LINE))
			(COND
			  [(AND (IEQP CHLIM (fetch CHARLIM of LINE))
				(EQ (fetch POINT of SEL)
				    (QUOTE RIGHT))
				(IEQP (fetch DCH of SEL)
				      0)
				(fetch NEXTLINE of LINE)
				(fetch CR\END of LINE))      (* This selection starts AFTER the CR on a line, and 
							     doesn't include it.)
			    (replace LN of SEL with (fetch NEXTLINE of LINE))
                                                             (* Change the selection to start on the next line, at 
							     the margin, instead.)
			    (replace XLIM of SEL with (fetch LEFTMARGIN of (fetch LN of SEL)))
			    (replace YLIM of SEL with (fetch YBOT of (fetch LN of SEL]
			  ((ILESSP CHLIM (IMIN (fetch CHARLIM of LINE)
					       (fetch TEXTLEN of TEXTOBJ)))
                                                             (* Only bother formatting if the selection doesn't 
							     include the last char on the line)
			    (COND
			      ((NEQ (fetch DESC of THISLINE)
				    LINE)                    (* If this line isn't cached in THISLINE, then reformat 
							     it.)
				(\FORMATLINE TEXTOBJ NIL (fetch CHAR1 of LINE)
					     LINE)))
			    (COND
			      ((IGEQ (fetch LEN of THISLINE)
				     0)
				(bind (LOOKNO ← 0) for I from 0 to (fetch LEN of THISLINE)
				   as CHNO from (fetch CHAR1 of LINE)
				   do (SETQ DX (\WORDELT WLIST I))
				      (SETQ TX (IPLUS TX DX))
				      (COND
					((IGREATERP CHNO CHLIM)
					  (RETURN))
					[(EQ 401 (\EDITELT CHLIST I))
                                                             (* This is a run of INVISIBLE characters.
							     Count them in the character position, though.)
					  (add LOOKNO 1)
					  (add CHNO (SUB1 (\EDITELT LOOKS LOOKNO]
					((EQ 400 (\EDITELT CHLIST I))
                                                             (* This is a format effector--reduce CHNO to ignore it)
					  (SETQ CHNO (SUB1 CHNO))
					  (add LOOKNO 1))
					(T (replace XLIM of SEL with TX]
		      ((IEQP CHLIM (ADD1 (fetch CHARLIM of LINE)))
                                                             (* The selection ends either here or at the start of the
							     next line.)
			(replace YLIM of SEL with (fetch YBOT of LINE))
			(replace LN of SEL with LINE)
			(replace XLIM of SEL with (fetch LXLIM of LINE]
		    (SETQ PREVLINE LINE)
		    (SETQ LINE (fetch NEXTLINE of LINE)))
	      (COND
		[(IEQP 0 (fetch DCH of SEL))                 (* If this is a point selection, put it on the correct 
							     side of the character we selected.)
		  (replace DX of SEL with 0)
		  (COND
		    ((EQ (fetch POINT of SEL)
			 (QUOTE LEFT))
		      (replace XLIM of SEL with (fetch X0 of SEL)))
		    (T (replace X0 of SEL with (fetch XLIM of SEL]
		(T                                           (* Otherwise, fix DX for the selection)
		   (replace DX of SEL with (IDIFFERENCE (fetch XLIM of SEL)
							(fetch X0 of SEL])

(\TEDIT.FIXDELSEL
  [LAMBDA (SELTOFIX TEXTOBJ CH#1 CH#LIM DCH)                 (* jds "12-JUL-83 13:55")
                                                             (* Fix up a SELTOFIX after deletion inside that textobj)
                                                             (* Only if the Selection is set, and is in THIS textobj)
    (COND
      ((AND (fetch SET of SELTOFIX)
	    (EQ TEXTOBJ (fetch \TEXTOBJ of SELTOFIX)))
	(COND
	  ((IGREATERP (fetch CH# of SELTOFIX)
		      CH#LIM)                                (* The selection is after the deleted text.
							     Just move it forward)
	    (replace CH# of SELTOFIX with (IDIFFERENCE (fetch CH# of SELTOFIX)
						       DCH))
	    (replace CHLIM of SELTOFIX with (IDIFFERENCE (fetch CHLIM of SELTOFIX)
							 DCH)))
	  ((IGEQ (fetch CHLIM of SELTOFIX)
		 CH#1)                                       (* It overlaps, at least partially.)
	    (COND
	      ((IGEQ (fetch CH# of SELTOFIX)
		     CH#1)                                   (* If the start of the selection was inside the deleted 
							     area, it now starts where the deletion left off.)
		(replace CH# of SELTOFIX with CH#1)))
	    (replace CHLIM of SELTOFIX with (IMAX CH#1 (IDIFFERENCE (fetch CHLIM of SELTOFIX)
								    DCH)))
	    (replace DCH of SELTOFIX with (COND
					    ((IEQP (fetch CHLIM of SELTOFIX)
						   CH#1)
					      0)
					    (T (ADD1 (IDIFFERENCE (fetch CHLIM of SELTOFIX)
								  (fetch CH# of SELTOFIX])

(\TEDIT.FIXSELS
  [LAMBDA (TEXTOBJ EXCEPT)                                   (* jds " 3-AUG-83 13:05")
                                                             (* Fixes all the sels for a given textobj.)
    (for SELN in (LIST (fetch SEL of TEXTOBJ)
		       (fetch SHIFTEDSEL of TEXTOBJ)
		       (fetch MOVESEL of TEXTOBJ)
		       (fetch DELETESEL of TEXTOBJ))
       when (NEQ SELN EXCEPT) do (AND (fetch SET of SELN)
				      (\FIXSEL SELN TEXTOBJ])

(\TEDIT.SELECT.CHARACTER
  [LAMBDA (TEXTOBJ SEL PREVCH LINE X Y TXB SELWINDOW)        (* jds " 2-May-84 17:44")
                                                             (* We have moved over a particular character.
							     If it's really a character, OK.
							     Otherwise, call in the selection function!)
    (DECLARE (USEDFREE . WORDSELFLG))
    (COND
      ((SMALLP PREVCH)
	(replace SELOBJ of SEL with NIL))
      (T (SETQ WORDSELFLG NIL)
	 (replace (SELECTION SELOBJ) of SEL with PREVCH)
	 (replace (SELECTION X0) of SEL with TXB)
	 (replace (SELECTION Y0) of SEL with (fetch YBOT of LINE))
	 (PROG ([OBJBOX (OR (IMAGEOBJPROP PREVCH (QUOTE BOUNDBOX))
			    (IMAGEBOX PREVCH SELWINDOW (QUOTE DISPLAY]
		(DS (fetch DS of TEXTOBJ))
		SELRES)
	       (RESETLST (RESETSAVE (DSPXOFFSET (IDIFFERENCE (IPLUS TXB (DSPXOFFSET NIL DS))
							     (fetch XKERN of OBJBOX))
						DS)
				    (LIST (FUNCTION DSPXOFFSET)
					  (DSPXOFFSET NIL DS)
					  DS))
			 (RESETSAVE (DSPYOFFSET (IDIFFERENCE (IPLUS (fetch YBASE of LINE)
								    (DSPYOFFSET NIL DS))
							     (fetch YDESC of OBJBOX))
						DS)
				    (LIST (FUNCTION DSPYOFFSET)
					  (DSPYOFFSET NIL DS)
					  DS))
			 (RESETSAVE (DSPCLIPPINGREGION (create REGION
							       LEFT ← 0
							       BOTTOM ← 0
							       WIDTH ←(IMIN (fetch XSIZE
									       of OBJBOX)
									    (IDIFFERENCE
									      (fetch WRIGHT
										 of TEXTOBJ)
									      TXB))
							       HEIGHT ←(fetch YSIZE of OBJBOX))
						       DS)
				    (LIST (FUNCTION DSPCLIPPINGREGION)
					  (DSPCLIPPINGREGION NIL DS)
					  DS))
			 [SETQ SELRES (ERSETQ (APPLY* (IMAGEOBJPROP PREVCH (QUOTE BUTTONEVENTINFN))
						      PREVCH DS SEL (IDIFFERENCE X TXB)
						      (IDIFFERENCE Y (fetch YBOT of LINE))
						      SELWINDOW
						      (fetch STREAMHINT of TEXTOBJ]
                                                             (* Go tell him he's being pointed at.)
			 (COND
			   ((NULL SELRES)                    (* If the event fn returns NIL, do nothing untoward)
			     )
			   ((EQ (CAR SELRES)
				(QUOTE DON'T))               (* The object declines to be selected.
							     Don't permit the select to happen.)
			     (replace SET of SEL with NIL))
			   ((NULL (CAR SELRES))              (* If it returns something with a CAR of NIL, then 
							     UN-SET the object-ness of the selection)
			     (replace SELOBJ of SEL with NIL])

(\TEDIT.SHOWSELS
  [LAMBDA (TEXTOBJ HOW ON)                                   (* jds "22-MAR-83 14:47")
                                                             (* Turns all the selections for a given Textobj on or 
							     off)
    (for SELN in (LIST (fetch SEL of TEXTOBJ)
		       (fetch SHIFTEDSEL of TEXTOBJ)
		       (fetch MOVESEL of TEXTOBJ)
		       (fetch DELETESEL of TEXTOBJ))
       do (AND (fetch SET of SELN)
	       (\SHOWSEL SELN HOW ON])

(\TEDIT.UPDATE.SHOWSEL
  [LAMBDA (NSEL OSEL TSTFLG)                                 (* jds " 2-JUN-83 15:43")
                                                             (* Update the selection highlighting to reflect the 
							     differences between NSEL and OSEL)
    (PROG ((TEXTOBJ (fetch \TEXTOBJ of OSEL)))
          (PROG ((DS (ffetch DS of TEXTOBJ))
		 (SHADE (OR (fetch HOW of OSEL)
			    BLACKSHADE))
		 (SHADEHEIGHT (OR (fetch HOWHEIGHT of OSEL)
				  1))
		 (EXCHFLG NIL)
		 TSEL LL)
	        (replace ONFLG of NSEL with T)               (* Make the new selection think that we've really 
							     displayed all its new aspects.)
	        [COND
		  ((fetch HASCARET of OSEL)                  (* Turn off the caret, if need be)
		    (\EDIT.UPCARET (fetch CARET of TEXTOBJ]
	        [COND
		  ((NEQ (fetch CH# of NSEL)
			(fetch CH# of OSEL))                 (* The new selection starts earlier;
							     add hilight at the front)
		    (COND
		      ((ILESSP (fetch CH# of OSEL)
			       (fetch CH# of NSEL))          (* Actually, it starts later;
							     just exchange the selections)
			(SETQ TSEL OSEL)
			(SETQ OSEL NSEL)
			(SETQ NSEL TSEL)
			(SETQ EXCHFLG T)))
		    (COND
		      ((EQ (fetch L1 of OSEL)
			   (fetch L1 of NSEL))               (* The left ends are on the same line.
							     Just blacken the space between them)
			(BITBLT NIL 0 0 DS (fetch X0 of NSEL)
				(fetch Y0 of NSEL)
				(IDIFFERENCE (fetch X0 of OSEL)
					     (fetch X0 of NSEL))
				(IMIN SHADEHEIGHT (fetch LHEIGHT of (fetch L1 of OSEL)))
				(QUOTE TEXTURE)
				(QUOTE INVERT)
				SHADE))
		      (T                                     (* They start on different lines;
							     blacken the intervening lines.)
			 (AND (fetch L1 of NSEL)
			      (BITBLT NIL 0 0 DS (fetch X0 of NSEL)
				      (fetch Y0 of NSEL)
				      (IDIFFERENCE (fetch LXLIM of (fetch L1 of NSEL))
						   (fetch X0 of NSEL))
				      (IMIN SHADEHEIGHT (fetch LHEIGHT of (fetch L1 of NSEL)))
				      (QUOTE TEXTURE)
				      (QUOTE INVERT)
				      SHADE))
			 (SETQ LL (OR (fetch L1 of NSEL)
				      (fetch LINES of TEXTOBJ)))
			 (AND LL (SETQ LL (fetch NEXTLINE of LL)))
			 (while LL until (OR (EQ LL (fetch L1 of OSEL))
					     (ILEQ (fetch YBOT of LL)
						   (fetch WBOTTOM of TEXTOBJ)))
			    do (BITBLT NIL 0 0 DS (fetch LEFTMARGIN of LL)
				       (fetch YBOT of LL)
				       (IDIFFERENCE (fetch LXLIM of LL)
						    (fetch LEFTMARGIN of LL))
				       (IMIN SHADEHEIGHT (fetch LHEIGHT of LL))
				       (QUOTE TEXTURE)
				       (QUOTE INVERT)
				       SHADE)
			       (SETQ LL (fetch NEXTLINE of LL)))
			 (AND LL (IGREATERP (fetch YBOT of LL)
					    (fetch WBOTTOM of TEXTOBJ))
			      (BITBLT NIL 0 0 DS (fetch LEFTMARGIN of LL)
				      (fetch YBOT of LL)
				      (IDIFFERENCE (fetch X0 of OSEL)
						   (fetch LEFTMARGIN of LL))
				      (IMIN SHADEHEIGHT (fetch LHEIGHT of LL))
				      (QUOTE TEXTURE)
				      (QUOTE INVERT)
				      SHADE]
	        (COND
		  (EXCHFLG                                   (* Put the selections back as they were.)
			   (SETQ TSEL OSEL)
			   (SETQ OSEL NSEL)
			   (SETQ NSEL TSEL)
			   (SETQ EXCHFLG NIL)))
	        [COND
		  ((NEQ (fetch CHLIM of OSEL)
			(fetch CHLIM of NSEL))               (* NSEL ends later -- go add hilite at the end)
		    (COND
		      ((ILESSP (fetch CHLIM of NSEL)
			       (fetch CHLIM of OSEL))        (* NO it ends earlier; just switch the selections and go
							     ahead as usual)
			(SETQ TSEL OSEL)
			(SETQ OSEL NSEL)
			(SETQ NSEL TSEL)
			(SETQ EXCHFLG T)))
		    (COND
		      ((EQ (fetch LN of OSEL)
			   (fetch LN of NSEL))               (* They end on the same line;
							     blacken the DX space between them)
			(BITBLT NIL 0 0 DS (fetch XLIM of OSEL)
				(fetch YLIM of OSEL)
				(IDIFFERENCE (fetch XLIM of NSEL)
					     (fetch XLIM of OSEL))
				(IMIN SHADEHEIGHT (fetch LHEIGHT of (fetch LN of OSEL)))
				(QUOTE TEXTURE)
				(QUOTE INVERT)
				SHADE))
		      (T                                     (* They end on different lines;
							     blacken intervening lines)
			 (AND (fetch L1 of OSEL)
			      (BITBLT NIL 0 0 DS (fetch XLIM of OSEL)
				      (fetch YLIM of OSEL)
				      (IDIFFERENCE (fetch LXLIM of (fetch LN of OSEL))
						   (fetch XLIM of OSEL))
				      (IMIN SHADEHEIGHT (fetch LHEIGHT of (fetch LN of OSEL)))
				      (QUOTE TEXTURE)
				      (QUOTE INVERT)
				      SHADE))
			 (SETQ LL (OR (fetch LN of OSEL)
				      (fetch LINES of TEXTOBJ)))
			 (AND LL (SETQ LL (fetch NEXTLINE of LL)))
			 (while LL until (OR (EQ LL (fetch LN of NSEL))
					     (ILEQ (fetch YBOT of LL)
						   (fetch WBOTTOM of TEXTOBJ)))
			    do (BITBLT NIL 0 0 DS (fetch LEFTMARGIN of LL)
				       (fetch YBOT of LL)
				       (IDIFFERENCE (fetch LXLIM of LL)
						    (fetch LEFTMARGIN of LL))
				       (IMIN SHADEHEIGHT (fetch LHEIGHT of LL))
				       (QUOTE TEXTURE)
				       (QUOTE INVERT)
				       SHADE)
			       (SETQ LL (fetch NEXTLINE of LL)))
			 (AND LL (IGREATERP (fetch YBOT of LL)
					    (fetch WBOTTOM of TEXTOBJ))
			      (BITBLT NIL 0 0 DS (fetch LEFTMARGIN of LL)
				      (fetch YBOT of (fetch LN of NSEL))
				      (IDIFFERENCE (fetch XLIM of NSEL)
						   (fetch LEFTMARGIN of LL))
				      (IMIN SHADEHEIGHT (fetch LHEIGHT of LL))
				      (QUOTE TEXTURE)
				      (QUOTE INVERT)
				      SHADE]
	        (COND
		  (EXCHFLG                                   (* Put the selections back as they were.)
			   (SETQ TSEL OSEL)
			   (SETQ OSEL NSEL)
			   (SETQ NSEL TSEL)))
	        (COND
		  ((fetch HASCARET of NSEL)                  (* Now put the caret back up.)
		    (COND
		      ((EQ (fetch POINT of NSEL)
			   (QUOTE LEFT))                     (* Left end of the selection)
			(\SETCARET (fetch X0 of NSEL)
				   (fetch Y0 of NSEL)
				   DS TEXTOBJ))
		      (T                                     (* Right end of the selection)
			 (\SETCARET (fetch XLIM of NSEL)
				    (fetch YLIM of NSEL)
				    DS TEXTOBJ])
)
(DECLARE: DONTCOPY
  (FILEMAP (NIL (4117 14521 (TEDIT.SEL.AS.STRING 4127 . 5558) (TEDIT.SELECTED.PIECES 5560 . 7905) (
\TEDIT.FIND.FIRST.LINE 7907 . 10372) (\TEDIT.FIND.LAST.LINE 10374 . 11356) (
\TEDIT.FIND.OVERLAPPING.LINE 11358 . 11649) (\TEDIT.FIND.PROTECTED.END 11651 . 12733) (
\TEDIT.FIND.PROTECTED.START 12735 . 14060) (\TEDIT.WORD.BOUND 14062 . 14519)) (15505 80138 (\SHOWSEL 
15515 . 23427) (TEDIT.EXTEND.SEL 23429 . 30032) (TEDIT.GETSEL 30034 . 30248) (TEDIT.MAKESEL 30250 . 
31035) (TEDIT.RESET.EXTEND.PENDING.DELETE 31037 . 31495) (TEDIT.SCANSEL 31497 . 32083) (TEDIT.SELECT 
32085 . 34129) (TEDIT.SCAN.LINE 34131 . 44005) (TEDIT.SELECT.LINE.SCANNER 44007 . 51665) (
TEDIT.SET.SEL.LOOKS 51667 . 53233) (TEDIT.SETSEL 53235 . 56796) (TEDIT.SHOWSEL 56798 . 57306) (
\COPYSEL 57308 . 58940) (\FIXSEL 58942 . 67871) (\TEDIT.FIXDELSEL 67873 . 69529) (\TEDIT.FIXSELS 69531
 . 70062) (\TEDIT.SELECT.CHARACTER 70064 . 72698) (\TEDIT.SHOWSELS 72700 . 73235) (
\TEDIT.UPDATE.SHOWSEL 73237 . 80136)))))
STOP