(FILECREATED "12-Mar-85 07:33:23" {IVY}<TEDIT>TEDIT.;51 89850 changes to: (FNS TEDIT.DO.BLUEPENDINGDELETE COERCETEXTOBJ MAKETEDITFORM) previous date: " 7-Mar-85 04:19:43" {IVY}<TEDIT>TEDIT.;49) (* Copyright (c) 1983, 1984, 1985 by John Sybalsky & Xerox Corporation. All rights reserved.) (PRETTYCOMPRINT TEDITCOMS) (RPAQQ TEDITCOMS [(FILES TEXTOFD TEDITCOMMAND TEDITSCREEN TEDITABBREV TEDITLOOKS) (CONSTANTS (\SCRATCHLEN 64)) [VARS (TEDIT.TERMSA.FONTS NIL) (TEDIT.TENTATIVE NIL) (TEDIT.DEFAULT.PROPS NIL) (TEDIT.STARTUP.MONITORLOCK (CREATE.MONITORLOCK (QUOTE TEDIT.STARTUP))) (TEDIT.RESTART.MENU (CREATE MENU ITEMS← (QUOTE (NewEditProcess] (GLOBALVARS TEDIT.TENTATIVE TEDIT.DEFAULT.PROPS) (FNS \TEDIT2 COERCETEXTOBJ TEDIT TEDIT.CHARWIDTH TEDIT.COPY TEDIT.DELETE TEDIT.DO.BLUEPENDINGDELETE TEDIT.INSERT TEDIT.KILL TEDIT.MAPLINES TEDIT.MAPPIECES TEDIT.MOVE TEDIT.QUIT TEDIT.STRINGWIDTH TEDIT.\INSERT TEXTOBJ TEXTSTREAM \TEDIT.INCLUDE \TEDIT.INSERT.PIECES \TEDIT.MOVE.PIECEMAPFN \TEDIT.OBJECT.SHOWSEL \TEDIT.RESTARTFN \TEDIT.CHARDELETE \TEDIT.COPY.PIECEMAPFN \TEDIT.DELETE \TEDIT.DIFFUSE.PARALOOKS \TEDIT.FOREIGN.COPY? \TEDIT.QUIT \TEDIT.WORDDELETE \TEDIT1) (COMS (* Debugging functions) (FNS PLCHAIN PRINTLINE SEEFILE)) (COMS (* Object-oriented editing) (FNS TEDIT.INSERT.OBJECT TEDIT.EDIT.OBJECT TEDIT.FIND.OBJECT TEDIT.PUT.OBJECT TEDIT.GET.OBJECT TEDIT.OBJECT.CHANGED)) (FILES TEDITFIND TEDITHISTORY TEDITFILE TEDITWINDOW TEDITSELECTION IMAGEOBJ TFBRAVO TEDITHCPY TEDITMENU) (COMS (* TEDIT Support information) (E (SETQ TEDITSYSTEMDATE (DATE))) (VARS TEDITSYSTEMDATE (TEDITSUPPORT "TEditSupport.PA")) (FNS MAKETEDITFORM) (P (ADDTOVAR LAFITESPECIALFORMS ("TEdit Report" (QUOTE MAKETEDITFORM) "Report a problem with TEdit")) (SETQ LAFITEFORMSMENU NIL))) (COMS (* LISTFILES Interface, so the system can decide if a file is a TEdit file.) (ADDVARS (PRINTFILETYPES (TEDIT (TEST \TEDIT.FORMATTEDP1) (EXTENSION (TEDIT]) (FILESLOAD TEXTOFD TEDITCOMMAND TEDITSCREEN TEDITABBREV TEDITLOOKS) (DECLARE: EVAL@COMPILE (RPAQQ \SCRATCHLEN 64) (CONSTANTS (\SCRATCHLEN 64)) ) (RPAQQ TEDIT.TERMSA.FONTS NIL) (RPAQQ TEDIT.TENTATIVE NIL) (RPAQQ TEDIT.DEFAULT.PROPS NIL) (RPAQ TEDIT.STARTUP.MONITORLOCK (CREATE.MONITORLOCK (QUOTE TEDIT.STARTUP))) (RPAQ TEDIT.RESTART.MENU (CREATE MENU ITEMS← (QUOTE (NewEditProcess)))) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS TEDIT.TENTATIVE TEDIT.DEFAULT.PROPS) ) (DEFINEQ (\TEDIT2 [LAMBDA (TEXT WINDOW UNSPAWNED) (* jds "16-Jul-84 16:45") (* Does the actual editing work, once TEDIT has OPENTEXTSTREAMed the thing to be edited.) (\TEDIT.COMMAND.LOOP (fetch (TEXTSTREAM TEXTOBJ) of TEXT)) (* Run the editing engine) (CLOSEW WINDOW) (* Close the edit window) (\TEXTCLOSEF TEXT) (* Close the underlying files) (replace ACCESSBITS of TEXT with BothBits) (* But leave the stream itself accessible) (replace \WINDOW of (fetch (TEXTSTREAM TEXTOBJ) of TEXT) with NIL) (* And disconnect it from the TEXTOBJ) (AND (WINDOWPROP WINDOW (QUOTE TEDIT.AFTERQUITFN)) (APPLY* (WINDOWPROP WINDOW (QUOTE TEDIT.AFTERQUITFN)) WINDOW TEXT)) (* Apply any post-window-close (and post-QUIT) function) (COND (UNSPAWNED (* We're not a distinct process: Send back the edited text in some suitable form) (COND ((NEQ (fetch EDITFINISHEDFLG of (fetch (TEXTSTREAM TEXTOBJ) of TEXT)) T) (PROG1 (fetch EDITFINISHEDFLG of (fetch (TEXTSTREAM TEXTOBJ) of TEXT)) (replace EDITFINISHEDFLG of (fetch (TEXTSTREAM TEXTOBJ) of TEXT) with NIL))) ((STRINGP (fetch TXTFILE of (fetch (TEXTSTREAM TEXTOBJ) of TEXT))) (COERCETEXTOBJ (fetch (TEXTSTREAM TEXTOBJ) of TEXT) (QUOTE STRINGP))) (T TEXT]) (COERCETEXTOBJ [LAMBDA (STREAM TYPE OUTPUTSTREAM) (* jds "12-Mar-85 03:37") (* Coerce the contents of the TEXOTBJ to be of the given type. This is for making a string from a textobj, e.g.) (PROG ((TEXTOBJ (COND ((type? STREAM STREAM) (fetch (TEXTSTREAM TEXTOBJ) of STREAM)) (T STREAM))) OFILE FMTFILE) (OR (type? TEXTOBJ TEXTOBJ) (\ILLEGAL.ARG TEXTOBJ)) (* If we haven't got a TEXTOBJ, something is wrong.) (RETURN (SELECTQ TYPE [(STRINGP STRING) (AND (ILEQ (fetch TEXTLEN of TEXTOBJ) 65535) (PROG ((STR (ALLOCSTRING (fetch TEXTLEN of TEXTOBJ))) PC (CH# 1) (PCTB (fetch PCTB of TEXTOBJ)) (DELTA 0) PFILE) [for I from (ADD1 \FirstPieceOffset) to (IDIFFERENCE (\EDITELT PCTB \PCTBLastPieceOffset) 2) by \EltsPerPiece do (SETQ PC (\EDITELT PCTB I)) (COND ((ATOM PC) (* It's the lastpiece atom -- do nothing.) ) ((fetch CLINVISIBLE of (fetch PLOOKS of PC)) (* If the characters are invisible, do nothing. HOWEVER, we have to shrink the final string to account for the characters we ignored.) (add DELTA (fetch PLEN of PC))) ((fetch PSTR of PC) [OR (ZEROP (fetch PLEN of PC)) (RPLSTRING STR CH# (SUBSTRING (fetch PSTR of PC) 1 (fetch PLEN of PC] (add CH# (fetch PLEN of PC))) ((SETQ PFILE (fetch PFILE of PC)) [COND ((NOT (OPENP PFILE)) (SETQ PFILE (\TEDIT.REOPEN.STREAM STREAM PFILE] (SETFILEPTR PFILE (fetch PFPOS of PC)) (for C from CH# as I from 1 to (fetch PLEN of PC) do (RPLCHARCODE STR C (BIN PFILE))) (add CH# (fetch PLEN of PC))) ((fetch POBJ of PC) (* DO NOTHING FOR OBJECTS) (add CH# (fetch PLEN of PC)) (add DELTA (fetch PLEN of PC))) (T (ERROR "CANNOT GET TEXT FROM A 'PIECE.'" PC] [COND ((ZEROP DELTA) (* No change in the length; do nothing.) ) (T (* The string got shortened to account for invisible chars. Chop it off) (SETQ STR (SUBSTRING STR 1 (IDIFFERENCE (fetch TEXTLEN of TEXTOBJ) DELTA] (RETURN STR] (STREAM (COND ((type? STREAM (fetch TXTFILE of TEXTOBJ)) (OPENFILE (fetch FULLNAME of (fetch TXTFILE of TEXTOBJ)) (QUOTE INPUT)) (replace ACCESSBITS of (fetch TXTFILE of TEXTOBJ) with ReadBit))) (\SETUPGETCH 1 TEXTOBJ) STREAM) (FILE [SETQ OFILE (OR (AND OUTPUTSTREAM (OPENP OUTPUTSTREAM (QUOTE OUTPUT)) ) (OPENSTREAM (QUOTE {NODIRCORE}) (QUOTE BOTH) (QUOTE NEW] (TEDIT.PUT.PCTB TEXTOBJ OFILE) (OR OUTPUTSTREAM (CLOSEF OFILE)) OFILE) (SPLIT (* I.e., Return 2 files, one with plain text, one with formatting info, such that concatenating them will do the right thing.) (SETQ OFILE (OPENFILE (QUOTE {NODIRCORE}) (QUOTE BOTH) (QUOTE NEW))) (SETQ FMTFILE (CAR (TEDIT.PUT.PCTB TEXTOBJ (\GETSTREAM OFILE (QUOTE BOTH)) NIL T))) (CLOSEF OFILE) (CONS OFILE FMTFILE)) NIL]) (TEDIT [LAMBDA (TEXT WINDOW DONTSPAWN PROPS) (* jds "24-Dec-84 14:17") (* User entry to the text editor. Takes an optional window to be used for editing) (* DONTSPAWN => Don't try to create a new process for this edit.) (PROG (PROC) (* Inlcude the default properties in the list.) [COND ((AND TEXT (ATOM TEXT)) (* Make sure the file exists before trying to open the window.) (SETQ TEXT (OPENFILE TEXT (QUOTE INPUT) (QUOTE OLD] (WITH.MONITOR TEDIT.STARTUP.MONITORLOCK [OR WINDOW (SETQ WINDOW (COND [(OR (NOT TEDIT.DEFAULT.WINDOW) (\TEDIT.ACTIVE.WINDOWP TEDIT.DEFAULT.WINDOW)) (TEDIT.CREATEW (COND ((AND TEXT (ATOM TEXT)) (CONCAT "Please specify an editing window for " TEXT)) (T "Please specify a region for the editing window.")) TEXT (APPEND PROPS (COPY TEDIT.DEFAULT.PROPS] (T (\TEDIT.CREATEW.FROM.REGION (WINDOWPROP TEDIT.DEFAULT.WINDOW (QUOTE REGION)) TEXT (APPEND PROPS (COPY TEDIT.DEFAULT.PROPS))) (* Replace the old title) TEDIT.DEFAULT.WINDOW] (SETQ TEXT (OPENTEXTSTREAM TEXT WINDOW NIL NIL PROPS))) (COND (DONTSPAWN (* Either no processes running, or specifically not to spawn one.) (RETURN (\TEDIT2 TEXT WINDOW T))) (T (* Spawn a process to do the edit.) [SETQ PROC (ADD.PROCESS (LIST (QUOTE \TEDIT2) (KWOTE TEXT) WINDOW NIL) (QUOTE NAME) (QUOTE TEdit) (QUOTE RESTARTABLE) (QUOTE HARDRESET) (QUOTE RESTARTFORM) (LIST (QUOTE \TEDIT.RESTARTFN) (KWOTE TEXT) WINDOW (KWOTE PROPS] (PROCESSPROP PROC (QUOTE WINDOW) WINDOW) (COND ((NOT (LISTGET (APPEND PROPS (COPY TEDIT.DEFAULT.PROPS)) (QUOTE LEAVETTY))) (* Unless he asked us to leave the tty where it is, TEdit should get it.) (TTY.PROCESS PROC))) (RETURN PROC]) (TEDIT.CHARWIDTH [LAMBDA (CH FONT TERMSA) (* jds "22-OCT-83 19:32") (* Returns the width of CH in FONT printed according to any special printing instructions in CHARTABLE TERMSA) (COND (TERMSA (* There IS a TERMTABLE to account for) (SELECTC (fetch CCECHO of (\SYNCODE TERMSA CH)) (INDICATE.CCE (IPLUS (COND ((IGREATERP CH 127) (* META character) (SETQ CH (LOGAND CH 127)) (CHARWIDTH (CHARCODE #) FONT)) (T 0)) (COND ((ILESSP CH 32) (* CONTROL character) (SETQ CH (LOGOR CH 64)) (CHARWIDTH (CHARCODE ↑) FONT)) (T 0)) (CHARWIDTH CH FONT))) (SIMULATE.CCE (SELCHARQ CH ((EOL CR LF) (IMAX 6 (CHARWIDTH CH FONT))) (ESCAPE (CHARWIDTH (CHARCODE $) FONT)) (BELL 0) (TAB 36) (CHARWIDTH CH FONT))) (REAL.CCE (CHARWIDTH CH FONT)) (IGNORE.CCE 0) (SHOULDNT))) (T (* The usual case is to treat every character as a graphic.) (SELCHARQ CH (CR (IMAX 6 (CHARWIDTH CH FONT))) (TAB 36) (CHARWIDTH CH FONT]) (TEDIT.COPY [LAMBDA (FROM TO) (* jds " 6-Mar-85 21:20") (SETQ TEDIT.COPY.PENDING NIL) (* First, Turn off the global flag that got us here.) (COND ((NOT (AND FROM (fetch SET of FROM))) (* There MUST be a source selected first.) (TEDIT.PROMPTPRINT (fetch \TEXTOBJ of TO) "Copy source selection hasn't been set yet." T)) ((ZEROP (fetch DCH of FROM)) (* The source is empty. Just turn off the selection hilite and ignore the request.) (\SHOWSEL FROM NIL NIL)) (T (\SHOWSEL FROM NIL NIL) (* Before all else, make sure the copy source selection is turned off) (replace SET of FROM with NIL) (COND ((AND TO (fetch SET of TO)) (* Can only do copy if there's a target selection) (PROG ((TOOBJ (fetch \TEXTOBJ of TO)) (FROMOBJ (fetch \TEXTOBJ of FROM)) (CROSSCOPY (NEQ (fetch \TEXTOBJ of FROM) (fetch \TEXTOBJ of TO))) TOLEN LEN INSPC INSPC# PC NPC PCCH NPCCH OPLEN EVENT REPLACING INSERTCH# PCLST OBJ COPYFN UNDOCHAIN) (SETQ PCLST (TEDIT.SELECTED.PIECES FROMOBJ FROM CROSSCOPY (FUNCTION \TEDIT.COPY.PIECEMAPFN) FROMOBJ TOOBJ)) (* Get the list of pieces to be copied) (SETQ REPLACING (TEDIT.DO.BLUEPENDINGDELETE TO TOOBJ)) (* Do any blue-pending-delete) (SETQ TOLEN (fetch TEXTLEN of TOOBJ)) (\SHOWSEL TO NIL NIL) (* NOW turn off the target selection.) [COND ((EQ (fetch POINT of TO) (QUOTE LEFT)) (SETQ INSERTCH# (fetch CH# of TO))) (T (SETQ INSERTCH# (IMIN (fetch CHLIM of TO) (ADD1 TOLEN] (* Figure out where to do the insertion.) (SETQ UNDOCHAIN (\TEDIT.INSERT.PIECES TOOBJ INSERTCH# PCLST (SETQ LEN (IDIFFERENCE (fetch CHLIM of FROM) (fetch CH# of FROM))) NIL NIL CROSSCOPY)) (SETQ EVENT (fetch TXTHISTORY of TOOBJ)) (\TEDIT.HISTORYADD TOOBJ (create TEDITHISTORYEVENT THACTION ←(COND (REPLACING (QUOTE Replace)) (T (QUOTE Copy))) THLEN ← LEN THCH# ← INSERTCH# THFIRSTPIECE ← UNDOCHAIN THOLDINFO ←(AND REPLACING EVENT))) (* Make a history-list entry for the COPY.) (replace \DIRTY of TOOBJ with T) (* Mark the document changed) (replace TEXTLEN of TOOBJ with (IPLUS LEN TOLEN)) (* Set the new length) (\FIXILINES TOOBJ TO INSERTCH# LEN TOLEN) (* Fix LINES and SELs) (COND ((EQ (fetch FORMATTEDP of TOOBJ) (fetch FORMATTEDP of FROMOBJ)) (* Either both of the files are formatted or neither is. This case is OK) ) ((fetch FORMATTEDP of TOOBJ) (* The source wasn't formatted, but the target is. Go convert the copied text.) (\TEDIT.CONVERT.TO.FORMATTED TOOBJ INSERTCH# (IPLUS INSERTCH# LEN))) (T (* The source is formatted and the target isn't. Give the guy a choice.) (* For now, convert the target file to formatted.) (\TEDIT.CONVERT.TO.FORMATTED TOOBJ))) (TEDIT.UPDATE.SCREEN TOOBJ) (* Refresh the display) (replace CH# of TO with INSERTCH#) (* Correct the target selection) (replace CHLIM of TO with (IPLUS INSERTCH# LEN)) (replace DCH of TO with LEN) (replace (SELECTION DX) of TO with 0) (replace POINT of TO with (QUOTE RIGHT)) (* (replace CARETLOOKS of TOOBJ with (\TEDIT.GET.INSERT.CHARLOOKS TOOBJ TO))) (* Make any later type-in look like what we just copied.) (replace \INSERTPCVALID of TOOBJ with NIL) (* And make sure that the pieces copied never have their strings smashed by back spacing.) (replace \INSERTPCVALID of FROMOBJ with NIL) (\FIXSEL TO TOOBJ) (\SHOWSEL TO NIL T))) (T (* There is no target selection -- complain) (TEDIT.PROMPTPRINT (fetch \TEXTOBJ of FROM) "Please select a destination for the copy first." T]) (TEDIT.DELETE [LAMBDA (STREAM SEL LEN) (* jds "15-Feb-84 16:16") (* DELETE THE CHARACTERS SPECIFIED FROM THE MAIN TEXT.) (PROG ((TEXTOBJ (TEXTOBJ STREAM))) [COND ((FIXP SEL) (TEDIT.SETSEL STREAM SEL LEN) (SETQ SEL (fetch SEL of TEXTOBJ] (OR SEL (SETQ SEL (fetch SEL of TEXTOBJ))) (\TEDIT.DELETE SEL TEXTOBJ]) (TEDIT.DO.BLUEPENDINGDELETE [LAMBDA (SEL TEXTOBJ) (* jds "12-Mar-85 07:32") (* Check for blue-pending-delete, and do it if it's there.) (* Return T if the deletion was made. For people who need to know) (COND ((fetch BLUEPENDINGDELETE of TEXTOBJ) (* If he's in a Blue-pending-delete state, delete the selection.) (PROG1 (fetch BLUEPENDINGDELETE of TEXTOBJ) (COND ((NOT (ZEROP (fetch DCH of SEL))) (* There really IS something to delete.) (\SHOWSEL SEL NIL NIL) (* Turn off the selection) (\DELETECH (fetch CH# of SEL) (fetch CHLIM of SEL) (fetch DCH of SEL) TEXTOBJ) (* Delete the characters.) (\FIXDLINES (fetch LINES of TEXTOBJ) SEL (fetch CH# of SEL) (fetch CHLIM of SEL) TEXTOBJ) (* Fix up any line descriptors to reflect the deletion.) (TEDIT.RESET.EXTEND.PENDING.DELETE SEL) (* Make it a normal selection again.) (replace CHLIM of SEL with (fetch CH# of SEL)) (* Fix up the selection, so that it is 0 wide, where the old text used to be.) (replace DCH of SEL with 0) (replace POINT of SEL with (QUOTE LEFT)) (\FIXSEL SEL TEXTOBJ) (* Make its line descriptors &c reflect the new reality) (\SHOWSEL SEL NIL T) (* And turn it back on.) ) (T (* Don't do it, since it's zero-width. However, DO turn off the blue-pendingness of it.) (TEDIT.RESET.EXTEND.PENDING.DELETE SEL]) (TEDIT.INSERT [LAMBDA (STREAM TEXT CH#ORSEL LOOKS DONTSCROLL) (* jds " 6-Mar-85 21:25") (* Insert TEXT (character, litatom or string) at the appropriate spot in the text.) (SETQ STREAM (TEXTSTREAM STREAM)) [COND ((FIXP CH#ORSEL) (* He gave us a ch# to insert before) (TEDIT.SETSEL STREAM CH#ORSEL 1 (QUOTE LEFT] [COND ((LITATOM TEXT) (SETQ TEXT (MKSTRING TEXT] [OR (type? SELECTION CH#ORSEL) (SETQ CH#ORSEL (fetch SEL of (fetch (TEXTSTREAM TEXTOBJ) of STREAM] (COND ((AND CH#ORSEL (fetch SET of CH#ORSEL)) (PROG ((TEXTOBJ (fetch (TEXTSTREAM TEXTOBJ) of STREAM)) CH# LINE XPOINT OTEXTLEN DS LINES CHARS BLANKSEEN CRSEEN) (TEDIT.DO.BLUEPENDINGDELETE CH#ORSEL TEXTOBJ) (* If the selected text was for pending delete, delete it before doing the insert.) (COND (LOOKS (* If looks for this insertion were specified, set them up.) (TEDIT.CARETLOOKS STREAM LOOKS))) (SETQ OTEXTLEN (fetch TEXTLEN of TEXTOBJ)) (* The PRE-INSERT text length, for starting the screen update process) (COND ((fetch \WINDOW of TEXTOBJ) (* If this text is in a window, move it so the insertion point is on-screen, then turn off the selection highlight) (COND ((NOT DONTSCROLL) (* If DONTSCROLL is T, then don't bother scrolling the window to show the change.) (TEDIT.NORMALIZECARET TEXTOBJ CH#ORSEL))) (\SHOWSEL CH#ORSEL NIL NIL))) (SETQ CH# (IMAX 1 (SELECTQ (fetch POINT of CH#ORSEL) (LEFT (fetch CH# of CH#ORSEL)) [RIGHT (IMIN (fetch CHLIM of CH#ORSEL) (ADD1 (fetch TEXTLEN of TEXTOBJ] NIL))) (SETQ XPOINT (SELECTQ (fetch POINT of CH#ORSEL) (LEFT (fetch X0 of CH#ORSEL)) (RIGHT (fetch XLIM of CH#ORSEL)) NIL)) [COND [(type? STRINGP TEXT) (* It's a string: Count the characters and Insert them one by one into the text stream) (SETQ CHARS (NCHARS TEXT)) (for ACHAR instring TEXT as NCH# from CH# by 1 do (SELCHARQ ACHAR ((CR #↑M) (SETQ CRSEEN T) (\INSERTCR ACHAR NCH# TEXTOBJ)) (SPACE (SETQ BLANKSEEN T) (\INSERTCH ACHAR NCH# TEXTOBJ)) (\INSERTCH ACHAR NCH# TEXTOBJ] (T (* It's a singe character. Just insert it.) (SETQ CHARS 1) (SELCHARQ TEXT ((CR #↑M) (SETQ CRSEEN T) (\INSERTCR TEXT CH# TEXTOBJ)) (SPACE (SETQ BLANKSEEN T) (\INSERTCH TEXT CH# TEXTOBJ)) (\INSERTCH TEXT CH# TEXTOBJ] (\FIXILINES TEXTOBJ CH#ORSEL CH# CHARS OTEXTLEN) (* Fix up the line descriptors and the Selection.) (TEDIT.INSERT.UPDATESCREEN TEXT CH# CHARS XPOINT TEXTOBJ CH#ORSEL OTEXTLEN BLANKSEEN CRSEEN DONTSCROLL) (* Update the edit window.) )) (T (TEDIT.PROMPTPRINT (TEXTOBJ STREAM) "Please select a place for the insertion." T]) (TEDIT.KILL [LAMBDA (STREAM) (* jds "11-Feb-85 00:59") (* Force the edit session supported by STREAM to terminate, and to return VALUE) (COND ((type? STREAM STREAM) (* If he gave us a textofd, get the textobj) (SETQ STREAM (fetch (TEXTSTREAM TEXTOBJ) of STREAM))) [(WINDOWP STREAM) (* Take a window, and do the obvious with it.) (SETQ STREAM (WINDOWPROP STREAM (QUOTE TEXTOBJ] ((type? TEXTOBJ STREAM) (* A Textobj is just fine) ) (T (* Anything else is ungood, double-plus) (\ILLEGAL.ARG STREAM))) (replace EDITFINISHEDFLG of STREAM with T) (PROG (TEDW TEDPROC) (AND (SETQ TEDW (CAR (fetch \WINDOW of STREAM))) [PROCESSP (SETQ TEDPROC (WINDOWPROP TEDW (QUOTE PROCESS] (NEQ TEDPROC (THIS.PROCESS)) (DEL.PROCESS TEDPROC) (TEDIT.DEACTIVATE.WINDOW TEDW]) (TEDIT.MAPLINES [LAMBDA (TEXTOBJ FN) (* jds "21-Aug-84 12:07") (* Go thru the visible lines in a textobj and call a mapping fn on them) (* FN has 2 args: the LINEDESCRIPTOR, and a VISIBLEFLG to say if the line is visible on the screen.) (bind (LINE ←(fetch NEXTLINE of (fetch LINES of TEXTOBJ))) (BOT ←(fetch WBOTTOM of TEXTOBJ)) [TOP ←(fetch HEIGHT of (DSPCLIPPINGREGION (\TEDIT.PRIMARYW TEXTOBJ] while LINE do (COND ((EQ (APPLY* FN LINE (AND (ILESSP (fetch YBOT of LINE) TOP) (IGEQ (fetch YBOT of LINE) BOT))) (QUOTE STOP)) (RETURN))) (SETQ LINE (fetch NEXTLINE of LINE]) (TEDIT.MAPPIECES [LAMBDA (TEXTOBJ FN FNARG) (* jds "28-Mar-84 17:58") (* Go thru all the pieces in a document, applying a function to them serially) (* FN is a function of 3 args (PIECE CH#-of-1st-char-in-piece PIECE# in table FNARG)) (PROG ((PCTB (fetch PCTB of TEXTOBJ))) (RETURN (bind (BASE ←(\ADDBASE2 (fetch (ARRAYP BASE) of PCTB) \FirstPieceOffset)) for I from \FirstPieceOffset to (IDIFFERENCE (ELT PCTB \PCTBLastPieceOffset) \EltsPerPiece) by \EltsPerPiece do [COND ((EQ (APPLY* FN (\GETBASEPTR BASE 0) (\GETBASEPTR BASE 2) I FNARG) (QUOTE STOP)) (RETURN (LIST (\GETBASEPTR BASE 0) (\GETBASEPTR BASE 2) I] (SETQ BASE (\ADDBASE BASE (CONSTANT (IPLUS \EltsPerPiece \EltsPerPiece]) (TEDIT.MOVE [LAMBDA (FROM TO) (* jds " 6-Mar-85 21:28") (* Move the text described by the selection FROM to the place described by the selection TO) (SETQ TEDIT.MOVE.PENDING NIL) (* First, Turn off the global flag that got us here.) (COND ((NOT (AND FROM (fetch SET of FROM))) (* There MUST be a source selected first.) (TEDIT.PROMPTPRINT (fetch \TEXTOBJ of TO) "Move source selection hasn't been set yet." T)) ((ZEROP (fetch DCH of FROM)) (* The source selection is empty. Just turn it off.) (\SHOWSEL FROM NIL NIL)) (T (\SHOWSEL FROM NIL NIL) (* Before all else, make sure the copy source selection is turned off) (COND ((AND TO (fetch SET of TO)) (* Can only do copy if there's a target selection) (PROG ((TOOBJ (fetch \TEXTOBJ of TO)) (FROMOBJ (fetch \TEXTOBJ of FROM)) (TOLEN (fetch TEXTLEN of (fetch \TEXTOBJ of TO))) (TOPCTB (fetch PCTB of (fetch \TEXTOBJ of TO))) (FROMPCTB (fetch PCTB of (fetch \TEXTOBJ of FROM))) (CROSSCOPY (NEQ (fetch \TEXTOBJ of FROM) (fetch \TEXTOBJ of TO))) LEN INSPC INSPC# PC NPC PCCH NPCCH OPLEN EVENT REPLACING INSERTCH# PCLST OBJ COPYFN UNDOCHAIN) (* Find the insertion point) (SETQ PCLST (TEDIT.SELECTED.PIECES FROMOBJ FROM CROSSCOPY (FUNCTION \TEDIT.MOVE.PIECEMAPFN) FROMOBJ TOOBJ)) (SETQ REPLACING (TEDIT.DO.BLUEPENDINGDELETE TO TOOBJ)) (* Do any blue-pending-delete) (SETQ TOPCTB (fetch PCTB of TOOBJ)) (* Get the new PCTB and text length) (SETQ EVENT (fetch TXTHISTORY of TOOBJ)) (SETQ LEN (IDIFFERENCE (fetch CHLIM of FROM) (fetch CH# of FROM))) (* Keep \DELETECH from playing clever games with the piece if it's new type-in: Don't let it be reclaimed by the deletion.) (\DELETECH (fetch CH# of FROM) (fetch CHLIM of FROM) (fetch DCH of FROM) FROMOBJ) (* Now delete the text from its old place) (\FIXDLINES (fetch LINES of FROMOBJ) FROM (fetch CH# of FROM) (fetch CHLIM of FROM) FROMOBJ) (SETQ TOLEN (fetch TEXTLEN of TOOBJ)) (\SHOWSEL TO NIL NIL) (* NOW turn off the target selection.) (replace SET of FROM with NIL) [COND ((EQ (fetch POINT of TO) (QUOTE LEFT)) (SETQ INSERTCH# (fetch CH# of TO))) (T (SETQ INSERTCH# (fetch CHLIM of TO] (* Figure out where to do the insertion.) (SETQ UNDOCHAIN (\TEDIT.INSERT.PIECES TOOBJ INSERTCH# PCLST LEN NIL NIL CROSSCOPY)) (replace \INSERTPCVALID of TOOBJ with NIL) (* Keep \DELETECH from playing clever games with the piece if it's new type-in: Don't let it be reclaimed by the deletion.) (replace \INSERTPCVALID of FROMOBJ with NIL) (\TEDIT.HISTORYADD TOOBJ (create TEDITHISTORYEVENT THTEXTOBJ ← TOOBJ THACTION ←(COND (REPLACING (QUOTE ReplaceMove)) (T (QUOTE Move))) THLEN ← LEN THCH# ← INSERTCH# THFIRSTPIECE ← UNDOCHAIN THAUXINFO ← FROMOBJ THOLDINFO ←(fetch CH# of FROM))) (* Make a history-list entry for the COPY.) (replace \DIRTY of TOOBJ with T) (* Mark the document changed) (replace TEXTLEN of TOOBJ with (IPLUS LEN TOLEN)) (* Set the new length) (\FIXILINES TOOBJ TO INSERTCH# LEN TOLEN) (* Fix LINES and SELs) (COND ((EQ (fetch FORMATTEDP of TOOBJ) (fetch FORMATTEDP of FROMOBJ)) (* Either both of the files are formatted or neither is. This case is OK) ) ((fetch FORMATTEDP of TOOBJ) (* The source wasn't formatted, but the target is. Go convert the copied text.) (\TEDIT.CONVERT.TO.FORMATTED TOOBJ INSERTCH# (IPLUS INSERTCH# LEN))) (T (* The source is formatted and the target isn't. Give the guy a choice.) (* For now, convert the target file to formatted.) (\TEDIT.CONVERT.TO.FORMATTED TOOBJ))) (TEDIT.UPDATE.SCREEN FROMOBJ (fetch NEXTLINE of (fetch LINES of FROMOBJ))) (TEDIT.UPDATE.SCREEN TOOBJ (fetch NEXTLINE of (fetch LINES of TOOBJ))) (* Refresh the display) (replace CH# of TO with INSERTCH#) (* Correct the target selection) (replace CHLIM of TO with (IPLUS INSERTCH# LEN)) (replace DCH of TO with LEN) (replace (SELECTION DX) of TO with 0) (replace POINT of TO with (QUOTE RIGHT)) (\FIXSEL TO TOOBJ) (\SHOWSEL TO NIL T))) (T (* There is no target selection -- complain) (TEDIT.PROMPTPRINT (fetch \TEXTOBJ of FROM) "Please select a destination for the copy first." T]) (TEDIT.QUIT [LAMBDA (STREAM VALUE) (* jds "19-Jun-84 00:27") (* Force the edit session supported by STREAM to terminate, and to return VALUE) (COND ((type? STREAM STREAM) (* If he gave us a textofd, get the textobj) (SETQ STREAM (fetch (TEXTSTREAM TEXTOBJ) of STREAM))) ((type? TEXTOBJ STREAM) (* A Textobj is just fine) ) (T (* Anything else is ungood, double-plus) (\ILLEGAL.ARG STREAM))) (replace EDITFINISHEDFLG of STREAM with (OR VALUE T)) (* tell the command loop to stop next time through) (PROG (MAINW) (COND ([AND (fetch \WINDOW of STREAM) (NEQ (SETQ MAINW (\TEDIT.PRIMARYW STREAM)) (PROCESSPROP (TTY.PROCESS) (QUOTE WINDOW] (* there is a main window of the stream, and it is not the window of the tty process, so give it the tty) (TTY.PROCESS (WINDOWPROP MAINW (QUOTE PROCESS]) (TEDIT.STRINGWIDTH [LAMBDA (STR FONT TERMSA) (* jds "19-AUG-83 14:40") (COND (TERMSA (* We have a terminal table to take account of. Do so.) (for CH instring STR sum (TEDIT.CHARWIDTH CH FONT TERMSA))) (T (* Just use the native character widths) (for CH instring STR sum (SELCHARQ CH (TAB 36) (CHARWIDTH CH FONT]) (TEDIT.\INSERT [LAMBDA (CH SEL STREAM) (* jds "14-Feb-85 19:17") (* Insert the character CH at the appropriate spot in the text.) (DECLARE (LOCALVARS . T)) (PROG [(TEXTOBJ (COND ((type? STREAM STREAM) (* If we got a STREAM, change it into a textobj) (fetch (TEXTSTREAM TEXTOBJ) of STREAM)) (T STREAM] (COND ((NOT (AND SEL (fetch SET of SEL))) (TEDIT.PROMPTPRINT TEXTOBJ "Please select a place for the insertion." T) (RETURN))) (COND ((fetch \WINDOW of TEXTOBJ) (* There is a window; make sure the insert point is on-screen, and turn off any highlighted selection) (TEDIT.NORMALIZECARET TEXTOBJ SEL) (\SHOWSEL SEL NIL NIL))) (PROG ((CH# (TEDIT.GETPOINT STREAM SEL)) (XPOINT (SELECTQ (fetch POINT of SEL) (LEFT (fetch X0 of SEL)) (RIGHT (fetch XLIM of SEL)) NIL)) (OTEXTLEN (fetch TEXTLEN of TEXTOBJ))) (SELCHARQ CH ((CR #↑M) (* This was a CR. Go do the para breaking as needed) (\INSERTCR CH CH# TEXTOBJ)) (\INSERTCH CH CH# TEXTOBJ)) (\FIXILINES TEXTOBJ SEL CH# 1 OTEXTLEN) (TEDIT.INSERT.UPDATESCREEN CH CH# 1 XPOINT TEXTOBJ SEL OTEXTLEN NIL NIL NIL T]) (TEXTOBJ [LAMBDA (STREAM) (* jds "26-Dec-84 16:04") (* Convert from a text stream to the associated textobj) (COND ((type? TEXTOBJ STREAM) STREAM) ((AND (type? STREAM STREAM) (fetch (TEXTSTREAM TEXTOBJ) of STREAM) (type? TEXTOBJ (fetch (TEXTSTREAM TEXTOBJ) of STREAM))) (fetch (TEXTSTREAM TEXTOBJ) of STREAM)) ((AND (PROCESSP STREAM) (PROCESS.WINDOW STREAM)) (WINDOWPROP (PROCESS.WINDOW STREAM) (QUOTE TEXTOBJ))) [(AND (WINDOWP STREAM) (WINDOWPROP STREAM (QUOTE TEXTOBJ] [(AND (DISPLAYSTREAMP STREAM) (WINDOWPROP STREAM (QUOTE TEXTOBJ] ((\ILLEGAL.ARG STREAM]) (TEXTSTREAM [LAMBDA (STREAM) (* jds "26-Dec-84 16:03") (* Force a textobj or stream to be a stream) (COND ((AND (type? STREAM STREAM) (fetch (TEXTSTREAM TEXTOBJ) of STREAM) (type? TEXTOBJ (fetch (TEXTSTREAM TEXTOBJ) of STREAM))) (* It's a stream, and is really a TEXT stream. Just return it.) STREAM) ((type? TEXTOBJ STREAM) (* It's a TEXTOBJ, so grab the stream hint field and return that.) (fetch STREAMHINT of STREAM)) ((AND (PROCESSP STREAM) (PROCESS.WINDOW STREAM)) (* It's an edit process, so grab the text stream from the edit window.) (WINDOWPROP (PROCESS.WINDOW STREAM) (QUOTE TEXTSTREAM))) [(AND (WINDOWP STREAM) (WINDOWPROP STREAM (QUOTE TEXTSTREAM] [(AND (DISPLAYSTREAMP STREAM) (WINDOWPROP STREAM (QUOTE TEXTSTREAM] ((\ILLEGAL.ARG STREAM) (* Not a reasonable coercion to the text stream. Punt.) ]) (\TEDIT.INCLUDE [LAMBDA (TEXTOBJ FILE START END) (* jds " 6-Mar-85 21:29") (* A NATIVE text includer: Includes part of a file, without checking to see if it's a bravo file, a TEdit file or whatever.) (PROG ((LEN (IDIFFERENCE (OR END (GETEOFPTR FILE)) (OR START 0))) (SEL (fetch SEL of TEXTOBJ)) NPC) (SETQ NPC (create PIECE PFILE ←(\GETOFD FILE (QUOTE INPUT)) PFPOS ←(OR START 0) PLEN ← LEN PLOOKS ←(\TEDIT.GET.INSERT.CHARLOOKS TEXTOBJ SEL) PPARALOOKS ← NIL)) (* Create a PIECE to describe the text) (\TEDIT.INSERT.PIECES TEXTOBJ (fetch CH# of SEL) NPC LEN) (* Insert it in the document) (add (fetch TEXTLEN of TEXTOBJ) LEN) (* And update the document's length) (\TEDIT.MARK.LINES.DIRTY TEXTOBJ (fetch CH# of SEL) (IPLUS (fetch CH# of SEL) LEN)) (* Mark the screen dirty, so updating it will find something to do) (replace CHLIM of SEL with (IPLUS (fetch CH# of SEL) LEN)) (replace DCH of SEL with LEN) (replace (SELECTION DX) of SEL with 0) (replace POINT of SEL with (QUOTE RIGHT)) (replace SELKIND of SEL with (QUOTE CHAR)) (replace SELOBJ of SEL with NIL) (COND ((fetch \WINDOW of TEXTOBJ) (\SHOWSEL SEL NIL NIL) (TEDIT.UPDATE.SCREEN TEXTOBJ) (\FIXSEL SEL TEXTOBJ) (\SHOWSEL SEL NIL T))) (* Update the screen) (replace \DIRTY of TEXTOBJ with T) (\SETUPGETCH (fetch CH# of SEL) TEXTOBJ]) (\TEDIT.INSERT.PIECES [LAMBDA (TEXTOBJ CH# FIRSTPIECE #CHARS INSPC INSPC# CROSSCOPY) (* jds "26-Feb-85 16:14") (* Inserts a series of pieces into TEXTOBJ in front of character CH#. If FIRSTPIECE is a PIECE, this will follow the next-piece pointer chain; if FIRSTPIECE is a list, it is a list of pieces to insert. If CROSSCOPY is non-NIL, the pieces' contents will be copied, to preserve text in case the original is deleted. INSPC and INSPC# are accelerators for where in the PCTB the new pieces should go.) (* It is the CALLER'S RESPONSIBILITY to make sure the pieces to be inserted are "safe" --that they are, if necessary, copies of the originals, and can safely be modified.) (* NB THAT THIS DOES NOT UPDATE TEXTLEN) (PROG ((TOLEN (fetch TEXTLEN of TEXTOBJ)) (TOPCTB (fetch PCTB of TEXTOBJ)) LEN PC PREVPC NPC UNDOCHAIN PSTR PFILE) [SETQ INSPC# (OR INSPC# (\CHTOPCNO CH# TOPCTB) (SUB1 (\EDITELT TOPCTB \PCTBLastPieceOffset] (* Get a handle on the piece we're to insert within or in front of) [SETQ INSPC (OR INSPC (\EDITELT TOPCTB (ADD1 INSPC#] (* And the piece, itself.) (replace \INSERTPCVALID of TEXTOBJ with NIL) (* Force later insertions to make new pieces.) (COND ((IGREATERP CH# TOLEN) (* We're inserting at end of file; leave the piece to insert before as LASTPIECE) ) ((IEQP CH# (\EDITELT TOPCTB INSPC#)) (* The insertion is IN FRONT of this piece; just continue on) ) (T (SETQ INSPC (\SPLITPIECE INSPC CH# TEXTOBJ INSPC#)) (add INSPC# \EltsPerPiece))) (* Nope, we're inserting INSIDE this piece. Split it in two.) (COND ((NEQ INSPC (QUOTE LASTPIECE)) (* Not the last piece, so back up using the pointer.) (SETQ PREVPC (fetch PREVPIECE of INSPC))) [(NOT (ZEROP (fetch TEXTLEN of TEXTOBJ))) (* If we are at the end, AND there is text before us, find it thru the pctb.) (SETQ PREVPC (\EDITELT TOPCTB (IDIFFERENCE (\EDITELT TOPCTB \PCTBLastPieceOffset) \EltsPerPiece] (T (* Otherwise, there is no piece before where we're inserting.) (SETQ PREVPC NIL))) (* For pushing para looks in) (bind (PC ←(COND ((LISTP FIRSTPIECE) (pop FIRSTPIECE)) (T FIRSTPIECE))) (LEN ← 0) (PCCOUNT ← 0) first (SETQ UNDOCHAIN PC) while (AND PC (OR (NOT #CHARS) (ILESSP LEN #CHARS))) do (* Now insert the copied pieces into the new place) (COND ((AND CROSSCOPY (SETQ PFILE (fetch PFILE of PC))) (* If this is a cross-document copy, and the text comes from a file, we must REALLY make a copy of the text, lest the source file be deleted.) [replace PSTR of PC with (SETQ PSTR (ALLOCSTRING (fetch PLEN of PC] [COND ((NOT (OPENP PFILE)) (* The source file was CLOSED -- reopen it, for our us) (replace PFILE of PC with (SETQ PFILE (OPENSTREAM PFILE (QUOTE INPUT) (QUOTE OLD] (SETFILEPTR PFILE (fetch PFPOS of PC)) (bind (BASE ←(fetch (STRINGP BASE) of PSTR)) (OFFST ←(fetch (STRINGP OFFST) of PSTR)) for I from 0 to (SUB1 (fetch PLEN of PC)) do (* Copy the characters to the string) (PUTBASEBYTE BASE (IPLUS OFFST I) (\BIN PFILE))) (replace PFILE of PC with NIL) (* And the piece no longer has a file attached.) )) (replace PLOOKS of PC with (\TEDIT.UNIQUIFY.CHARLOOKS (fetch PLOOKS of PC) TEXTOBJ)) (replace PPARALOOKS of PC with (\TEDIT.UNIQUIFY.PARALOOKS (fetch PPARALOOKS of PC) TEXTOBJ)) (* Assure that the new document knows about this piece's looks) [COND ((NULL FIRSTPIECE) (SETQ NPC NIL)) ((LISTP FIRSTPIECE) (* If the piece list really IS a list, grab the next piece from the front) (SETQ NPC (pop FIRSTPIECE))) (T (* Otherwise, follow the NEXTPIECE chain among pieces) (SETQ NPC (fetch NEXTPIECE of PC] (\INSERTPIECE PC INSPC TEXTOBJ NIL INSPC#) (* Insert the piece into the new document) (add INSPC# \EltsPerPiece) (add LEN (fetch PLEN of PC)) (SETQ PC NPC)) (\TEDIT.DIFFUSE.PARALOOKS PREVPC INSPC) (RETURN UNDOCHAIN]) (\TEDIT.MOVE.PIECEMAPFN [LAMBDA (PC TEXTOBJ FROMOBJ TOOBJ) (* jds " 8-Feb-85 18:14") (* Called by TEDIT.MOVE via TEDIT.SELECTED.PIECES, to do the move-operation processing on the candidate pieces.) (PROG (OBJ MOVEFN) (SETQ PC (create PIECE using PC PNEW ← T)) (* No matter what, we need a fresh copy.) [COND [(fetch POBJ of PC) (* This piece describes an object) (* Call its WHENMOVEDFN.) (SETQ OBJ (fetch POBJ of PC)) (COND ((SETQ MOVEFN (IMAGEOBJPROP OBJ (QUOTE WHENMOVEDFN))) (* If there's an eventfn for moving, use it.) (APPLY* MOVEFN OBJ (CAR (fetch \WINDOW of TOOBJ)) (fetch STREAMHINT of FROMOBJ) (fetch STREAMHINT of TOOBJ] ((fetch PSTR of PC) (* If the piece is a string, make our own copy of the string header, even tho we share characters.) (replace PSTR of PC with (SUBSTRING (fetch PSTR of PC) 1 (fetch PLEN of PC] (RETURN PC]) (\TEDIT.OBJECT.SHOWSEL [LAMBDA (TEXTOBJ SEL ON SELWINDOW) (* jds " 8-Feb-85 18:14") (* We are hilighting (or dehilighting) a selected object. Let it know.) (PROG ((X (fetch X0 of SEL)) (Y (fetch Y0 of SEL)) (OBJ (fetch SELOBJ of SEL)) (WIDTH (fetch (SELECTION DX) of SEL)) (XOFFSET (DSPXOFFSET NIL SELWINDOW)) (YOFFSET (DSPYOFFSET NIL SELWINDOW)) (IMAGEFN (IMAGEOBJPROP (fetch SELOBJ of SEL) (QUOTE WHENOPERATEDONFN))) IMAGEBOX) (SETQ IMAGEBOX (OR (IMAGEOBJPROP OBJ (QUOTE BOUNDBOX)) (APPLY* (IMAGEOBJPROP OBJ (QUOTE IMAGEBOXFN)) OBJ SELWINDOW))) (RESETLST [RESETSAVE (DSPXOFFSET (IDIFFERENCE (IPLUS X XOFFSET) (fetch XKERN of IMAGEBOX)) SELWINDOW) (LIST (FUNCTION DSPXOFFSET) XOFFSET (WINDOWPROP SELWINDOW (QUOTE DSP] (RESETSAVE (DSPYOFFSET (IPLUS Y YOFFSET) SELWINDOW) (LIST (FUNCTION DSPYOFFSET) YOFFSET SELWINDOW)) (RESETSAVE (DSPCLIPPINGREGION (create REGION LEFT ← 0 BOTTOM ← 0 WIDTH ←(IMIN WIDTH (IDIFFERENCE (fetch WRIGHT of TEXTOBJ) X)) HEIGHT ←(fetch YSIZE of IMAGEBOX)) SELWINDOW) (LIST (FUNCTION DSPCLIPPINGREGION) (DSPCLIPPINGREGION NIL SELWINDOW) SELWINDOW)) (AND IMAGEFN (ERSETQ (APPLY* IMAGEFN OBJ SELWINDOW (COND (ON (QUOTE HIGHLIGHTED)) (T (QUOTE UNHIGHLIGHTED))) SEL]) (\TEDIT.RESTARTFN [LAMBDA (TEXT WINDOW PROPS) (* jds "13-Nov-84 12:23") (* Restarts a TEdit session.) (replace \WINDOW of (fetch (TEXTSTREAM TEXTOBJ) of TEXT) with NIL) (* Unattach the window, so we do a redisplay.) (PROG [(ODIRTY (fetch \DIRTY of (fetch (TEXTSTREAM TEXTOBJ) of TEXT] (SETQ TEXT (OPENTEXTSTREAM TEXT WINDOW NIL NIL PROPS)) (replace \DIRTY of (fetch (TEXTSTREAM TEXTOBJ) of TEXT) with ODIRTY)) (* Now reconnect the world together again) (\TEDIT.COMMAND.LOOP (fetch (TEXTSTREAM TEXTOBJ) of TEXT)) (* Run the editing engine) (CLOSEW WINDOW) (* Close the edit window) (\TEXTCLOSEF TEXT) (* Close the underlying files) (replace ACCESSBITS of TEXT with BothBits) (* But leave the stream itself accessible) (replace \WINDOW of (fetch (TEXTSTREAM TEXTOBJ) of TEXT) with NIL) (* And disconnect it from the TEXTOBJ) (AND (WINDOWPROP WINDOW (QUOTE TEDIT.AFTERQUITFN)) (APPLY* (WINDOWPROP WINDOW (QUOTE TEDIT.AFTERQUITFN)) WINDOW TEXT)) (* Apply any post-window-close (and post-QUIT) function) ]) (\TEDIT.CHARDELETE [LAMBDA (TEXTOBJ SCRATCHSTRING SEL) (* jds " 7-Mar-85 03:49") (* Do character-backspace deletion for TEDIT) (SETQ TEXTOBJ (TEXTOBJ TEXTOBJ)) (PROG ((PCTB (fetch PCTB of TEXTOBJ)) TLEN INSCH# INSPC INSPC# TLOOKS) (COND [NIL [NOT (ZEROP (SETQ TLEN (fetch (STRINGP OFFST) of SCRATCHSTRING] (* If we didn't really insert the text yet, just remove from the text to be inserted) (replace (STRINGP OFFST) of SCRATCHSTRING with (SUB1 TLEN)) (replace (STRINGP LENGTH) of SCRATCHSTRING with (ADD1 (fetch (STRINGP LENGTH) of SCRATCHSTRING] (T (* Delete the character just before the current insertpoint.) (SELECTQ (fetch POINT of SEL) [LEFT (SETQ INSCH# (SUB1 (fetch CH# of SEL] [RIGHT (SETQ INSCH# (SUB1 (fetch CHLIM of SEL] NIL) (COND ((ILEQ INSCH# 0) (* Can't backspace past start of document) (RETURN))) [SETQ INSPC (\EDITELT PCTB (ADD1 (SETQ INSPC# (\CHTOPCNO INSCH# PCTB] (SETQ TLOOKS (\TEDIT.APPLY.STYLES (fetch PLOOKS of INSPC) INSPC TEXTOBJ)) [while (AND INSPC (fetch CLINVISIBLE of TLOOKS)) do (* Back over any invisible text, which we're no allowed to delete.) (SETQ INSPC (fetch PREVPIECE of INSPC)) (SETQ INSCH# (SUB1 (\EDITELT PCTB INSPC#))) (SETQ INSPC# (IDIFFERENCE INSPC# \EltsPerPiece)) (COND (INSPC (SETQ TLOOKS (\TEDIT.APPLY.STYLES (fetch PLOOKS of INSPC) INSPC TEXTOBJ] (COND ((ILEQ INSCH# 0) (* We backed up to the start of the document. Can't go no further.) (RETURN)) ((NOT (fetch CLPROTECTED of TLOOKS)) (* Can only backspace if the char to go isn't protected.) (replace CHLIM of SEL with (ADD1 (replace CH# of SEL with INSCH#))) (* Set up the selection to point to the character which is to be deleted.) (replace DCH of SEL with 1) (\SHOWSEL SEL NIL NIL) (* Turn off the underlining, if any, so there's no garbage.) (\FIXSEL SEL TEXTOBJ) (* Fix the selection up so it points to the right line and all) (\TEDIT.DELETE SEL TEXTOBJ T) (* And delete it.) ]) (\TEDIT.COPY.PIECEMAPFN [LAMBDA (PC TEXTOBJ FROMOBJ TOOBJ) (* jds "26-Feb-85 10:58") (* Called by TEDIT.COPY via TEDIT.SELECTED.PIECES, to do the copy-operation processing on the candidate pieces.) (PROG (OBJ NEWOBJ COPYFN) (SETQ PC (create PIECE using PC PNEW ← T)) (* No matter what, we need a fresh copy.) [COND ((fetch POBJ of PC) (* This piece describes an object) (SETQ OBJ (fetch POBJ of PC)) [COND [(SETQ COPYFN (IMAGEOBJPROP OBJ (QUOTE COPYFN))) (SETQ NEWOBJ (APPLY* COPYFN OBJ (fetch STREAMHINT of FROMOBJ) (fetch STREAMHINT of TOOBJ))) (COND ((EQ NEWOBJ (QUOTE DON'T)) (* He said not to copy this piece -- abort the whole copy.) (TEDIT.PROMPTPRINT TEXTOBJ "COPY of this object not allowed." T) (RETFROM (QUOTE TEDIT.COPY))) (NEWOBJ (replace POBJ of PC with NEWOBJ)) (T (replace POBJ of PC with (COPYALL OBJ] (OBJ (* No copy fn; just strike off a copy of our own) (replace POBJ of PC with (COPYALL OBJ] (COND ((SETQ COPYFN (IMAGEOBJPROP OBJ (QUOTE WHENCOPIEDFN))) (* If there's an eventfn for copying, use it.) (APPLY* COPYFN OBJ (WINDOWPROP (CAR (fetch \WINDOW of TOOBJ)) (QUOTE DSP)) (fetch STREAMHINT of FROMOBJ) (fetch STREAMHINT of TOOBJ] [COND ((fetch CLPROTECTED of (fetch PLOOKS of PC)) (* The source text was protected; unprotect the copy.) (replace PLOOKS of PC with (\TEDIT.UNIQUIFY.CHARLOOKS (create CHARLOOKS using (fetch PLOOKS of PC) CLPROTECTED ← NIL CLSELHERE ← NIL) TOOBJ] (RETURN PC]) (\TEDIT.DELETE [LAMBDA (SEL STREAM SELOFF) (* jds " 6-Mar-85 21:35") (* DELETE THE CHARACTERS SPECIFIED FROM THE MAIN TEXT.) (* SELOFF => The selection is already turned off.) (PROG [(TEXTOBJ (COND ((type? STREAM STREAM) (* If we got a STREAM, change it into a textobj) (fetch (TEXTSTREAM TEXTOBJ) of STREAM)) (T STREAM] (PROG ((CH# (fetch CH# of SEL)) (CHLIM (fetch CHLIM of SEL)) (LINES (fetch LINES of TEXTOBJ)) (WINDOW (fetch \WINDOW of TEXTOBJ)) (HEIGHTCHANGED NIL) (NLINE1 NIL) (CRFLAG NIL) (LINES\DELETED NIL) OLINE1 OLINEN LEN NEXTLINE NL OLINE DX OCHLIM OXLIM OLHEIGHT OLASCENT OLDESCENT DY PREVLINE TEXTLEN OCR\END SAVEWIDTH IMAGECACHE) [SETQ LEN (COND ((IGREATERP CH# (fetch TEXTLEN of TEXTOBJ)) (* Past end of text, so don't delete any) 0) ((IGEQ CH# CHLIM) (* Start is past end, so don't delete any.) 0) ((ZEROP (fetch DCH of SEL)) (* Just a caret--no text really selected--so don't delete any) 0) ((ZEROP CHLIM) (* CHLIM is before start of text, so don't delete any) 0) (T (* The normal case.) (IDIFFERENCE CHLIM CH#] (* # of characters to be deleted) (COND ((OR (NOT (fetch SET of SEL)) (ZEROP LEN)) (* If the selection isn't set, don't do anything.) (RETURN))) (AND WINDOW (TEDIT.NORMALIZECARET TEXTOBJ SEL)) (* If the text appears in a window, move the deletion point on-screen) (SETQ OLINE1 (fetch L1 of SEL)) (SETQ OLINEN (fetch LN of SEL)) (\TEDIT.SHOWSELS TEXTOBJ NIL NIL) (* Turn off the selection's highlighting) (AND LINES (\FIXDLINES LINES SEL CH# CHLIM TEXTOBJ)) (* Update the line descriptors to account for the deletion) (\DELETECH CH# CHLIM LEN TEXTOBJ) (* Do the actual deletion of characters) (replace THPOINT of (fetch TXTHISTORY of TEXTOBJ) with (fetch POINT of SEL)) (* Remember which side of the selection we were on, in case it gets undone.) (replace CH# of SEL with (IMAX 1 CH#)) (replace CHLIM of SEL with (fetch CH# of SEL)) (replace POINT of SEL with (QUOTE LEFT)) (replace DCH of SEL with 0) (COND ((NOT WINDOW) (* If there's no window to update, don't bother) (RETURN))) (SETQ TEXTLEN (fetch TEXTLEN of TEXTOBJ)) (* The new text length) (for OLINE1 inside (fetch L1 of SEL) as OLINEN inside (fetch LN of SEL) as TOPLINE inside (fetch LINES of TEXTOBJ) as THISW inside WINDOW do (SETQ LINES\DELETED (\TEDIT.CLOSEUPLINES TEXTOBJ (OR (AND OLINE1 (COND ((fetch DELETED of OLINE1) (fetch PREVLINE of OLINE1)) (T OLINE1))) TOPLINE) (AND OLINEN (COND ((fetch DELETED of OLINEN) (fetch NEXTLINE of OLINEN)) (T OLINEN))) NIL THISW))) (* Remove any lines which were completely deleted.) (COND ((OR T (LISTP WINDOW) (TEXTPROP TEXTOBJ (QUOTE SLOWUPDATE)) (NOT OLINE1) (NOT OLINEN) (OR (NEQ (fetch QUAD of (fetch LFMTSPEC of OLINE1)) (QUOTE LEFT)) (IGREATERP (fetch RIGHTMAR of (fetch LFMTSPEC of OLINE1)) (fetch WRIGHT of TEXTOBJ))) (fetch LHASTABS of OLINE1) (fetch LHASTABS of OLINEN)) (* This line must needs be reformatted the hard way--it isn't a left ragged line or one of the lines is off-screen.) (replace (SELECTION DX) of SEL with 0) (TEDIT.UPDATE.SCREEN TEXTOBJ NIL T) (* Correct the text that's displayed already) (\FIXSEL SEL TEXTOBJ) (* Then fix up the selection as needed.) (\TEDIT.SHOWSELS TEXTOBJ NIL T) (RETURN]) (\TEDIT.DIFFUSE.PARALOOKS [LAMBDA (PRIORPC SUCCEEDINGPC) (* jds " 6-Dec-84 13:34") (* Given a discontinuity in paragraph looks, caused by an insertion or by a deletion: Diffuse the existing paragraph looks across the discontinuity, so that all the pieces in a single paragraph have consistent looks. Give preference to diffusion toward the END of the document. This means that if you delete a CR between paragraphs, the second para is absorbed into the first.) (* PRIORPC and SUCCEEDINGPC are the PIECEs that bound the area of potential discontinuity: the change will occur at one boundary or the other....) [COND ((AND PRIORPC (NOT (fetch PPARALAST of PRIORPC))) (* The discontinuity is inside a paragraph. Must copy para looks forward into the text.) (bind (PPLOOKS ←(fetch PPARALOOKS of PRIORPC)) (PC ←(fetch NEXTPIECE of PRIORPC)) while PC do (* Copy para looks info in from the left, up the the first para break.) (replace PPARALOOKS of PC with PPLOOKS) (COND ((fetch PPARALAST of PC) (* If this piece ends a paragraph, we're done.) (RETURN))) (SETQ PC (fetch NEXTPIECE of PC] (COND ((AND SUCCEEDINGPC (NEQ SUCCEEDINGPC (QUOTE LASTPIECE))) (* Only copy para looks in from the right if there is text to the right.) (bind (PPLOOKS ←(fetch PPARALOOKS of SUCCEEDINGPC)) (PC ←(fetch PREVPIECE of SUCCEEDINGPC)) while (NEQ PC PRIORPC) do (* Copy para looks in from the right, up to the first para break) (COND ((fetch PPARALAST of PC) (* If this piece ends a paragraph, we're done.) (RETURN))) (replace PPARALOOKS of PC with PPLOOKS) (SETQ PC (fetch PREVPIECE of PC]) (\TEDIT.FOREIGN.COPY? [LAMBDA (SEL) (* jds "22-May-84 14:47") (* IF the current process's window isn't a TEdit window, do a "Copy" by BKSYSBUFing the selected text. Then turn off all the various indicators.) (PROG (PROCW (SOURCE.TEXTOBJ (fetch \TEXTOBJ of SEL)) CH STREAM DEST.TEDIT? DEST.TEXTOBJ) [SETQ DEST.TEDIT? (AND (SETQ PROCW (PROCESSPROP (TTY.PROCESS) (QUOTE WINDOW))) (SETQ DEST.TEXTOBJ (WINDOWPROP PROCW (QUOTE TEXTOBJ] (COND ((OR (NOT DEST.TEDIT?) (AND PROCW DEST.TEXTOBJ (NEQ SOURCE.TEXTOBJ DEST.TEXTOBJ) (fetch EDITOPACTIVE of DEST.TEXTOBJ))) (* OK -- receiver isn't TEdit. Do it the hard way.) (\SETUPGETCH (fetch CH# of SEL) SOURCE.TEXTOBJ) (SETQ STREAM (fetch STREAMHINT of SOURCE.TEXTOBJ)) (for I from 1 to (fetch DCH of SEL) when (FIXP (SETQ CH (\BIN STREAM))) do (BKSYSBUF (CHARACTER CH))) (\SHOWSEL SEL NIL NIL) (SETQ TEDIT.COPY.PENDING NIL]) (\TEDIT.QUIT [LAMBDA (W NOFORCE) (* jds " 5-Mar-85 17:16") (* Called by the default TEDIT.DEFAULT.MENUFN to perform the QUIT command.) (PROG ((TEXTOBJ (WINDOWPROP W (QUOTE TEXTOBJ))) (QUITFNS (WINDOWPROP W (QUOTE TEDIT.QUITFN))) QUITFLG RESP) [for QUITFN inside QUITFNS while (AND (NEQ QUITFLG (QUOTE DON'T)) (NEQ QUITFLG T)) do (COND ((EQ QUITFN T) (SETQ QUITFLG T)) (T (AND QUITFN (NEQ QUITFN T) (SETQ QUITFLG (APPLY* QUITFN W (fetch STREAMHINT of TEXTOBJ) TEXTOBJ (fetch EDITPROPS of TEXTOBJ] (COND ((EQ QUITFLG (QUOTE DON'T)) (* The user supplied a QUITFN, and it returned "DON'T", so just ignore all this Fooferaw and keep editing.) (RETURN)) [(AND (fetch \DIRTY of TEXTOBJ) (NOT (fetch MENUFLG of TEXTOBJ)) (NEQ QUITFNS T) (NEQ QUITFLG T)) (* If this document has changed, check with the user to make sure he really wants to do it.) (replace EDITFINISHEDFLG of TEXTOBJ with (MOUSECONFIRM "Not saved yet; LEFT to Quit anyway." T (fetch PROMPTWINDOW of TEXTOBJ] (T (* Go ahead and quit the next time we see the main command loop.) (replace EDITFINISHEDFLG of TEXTOBJ with T))) [AND (fetch \WINDOW of TEXTOBJ) (NOT NOFORCE) (NEQ (\TEDIT.PRIMARYW TEXTOBJ) (PROCESSPROP (TTY.PROCESS) (QUOTE WINDOW))) (TTY.PROCESS (WINDOWPROP (\TEDIT.PRIMARYW TEXTOBJ) (QUOTE PROCESS] (RETURN (fetch EDITFINISHEDFLG of TEXTOBJ]) (\TEDIT.WORDDELETE [LAMBDA (TEXTOBJ) (* jds " 7-Mar-85 03:50") (* Delete the word to the left of the caret.) (PROG ((SEL (fetch SEL of TEXTOBJ)) (STREAM (fetch STREAMHINT of TEXTOBJ)) (READSA (fetch READSA of (OR (fetch TXTWTBL of TEXTOBJ) TEDIT.WORDBOUND.READTABLE))) INSCH# CH CHNO) (* Back word.) (SETQ INSCH# (SELECTQ (fetch POINT of SEL) (LEFT (SUB1 (fetch CH# of SEL))) (RIGHT (SUB1 (fetch CHLIM of SEL))) NIL)) (* Find the place to delete backward from) (COND ((IGREATERP INSCH# 0) (* Don't try to back up past start of file.) (\SETUPGETCH INSCH# TEXTOBJ) (SETQ CH (\BIN STREAM)) (for old CHNO from INSCH# to 1 by -1 while [AND (SELECTC (COND ((FIXP CH) (\SYNCODE READSA CH)) (T (* It's an object!) TEXT.TTC)) (TEXT.TTC NIL) T) (NOT (fetch CLPROTECTED of (fetch PLOOKS of (fetch (TEXTSTREAM PIECE) of STREAM] do (SETQ CH (\GETCHB TEXTOBJ))) (* Skip over any initial separator characters) (for old CHNO from CHNO to 1 by -1 while [AND (SELECTC (COND ((FIXP CH) (\SYNCODE READSA CH)) (T (* It's an object!) TEXT.TTC)) (TEXT.TTC T) NIL) (NOT (fetch CLPROTECTED of (fetch PLOOKS of (fetch (TEXTSTREAM PIECE) of STREAM] do (SETQ CH (\GETCHB TEXTOBJ))) (* Skip over the next group of non-separators (= a "word")) (\SHOWSEL SEL NIL NIL) [replace CH# of SEL with (COND ((ILEQ CHNO 1) 1) (T (IPLUS 2 CHNO] (* First character to delete) (replace CHLIM of SEL with (ADD1 INSCH#)) (replace DCH of SEL with (IDIFFERENCE INSCH# CHNO)) (\FIXSEL SEL TEXTOBJ) (\SHOWSEL SEL NIL T) (\TEDIT.DELETE SEL TEXTOBJ]) (\TEDIT1 [LAMBDA (TEXT WINDOW UNSPAWNED PROPS) (* jds "16-Jul-84 16:46") (* Does the actual editing work, and re-coercion or process kill when done. Called by TEDIT directly, or ADD.PROCESSed by it.) (SETQ TEXT (OPENTEXTSTREAM TEXT WINDOW NIL NIL PROPS)) (* Open the text for editing) (\TEDIT.COMMAND.LOOP (fetch (TEXTSTREAM TEXTOBJ) of TEXT)) (* Run the editing engine) (CLOSEW WINDOW) (replace \WINDOW of (fetch (TEXTSTREAM TEXTOBJ) of TEXT) with NIL) (AND (WINDOWPROP WINDOW (QUOTE TEDIT.AFTERQUITFN)) (APPLY* (WINDOWPROP WINDOW (QUOTE TEDIT.AFTERQUITFN)) WINDOW TEXT)) (* Apply any post-window-close (and post-QUIT) function) (COND (UNSPAWNED (* We're not a distinct process: Send back the edited text in some suitable form) (COND ((NEQ (fetch EDITFINISHEDFLG of (fetch (TEXTSTREAM TEXTOBJ) of TEXT)) T) (PROG1 (fetch EDITFINISHEDFLG of (fetch (TEXTSTREAM TEXTOBJ) of TEXT)) (replace EDITFINISHEDFLG of (fetch (TEXTSTREAM TEXTOBJ) of TEXT) with NIL))) ((STRINGP (fetch TXTFILE of (fetch (TEXTSTREAM TEXTOBJ) of TEXT))) (COERCETEXTOBJ (fetch (TEXTSTREAM TEXTOBJ) of TEXT) (QUOTE STRINGP))) (T TEXT]) ) (* Debugging functions) (DEFINEQ (PLCHAIN [LAMBDA (LN) (* jds "21-JAN-82 09:57") (PRINTLINE LN) (COND ((fetch NEXTLINE of LN) (PLCHAIN (fetch NEXTLINE of LN]) (PRINTLINE [LAMBDA (LN) (* jds "27-Aug-84 15:35") (* Print out a line descriptor in a reasonable form.) (printout T "-----" T LN " Bot: " (fetch YBOT of LN) " Base: " (fetch YBASE of LN) " Height: " (fetch LHEIGHT of LN) " Ascent: " (fetch ASCENT of LN) " Descent: " (fetch DESCENT of LN) T "Char1: " (fetch CHAR1 of LN) " Lim: " (fetch CHARLIM of LN) " Top: " (fetch CHARTOP of LN)) (COND ((fetch DIRTY of LN) (PRIN1 " DIRTY"))) (COND ((fetch CR\END of LN) (PRIN1 " CR-at-end"))) (COND ((fetch DELETED of LN) (PRIN1 " DELETED"))) (COND ((fetch LHASPROT of LN) (PRIN1 " [Protected text]"))) (COND ((fetch LHASTABS of LN) (PRIN1 " Has Tabs"))) (PRIN1 ". ") (printout T "RMar: " (fetch RIGHTMARGIN of LN) " XLim: " (fetch LXLIM of LN) " Left: " (fetch SPACELEFT of LN) T "Prev: " (fetch PREVLINE of LN) T "Next: " (fetch NEXTLINE of LN) T) (COND ((AND (IGEQ (fetch CHAR1 of LN) 1) (ILEQ (fetch CHAR1 of LN) (fetch TEXTLEN of TEXTOBJ))) (* The line is real -- print it.) (\SETUPGETCH (fetch CHAR1 of LN) TEXTOBJ) (PRIN1 "|") [bind CH for CHNO from (fetch CHAR1 of LN) to (IMIN (fetch TEXTLEN of TEXTOBJ) (fetch CHARLIM of LN)) do (SETQ CH (\GETCH TEXTOBJ)) (COND ((SMALLP CH) (PRIN1 (CHARACTER CH))) (T (PRINT CH] (PRIN1 "| "]) (SEEFILE [LAMBDA (FILE ST ND) (* jds " 4-NOV-83 20:21") (PROG (CH) [SETQ FILE (OR (OPENP FILE) (OPENSTREAM FILE (QUOTE INPUT] (SETFILEPTR FILE (OR ST 0)) (for I from (OR ST 0) to (OR ND (SUB1 (GETEOFPTR FILE))) do (printout T I 5 (SETQ CH (BIN FILE)) 9 (COND [(ILEQ CH (CHARCODE ↑Z)) (CONCAT "↑" (CHARACTER (IPLUS CH (CHARCODE @] (T (CHARACTER CH))) T]) ) (* Object-oriented editing) (DEFINEQ (TEDIT.INSERT.OBJECT [LAMBDA (OBJECT STREAM CH#) (* jds " 6-Mar-85 21:44") (* Inserts the annotation OBJECT into text STREAM in front of character CH.) (PROG ((TEXTOBJ (TEXTOBJ STREAM)) SEL SUBSTREAM) (SETQ SEL (fetch SEL of TEXTOBJ)) (COND ((NULL CH#) (* Omitted CH# means put it at the current spot.) (SETQ CH# SEL))) [COND ((type? SELECTION CH#) (* If the CH# passed in was a selection (or we set it because he defaulted CH#), then compute the REAL CH#.) (SETQ CH# (SELECTQ (fetch POINT of CH#) (LEFT (fetch CH# of CH#)) (RIGHT (fetch CHLIM of CH#)) (SHOULDNT] (PROG ((PCTB (ffetch PCTB of TEXTOBJ)) TEXTLEN PC PCNO CHNO NEWPC PREVPC INSERTFN) (TEDIT.DO.BLUEPENDINGDELETE SEL TEXTOBJ) (* Do the pending delete, if there is one.) (\SHOWSEL SEL NIL NIL) (* Turn off the selection for now) (SETQ TEXTLEN (fetch TEXTLEN of TEXTOBJ)) (SETQ CH# (IMIN CH# (ADD1 TEXTLEN))) (* CH# we're to insert these characters in front of) (freplace \INSERTFIRSTCH of TEXTOBJ with -1) [SETQ PC (COND ((ILEQ CH# TEXTLEN) (SETQ PCNO (\CHTOPCNO CH# PCTB)) (\EDITELT PCTB (ADD1 PCNO))) (T (SETQ PCNO (SUB1 (\EDITELT PCTB \PCTBLastPieceOffset))) (QUOTE LASTPIECE] (* Piece we're to insert in front of or inside) (SETQ NEWPC (create PIECE PSTR ← NIL PFILE ← NIL POBJ ← OBJECT PLEN ← 1)) (* The new piece we're inserting) [COND ((SETQ SUBSTREAM (IMAGEOBJPROP OBJECT (QUOTE SUBSTREAM))) (* If this is computed text in bulk, fix the length.) (replace PLEN of NEWPC with (fetch TEXTLEN of (fetch (TEXTSTREAM TEXTOBJ) of SUBSTREAM] [COND ((OR (IGREATERP CH# TEXTLEN) (IEQP CH# (\EDITELT PCTB PCNO))) (* We're inserting on a piece boundary; do it, then remember the prior piece.) (\INSERTPIECE NEWPC PC TEXTOBJ NIL PCNO)) (T (* Not on a piece boundary; split the piece we're inside of, then insert.) (\INSERTPIECE NEWPC (\SPLITPIECE PC CH# TEXTOBJ) TEXTOBJ NIL (IPLUS PCNO \EltsPerPiece] (COND ((SETQ INSERTFN (IMAGEOBJPROP OBJECT (QUOTE WHENINSERTEDFN))) (* If there is a WHENINSERTEDFN, apply it.) (APPLY* INSERTFN OBJECT (WINDOWPROP (CAR (fetch \WINDOW of TEXTOBJ)) (QUOTE DSP)) NIL STREAM))) (SETQ PCTB (fetch PCTB of TEXTOBJ)) (SETQ PREVPC (fetch PREVPIECE of NEWPC)) (* Fill in the para looks) [COND [PREVPC (COND [(AND (fetch PPARALAST of PREVPC) (fetch NEXTPIECE of NEWPC)) (replace PPARALOOKS of NEWPC with (fetch PPARALOOKS of (fetch NEXTPIECE of NEWPC] (T (replace PPARALOOKS of NEWPC with (fetch PPARALOOKS of PREVPC] (T (COND ((SETQ PREVPC (fetch NEXTPIECE of NEWPC)) (replace PPARALOOKS of NEWPC with (fetch PPARALOOKS of PREVPC))) (T (replace PPARALOOKS of NEWPC with (fetch FMTSPEC of TEXTOBJ] (replace PLOOKS of NEWPC with (fetch CARETLOOKS of TEXTOBJ)) (\TEDIT.HISTORYADD TEXTOBJ (create TEDITHISTORYEVENT THACTION ←(QUOTE Insert) THCH# ← CH# THLEN ← 1 THFIRSTPIECE ← NEWPC)) (SETQ TEXTLEN (freplace TEXTLEN of TEXTOBJ with (IPLUS (fetch PLEN of NEWPC) TEXTLEN))) (replace \INSERTPCVALID of TEXTOBJ with NIL) (* Since adding an IMAGEOBJ creates a new piece, the old insertion cache piece is no longer valid.) (replace \DIRTY of TEXTOBJ with T) (replace DESC of (fetch THISLINE of TEXTOBJ) with NIL) (replace SELKIND of SEL with (QUOTE CHAR)) (COND ((fetch \WINDOW of TEXTOBJ) (\FIXILINES TEXTOBJ SEL CH# (fetch PLEN of NEWPC) (SUB1 TEXTLEN)) (replace DCH of SEL with 0) (replace (SELECTION DX) of SEL with 0) (TEDIT.UPDATE.SCREEN TEXTOBJ) (\FIXSEL SEL TEXTOBJ) (\SHOWSEL SEL NIL T)) (T [replace CHLIM of SEL with (replace CH# of SEL with (IPLUS CH# (fetch PLEN of NEWPC] (replace DCH of SEL with 0) (replace (SELECTION DX) of SEL with 0) (replace POINT of SEL with (QUOTE LEFT)) (replace DESC of (fetch THISLINE of TEXTOBJ) with NIL))) (\COPYSEL SEL TEDIT.SELECTION]) (TEDIT.EDIT.OBJECT [LAMBDA (STREAM OBJ) (* jds " 6-Mar-85 21:07") (PROG ([TEXTOBJ (COND ((type? TEXTOBJ STREAM) STREAM) ((type? STREAM STREAM) (fetch (TEXTSTREAM TEXTOBJ) of STREAM)) ((SHOULDNT] SEL LL CH# SELOBJ EDITFN) [COND [(AND OBJ (IMAGEOBJP OBJ)) (SETQ CH# (TEDIT.FIND.OBJECT TEXTOBJ OBJ)) (COND (CH# (SETQ SEL (fetch SCRATCHSEL of TEXTOBJ)) (replace CH# of SEL with CH#) (replace CHLIM of SEL with (ADD1 CH#)) (SETQ SELOBJ OBJ) (replace DCH of SEL with 1) (replace \TEXTOBJ of SEL with TEXTOBJ) (\FIXSEL SEL TEXTOBJ)) (T (TEDIT.PROMPTPRINT TEXTOBJ "Can't find specified object." T] (T (SETQ SEL (fetch SEL of TEXTOBJ)) (SETQ OBJ (fetch SELOBJ of SEL] (COND [OBJ (* OK There's an object selected. Edit it.) (SETQ EDITFN (IMAGEOBJPROP OBJ (QUOTE EDITFN))) (COND ((AND EDITFN (APPLY* EDITFN OBJ)) (* If the editfn makes a change, update the screen.) (for LINE inside (fetch L1 of SEL) do (replace DIRTY of LINE with T)) (replace TXTNEEDSUPDATE of TEXTOBJ with T) (TEDIT.UPDATE.SCREEN TEXTOBJ] (T (* No object selected.) (TEDIT.PROMPTPRINT TEXTOBJ "Please select an editable object first." T]) (TEDIT.FIND.OBJECT [LAMBDA (TEXTOBJ OBJ) (* jds "22-OCT-83 17:36") (* Find OBJ, if it's in TEXTOBJ, and return CH#. Else return nil) (SETQ TEXTOBJ (TEXTOBJ TEXTOBJ)) (PROG ((PCTB (fetch PCTB of TEXTOBJ)) PC) (RETURN (for PCNO from (ADD1 \FirstPieceOffset) to (\EDITELT PCTB \PCTBLastPieceOffset) by \EltsPerPiece do (SETQ PC (\EDITELT PCTB PCNO)) (COND ((EQ (fetch POBJ of PC) OBJ) (RETURN (\EDITELT PCTB (SUB1 PCNO]) (TEDIT.PUT.OBJECT [LAMBDA (PIECE OFILE FONTFILE CURCH#) (* jds "19-Feb-85 10:12") (* Given a piece which describes an object, put the object out there.) (PROG ((OBJECT (fetch POBJ of PIECE)) (FONTCH# (GETFILEPTR FONTFILE)) TOFILE LEN) (\DWOUT FONTFILE 0) (* Placeholder for length of the object's description) (\SMALLPOUT FONTFILE \PieceDescriptorOBJECT) (* Mark this as setting the piece's looks) (\ATMOUT FONTFILE (IMAGEOBJPROP OBJECT (QUOTE GETFN))) (* The FN to apply to reconstruct the object) (APPLY* (IMAGEOBJPROP OBJECT (QUOTE PUTFN)) OBJECT OFILE) (SETFILEPTR FONTFILE FONTCH#) (* Now go back and fill in the length of the text description of the object.) [\DWOUT FONTFILE (SETQ LEN (ADD1 (IDIFFERENCE (GETEOFPTR OFILE) CURCH#] (SETFILEPTR FONTFILE -1) (* Make sure we're at the end of the font file) (AND (RANDACCESSP OFILE) (SETFILEPTR OFILE -1)) (* And the text part of the file) (RETURN LEN]) (TEDIT.GET.OBJECT [LAMBDA (STREAM PIECE FILE CURCH#) (* jds "22-Feb-85 14:31") (* Get an object from the file) (* CURCH# = fileptr within the text section of the file where the object's text starts.) (PROG ((TEXTOBJ (fetch (TEXTSTREAM TEXTOBJ) of STREAM)) FILEPTRSAVE NAMELEN GETFN OBJ) (SETQ GETFN (\ATMIN FILE)) (* The GETFN for this kind of IMAGEOBJ) (SETQ FILEPTRSAVE (GETFILEPTR FILE)) (* Save our file location thru the building of the object) (SETFILEPTR FILE CURCH#) (SETQ OBJ (READIMAGEOBJ FILE GETFN)) (SETFILEPTR FILE FILEPTRSAVE) (replace POBJ of PIECE with OBJ) (replace PFILE of PIECE with NIL) (replace PSTR of PIECE with NIL) [replace PLOOKS of PIECE with (COND ((fetch PREVPIECE of PIECE) (fetch PLOOKS of (fetch PREVPIECE of PIECE))) (T (OR (fetch DEFAULTCHARLOOKS of TEXTOBJ) (\TEDIT.UNIQUIFY.CHARLOOKS (CHARLOOKS.FROM.FONT DEFAULTFONT) TEXTOBJ] (RETURN (fetch POBJ of PIECE]) (TEDIT.OBJECT.CHANGED [LAMBDA (STREAM OBJECT) (* jds " 7-Feb-85 13:44") (* Notify TEdit that an object has changed, and the display may need to be updated.) (PROG ((TEXTOBJ (TEXTOBJ STREAM)) (LINES (fetch LINES of (TEXTOBJ STREAM))) PCINFO CHANGED CHANGEDCH#) (SETQ PCINFO (TEDIT.MAPPIECES TEXTOBJ [FUNCTION (LAMBDA (CH# PC PCNO OBJ) (AND (EQ OBJ (fetch POBJ of PC)) (QUOTE STOP] OBJECT)) (* Find the piece containing this object) (OR PCINFO (HELP "Changed OBJECT not found!?")) (SETQ CHANGEDCH# (CAR PCINFO)) (* Get the CH# of the changed object) (\TEDIT.MARK.LINES.DIRTY TEXTOBJ CHANGEDCH# CHANGEDCH#) (* Mark affected lines) (replace \DIRTY of TEXTOBJ with T) (* And mark the document dirty.) (\SHOWSEL (fetch SEL of TEXTOBJ) NIL NIL) (TEDIT.UPDATE.SCREEN TEXTOBJ) (\FIXSEL (fetch SEL of TEXTOBJ) TEXTOBJ) (\SHOWSEL (fetch SEL of TEXTOBJ) NIL T]) ) (FILESLOAD TEDITFIND TEDITHISTORY TEDITFILE TEDITWINDOW TEDITSELECTION IMAGEOBJ TFBRAVO TEDITHCPY TEDITMENU) (* TEDIT Support information) (RPAQQ TEDITSYSTEMDATE "12-Mar-85 07:35:58") (RPAQ TEDITSUPPORT "TEditSupport.PA") (DEFINEQ (MAKETEDITFORM [LAMBDA NIL (* jds "12-Mar-85 04:00") (* Builds a trouble-report form for TEdit.) (MAKEXXXSUPPORTFORM "TEdit" TEDITSUPPORT TEDITSYSTEMDATE]) ) (ADDTOVAR LAFITESPECIALFORMS ("TEdit Report" (QUOTE MAKETEDITFORM) "Report a problem with TEdit")) (SETQ LAFITEFORMSMENU NIL) (* LISTFILES Interface, so the system can decide if a file is a TEdit file.) (ADDTOVAR PRINTFILETYPES (TEDIT (TEST \TEDIT.FORMATTEDP1) (EXTENSION (TEDIT)))) (PUTPROPS TEDIT COPYRIGHT ("John Sybalsky & Xerox Corporation" 1983 1984 1985)) (DECLARE: DONTCOPY (FILEMAP (NIL (2609 73766 (\TEDIT2 2619 . 4572) (COERCETEXTOBJ 4574 . 8814) (TEDIT 8816 . 11667) ( TEDIT.CHARWIDTH 11669 . 13212) (TEDIT.COPY 13214 . 18710) (TEDIT.DELETE 18712 . 19238) ( TEDIT.DO.BLUEPENDINGDELETE 19240 . 21397) (TEDIT.INSERT 21399 . 25201) (TEDIT.KILL 25203 . 26454) ( TEDIT.MAPLINES 26456 . 27422) (TEDIT.MAPPIECES 27424 . 28549) (TEDIT.MOVE 28551 . 35098) (TEDIT.QUIT 35100 . 36361) (TEDIT.STRINGWIDTH 36363 . 36912) (TEDIT.\INSERT 36914 . 38495) (TEXTOBJ 38497 . 39380) (TEXTSTREAM 39382 . 40726) (\TEDIT.INCLUDE 40728 . 42812) (\TEDIT.INSERT.PIECES 42814 . 48415) ( \TEDIT.MOVE.PIECEMAPFN 48417 . 49845) (\TEDIT.OBJECT.SHOWSEL 49847 . 51684) (\TEDIT.RESTARTFN 51686 . 53434) (\TEDIT.CHARDELETE 53436 . 56460) (\TEDIT.COPY.PIECEMAPFN 56462 . 58716) (\TEDIT.DELETE 58718 . 63919) (\TEDIT.DIFFUSE.PARALOOKS 63921 . 66227) (\TEDIT.FOREIGN.COPY? 66229 . 67508) (\TEDIT.QUIT 67510 . 69586) (\TEDIT.WORDDELETE 69588 . 72047) (\TEDIT1 72049 . 73764)) (73799 76520 (PLCHAIN 73809 . 74033) (PRINTLINE 74035 . 76013) (SEEFILE 76015 . 76518)) (76557 88895 (TEDIT.INSERT.OBJECT 76567 . 82231) (TEDIT.EDIT.OBJECT 82233 . 83930) (TEDIT.FIND.OBJECT 83932 . 84618) (TEDIT.PUT.OBJECT 84620 . 86056) (TEDIT.GET.OBJECT 86058 . 87522) (TEDIT.OBJECT.CHANGED 87524 . 88893)) (89141 89438 ( MAKETEDITFORM 89151 . 89436))))) STOP