(FILECREATED " 6-Oct-86 12:47:55" {ERIS}<TEDIT>TEDITSELECTION.;18 133119 

      changes to:  (VARS TEDITSELECTIONCOMS)

      previous date: "25-Sep-86 22:38:05" {ERIS}<TEDIT>TEDITSELECTION.;17)


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

(PRETTYCOMPRINT TEDITSELECTIONCOMS)

(RPAQQ TEDITSELECTIONCOMS ((FILES TEDITDECLS)
                           (DECLARE: EVAL@COMPILE DONTCOPY (CONSTANTS (\SCRATCHLEN 64))
                                  (FILES (LOADCOMP)
                                         TEDITDECLS))
                           (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)
                           (INITVARS (TEDIT.EXTEND.PENDING.DELETE T))
                           (VARS (TEDIT.SELECTION (create SELECTION))
                                 (TEDIT.SCRATCHSELECTION (create SELECTION))
                                 (TEDIT.SHIFTEDSELECTION (create SELECTION HOW←COPYSELSHADE 
                                                                HASCARET←NIL))
                                 (TEDIT.COPYLOOKSSELECTION (create SELECTION HOW←COPYLOOKSSELSHADE 
                                                                  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.COPYLOOKSSELECTION 
                                  TEDIT.DELETESELECTION TEDIT.SELPENDING TEDIT.EXTEND.PENDING.DELETE)
                           (COMS (* Selection manipulating code)
                                 (FNS TEDIT.EXTEND.SEL TEDIT.SELECT TEDIT.SCAN.LINE 
                                      TEDIT.SELECT.LINE.SCANNER \TEDIT.SELECT.CHARACTER)
                                 (FNS \FIXSEL \TEDIT.FIXDELSEL \TEDIT.FIXINSSEL \TEDIT.FIXSELS)
                                 (FNS TEDIT.RESET.EXTEND.PENDING.DELETE \TEDIT.SET.SEL.LOOKS)
                                 (FNS \SHOWSEL \SHOWSEL.HILIGHT \TEDIT.UPDATE.SHOWSEL \TEDIT.SHOWSELS 
                                      \TEDIT.REFRESH.SHOWSEL)
                                 (FNS \COPYSEL \TEDIT.SEL.CHANGED?))
                           (COMS (* * User entries to the selection code)
                                 (FNS TEDIT.GETPOINT TEDIT.GETSEL TEDIT.MAKESEL TEDIT.SCANSEL 
                                      TEDIT.SET.SEL.LOOKS TEDIT.SETSEL TEDIT.SHOWSEL))))
(FILESLOAD TEDITDECLS)
(DECLARE: EVAL@COMPILE DONTCOPY 
(DECLARE: EVAL@COMPILE 

(RPAQQ \SCRATCHLEN 64)

(CONSTANTS (\SCRATCHLEN 64))
)

(FILESLOAD (LOADCOMP)
       TEDITDECLS)
)
(DEFINEQ

(TEDIT.SEL.AS.STRING
  [LAMBDA (STREAM SEL)                                       (* jds "29-Jul-85 14:00")
                                                             (* 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
             ((ZEROP LEN)                                    (* There is no selection, or it's 
                                                             zero-width. Return "")
              (RETURN ""))
             (T (SETQ RESULT (ALLOCSTRING LEN (CHARCODE SPACE)))
                                                             (* The resulting string)
                (\SETUPGETCH (fetch CH# of TSEL)
                       TEXTOBJ)                              (* Starting point for the string is 
                                                             start of selection.)
                (for I from 1 to LEN do                      (* Get chars from the stream, and put 
                                                             them in the string.)
                                        (RPLCHARCODE RESULT I (\GETCH TEXTOBJ)))
                (RETURN RESULT])

(TEDIT.SELECTED.PIECES
  [LAMBDA (TEXTOBJ SEL CROSSCOPY PIECEMAPFN FNARG1 FNARG2)   (* jds " 6-Mar-85 22:10")
          
          (* 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.)
                    )
                   ((IGEQ 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 NPCCH)               (* This piece overlaps the end of the 
                                                             copy region. Shorten it at the end.)
                          (\SPLITPIECE PC 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 "21-Nov-84 11:18")
                                                             (* 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 "21-Aug-84 12:16")
                                                             (* 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 (IGEQ (fetch YBOT of LINE)
                                                                   (fetch WBOTTOM of TEXTOBJ)))
           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 " 9-Jan-85 13:25")
          
          (* Starting from a CH# in a selectable region, find the CH# of the last 
          selectable character following that. This is used to limit selections to 
          unprotected text, and to prevent selection of the protected text between tow 
          unprotected areas.)
                                                             (* If LIMITCH# is given, the search 
                                                             will stop there.)
    (bind (OURLIMIT ← (IMIN (OR LIMITCH# (fetch TEXTLEN of TEXTOBJ))
                            (fetch TEXTLEN of TEXTOBJ)))
          (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 (* Move forward thru the pieces of the document, looking for one that contains 
          protected text. If that comes before the end of the region we're interested in, 
          tell the caller about the earlier end to selectable text.)
          (COND
             ((IGREATERP (\EDITELT PCTB (SUB1 I))
                     OURLIMIT)                               (* We've passed the limit, so it's 
                                                             time to give up. Just return the 
                                                             LIMITCH#)
              (RETURN OURLIMIT))
             ((fetch CLPROTECTED of (fetch PLOOKS of (\EDITELT PCTB I)))
                                                             (* We've found the beginning of a 
                                                             protected region -- i.e., the end of 
                                                             the selectable region.
                                                             Tell the caller about it.)
              (RETURN (SUB1 (\EDITELT PCTB (SUB1 I])

(\TEDIT.FIND.PROTECTED.START
  [LAMBDA (TEXTOBJ CH# LIMITCH#)                             (* jds " 5-Feb-85 14:47")
          
          (* Starting from a CH# in a selectable region, find the CH# of the earliest 
          contiguously-selectable character preceding that.
          This is used to limit selections to unprotected text, and to prevent selection 
          of the protected text between tow unprotected areas.)
                                                             (* Will stop looking when it passes 
                                                             LIMITCH#, or at the beginning of the 
                                                             document.)
    (bind (OURLIMIT ← (OR LIMITCH# 1))
          (PCTB ← (fetch PCTB of TEXTOBJ)) for I
       from (ADD1 (\CHTOPCNO (IMAX 1 (IMIN CH# (fetch TEXTLEN of TEXTOBJ)))
                         (fetch PCTB of TEXTOBJ))) to \FirstPieceOffset by (IMINUS \EltsPerPiece)
       do (COND
             ((ILEQ (\EDITELT PCTB (SUB1 I))
                    OURLIMIT)                                (* If he specified a LIMITCH#, and we 
                                                             have passed it, stop bothering and 
                                                             return the LIMITCH#)
              (RETURN OURLIMIT))
             ((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])

(\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])
)

(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.COPYLOOKSSELECTION (create SELECTION HOW←COPYLOOKSSELSHADE 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

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



(* Selection manipulating code)

(DEFINEQ

(TEDIT.EXTEND.SEL
  [LAMBDA (X Y OSEL TEXTOBJ SELOPERATION SELWINDOW NEWSEL)   (* jds " 7-Mar-85 02:48")
                                                             (* Gather a new selected character, 
                                                             and extend OSEL to include it.
                                                             Return the extended selection.)
    (PROG ((NSEL (OR NEWSEL (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)
           (FIXUPNEEDED 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)
                                                       (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 (COPY (fetch LN of OSEL)))
                        (COND
                           ((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
                                                             (SUB1 (fetch CHLIM of OSEL))
                                                             (fetch CH# of NSEL]
                            (SETQ FIXUPNEEDED T)             (* Note that the L1/LN may be invalid 
                                                             as a result of this contraction.
                                                             Force a \FIXSEL later.)
                            )))
                  (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 (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 (COPY (fetch L1 of OSEL)))
                         (COND
                            ((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)
                                           (ADD1 (\TEDIT.FIND.PROTECTED.END
                                                  TEXTOBJ
                                                  (fetch CH# of OSEL)
                                                  (ADD1 (\TEDIT.FIND.PROTECTED.END
                                                         TEXTOBJ
                                                         (fetch CH# of OSEL)
                                                         (SUB1 (fetch CHLIM of NSEL]
                             (replace CH# of NSEL with (IMIN (fetch CHLIM of NSEL)
                                                             (fetch CH# of NSEL)))
                             (SETQ FIXUPNEEDED T)            (* Note that the L1/LN may be invalid 
                                                             as a result of this contraction.
                                                             Force a \FIXSEL later.)
                             )))
                  (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 (COPY (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 (COPY (fetch L1 of OSEL)))
                         (SETQ NPOINT (fetch POINT of OSEL]
              (replace DCH of NSEL with (IDIFFERENCE (IMIN (ADD1 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)
                                                 (fetch DCH of NSEL)))
                                                             (* This assures that the CHLIM 
                                                             corresponds to the DCH.)
              (replace POINT of NSEL with NPOINT)
              (replace (SELECTION 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
                 (FIXUPNEEDED                                (* We're in a menu, and this selection 
                                                             got contracted because of a protection 
                                                             violation. Fix up everything.)
                        (\FIXSEL NSEL TEXTOBJ)))
              (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.SELECT
  [LAMBDA (X Y TEXTOBJ REGION WORDSELFLG SELOPERATION WINDOW)(* jds "11-Sep-85 14:07")
                                                             (* Select the character word, line, or 
                                                             paragraph the mouse is pointing at.)
    (PROG ((SEL NIL)
           (TEXTLEN (fetch TEXTLEN of TEXTOBJ))
           PREVLINE L1 LN)
          (SETQ SEL (TEDIT.SELECT.LINE.SCANNER X Y TEXTOBJ (\TEDIT.LINE.LIST TEXTOBJ WINDOW)
                           REGION WORDSELFLG SELOPERATION WINDOW))
          (COND
             ((AND (type? SELECTION SEL)
                   (fetch SET of SEL))                       (* He pointed at something real;
                                                             return that.)
              (\TEDIT.SET.SEL.LOOKS SEL SELOPERATION)
              [COND
                 ([AND (CAR (fetch L1 of SEL))
                       (fetch FMTHARDCOPY of (fetch LFMTSPEC of (CAR (fetch L1 of SEL]
                  (replace X0 of SEL with (FIXR (FQUOTIENT (fetch X0 of SEL)
                                                       35.27778]
              [COND
                 ([AND (CAR (fetch LN of SEL))
                       (fetch FMTHARDCOPY of (fetch LFMTSPEC of (CAR (fetch LN of SEL]
                  (replace XLIM of SEL with (FIXR (FQUOTIENT (fetch XLIM of SEL)
                                                         35.27778]
              (replace DX of SEL with (IDIFFERENCE (fetch XLIM of SEL)
                                             (fetch X0 of SEL)))
              (\FIXSEL SEL TEXTOBJ WINDOW T)
              (RETURN SEL))
             ((type? LINEDESCRIPTOR SEL)                     (* He pointed below the bottom of the 
                                                             text. Select to the right of the last 
                                                             character on the screen.)
              (COND
                 ((fetch LHASPROT of SEL)                    (* The last line is protected.
                                                             Don't select anything.)
                  (RETURN)))
              (SETQ PREVLINE SEL)
              (SETQ SEL (fetch SCRATCHSEL of TEXTOBJ))
              (replace SET of SEL with T)
              (replace \TEXTOBJ of SEL with TEXTOBJ)
              [replace CH# of SEL with (IMAX 1 (ADD1 (IMIN TEXTLEN (fetch CHARLIM of PREVLINE]
              (replace CHLIM of SEL with (fetch CH# of SEL))
              (replace DCH of SEL with 0)
              [replace POINT of SEL with (COND
                                            ((IGREATERP (fetch CH# of SEL)
                                                    (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 SEL SELOPERATION)
              (\FIXSEL SEL TEXTOBJ)
              (RETURN SEL])

(TEDIT.SCAN.LINE
  [LAMBDA (TEXTOBJ LINE THISLINE X Y WORDSELFLG SELOPERATION WINDOW)
                                                             (* jds "31-Jul-85 19:53")
                                                             (* Given a line, find the character 
                                                             which straddles the mouse.)
    (PROG ((L NIL)
           (WLIST (fetch (THISLINE WIDTHS) of THISLINE))
           (CHLIST (fetch (THISLINE CHARS) of THISLINE))
           (LLIST (fetch (THISLINE LOOKS) of THISLINE))
           (LOOKNO 1)
           (DX 0)
           OTX YBOT YBASE TX (CH (CHARCODE SPACE))
           PREVCH CHOBJB TXB CHB (TEXTLEN (fetch TEXTLEN of TEXTOBJ))
           L1 LN 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)))
          [COND
             ((fetch FMTHARDCOPY of (fetch LFMTSPEC of LINE))(* This is a hardcopy-mode line.
                                                             Convert units to micas)
              (SETQ X (FIXR (FTIMES X 35.27778]
          [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 LMInvisibleRun)                   (* 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 LMInvisibleRun))       (* Can't have 2 invisible runs in a 
                                                             row.)
                [COND
                   ((EQ CH LMLooksChange)                    (* 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 (SELECTION 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)
                                                       (ADD1 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 (ADD1 (COND
                                                      ((fetch CLSELHERE of PCLOOKS)
                                                       CHNO)
                                                      (WORDSELFLG CHNO)
                                                      (T CHNO]
                    (replace YLIM of L with (fetch YBOT of LINE))
                    (for L1 on (fetch L1 of L) as LN on (fetch LN of L) as WW
                       inside (fetch \WINDOW of TEXTOBJ) when (EQ WW WINDOW)
                       do (RPLACA L1 LINE)
                          (RPLACA LN 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 (SELECTION 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))
                  (for L1 on (fetch L1 of L) as LN on (fetch LN of L) as WW
                     inside (fetch \WINDOW of TEXTOBJ) when (EQ WW WINDOW)
                     do (RPLACA L1 LINE)
                        (RPLACA LN 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 (SELECTION 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 (ADD1 (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 (COND
                                                            (WORDSELFLG 
                                                             (* If it's a word, check our location 
                                                             against mid-word to see which side to 
                                                             put the caret on)
                                                                   (LRSH (IPLUS TX TXB)
                                                                         1))
                                                            (T 
                                                             (* Otherwise, check against 
                                                             mid-character)
                                                               (IDIFFERENCE TX (LRSH DX 1]
                                                             (* If we're to the right of mid-item, 
                                                             put the caret on the right.)
                                                 (QUOTE RIGHT))
                                                (T           (* Otherwise, put it on the left.)
                                                   (QUOTE LEFT]
                                            (T (QUOTE LEFT]
                (for L1 on (fetch L1 of L) as LN on (fetch LN of L) as WW
                   inside (fetch \WINDOW of TEXTOBJ) when (EQ WW WINDOW)
                   do (RPLACA L1 LINE)
                      (RPLACA LN 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 "21-Apr-86 14:00")
                                                             (* Find the text line the mouse is 
                                                             pointing at.)
                                                             (* LINE.LIST is the dummy first line 
                                                             for the window in which selection 
                                                             happened.)
    (PROG ((L NIL)
           (WWIDTH (fetch WRIGHT of TEXTOBJ))
           (THISLINE (fetch THISLINE of TEXTOBJ))
           (TEXTLEN (fetch TEXTLEN of TEXTOBJ))
           (WREG (DSPCLIPPINGREGION NIL WINDOW))
           PREVLINE PARABOUNDS PARASTART PARAEND L1 LN)
          (bind (LINE ← (fetch NEXTLINE of LINE.LIST))
             while (AND LINE (IGEQ (fetch YBOT of LINE)
                                   (fetch BOTTOM of WREG)))
             do
          
          (* Search thru the list of (real) 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 WINDOW)                          (* 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))
                           (for TL1 on (fetch L1 of L) as TLN on (fetch LN of L) as WW
                              inside (fetch \WINDOW of TEXTOBJ) when (EQ WW WINDOW)
                              do (SETQ L1 TL1)
                                 (SETQ LN TLN)
                                 (RETURN))
                           (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]
                               (RPLACA L1 LINE)
                               (RPLACA LN LINE)
                               (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                         (* Walk forward thru the lines, 
                                                             looking for the last line in the 
                                                             paragraph.)
                                     [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 (RPLACA LN LL))    (* SEARCH BACK TO A LINE WITH A CR OR 
                                                             BOTEXT)
                               [COND
                                  ((IGREATERP (fetch CHAR1 of LINE)
                                          1)                 (* Only search backward if we're not 
                                                             on the first line already.)
                                   (bind (LL ← LINE)
                                      while [AND (IGREATERP (fetch CHAR1 of LL)
                                                        1)
                                                 (COND
                                                    ((fetch FORMATTEDP of TEXTOBJ)
                                                     (IGREATERP (fetch CHAR1 of LL)
                                                            PARASTART))
                                                    (T (NOT (fetch CR\END
                                                               of (fetch PREVLINE of LL]
                                      do 
          
          (* Back up until we find the first line of the paragraph, or we hit the dummy 
          top line (which claims to end in CR.))

                                         (SETQ LL (fetch PREVLINE of LL))
                                      finally (RPLACA L1
                                                     (COND
                                                        ((AND (fetch FORMATTEDP of TEXTOBJ)
                                                              (IEQP (fetch CHAR1 of LL)
                                                                    PARASTART))
                                                             (* We found a true start of para.)
                                                         LL)
                                                        ([AND (fetch PREVLINE of LL)
                                                              (NOT (ZEROP (fetch CHARLIM
                                                                             of (fetch PREVLINE
                                                                                   of LL]
                                                             (* We hit the first line in the 
                                                             paragraph, fair and square)
                                                         LL)
                                                        ((IEQP 1 (fetch CHAR1 of LL))
                                                             (* We hit the front of the document.)
                                                         LL)
                                                        (T (\BACKFORMAT LINE.LIST TEXTOBJ
                                                                  (fetch PTOP of WREG))
                                                           (fetch NEXTLINE of LINE.LIST]
                               [replace CH# of L with (OR PARASTART (fetch CHAR1 of (CAR L1]
                               [replace CHLIM of L with (ADD1 (OR PARAEND (fetch CHARLIM
                                                                             of (CAR LN]
                               [replace POINT of L with (COND
                                                           ((ILEQ (IDIFFERENCE LINE:CHAR1 L:CH#)
                                                                  (IDIFFERENCE L:CHLIM LINE:CHARLIM))
                                                            (QUOTE LEFT))
                                                           (T (QUOTE RIGHT]
                               (replace DCH of L with (IDIFFERENCE (fetch CHLIM of L)
                                                             (fetch CH# of L)))
                               (COND
                                  ((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 (CAR L1)))
                                     (replace YLIM of L with (fetch YBOT of (CAR LN)))
                                     (replace X0 of L with (fetch LEFTMARGIN of (CAR L1)))
                                     (replace XLIM of L with (fetch LXLIM of (CAR LN)))
                                     (replace (SELECTION 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))
                                 (RPLACA L1 LINE)
                                 (RPLACA LN LINE)
                                 (replace CH# of L with (fetch CHAR1 of LINE))
                                 (replace CHLIM of L with (ADD1 (fetch CHARLIM of LINE)))
                                 (replace (SELECTION 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 (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.SELECT.CHARACTER
  [LAMBDA (TEXTOBJ SEL PREVCH LINE X Y TXB SELWINDOW)        (* jds "16-May-85 13:20")
                                                             (* 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 (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 (WINDOWPROP SELWINDOW (QUOTE DSP)))
                 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 YBASE of LINE))
                                                   SELWINDOW
                                                   (fetch STREAMHINT of TEXTOBJ)
                                                   (COND
                                                      (WORDSELFLG (QUOTE MIDDLE))
                                                      (T (QUOTE LEFT]
                                                             (* Go tell him he's being pointed at.)
                       )
                (COND
                   ((NULL SELRES)                            (* If the event fn returns NIL, do 
                                                             nothing untoward)
                    )
                   ((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))
                   (T                                        (* Otherwise, check to see what he 
                                                             wants us to do)
                      (COND
                         ((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))
                         ((AND (LISTP (CAR SELRES))
                               (FMEMB (QUOTE DON'T)
                                      (CAR SELRES)))         (* The object declines to be selected.
                                                             Don't permit the select to happen.)
                          (replace SET of SEL with NIL)))
                      (COND
                         ((EQ (CAR SELRES)
                              (QUOTE CHANGED))               (* If the object claims to have 
                                                             changed, update the screen.)
                          (TEDIT.OBJECT.CHANGED TEXTOBJ (fetch SELOBJ of SEL)))
                         ((AND (LISTP (CAR SELRES))
                               (FMEMB (QUOTE CHANGED)
                                      (CAR SELRES)))         (* If the object claims to have 
                                                             changed, update the screen.)
                          (TEDIT.OBJECT.CHANGED TEXTOBJ (fetch SELOBJ of SEL]
          (SETQ WORDSELFLG NIL])
)
(DEFINEQ

(\FIXSEL
  [LAMBDA (SEL TEXTOBJ THISWINDOW AVOIDINGTHISW)             (* jds "31-Jul-85 20:14")
                                                             (* 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 \WINDOW of TEXTOBJ))
            (THISW (OR THISWINDOW (\TEDIT.MAINW TEXTOBJ)))
            (WREG (AND THISW (DSPCLIPPINGREGION NIL THISW)))
            (STARTFOUND NIL)
            (ENDFOUND NIL)
            WLIST CHLIST LOOKS LINE PREVLINE L1HCPY LNHCPY)
           (COND
              ((NOT THISW)                                   (* There is no window to go with this 
                                                             edit; don't bother to try updating the 
                                                             selection)
               (RETURN)))
           [COND
              ((AND AVOIDINGTHISW (fetch Y0 of SEL)))
              (T (replace Y0 of SEL with (fetch PTOP of WREG]
           (COND
              ((AND AVOIDINGTHISW (fetch YLIM of SEL)))
              (T (replace YLIM of SEL with -1)))
           (OR (fetch XLIM of SEL)
               (replace XLIM of SEL with -1))                (* Initialize it, if need be.)
           (for WW inside WINDOW as L1 on (fetch L1 of SEL) as LN on (fetch LN of SEL) as LINES
              inside (fetch LINES of TEXTOBJ)
              do (COND
                    ([AND (fetch SET of SEL)
                          (OR (NOT THISWINDOW)
                              (NEQ AVOIDINGTHISW (EQ THISWINDOW WW]
                                                             (* Only if a "real" SELECTION proceed)
                     (SETQ WLIST (fetch (THISLINE WIDTHS) of THISLINE))
                     (SETQ CHLIST (fetch (THISLINE CHARS) of THISLINE))
                     (SETQ LOOKS (fetch (THISLINE LOOKS) of THISLINE))
                     (RPLACA L1 NIL)
                     (RPLACA LN NIL)
                     (bind (LINE ← (fetch NEXTLINE of LINES))
                           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))
                               (SETQ L1HCPY (fetch FMTHARDCOPY of (fetch LFMTSPEC of LINE)))
                                                             (* Remember that this is a 
                                                             hardcopy-mode line)
                               (RPLACA L1 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
                                  ((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 
          
          (* Run thru the characters on the line, looking for the first selected one.
          Keep track of our X position, so we know where the selection starts.)

                                             (SETQ DX (\WORDELT WLIST I))
                                             (SETQ TX (IPLUS TX DX))
                                             (COND
                                                ((IGEQ CHNO CH#)
                                                             (* We've found that first character.
                                                             Time to bail out.)
                                                 (RETURN))
                                                [(EQ LMInvisibleRun (\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 LMLooksChange (\EDITELT CHLIST I))
                                                             (* This is a format effector--reduce 
                                                             CHNO to ignore it)
                                                 (add LOOKNO 1)
                                                 (SETQ CHNO (SUB1 CHNO)))
                                                (T           (* Not yet; update our running 
                                                             X-position in the SEL.)
                                                   (replace X0 of SEL with TX]
                              ((AND (IEQP CH# (ADD1 (fetch CHARLIM of LINE)))
                                    (IGREATERP CH# (fetch TEXTLEN of TEXTOBJ)))
                                                             (* The selection starts after the end 
                                                             of this line, but it's also the end of 
                                                             the text. Go ahead and select there.)
                               (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)))
                               (replace Y0 of SEL with (fetch YBOT of LINE))
                               (RPLACA L1 LINE)              (* Make this line be the first in the 
                                                             selection)
                               (SETQ L1HCPY (fetch FMTHARDCOPY of (fetch LFMTSPEC of LINE)))
                               (replace X0 of SEL with (fetch LXLIM of LINE)))
                              ((AND (NOT STARTFOUND)
                                    (IGREATERP (fetch CHAR1 of LINE)
                                           CH#)
                                    (ILESSP (fetch CHAR1 of LINE)
                                           CHLIM))           (* The selection starts before this 
                                                             line, so play catch-up)
                               (replace Y0 of SEL with (fetch YBOT of LINE))
                               (RPLACA L1 LINE)              (* Grab this line and make it the 
                                                             apparent first line.)
                               (SETQ L1HCPY (fetch FMTHARDCOPY of (fetch LFMTSPEC of LINE)))
                               (replace X0 of SEL with (fetch LEFTMARGIN of LINE))
                               (SETQ STARTFOUND T)))
                           [COND
                              ([AND (ILEQ CH# (fetch CHARLIM of LINE))
                                    (IGEQ CHLIM (fetch CHAR1 of LINE))
                                    (ILEQ CHLIM (ADD1 (fetch CHARLIM of LINE]
                                                             (* The selection ends in this line.
                                                             Fix LN, XLIM, and YLIM.)
          
          (* NB that it also has to START before the end of this line.
          This eliminates the case of a 0-wide selection right after the last char on 
          this line.)

                               (replace YLIM of SEL with (fetch YBOT of LINE))
                                                             (* Set the lowest-Y value for the 
                                                             selection)
                               (RPLACA LN LINE)              (* Remember the final line)
                               (SETQ LNHCPY (fetch FMTHARDCOPY of (fetch LFMTSPEC of LINE)))
                               (SETQ TX (fetch LEFTMARGIN of LINE))
                                                             (* Temp X position)
                               (replace XLIM of SEL with (fetch LXLIM of LINE))
                                                             (* Start by assuming that the 
                                                             selection extends all the way across 
                                                             the line)
                               [COND
                                  [(AND (IEQP CHLIM (ADD1 (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.)
                                   (RPLACA LN (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 (CAR LN)))
                                   (replace YLIM of SEL with (fetch YBOT of (CAR LN]
                                  ((ILEQ 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)              (* If there are characters on the 
                                                             line, go looking for the one that ends 
                                                             the selection.)
                                       (bind (LOOKNO ← 0) for I from 0
                                          to (fetch LEN of THISLINE) as CHNO
                                          from (fetch CHAR1 of LINE)
                                          do 
          
          (* Run thru the characters, until we find the final one that is selected.
          Kep running track of our X position on the line, so we know how wide the final 
          line's hiliting should be.)

                                             (SETQ DX (\WORDELT WLIST I)) 
                                                             (* The current character's width)
                                             (SETQ TX (IPLUS TX DX)) 
                                                             (* Running Temp-X position)
                                             (COND
                                                ((IGEQ CHNO CHLIM)
                                                             (* OK; this character is past the end 
                                                             of the selection. Stop here.)
                                                 (RETURN))
                                                [(EQ LMInvisibleRun (\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 LMLooksChange (\EDITELT CHLIST I))
                                                             (* This is a format effector--reduce 
                                                             CHNO to ignore it)
                                                 (SETQ CHNO (SUB1 CHNO))
                                                 (add LOOKNO 1))
                                                (T           (* Keep track of how far across we've 
                                                             gotten.)
                                                   (replace XLIM of SEL with TX]
                               (RETURN)                      (* And stop looking for an ending 
                                                             line--we've obviously found it!)
                               )
                              ((AND (IEQP CHLIM (ADD1 (fetch CHARLIM of LINE)))
                                    (ILEQ CH# (fetch CHARLIM of LINE)))
                                                             (* The selection ends either here or 
                                                             at the start of the next line.)
                                                             (* ANN there is something on this line 
                                                             really selected.)
                               (replace YLIM of SEL with (fetch YBOT of LINE))
                               (SETQ LNHCPY (fetch FMTHARDCOPY of (fetch LFMTSPEC of LINE)))
                               (RPLACA LN LINE)
                               (replace XLIM of SEL with (fetch LXLIM of LINE]
                           (SETQ PREVLINE LINE)
                           (SETQ LINE (fetch NEXTLINE of LINE)))
                     [COND
                        (L1HCPY                              (* The first line of the selection is 
                                                             hardcopy-mode. Convert the X0 value to 
                                                             screen units)
                               (replace X0 of SEL with (FIXR (FQUOTIENT (fetch X0 of SEL)
                                                                    35.27778]
                     [COND
                        (LNHCPY                              (* The last line of the selection is 
                                                             hardcopy-mode. Convert the XLIM value 
                                                             to screen units)
                               (replace XLIM of SEL with (FIXR (FQUOTIENT (fetch XLIM of SEL)
                                                                      35.27778]
                     (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 (SELECTION 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 (SELECTION DX) of SEL with (IDIFFERENCE (fetch XLIM of SEL)
                                                                      (fetch X0 of SEL])

(\TEDIT.FIXDELSEL
  [LAMBDA (SELTOFIX TEXTOBJ CH#1 CH#LIM DCH)                 (* jds " 6-Mar-85 22:18")
                                                             (* 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
           ((IGEQ (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)))
           ((IGREATERP (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 (IDIFFERENCE (fetch CHLIM of SELTOFIX)
                                                       (fetch CH# of SELTOFIX])

(\TEDIT.FIXINSSEL
  [LAMBDA (SELTOFIX TEXTOBJ CH#1 DCH)                        (* jds " 6-Mar-85 22:18")
                                                             (* Fix up a SELTOFIX after deletion 
                                                             inside that textobj)
                                                             (* Only if the Selection is set, and 
                                                             is in THIS textobj)
    (PROG (CH# CHLIM)
          (COND
             ((AND (fetch SET of SELTOFIX)
                   (EQ TEXTOBJ (fetch \TEXTOBJ of SELTOFIX)))
              [COND
                 ((IGEQ (SETQ CH# (ffetch CH# of SELTOFIX))
                        CH#1)                                (* Fix up the selection;
                                                             if we're beyond the insert point, move 
                                                             the whole sel forward)
                  (freplace CH# of SELTOFIX with (IPLUS CH# DCH]
              (COND
                 ((IGREATERP (SETQ CHLIM (ffetch CHLIM of SELTOFIX))
                         CH#1)                               (* And the tail end of the sel, too.)
                  (freplace CHLIM of SELTOFIX with (IPLUS CHLIM DCH])

(\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])
)
(DEFINEQ

(TEDIT.RESET.EXTEND.PENDING.DELETE
  [LAMBDA (SEL)                                              (* jds "13-Dec-84 11:01")
                                                             (* 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.SET.SEL.LOOKS
  [LAMBDA (SEL OPERATION)                                    (* jds "13-Dec-84 10:55")
                                                             (* 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))
        (COPYLOOKS                                           (* copylooks source)
                   (replace HOW of SEL with COPYLOOKSSELSHADE)
                   (replace HOWHEIGHT of SEL with 2)
                   (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)
        (INVERTED                                            (* For people who really want to see 
                                                             what's selected.)
                  (replace HOW of SEL with BLACKSHADE)
                  (replace HOWHEIGHT of SEL with 16384)
                  (replace HASCARET of SEL with T)
                  NIL)
        NIL])
)
(DEFINEQ

(\SHOWSEL
  [LAMBDA (SEL HOW ON)                                       (* jds "24-Sep-86 01:34")
                                                             (* Highlight the selection SEL, 
                                                             according to HOW, turning it on or off 
                                                             according to ON)
    (PROG ((TEXTOBJ (fetch \TEXTOBJ of SEL))
           (SHADE (OR (fetch HOW of SEL)
                      BLACKSHADE))
           (SHADEHEIGHT (OR (fetch HOWHEIGHT of SEL)
                            1))
           LL SHOWFN)
          (COND
             ([OR (NOT (fetch SET of SEL))
                  (NOT (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.)
              (RETURN))
             ((fetch TXTDON'TUPDATE of TEXTOBJ)              (* ; 
                                   "We're suppressing screen updating, so don't do anything visible.")
              (RETURN)))
          [for DS inside (fetch \WINDOW of TEXTOBJ) as LINES inside (fetch LINES of TEXTOBJ)
             as L1 in (fetch L1 of SEL) as LN in (fetch LN of SEL) as CARET
             inside (fetch CARET of TEXTOBJ)
             do (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)
                    (\SHOWSEL.HILIGHT TEXTOBJ SEL LINES L1 LN DS SHADEHEIGHT SHADE)
                    (COND
                       ((fetch HASCARET of SEL)              (* If the selection has a caret, turn 
                                                             one on.)
                        (COND
                           [(EQ (fetch POINT of SEL)
                                (QUOTE LEFT))                (* At the LEFT end of the selection)
                            (COND
                               ((AND L1 (IGEQ (fetch YBOT of L1)
                                              0))
                                (\SETCARET (fetch X0 of SEL)
                                       (fetch YBASE of L1)
                                       DS TEXTOBJ CARET))
                               (T (MOVETO -10 -10 DS]
                           ((AND LN (IGEQ (fetch YBOT of LN)
                                          0))                (* Or at the RIGHT end.)
                            (\SETCARET (fetch XLIM of SEL)
                                   (fetch YBASE of LN)
                                   DS TEXTOBJ CARET))
                           (T                                (* Neither end is on screen.
                                                             For self-caret flashers, move the 
                                                             caret location off-screen)
                              (MOVETO -10 -10 DS]
                   ((AND (NOT ON)
                         (fetch ONFLG of SEL))               (* The selection is highlighted and we 
                                                             want to turn it 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.)
                        (\EDIT.UPCARET CARET)                (* Pick the caret up off the screen.)
                        ))
                    (\SHOWSEL.HILIGHT TEXTOBJ SEL LINES L1 LN DS SHADEHEIGHT SHADE]
          (replace ONFLG of SEL with ON])

(\SHOWSEL.HILIGHT
  [LAMBDA (TEXTOBJ SEL LINES L1 LN DS SHADEHEIGHT SHADE X0 XLIM)
                                                             (* jds "15-Oct-85 17:19")
          
          (* * Do the actual highlighting and unhighlighting of a selection for \SHOWSEL)

    (PROG (LL LEFT RIGHT)
          (COND
             ((OR L1 LN)                                     (* One end or the other is on-screen, 
                                                             so it makes sense to try displaying 
                                                             something.)
              (COND
                 ((AND L1 (EQ L1 LN)
                       (IGEQ (fetch YBOT of L1)
                             0))                             (* It's all in a single line;
                                                             just underline the right section and 
                                                             beat it)
                  (BITBLT NIL 0 0 DS (OR X0 (fetch X0 of SEL))
                         (fetch YBOT of L1)
                         (IDIFFERENCE (OR XLIM (fetch XLIM of SEL))
                                (OR X0 (fetch X0 of SEL)))
                         (IMIN SHADEHEIGHT (fetch LHEIGHT of L1))
                         (QUOTE TEXTURE)
                         (QUOTE INVERT)
                         SHADE))
                 (T                                          (* Different lines.)
                    (COND
                       ((AND L1 (IGEQ (fetch YBOT of L1)
                                      0))                    (* If the first line is known, 
                                                             underline the right section of it.)
                        [SETQ RIGHT (COND
                                       ((fetch FMTHARDCOPY of (fetch LFMTSPEC of L1))
                                        (FIXR (FQUOTIENT (fetch LXLIM of L1)
                                                     35.27778)))
                                       (T (fetch LXLIM of L1]
                        (BITBLT NIL 0 0 DS (OR X0 (fetch X0 of SEL))
                               (fetch YBOT of L1)
                               (IDIFFERENCE RIGHT (OR X0 (fetch X0 of SEL)))
                               (IMIN SHADEHEIGHT (fetch LHEIGHT of L1))
                               (QUOTE TEXTURE)
                               (QUOTE INVERT)
                               SHADE)))
                    (SETQ LL (OR L1 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 LN)
                                        (ILESSP (fetch YBOT of LL)
                                               (fetch WBOTTOM of TEXTOBJ)))
                       do                                    (* Highlight every line between first 
                                                             and last)
                          [COND
                             [(fetch FMTHARDCOPY of (fetch LFMTSPEC of LL))
                                                             (* This line is in hardcopy mode.
                                                             Scale the margin values)
                              (SETQ LEFT (\MICASTOPTS (fetch LEFTMARGIN of LL)))
                              (SETQ RIGHT (\MICASTOPTS (fetch LXLIM of LL]
                             (T (SETQ LEFT (fetch LEFTMARGIN of LL))
                                (SETQ RIGHT (fetch LXLIM of LL]
                          (BITBLT NIL 0 0 DS LEFT (fetch YBOT of LL)
                                 (IDIFFERENCE RIGHT LEFT)
                                 (IMIN SHADEHEIGHT (fetch LHEIGHT of LL))
                                 (QUOTE TEXTURE)
                                 (QUOTE INVERT)
                                 SHADE)
                          (SETQ LL (fetch NEXTLINE of LL)))
                    (COND
                       ((AND LL (IGEQ (fetch YBOT of LL)
                                      (fetch WBOTTOM of TEXTOBJ)))
                                                             (* The final line is on-screen.
                                                             Hilight it, too.)
                        [SETQ LEFT (COND
                                      ((fetch FMTHARDCOPY of (fetch LFMTSPEC of LL))
                                       (\MICASTOPTS (fetch LEFTMARGIN of LL)))
                                      (T (fetch LEFTMARGIN of LL]
                        (BITBLT NIL 0 0 DS LEFT (fetch YBOT of LN)
                               (IDIFFERENCE (OR XLIM (fetch XLIM of SEL))
                                      LEFT)
                               (IMIN SHADEHEIGHT (fetch LHEIGHT of LL))
                               (QUOTE TEXTURE)
                               (QUOTE INVERT)
                               SHADE)))                      (* Highlight the final line of the 
                                                             selection)
                    ])

(\TEDIT.UPDATE.SHOWSEL
  [LAMBDA (NSEL OSEL TSTFLG)                                 (* jds "31-Jul-85 21:03")
                                                             (* Update the selection highlighting 
                                                             to reflect the differences between 
                                                             NSEL and OSEL)
    (PROG ((TEXTOBJ (fetch \TEXTOBJ of OSEL)))
          (PROG ((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)
                    (for CARET inside (fetch CARET of TEXTOBJ) do (\EDIT.UPCARET CARET]
                [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)
                        (swap OSEL NSEL)
                        (SETQ EXCHFLG T)))
                    (for NEWL1 inside (fetch L1 of NSEL) as OLDL1 inside (fetch L1 of OSEL)
                       as LINES inside (fetch LINES of TEXTOBJ) as DS
                       inside (fetch \WINDOW of TEXTOBJ)
                       do (\SHOWSEL.HILIGHT TEXTOBJ OSEL LINES NEWL1 OLDL1 DS SHADEHEIGHT SHADE
                                 (fetch X0 of NSEL)
                                 (fetch X0 of OSEL]
                (COND
                   (EXCHFLG                                  (* Put the selections back as they 
                                                             were.)
                          (swap OSEL NSEL)
                          (SETQ EXCHFLG NIL)))
                (COND
                   ((ILESSP (fetch CHLIM of NSEL)
                           (fetch CHLIM of OSEL))            (* Arrange for NSEL to be the 
                                                             selection that ends later, so that one 
                                                             set of code will do both earlier AND 
                                                             later cases.)
                    (swap OSEL NSEL)
                    (SETQ EXCHFLG T)))
                (for OLDLN in (fetch LN of OSEL) as NEWLN in (fetch LN of NSEL) as LINES
                   inside (fetch LINES of TEXTOBJ) as OLDL1 in (fetch L1 of OSEL) as DS
                   inside (fetch \WINDOW of TEXTOBJ)
                   do (\SHOWSEL.HILIGHT TEXTOBJ OSEL LINES OLDLN NEWLN DS SHADEHEIGHT SHADE
                             (fetch XLIM of OSEL)
                             (fetch XLIM of NSEL)))
                (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.)
                    (for L1 in (fetch L1 of NSEL) as LN in (fetch LN of NSEL) as DS
                       inside (fetch \WINDOW of TEXTOBJ) as CARET inside (fetch CARET of TEXTOBJ)
                       do (COND
                             ((EQ (fetch POINT of NSEL)
                                  (QUOTE LEFT))              (* Left end of the selection)
                              (AND L1 (\SETCARET (fetch X0 of NSEL)
                                             (fetch YBOT of L1)
                                             DS TEXTOBJ CARET)))
                             (LN                             (* Right end of the selection)
                                 (\SETCARET (fetch XLIM of NSEL)
                                        (fetch YBOT of LN)
                                        DS TEXTOBJ CARET])

(\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.REFRESH.SHOWSEL
  [LAMBDA (TEXTOBJ NEWSEL OLDSEL OLDOP NEWOP EXTENDING)      (* jds "30-Sep-85 11:24")
          
          (* * Update the screen hilighting to account for the changes that have taken 
          place between OLDSEL and NEWSEL.)

    (DECLARE (USEDFREE . GLOBALSEL))
    (PROG (NOSEL)
          (COND
             ((AND EXTENDING (EQ OLDOP NEWOP))               (* If we're extending a selection and 
                                                             the looks haven't changed, we can do 
                                                             it the fast way, to prevent flicker.)
              (\TEDIT.UPDATE.SHOWSEL NEWSEL OLDSEL)
              (\COPYSEL NEWSEL OLDSEL)
              (replace ONFLG of OLDSEL with T))
             (T                                              (* Otherwise, we have to turn the old 
                                                             one off, change things, and turn the 
                                                             new one on.)
                (\SHOWSEL OLDSEL NIL NIL)
                (COND
                   ((NEQ OLDOP NEWOP)                        (* He changed his mind about copying, 
                                                             deleting, or whatever --
                                                             change the kind of selection it is.)
                    (SELECTQ NEWOP
                        ((NORMAL PENDINGDEL) 
                             (SETQ GLOBALSEL TEDIT.SELECTION)
                             (SETQ NOSEL (fetch SEL of TEXTOBJ)))
                        (COPY (SETQ GLOBALSEL TEDIT.SHIFTEDSELECTION)
                              (SETQ NOSEL (fetch SHIFTEDSEL of TEXTOBJ)))
                        (MOVE (SETQ GLOBALSEL TEDIT.MOVESELECTION)
                              (SETQ NOSEL (fetch MOVESEL of TEXTOBJ)))
                        (DELETE (SETQ GLOBALSEL TEDIT.DELETESELECTION)
                                (SETQ NOSEL (fetch DELETESEL of TEXTOBJ)))
                        (COPYLOOKS (SETQ GLOBALSEL TEDIT.COPYLOOKSSELECTION)
                                   (SETQ NOSEL (fetch SHIFTEDSEL of TEXTOBJ)))
                        NIL)                                 (* Remember the new operation type.)
                    (replace SET of OLDSEL with NIL)         (* Turn off the old kind of selection, 
                                                             so it doesn't reappear to haunt us.)
                    (AND (fetch SET of NOSEL)
                         (\SHOWSEL NOSEL NIL NIL))           (* If there was a new-type selection 
                                                             around, turn it off.)
                    (SETQ OLDSEL NOSEL)                      (* Now cut over to the new selection)
                    (\TEDIT.SET.SEL.LOOKS OLDSEL NEWOP)      (* And set it up looking right.)
                    ))
                (\COPYSEL NEWSEL OLDSEL)
                (replace ONFLG of OLDSEL with NIL)           (* Make sure we can turn the 
                                                             highlighting on.)
                (\SHOWSEL OLDSEL NIL T)))
          (RETURN (OR NOSEL OLDSEL])
)
(DEFINEQ

(\COPYSEL
  [LAMBDA (FROM TO)                                          (* jds "21-Jan-85 18:39")
                                                             (* 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 (SELECTION DX) of TO with (fetch (SELECTION 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 (COPY (fetch L1 of FROM)))
    (replace LN of TO with (COPY (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])

(\TEDIT.SEL.CHANGED?
  [LAMBDA (NEWSEL OLDSEL OLDSELOP NEWSELOP)                  (* jds "18-Aug-84 13:23")
                                                             (* Decide whether there has been an 
                                                             interesting change in the selection, 
                                                             so we can decide whether to refresh 
                                                             its hilighting on the screen.)
    (AND NEWSEL (fetch SET of NEWSEL)
         (NOT (AND (fetch SET of OLDSEL)
                   (EQ (fetch SET of OLDSEL)
                       (fetch SET of NEWSEL))
                   (EQUAL (fetch CH# of NEWSEL)
                          (fetch CH# of OLDSEL))
                   (EQUAL (fetch CHLIM of NEWSEL)
                          (fetch CHLIM of OLDSEL))
                   (EQ (fetch \TEXTOBJ of NEWSEL)
                       (fetch \TEXTOBJ of OLDSEL))
                   (IEQP (fetch (SELECTION DX) of NEWSEL)
                         (fetch (SELECTION DX) of OLDSEL))
                   (EQ (fetch POINT of NEWSEL)
                       (fetch POINT of OLDSEL))
                   (EQ (fetch HOW of NEWSEL)
                       (fetch HOW of OLDSEL))
                   (EQ (fetch HOWHEIGHT of NEWSEL)
                       (fetch HOWHEIGHT of OLDSEL))
                   (EQ OLDSELOP NEWSELOP])
)
(* * User entries to the selection code)

(DEFINEQ

(TEDIT.GETPOINT
  [LAMBDA (STREAM SEL)                                       (* jds " 6-Mar-85 22:07")
          
          (* Given a selection, tell the CH# that type-in would be inserted in front of.
          IF SEL is given, use it to decide. Otherwise, use STREAM's current selection.)

    (PROG [(TSEL (OR SEL (fetch SEL of (TEXTOBJ STREAM]
          (RETURN (IMAX 1 (SELECTQ (fetch POINT of TSEL)
                              (LEFT (fetch CH# of TSEL))
                              (RIGHT (fetch CHLIM of TSEL))
                              (SHOULDNT "Selection's POINT is neither RIGHT nor LEFT."])

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

(TEDIT.MAKESEL
  [LAMBDA (STREAM CH# LEN POINT)                             (* jds " 6-Mar-85 21:18")
    (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)))
          (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.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.SET.SEL.LOOKS
  [LAMBDA (SEL OPERATION)                                    (* jds "13-Dec-84 11:04")
                                                             (* Set what the selection should be 
                                                             displayed like, given what it's for
                                                             (NORMAL, COPY, MOVE, etc.))
    (PROG ((WASON (fetch ONFLG of SEL)))
          (\SHOWSEL SEL NIL NIL)
          (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))
              (COPYLOOKS                                     (* copylooks source)
                         (replace HOW of SEL with COPYLOOKSSELSHADE)
                         (replace HOWHEIGHT of SEL with 2)
                         (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)
              (INVERTED                                      (* For people who really want to see 
                                                             what's selected.)
                        (replace HOW of SEL with BLACKSHADE)
                        (replace HOWHEIGHT of SEL with 16384)
                        (replace HASCARET of SEL with T)
                        NIL)
              NIL)
          (\SHOWSEL SEL NIL WASON])

(TEDIT.SETSEL
  [LAMBDA (STREAM CH# LEN POINT PENDINGDELFLG LEAVECARETLOOKS OPERATION)
                                                             (* jds " 6-Mar-85 22:21")
                                                             (* 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 (IMAX 1 CH# (IMIN (IPLUS CH# LEN)
                                                             (ADD1 TEXTLEN]
                                                             (* Last selected character)
                [replace DCH of SEL with (IMIN LEN TEXTLEN (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 (OR OPERATION (QUOTE PENDINGDEL)))
                                                             (* And make the selection look right.)
                    )
             (T                                              (* This selection is to be a 
                                                             pending-deletion sel.)
                (TEDIT.RESET.EXTEND.PENDING.DELETE SEL)
                (\TEDIT.SET.SEL.LOOKS SEL (OR OPERATION (QUOTE NORMAL]
          (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])
)
(PUTPROPS TEDITSELECTION COPYRIGHT ("John Sybalsky & Xerox Corporation" 1983 1984 1985 1986))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (3314 18079 (TEDIT.SEL.AS.STRING 3324 . 4945) (TEDIT.SELECTED.PIECES 4947 . 8211) (
\TEDIT.FIND.FIRST.LINE 8213 . 11708) (\TEDIT.FIND.LAST.LINE 11710 . 13046) (
\TEDIT.FIND.OVERLAPPING.LINE 13048 . 13416) (\TEDIT.FIND.PROTECTED.END 13418 . 15592) (
\TEDIT.FIND.PROTECTED.START 15594 . 17542) (\TEDIT.WORD.BOUND 17544 . 18077)) (18960 72052 (
TEDIT.EXTEND.SEL 18970 . 30435) (TEDIT.SELECT 30437 . 34133) (TEDIT.SCAN.LINE 34135 . 51971) (
TEDIT.SELECT.LINE.SCANNER 51973 . 66110) (\TEDIT.SELECT.CHARACTER 66112 . 72050)) (72053 96141 (
\FIXSEL 72063 . 91698) (\TEDIT.FIXDELSEL 91700 . 94106) (\TEDIT.FIXINSSEL 94108 . 95489) (
\TEDIT.FIXSELS 95491 . 96139)) (96142 99291 (TEDIT.RESET.EXTEND.PENDING.DELETE 96152 . 96688) (
\TEDIT.SET.SEL.LOOKS 96690 . 99289)) (99292 118835 (\SHOWSEL 99302 . 103916) (\SHOWSEL.HILIGHT 103918
 . 109563) (\TEDIT.UPDATE.SHOWSEL 109565 . 114738) (\TEDIT.SHOWSELS 114740 . 115416) (
\TEDIT.REFRESH.SHOWSEL 115418 . 118833)) (118836 122157 (\COPYSEL 118846 . 120569) (
\TEDIT.SEL.CHANGED? 120571 . 122155)) (122205 133003 (TEDIT.GETPOINT 122215 . 122878) (TEDIT.GETSEL 
122880 . 123098) (TEDIT.MAKESEL 123100 . 123900) (TEDIT.SCANSEL 123902 . 124659) (TEDIT.SET.SEL.LOOKS 
124661 . 127540) (TEDIT.SETSEL 127542 . 132389) (TEDIT.SHOWSEL 132391 . 133001)))))
STOP