home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-07-17 | 48.5 KB | 1,349 lines |
- ;;; -*- Mode:lisp; Package:(BOXER GLOBAL 1000); Base:10.;Fonts:cptfont,cptfontb -*-
-
- #||
- Copyright 1985 Massachusetts Institute of Technology
-
- Permission to use, copy, modify, distribute, and sell this software
- and its documentation for any purpose is hereby granted without fee,
- provided that the above copyright notice appear in all copies and that
- both that copyright notice and this permission notice appear in
- supporting documentation, and that the name of M.I.T. not be used in
- advertising or publicity pertaining to distribution of the software
- without specific, written prior permission. M.I.T. makes no
- representations about the suitability of this software for any
- purpose. It is provided "as is" without express or implied warranty.
-
-
- +-Data--+
- This file is part of the | BOXER | system
- +-------+
-
- This file contains low-level code for the BOXER editor.
-
- ||#
-
- ;;;;INIT methods.
-
- (DEFUN MAKE-UNINITIALIZED-ROW (&REST INIT-PLIST)
- (INSTANTIATE-FLAVOR 'ROW (LOCF INIT-PLIST) NIL))
-
- (DEFUN MAKE-UNINITIALIZED-BOX (&REST INIT-PLIST)
- (INSTANTIATE-FLAVOR 'BOX (LOCF INIT-PLIST) NIL))
-
- (DEFUN MAKE-INITIALIZED-ROW (&REST INIT-PLIST)
- (INSTANTIATE-FLAVOR 'ROW (LOCF INIT-PLIST) T))
-
- (DEFUN MAKE-INITIALIZED-BOX (&REST INIT-PLIST)
- (INSTANTIATE-FLAVOR 'BOX (LOCF INIT-PLIST) T))
-
- (DEFUN MAKE-INITIALIZED-GRAPHICS-BOX (&REST INIT-PLIST)
- (INSTANTIATE-FLAVOR 'GRAPHICS-BOX (LOCF INIT-PLIST) T))
-
- (DEFMETHOD (ROW :INIT) (INIT-PLIST)
- (SETQ SUPERIOR-BOX (GET INIT-PLIST ':SUPERIOR-BOX)
- PREVIOUS-ROW (GET INIT-PLIST ':PREVIOUS-ROW)
- NEXT-ROW (GET INIT-PLIST ':NEXT-ROW)
- CHAS-ARRAY (OR (GET INIT-PLIST ':CHAS-ARRAY)
- (MAKE-CHAS-ARRAY))
- CACHED-ELEMENTS NIL
- CACHED-ENTRIES NIL))
-
- (DEFMETHOD (DOIT-BOX :BEFORE :INIT) (INIT-PLIST)
- (UNLESS (GET INIT-PLIST ':TYPE)
- (PUTPROP INIT-PLIST ':DOIT-BOX ':TYPE)))
-
- (DEFMETHOD (DATA-BOX :BEFORE :INIT) (INIT-PLIST)
- (UNLESS (GET INIT-PLIST ':TYPE)
- (PUTPROP INIT-PLIST ':DATA-BOX ':TYPE)))
-
- (DEFMETHOD (BOX :INIT) (INIT-PLIST)
- (SETQ ;; These we inherit from chas.
- SUPERIOR-ROW (GET INIT-PLIST ':SUPERIOR-ROW)
- CHA-CODE ':BOX
- FONT-NO NIL
- ;; These come from box proper.
- LOCAL-LIBRARY (GET INIT-PLIST ':LOCAL-LIBRARY)
- FIRST-INFERIOR-ROW NIL
- CACHED-ROWS NIL
- CACHED-CODE NIL)
- (WHEN (EQ 'BOX (TYPEP SELF)) ;is it a vanilla box ?, if so make it what it wants to be or
- (TELL SELF :SET-TYPE (OR (GET INIT-PLIST ':TYPE) ':DOIT-BOX)))) ;else a doit box
-
- (DEFMETHOD (LL-BOX :INIT) (INIT-PLIST)
- (SETQ ;; These we inherit from chas.
- SUPERIOR-ROW (GET INIT-PLIST ':SUPERIOR-ROW)
- CHA-CODE ':BOX
- FONT-NO NIL
- ;; these we inherit from vanilla boxes
- FIRST-INFERIOR-ROW NIL
- CACHED-ROWS NIL
- CACHED-CODE NIL
- STATIC-VARIABLES-ALIST (GET INIT-PLIST ':STATIC-VARIABLES-ALIST)
- EXPORTS *EXPORT-ALL-VARIABLES-MARKER*))
-
- (DEFMETHOD (GRAPHICS-BOX :INIT) (INIT-PLIST)
- (SETQ ;; These we inherit from chas.
- SUPERIOR-ROW (GET INIT-PLIST ':SUPERIOR-ROW)
- CHA-CODE ':BOX
- FONT-NO NIL
- ;; these we inherit from vanilla boxes
- LOCAL-LIBRARY (GET INIT-PLIST ':LOCAL-LIBRARY)
- FIRST-INFERIOR-ROW NIL
- CACHED-ROWS NIL
- CACHED-CODE NIL
- STATIC-VARIABLES-ALIST (GET INIT-PLIST ':STATIC-VARIABLES-ALIST)
- DISPLAY-STYLE-LIST (OR (GET INIT-PLIST ':DISPLAY-STYLE-LIST)
- `(:NORMAL
- ,(GET INIT-PLIST ':FIXED-WID)
- ,(GET INIT-PLIST ':FIXED-HEI)))
- ;; and this is from the graphics box itself
- GRAPHICS-SHEET (OR (GET INIT-PLIST ':GRAPHICS-SHEET)
- (MAKE-GRAPHICS-SHEET (GET INIT-PLIST ':FIXED-WID)
- (GET INIT-PLIST ':FIXED-HEI)
- SELF))))
-
- (DEFMETHOD (GRAPHICS-DATA-BOX :INIT) (INIT-PLIST)
- (SETQ ;; These we inherit from chas.
- SUPERIOR-ROW (GET INIT-PLIST ':SUPERIOR-ROW)
- CHA-CODE ':BOX
- FONT-NO NIL
- ;; These come from box proper.
- LOCAL-LIBRARY (GET INIT-PLIST ':LOCAL-LIBRARY)
- FIRST-INFERIOR-ROW NIL
- CACHED-ROWS NIL
- CACHED-CODE NIL
- GRAPHICS-SHEET (OR (GET INIT-PLIST ':GRAPHICS-SHEET)
- (MAKE-GRAPHICS-SHEET (GET INIT-PLIST ':FIXED-WID)
- (GET INIT-PLIST ':FIXED-HEI)
- SELF))))
-
- (DEFMETHOD (CHA :AFTER :INIT-SELF-FROM-OLD-INSTANCE) (OLD-INSTANCE)
- (LET ((SUPERIOR-CHAS-ARRAY (TELL-CHECK-NIL SUPERIOR-ROW :CHAS-ARRAY))
- (OLD-CHA-NO (TELL-CHECK-NIL (TELL OLD-INSTANCE :SUPERIOR-ROW)
- :CHA-CHA-NO OLD-INSTANCE)))
- (WHEN (AND (NOT-NULL OLD-CHA-NO) (NOT-NULL SUPERIOR-CHAS-ARRAY))
- (SETF (AREF SUPERIOR-CHAS-ARRAY OLD-CHA-NO)
- (FOLLOW-STRUCTURE-FORWARDING (AREF SUPERIOR-CHAS-ARRAY OLD-CHA-NO))))))
-
- ;;; this should go into BIND sometime
-
- (DEFUN BINDINGS-FOR-OBJECT (OBJECT BINDING-ALIST)
- (SUBSET #'(LAMBDA (X) (EQ OBJECT (CDR X))) BINDING-ALIST))
-
- (DEFMETHOD (BOX :AFTER :INIT-SELF-FROM-OLD-INSTANCE) (OLD-INSTANCE)
- (DOLIST (ROW (TELL SELF :ROWS))
- (TELL ROW :SET-SUPERIOR-BOX (FOLLOW-STRUCTURE-FORWARDING (TELL ROW :SUPERIOR-BOX))))
- (DOLIST (BINDING (BINDINGS-FOR-OBJECT
- OLD-INSTANCE
- (TELL (TELL SELF :SUPERIOR-BOX) :GET-STATIC-VARIABLES-ALIST)))
- (SETF (CDR BINDING) (FOLLOW-STRUCTURE-FORWARDING (CDR BINDING)))))
-
- (defMETHOD (GRAPHICS-BOX :BEFORE :SET-FLAVOR) (new)
- (tell self :erase-from-screen)
- (when (eq new 'graphics-data-box)
- (convert-screen-objs 'screen-box)
- ; (dolist (screen-obj (get-all-screen-objs self))
- ; (unless (eq (tell screen-obj :box-type) :port-box)
- ; (tell screen-obj :set-box-type ':graphics-data-box)))
- (tell self :modified)))
-
- (DEFUN-METHOD CONVERT-SCREEN-OBJS BOX (NEW-FLAVOR)
- (MAPCAR #'(LAMBDA (OBJ)(TELL OBJ :SET-FLAVOR NEW-FLAVOR)
- (UNLESS (PORT-BOX? (TELL OBJ :ACTUAL-OBJ))
- (TELL OBJ :SET-ACTUAL-OBJ SELF)))
- (GET-ALL-SCREEN-OBJS SELF)))
-
- (defun get-visible-screen-objs (graphics-box)
- (cond ((null (tell graphics-box :ports)) (tell graphics-box :displayed-screen-objs))
- (t (append (tell graphics-box :displayed-screen-objs)
- (loop for port in (tell graphics-box :ports)
- appending (tell port :displayed-screen-objs))))))
-
- (DEFUN GET-ALL-SCREEN-OBJS (BOX)
- (cond ((null (tell box :ports)) (tell box :screen-objs))
- (t (append (tell box :screen-objs)
- (loop for port in (tell box :ports)
- appending (tell port :screen-objs))))))
-
- (DEFMETHOD (GRAPHICS-BOX :AFTER :INIT-SELF-FROM-OLD-INSTANCE) (IGNORE)
- ;; presumably all the instance variables common with ordinary boxes will have been
- ;; already initialized by the primary method. All we have to do is...
- (CONVERT-SCREEN-OBJS 'GRAPHICS-SCREEN-BOX)
- (SETQ GRAPHICS-SHEET (MAKE-GRAPHICS-SHEET (CADR DISPLAY-STYLE-LIST)
- (CADDR DISPLAY-STYLE-LIST)
- SELF))
- (TELL SELF :MODIFIED))
-
- (DEFMETHOD (DOIT-BOX :AFTER :INIT-SELF-FROM-OLD-INSTANCE) (IGNORE)
- (CONVERT-SCREEN-OBJS 'SCREEN-BOX)
- (DOLIST (ROW (TELL SELF :ROWS))
- (TELL ROW :MODIFIED)))
-
- (DEFMETHOD (DATA-BOX :AFTER :INIT-SELF-FROM-OLD-INSTANCE) (IGNORE)
- (CONVERT-SCREEN-OBJS 'SCREEN-BOX)
- (DOLIST (ROW (TELL SELF :ROWS))
- (TELL ROW :MODIFIED)))
-
- (DEFMETHOD (BOX :AFTER :INIT) (INIT-PLIST)
- (TELL SELF :APPEND-ROW (OR (GET INIT-PLIST ':FIRST-INFERIOR-ROW)
- (MAKE-INITIALIZED-ROW))))
-
- (DEFMETHOD (BOX :SEMI-INIT) (INIT-PLIST)
- (SETQ ;;these come from box proper
- FIRST-INFERIOR-ROW (GET INIT-PLIST ':SUPERIOR-ROW)
- CACHED-ROWS NIL
- CACHED-CODE NIL
- NAME (WHEN (GET INIT-PLIST :NAME)
- (MAKE-NAME-ROW `(,(GET INIT-PLIST :NAME))))
- DISPLAY-STYLE-LIST (OR (GET INIT-PLIST ':DISPLAY-STYLE-LIST)
- DISPLAY-STYLE-LIST))
- (WHEN (NAME-ROW? NAME) (TELL NAME :SET-SUPERIOR-BOX SELF))
- (TELL SELF :SET-TYPE (OR (GET INIT-PLIST ':TYPE) ':DOIT-BOX)))
-
- (DEFMETHOD (PORT-BOX :AFTER :SEMI-INIT) (INIT-PLIST)
- ;; might as well look to see if it is there...
- (SETQ PORTS (OR (GET INIT-PLIST :PORTS) PORTS)))
-
- (DEFMETHOD (BOX :RETURN-INIT-PLIST-FOR-FILING) ()
- `(:TYPE ,(TELL SELF :TYPE)
- :DISPLAY-STYLE-LIST ,DISPLAY-STYLE-LIST))
-
- (DEFMETHOD (GRAPHICS-BOX :RETURN-INIT-PLIST-FOR-FILING) ()
- `(:TYPE ,(TELL SELF :TYPE)
- :DISPLAY-STYLE-LIST ,DISPLAY-STYLE-LIST
- :GRAPHICS-SHEET ,GRAPHICS-SHEET))
-
- (DEFMETHOD (BOX :RETURN-INIT-PLIST-FOR-COPY) ()
- (IF (NAME-ROW? NAME)
- `(:TYPE ,(TELL SELF :TYPE)
- :DISPLAY-STYLE-LIST ,DISPLAY-STYLE-LIST :NAME ,(TELL SELF :NAME))
- `(:TYPE ,(TELL SELF :TYPE)
- :DISPLAY-STYLE-LIST ,DISPLAY-STYLE-LIST)))
-
-
-
- ;;;;PRINT-SELF methods.
-
- (DEFMETHOD (ROW :SHOW-CHAS) ()
- (FORMAT STANDARD-OUTPUT "~%")
- (DOLIST (CHA (TELL SELF :CHAS))
- (IF (CHA? CHA)
- (FORMAT STANDARD-OUTPUT "~C" CHA)
- (TELL CHA :PRINT-SELF STANDARD-OUTPUT))))
-
- (DEFMETHOD (BOX :PRINT-SELF) (STREAM &REST IGNORE)
- (FORMAT STREAM "#<~a " (TELL SELF :TYPE))
- (BOX-PRINT-SELF-INTERNAL SELF STREAM)
- (FORMAT STREAM " >"))
-
- (DEFMETHOD (GRAPHICS-BOX :PRINT-SELF) (STREAM &REST IGNORE)
- (FORMAT STREAM "#<~a ~a >" (TELL SELF :TYPE) (tell self :NAME)))
-
- (DEFMETHOD (SCREEN-BOX :PRINT-SELF) (STREAM &REST IGNORE)
- (FORMAT STREAM "#<SCREEN-BOX ")
- (IF (GRAPHICS-BOX? ACTUAL-OBJ)
- (FORMAT STREAM "~a " (TELL ACTUAL-OBJ :TYPE))
- (BOX-PRINT-SELF-INTERNAL ACTUAL-OBJ STREAM))
- (FORMAT STREAM " >"))
-
- (DEFMETHOD (ROW :PRINT-SELF) (STREAM &REST IGNORE)
- (FORMAT STREAM "#<ROW ")
- (ROW-PRINT-SELF-INTERNAL SELF STREAM)
- (FORMAT STREAM " >"))
-
- (DEFMETHOD (NAME-ROW :PRINT-SELF) (STREAM &REST IGNORE)
- (FORMAT STREAM "#<NAME-ROW ")
- (ROW-PRINT-SELF-INTERNAL SELF STREAM)
- (FORMAT STREAM " >"))
-
- (DEFUN CHA-PRINT-SELF-INTERNAL (CHA STREAM)
- (COND ((BOX? CHA)
- (FORMAT STREAM "[]"))
- (T
- (FORMAT STREAM "~C" (CHA-CODE CHA)))))
-
- (DEFUN ROW-PRINT-SELF-INTERNAL (ROW STREAM)
- (PROG ()
- (DO-ROW-CHAS ((CHA ROW)
- (CHA-NO 0 (+ CHA-NO 1)))
- (COND ((> CHA-NO 5)
- (FORMAT STREAM "...")
- (RETURN))
- (T
- (CHA-PRINT-SELF-INTERNAL CHA STREAM))))))
-
- (DEFUN BOX-PRINT-SELF-INTERNAL (BOX STREAM)
- (LET ((FIRST-ROW (TELL BOX :ROW-AT-ROW-NO 0)))
- (COND ((NULL FIRST-ROW))
- (T
- (ROW-PRINT-SELF-INTERNAL FIRST-ROW STREAM)))))
-
-
-
- ;;keep these around for boxes to use...
-
- (DEFGET-METHODS ((CHA :SUPERIOR-ROW) :SUPERIOR-OBJ) SUPERIOR-ROW)
- (DEFSET-METHODS ((CHA :SET-SUPERIOR-ROW) :SET-SUPERIOR-OBJ) SUPERIOR-ROW)
-
- (DEFMETHOD (CHA :SUPERIOR-BOX) ()
- (TELL SUPERIOR-ROW :SUPERIOR-BOX))
-
-
-
-
-
-
-
- ;;;;USEFUL-MAPPING-FUNCTIONS
-
- (DEFUN MAP-OVER-ALL-INFERIOR-BOXES (SUPERIOR-BOX FUNCTION)
- (DO ((ROW (TELL SUPERIOR-BOX :FIRST-INFERIOR-ROW) (TELL ROW :NEXT-ROW)))
- ((NULL ROW))
- (DO* ((CHA-NO 0 (+ CHA-NO 1))
- (CHA (TELL ROW :CHA-AT-CHA-NO CHA-NO) (TELL ROW :CHA-AT-CHA-NO CHA-NO)))
- ((NULL CHA))
- (COND ((BOX? CHA)
- (FUNCALL FUNCTION CHA)
- (MAP-OVER-ALL-INFERIOR-BOXES CHA FUNCTION))))))
-
- (DEFUN MAP-OVER-INFERIOR-BOXES (SUPERIOR-BOX FUNCTION)
- (DOLIST (ROW (TELL SUPERIOR-BOX :ROWS))
- (DOLIST (CHA (TELL ROW :CHAS))
- (WHEN (BOX? CHA)
- (FUNCALL FUNCTION CHA)))))
-
-
-
- (DEFMETHOD (BOX :MODIFIED) (&OPTIONAL (DECACHE T))
- (WHEN (NOT-NULL DECACHE)
- (SETQ CACHED-ROWS NIL
- CACHED-CODE NIL)
- (TELL SELF :PUTPROP NIL 'CACHED-BUILD))
- (TELL-CHECK-NIL (TELL SELF :SUPERIOR-ROW) :MODIFIED))
-
- (DEFMETHOD (ROW :MODIFIED) (&OPTIONAL (DECACHE T))
- (WHEN (NOT-NULL DECACHE)
- (SETQ CACHED-CHAS NIL
- CACHED-ENTRIES NIL
- CACHED-ELEMENTS NIL
- CACHED-ITEMS NIL
- CACHED? NIL))
- (TELL-CHECK-NIL (TELL SELF :SUPERIOR-BOX) :MODIFIED T))
-
-
-
-
- ;;;;INCREMENT and SET-TYPE
-
- (DEFVAR *TOGGLING-BOX-TYPES* `(:DOIT-BOX :DATA-BOX)
- "This is a circular list of the different possible types of boxes.
- The list is circular to make it easy to define a next type for
- each type, this is used by (:method box :increment-type).")
-
- (DEFUN TOGGLING-BOX-TYPES-NEXT-BOX-TYPE (OLD-TYPE)
- (LET ((POS (FIND-POSITION-IN-LIST OLD-TYPE *TOGGLING-BOX-TYPES*))
- (LEN (LENGTH *TOGGLING-BOX-TYPES*)))
- (COND ((NULL POS) (CAR *TOGGLING-BOX-TYPES*))
- (T (NTH (REMAINDER (+ POS 1) LEN) *TOGGLING-BOX-TYPES*)))))
-
- (DEFMETHOD (LL-BOX :TOGGLE-TYPE) ()
- (BEEP))
-
- (DEFMETHOD (DOIT-BOX :TYPE) ()
- ':DOIT-BOX)
-
- (DEFMETHOD (DATA-BOX :TYPE) ()
- ':DATA-BOX)
-
- (DEFMETHOD (LL-BOX :TYPE) ()
- ':LL-BOX)
-
- (DEFMETHOD (PORT-BOX :TYPE) ()
- ':PORT-BOX)
-
- (DEFMETHOD (GRAPHICS-BOX :TYPE) ()
- ':GRAPHICS-BOX)
-
- (DEFMETHOD (INPUT-BOX :TYPE) ()
- ':INPUT-BOX)
-
- (DEFMETHOD (BOX :SET-TYPE) (NEW-TYPE)
- (SELECTQ NEW-TYPE
- ((:DOIT-BOX DOIT-BOX)
- (TELL SELF :SET-FLAVOR 'DOIT-BOX))
- ((:DATA-BOX DATA-BOX)
- (TELL SELF :SET-FLAVOR 'DATA-BOX))
- ((:PORT-BOX PORT-BOX)
- (TELL SELF :SET-FLAVOR 'PORT-BOX))
- ((:LL-BOX LL-BOX)
- (TELL SELF :SET-FLAVOR 'LL-BOX))
- ((:GRAPHICS-BOX GRAPHICS-BOX)
- (TELL SELF :SET-FLAVOR 'GRAPHICS-BOX))
- ((:graphics-data-box graphics-data-box)
- (tell self :set-flavor 'graphics-data-box))
- ((:sprite-box sprite-box)
- (tell self :set-flavor 'sprite-box))
- ((:INPUT-BOX INPUT-BOX)
- (TELL SELF :SET-FLAVOR 'INPUT-BOX))
- (OTHERWISE (FERROR "can't set ~s to ~s"SELF NEW-TYPE)))
- (TELL SELF :MODIFIED))
-
- (DEFMETHOD (BOX :TOGGLE-TYPE) ()
- (TELL SELF :SET-TYPE (TOGGLING-BOX-TYPES-NEXT-BOX-TYPE (TELL SELF :TYPE))))
-
- (DEFMETHOD (GRAPHICS-BOX :TOGGLE-TYPE) ()
- (TELL SELF :SET-TYPE 'GRAPHICS-DATA-BOX))
-
- (DEFMETHOD (GRAPHICS-DATA-BOX :TOGGLE-TYPE) ()
- (IF (EQ SELF (OUTERMOST-BOX)) (BEEP)
- (TELL SELF :SET-TYPE 'GRAPHICS-BOX)))
-
-
-
- ;;;; PORTS.
-
- (DEFMETHOD (PORT-BOX :SET-PORT-TO-BOX) (NEW-VALUE)
- (TELL NEW-VALUE :ADD-PORT SELF)
- (SETQ PORTS NEW-VALUE))
-
- (DEFMETHOD (BOX :ADD-PORT) (PORT-TO-ADD)
- (UNLESS (MEMQ PORT-TO-ADD PORTS)
- (PUSH PORT-TO-ADD PORTS)))
-
- (DEFMETHOD (PORT-BOX :ADD-PORT) (PORT-TO-ADD)
- (TELL PORTS :ADD-PORT PORT-TO-ADD))
-
- (DEFMETHOD (BOX :REMOVE-PORT) (PORT-TO-DELETE)
- (SETQ PORTS (DELQ PORT-TO-DELETE PORTS)))
-
- ;; what happens when a port's target is removed from the hierarchy ?
- ;; This is just a stub until we decide what to do. Old proposal to mark the port as "broken"
- ;; needs some redisplay hacking
- (DEFMETHOD (PORT-BOX :TARGET-HAS-BEEN-DELETED-HANDLER) ()
- )
-
- ;; Another stub
- (DEFMETHOD (PORT-BOX :TARGET-HAS-BEEN-INSERTED-HANDLER) (TARGET)
- TARGET)
-
- ;; Doesn't create the back pointer so that the port can eventually be GC'd
- ;; ports which use this should NEVER, NEVER, NEVER be inserted into the editor
- (DEFMETHOD (PORT-BOX :SET-PORT-TO-BOX-FOR-EVAL) (NEW-VALUE)
- (SETQ PORTS NEW-VALUE))
-
- (DEFMETHOD (PORT-BOX :FIRST-INFERIOR-ROW) ()
- (TELL-CHECK-NIL PORTS :FIRST-INFERIOR-ROW))
-
- (DEFMETHOD (PORT-BOX :FIRST-INFERIOR-OBJ) ()
- (TELL-CHECK-NIL PORTS :FIRST-INFERIOR-OBJ))
-
- (DEFMETHOD (PORT-BOX :ROW-AT-ROW-NO) (ROW-NO)
- (TELL-CHECK-NIL PORTS :ROW-AT-ROW-NO ROW-NO))
-
- (DEFMETHOD (PORT-BOX :TICK) ()
- (MAX (TELL-CHECK-NIL PORTS :TICK) TICK))
-
- (DEFWHOPPER (BOX :MODIFIED) (&OPTIONAL (DECACHE T))
- (CONTINUE-WHOPPER DECACHE)
- (IF (LISTP PORTS)
- (DOLIST (PORT PORTS)
- (TELL PORT :MODIFIED DECACHE))))
-
- ;;; These are needed to handle :MODIFIED for circular structures
- (DEFVAR *PORTS-ALREADY-MODIFIED* NIL)
-
- (DEFWHOPPER (PORT-BOX :MODIFIED) (&OPTIONAL (DECACHE T))
- (UNLESS (MEMQ SELF *PORTS-ALREADY-MODIFIED*)
- (LET ((*PORTS-ALREADY-MODIFIED* (APPEND *PORTS-ALREADY-MODIFIED* (NCONS SELF))))
- (CONTINUE-WHOPPER DECACHE))))
-
- (DEFMETHOD (BOX :CLEAR-PORTS)()
- ;; for debugging
- (SETQ PORTS NIL))
-
- (DEFMETHOD (BOX :PORTS) ()
- PORTS)
-
- (DEFMETHOD (PORT-BOX :GRAPHICS-SHEET) ()
- (TELL-CHECK-NIL PORTS :GRAPHICS-SHEET))
-
- (DEFMETHOD (PORT-BOX :BIT-ARRAY-WID) ()
- (TELL-CHECK-NIL PORTS :BIT-ARRAY-WID))
-
- (DEFMETHOD (PORT-BOX :BIT-ARRAY-HEI) ()
- (TELL-CHECK-NIL PORTS :BIT-ARRAY-HEI))
-
- (DEFMETHOD (PORT-BOX :GRAPHICS-SHEET-SIZE) ()
- (TELL-CHECK-NIL PORTS :GRAPHICS-SHEET-SIZE))
-
- (DEFMETHOD (PORT-BOX :TOGGLE-TYPE) ()
- (TELL-CHECK-NIL PORTS :TOGGLE-TYPE))
-
- (DEFMETHOD (PORT-BOX :SET-TYPE) (TYPE)
- (TELL-CHECK-NIL PORTS :SET-TYPE TYPE))
-
- (COMMENT ;flush as soon as fasdumper works
- ;;;true names are given to boxes which are being ported to and are only assigned
- ;;;when a box merits one {which is at port creation time}. If the port is
- ;;;streamified, then the true name is stored in the port-stream and both the
- ;;;true name and the box it refers to are stored in a hash table, the...
- ;;;...*port-hash-table*
-
- (DEFMETHOD (BOX :SET-TRUE-NAME) (NEW-NAME)
- (WHEN (NULL TRUE-NAME)
- (SETQ TRUE-NAME NEW-NAME)
- (INTERN NEW-NAME 'BOXER)))
-
- (DEFMETHOD (BOX :TRUE-NAME) ()
- TRUE-NAME)
-
- (DEFMETHOD (BOX :CHANGE-TRUE-NAME) ()
- (LET ((NEW-TRUE-NAME (GENSYM)))
- (INTERN NEW-TRUE-NAME 'BOXER)
- (SETQ TRUE-NAME NEW-TRUE-NAME)))
-
- ) ;end of comment
-
-
-
- ;;; Keeping track of Ports and their targets
-
- (DEFMETHOD (BOX :APPEND-INFERIOR-PORTS) (NEW-PORTS)
- (IF (LISTP NEW-PORTS) (SETQ INFERIOR-PORTS (CL:DELETE-DUPLICATES
- (APPEND INFERIOR-PORTS NEW-PORTS)))
- (UNLESS (MEMQ NEW-PORTS INFERIOR-PORTS)
- (SETQ INFERIOR-PORTS (APPEND INFERIOR-PORTS (NCONS NEW-PORTS)))))
- (TELL-CHECK-NIL (TELL SELF :SUPERIOR-BOX) :APPEND-INFERIOR-PORTS NEW-PORTS))
-
- (DEFMETHOD (BOX :REMOVE-INFERIOR-PORTS) (OLD-PORTS)
- (IF (LISTP OLD-PORTS) (SETQ INFERIOR-PORTS (CL:SET-DIFFERENCE INFERIOR-PORTS OLD-PORTS))
- (SETQ INFERIOR-PORTS (DELQ OLD-PORTS INFERIOR-PORTS)))
- (TELL-CHECK-NIL (TELL SELF :SUPERIOR-BOX) :REMOVE-INFERIOR-PORTS OLD-PORTS))
-
- (DEFMETHOD (BOX :APPEND-INFERIOR-TARGETS) (NEW-TARGETS)
- (IF (LISTP NEW-TARGETS) (SETQ INFERIOR-TARGETS (CL:DELETE-DUPLICATES
- (APPEND INFERIOR-TARGETS NEW-TARGETS)))
- (UNLESS (MEMQ NEW-TARGETS INFERIOR-TARGETS)
- (SETQ INFERIOR-TARGETS (APPEND INFERIOR-TARGETS (NCONS NEW-TARGETS)))))
- (TELL-CHECK-NIL (TELL SELF :SUPERIOR-BOX) :APPEND-INFERIOR-TARGETS NEW-TARGETS))
-
- (DEFMETHOD (BOX :REMOVE-INFERIOR-TARGETS) (OLD-TARGETS)
- (IF (LISTP OLD-TARGETS) (SETQ INFERIOR-TARGETS
- (CL:SET-DIFFERENCE INFERIOR-TARGETS OLD-TARGETS))
- (SETQ INFERIOR-TARGETS (DELQ OLD-TARGETS INFERIOR-TARGETS)))
- (TELL-CHECK-NIL (TELL SELF :SUPERIOR-BOX) :REMOVE-INFERIOR-TARGETS OLD-TARGETS))
-
-
- ;;; in/out of the editor hierarchy
-
- ;;; Every Box needs to hack the namespace and the deallocation of screen objs
-
- (DEFMETHOD (BOX :DELETE-SELF-ACTION) ()
- (LET ((SUPERIOR-BOX (TELL SELF :SUPERIOR-BOX)))
- (SETQ SCREEN-OBJS NIL)
- ;; update inferior port information
- (UNLESS (NULL INFERIOR-PORTS)
- (DOLIST (INFERIOR-PORT INFERIOR-PORTS)
- (TELL (TELL INFERIOR-PORT :PORTS) :REMOVE-PORT INFERIOR-PORT))
- (TELL-CHECK-NIL SUPERIOR-BOX :REMOVE-INFERIOR-PORTS INFERIOR-PORTS))
- ;; update inferior target information
- (COND ((AND (NULL INFERIOR-TARGETS) (NULL PORTS)))
- ((NULL PORTS)
- (DOLIST (INFERIOR-TARGET INFERIOR-TARGETS)
- (DOLIST (P (TELL INFERIOR-TARGET :PORTS))
- (TELL P :TARGET-HAS-BEEN-DELETED-HANDLER)))
- (TELL-CHECK-NIL SUPERIOR-BOX :REMOVE-INFERIOR-TARGETS INFERIOR-TARGETS))
- ((NULL INFERIOR-TARGETS)
- (DOLIST (P PORTS)
- (TELL P :TARGET-HAS-BEEN-DELETED-HANDLER))
- (TELL-CHECK-NIL SUPERIOR-BOX :REMOVE-INFERIOR-TARGETS SELF))
- (T
- (DOLIST (INFERIOR-TARGET INFERIOR-TARGETS)
- (DOLIST (P (TELL INFERIOR-TARGET :PORTS))
- (TELL P :TARGET-HAS-BEEN-DELETED-HANDLER)))
- (DOLIST (P PORTS)
- (TELL P :TARGET-HAS-BEEN-DELETED-HANDLER))
- (TELL-CHECK-NIL SUPERIOR-BOX :REMOVE-INFERIOR-TARGETS
- (LIST* SELF INFERIOR-TARGETS))))
- ;; update the namespace
- (TELL-CHECK-NIL SUPERIOR-BOX :REMOVE-ALL-STATIC-BINDINGS SELF)))
-
- (DEFMETHOD (PORT-BOX :DELETE-SELF-ACTION) ()
- (LET ((SUPERIOR-BOX (TELL SELF :SUPERIOR-BOX)))
- (SETQ SCREEN-OBJS NIL)
- (TELL-CHECK-NIL SUPERIOR-BOX :REMOVE-ALL-STATIC-BINDINGS SELF)
- (TELL-CHECK-NIL SUPERIOR-BOX :REMOVE-INFERIOR-PORTS SELF)
- (TELL PORTS :REMOVE-PORT SELF)
- (WHEN (NULL (TELL PORTS :PORTS))
- ;; if the target has run out of ports, then inform its superior
- (TELL-CHECK-NIL (TELL PORTS :SUPERIOR-BOX) :REMOVE-INFERIOR-TARGETS PORTS))))
-
- (DEFMETHOD (BOX :INSERT-SELF-ACTION) ()
- (LET ((SUPERIOR-BOX (TELL SELF :SUPERIOR-BOX)))
- (COND-EVERY ((NAME-ROW? NAME)
- (TELL NAME :UPDATE-BINDINGS T))
- ((NOT-NULL EXPORTS)
- (TELL-CHECK-NIL SUPERIOR-BOX
- :ADD-STATIC-VARIABLE-PAIR *EXPORTING-BOX-MARKER* SELF)))
- ;; update the inferior port information
- (UNLESS (NULL INFERIOR-PORTS)
- (DOLIST (INFERIOR-PORT INFERIOR-PORTS)
- (TELL (TELL INFERIOR-PORT :PORTS) :ADD-PORT INFERIOR-PORT))
- (TELL-CHECK-NIL SUPERIOR-BOX :APPEND-INFERIOR-PORTS INFERIOR-PORTS))
- ;; update the inferior target information
- (COND ((AND (NULL INFERIOR-TARGETS) (NULL PORTS)))
- ((NULL PORTS)
- (DOLIST (INFERIOR-TARGET INFERIOR-TARGETS)
- (DOLIST (P (TELL INFERIOR-TARGET :PORTS))
- (TELL P :TARGET-HAS-BEEN-INSERTED-HANDLER INFERIOR-TARGET)))
- (TELL-CHECK-NIL SUPERIOR-BOX :APPEND-INFERIOR-TARGETS INFERIOR-TARGETS))
- ((NULL INFERIOR-TARGETS)
- (DOLIST (P PORTS)
- (TELL P :TARGET-HAS-BEEN-INSERTED-HANDLER SELF))
- (TELL-CHECK-NIL SUPERIOR-BOX :APPEND-INFERIOR-TARGETS SELF))
- (T
- (DOLIST (INFERIOR-TARGET INFERIOR-TARGETS)
- (DOLIST (P (TELL INFERIOR-TARGET :PORTS))
- (TELL P :TARGET-HAS-BEEN-INSERTED-HANDLER INFERIOR-TARGET)))
- (DOLIST (P PORTS)
- (TELL P :TARGET-HAS-BEEN-INSERTED-HANDLER SELF))
- (TELL-CHECK-NIL SUPERIOR-BOX :APPEND-INFERIOR-TARGETS
- (LIST* SELF INFERIOR-TARGETS))))))
-
- (DEFMETHOD (PORT-BOX :INSERT-SELF-ACTION) ()
- (LET ((SUPERIOR-BOX (TELL SELF :SUPERIOR-BOX)))
- (COND-EVERY ((NAME-ROW? NAME)
- (TELL NAME :UPDATE-BINDINGS T))
- ((NOT-NULL EXPORTS)
- (TELL-CHECK-NIL SUPERIOR-BOX
- :ADD-STATIC-VARIABLE-PAIR *EXPORTING-BOX-MARKER* SELF)))
- (TELL-CHECK-NIL SUPERIOR-BOX :APPEND-INFERIOR-PORTS SELF)
- ;; The inferior target information is handled here because this is the point where we can
- ;; be absolutely sure that the port has been inserted/deleted from the hierarchy.
- ;; Otherwise ABORT in the middle of port creation would result in a spurious target entry
- (TELL-CHECK-NIL PORTS :ADD-PORT SELF)
- (TELL-CHECK-NIL (TELL-CHECK-NIL PORTS :SUPERIOR-BOX) :APPEND-INFERIOR-TARGETS PORTS)))
-
- (DEFMETHOD (LL-BOX :DELETE-SELF-ACTION) ()
- ;; we don't want to remove the local library from the environment structure
- NIL)
-
- (DEFMETHOD (LL-BOX :INSERT-SELF-ACTION) ()
- NIL)
-
- (DEFUN GET-BOX-NAME (NAME-ROW)
- (IF (ROW? NAME-ROW)
- (LET ((ROW-ENTRIES (TELL NAME-ROW :ENTRIES)))
- (COND ((NULL ROW-ENTRIES) NIL)
- (T (INTERN
- (LOOP WITH NAME = ""
- FOR ENTRY IN ROW-ENTRIES
- IF (EQ ENTRY (CAR ROW-ENTRIES))
- DO (SETQ NAME (STRING ENTRY))
- ELSE
- DO (SETQ NAME (STRING-APPEND NAME (FORMAT NIL "_~A" ENTRY)))
- FINALLY
- (RETURN NAME))
- PKG-BU-PACKAGE))))
- NIL))
-
- (DEFUN MAKE-NAME-ROW (STUFF &OPTIONAL (CACHED-NAME NIL))
- (COND ((ROW? STUFF)
- STUFF)
- (T
- (LET ((ROW-STREAM (MAKE-ROW-STREAM `(:ROW . ,STUFF)))
- (NEW-ROW (MAKE-INSTANCE 'NAME-ROW ':CACHED-NAME CACHED-NAME)))
- (TELL NEW-ROW :SET-CONTENTS-FROM-STREAM ROW-STREAM NIL)
- NEW-ROW))))
-
- (DEFMETHOD (NAME-ROW :AFTER :MODIFIED) (&REST IGNORE)
- ;(TELL SELF :UPDATE-BINDINGS)
- (DOLIST (ROW (TELL SUPERIOR-BOX :ROWS))
- (TELL ROW :MODIFIED)))
-
- (DEFMETHOD (BOX :NAME-ROW) ()
- (WHEN (NAME-ROW? NAME)
- NAME))
-
- (DEFMETHOD (BOX :MAKE-NAME-ROW) ()
- (LET ((NAME-ROW (MAKE-INSTANCE 'NAME-ROW)))
- (SETQ NAME NAME-ROW)
- (TELL NAME-ROW :SET-SUPERIOR-BOX SELF)))
-
-
-
-
- ;;;; BP's
-
- (DEFUN SET-BP-ROW (BP NEW-ROW)
- (CHECK-BP-ARG BP)
- (CHECK-ROW-ARG NEW-ROW)
- (LET ((OLD-ROW (BP-ROW BP)))
- (UNLESS (EQ OLD-ROW NEW-ROW)
- (SETF (%BP-ROW BP) NEW-ROW)
- (SETF (ROW-BPS OLD-ROW) (DELQ BP (ROW-BPS OLD-ROW)))
- (SETF (ROW-BPS NEW-ROW) (CONS BP (ROW-BPS NEW-ROW))))))
-
- (DEFUN SET-BP-CHA-NO (BP NEW-CHA-NO)
- (CHECK-ARG NEW-CHA-NO 'NUMBERP "A number")
- (SETF (%BP-CHA-NO BP) NEW-CHA-NO))
-
- (DEFUN SET-BP-SCREEN-BOX (BP NEW-SCREEN-BOX)
- (CHECK-BP-ARG BP)
- (OR (NULL NEW-SCREEN-BOX) (CHECK-SCREEN-BOX-ARG NEW-SCREEN-BOX))
- (LET ((OLD-SCREEN-BOX (BP-SCREEN-BOX BP)))
- (UNLESS (EQ OLD-SCREEN-BOX NEW-SCREEN-BOX)
- (SETF (%BP-SCREEN-BOX BP) NEW-SCREEN-BOX)
- (TELL OLD-SCREEN-BOX :DELETE-BP BP)
- (TELL NEW-SCREEN-BOX :ADD-BP BP))))
-
- (DEFUN SET-BP-FROM-BP (BP FROM-BP &OPTIONAL (SCREEN-BOX-TOO? T))
- "Changes the first BP to point to the same place as the second BP without changing
- the type. "
- (CHECK-BP-ARG BP)
- (CHECK-BP-ARG FROM-BP)
- (SET-BP-CHA-NO BP (BP-CHA-NO FROM-BP))
- (SET-BP-ROW BP (BP-ROW FROM-BP))
- (WHEN SCREEN-BOX-TOO?
- (SET-BP-SCREEN-BOX BP (BP-SCREEN-BOX FROM-BP))))
-
- (DEFUN SET-BP-TYPE (BP NEW-TYPE)
- (COND ((MEMQ NEW-TYPE '(:MOVING :FIXED))
- (SETF (%BP-TYPE BP) NEW-TYPE))
- (T
- (FERROR "~S is an illegal type for a BP."))))
-
- ;;; This is useful. Note that setting a BP's Box doesn't make any sense.
-
- (DEFUN BP-BOX (BP)
- (TELL (BP-ROW BP) :SUPERIOR-BOX))
-
- ;;; Comparing BP's. BP-> returns T if <BP1> is farther along in the buffer than <BP2>.
- ;;; Note that farther along is defined in a top-to-bottom left-to-right sense and that depth
- ;;; is ignored since the function traverses upward into the lowest common superior box before
- ;;; doing the compare
-
- ;; Both rows are assumed to be in the same box.
- (DEFUN ROW-> (ROW1 ROW2 &OPTIONAL (BOX (TELL ROW1 :SUPERIOR-BOX)))
- (LOOP FOR ROW = (TELL BOX :FIRST-INFERIOR-ROW) THEN (TELL ROW :NEXT-ROW)
- UNTIL (NULL ROW)
- WHEN (EQ ROW ROW1)
- RETURN NIL
- WHEN (EQ ROW ROW2)
- RETURN T))
-
- (DEFUN ROW-< (ROW1 ROW2 &OPTIONAL (BOX (TELL ROW1 :SUPERIOR-BOX)))
- (LOOP FOR ROW = (TELL BOX :FIRST-INFERIOR-ROW) THEN (TELL ROW :NEXT-ROW)
- UNTIL (NULL ROW)
- WHEN (EQ ROW ROW2)
- RETURN NIL
- WHEN (EQ ROW ROW1)
- RETURN T))
-
- ;; this assumes that the BP's are in the same box and have already been decoded
- ;; into ROWs and CHA-NOs and returns T if the BP represented by ROW1, CHA-NO1 come FIRST
- (DEFSUBST BP-COMPARE-INTERNAL-SIMPLE (ROW1 ROW2 CHA-NO1 CHA-NO2)
- (COND ((AND (EQ ROW1 ROW2) (= CHA-NO1 CHA-NO2)) :EQUAL)
- ((AND (EQ ROW1 ROW2) (< CHA-NO1 CHA-NO2)) T)
- ((EQ ROW1 ROW2) NIL)
- ((ROW-< ROW1 ROW2) T)
- (T NIL)))
-
- ;; this gets used ONLY IF the BP's aren't in the same box
- ;; returns the BP which occurs FIRST
- ;; since we are doing all this marching up and down in box structure, we might as well also
- ;; throw back the top level box which is inferior to the lowest common superior for each BP
- ;; so that other functions won't have to do all this work
- ;; The order of the values reurned are 1) Leading BP. 2) Leading box. 3) Trailing Box
-
- (DEFSUBST BP-COMPARE-INTERNAL-HAIRY (BP1 BP2 ROW1 ROW2 BOX1 BOX2)
- (MULTIPLE-VALUE-BIND (TOP12 PATH12)
- (FIND-PATH BOX1 BOX2)
- (MULTIPLE-VALUE-BIND (TOP21 PATH21)
- (FIND-PATH BOX2 BOX1)
- (LET ((APPARENT-ROW1 (TELL-CHECK-NIL (CAR PATH21) :SUPERIOR-ROW))
- (APPARENT-ROW2 (TELL-CHECK-NIL (CAR PATH12) :SUPERIOR-ROW)))
- (COND ((AND (NULL TOP12) ;BP2 is in some inferior of BOX1
- (BP-COMPARE-INTERNAL-SIMPLE
- ROW1 APPARENT-ROW2
- (BP-CHA-NO BP1) (TELL APPARENT-ROW2 :CHA-CHA-NO (CAR PATH12))))
- (VALUES BP1 (CAR PATH21) (CAR PATH12)))
- ((NULL TOP12)
- (VALUES BP2 (CAR PATH12) (CAR PATH21)))
- ((AND (NULL TOP21) ;BP1 is in some inferior of BOX2 and
- (EQ :EQUAL ;
- (BP-COMPARE-INTERNAL-SIMPLE
- APPARENT-ROW1 ROW2
- (TELL APPARENT-ROW1 :CHA-CHA-NO (CAR PATH21)) (BP-CHA-NO BP2))))
- (VALUES BP2 (CAR PATH12) (CAR PATH21)))
- ((AND (NULL TOP21) ;BP1 is in some inferior of BOX2
- (BP-COMPARE-INTERNAL-SIMPLE
- APPARENT-ROW1 ROW2
- (TELL APPARENT-ROW1 :CHA-CHA-NO (CAR PATH21)) (BP-CHA-NO BP2)))
- (VALUES BP1 (CAR PATH21) (CAR PATH12)))
- ((NULL TOP21)
- (VALUES BP2 (CAR PATH12) (CAR PATH21)))
- ;; neither box is contained in the other
- ((BP-COMPARE-INTERNAL-SIMPLE
- APPARENT-ROW1 APPARENT-ROW2
- (TELL APPARENT-ROW1 :CHA-CHA-NO (CAR PATH21))
- (TELL APPARENT-ROW2 :CHA-CHA-NO (CAR PATH12)))
- (VALUES BP1 (CAR PATH21) (CAR PATH12)))
- (T (VALUES BP2 (CAR PATH12) (CAR PATH21))))))))
-
- (DEFUN BP-COMPARE (BP1 BP2)
- "returns the BP which occurs FIRST. If they are in the same place, the first one
- is returned. If they are on different levels, and the superior BP points to the
- Box which contains the lower BP, then the superior BP is returned. "
- (LET ((ROW1 (BP-ROW BP1)) (BOX1 (BP-BOX BP1))
- (ROW2 (BP-ROW BP2)) (BOX2 (BP-BOX BP2)))
- (COND ((AND (EQ BOX1 BOX2)
- (BP-COMPARE-INTERNAL-SIMPLE ROW1 ROW2 (BP-CHA-NO BP1) (BP-CHA-NO BP2)))
- BP1)
- ((EQ BOX1 BOX2) BP2)
- ;; so much for the simple cases, it looks like we have to do some work
- (T (BP-COMPARE-INTERNAL-HAIRY BP1 BP2 ROW1 ROW2 BOX1 BOX2)))))
-
- (DEFUN BP-< (BP1 BP2)
- (IF (EQ BP2 (BP-COMPARE BP1 BP2)) NIL T))
-
- (DEFUN BP-> (BP1 BP2)
- (IF (EQ BP1 (BP-COMPARE BP1 BP2)) NIL T))
-
- (DEFUN BP-= (BP1 BP2)
- (AND (EQ (BP-ROW BP1) (BP-ROW BP2))
- (= (BP-CHA-NO BP1) (BP-CHA-NO BP2))))
-
- ;;; These two functions take two BP's and return two BP's which are ordered according to
- ;;; location in the BUFFER and are guaranteed to be at the same level i.e. corresponding
- ;;; to rows in the same BOX. Note that when the second BP is in a subbox, the returned
- ;;; second BP's CHA-NO will be one greater than the Box's own CHA-NO so that the Box itself
- ;;; will be included in the specified region.
- ;;; Note that ORDER-BPS creates new BP's to return so we don't have to worry about accidently
- ;;; mutating something like the *POINT*
-
- (DEFUN ORDER-BPS (BP1 BP2)
- (LET ((START-BP (MAKE-BP :FIXED))
- (STOP-BP (MAKE-BP :FIXED)))
- (MULTIPLE-VALUE-BIND (FIRST-BP FIRST-BOX LAST-BOX)
- (BP-COMPARE BP1 BP2)
- (COND ((AND (NULL FIRST-BOX) (NULL LAST-BOX) ;both BPs are at the same level
- (EQ FIRST-BP BP1)) ;and are ordered correctly
- (MOVE-BP START-BP (BP-VALUES BP1)) ;place the BP's to be returned in the
- (MOVE-BP STOP-BP (BP-VALUES BP2)) ;right places
- (VALUES START-BP STOP-BP))
- ((AND (NULL FIRST-BOX) (NULL LAST-BOX))
- (MOVE-BP START-BP (BP-VALUES BP2))
- (MOVE-BP STOP-BP (BP-VALUES BP1))
- (VALUES START-BP STOP-BP))
- ;; looks like the BPs are in different boxes
- ;; first we look for the case where on BP's box is inside the other one's
- ((AND (NULL FIRST-BOX) (EQ FIRST-BP BP1)) ;the leading BP is at the right level
- (MOVE-BP START-BP (BP-VALUES BP1))
- (MOVE-BP STOP-BP (BOX-SELF-BP-VALUES LAST-BOX)) ;point to where the box is
- (SET-BP-CHA-NO STOP-BP (1+ (BP-CHA-NO STOP-BP))) ;include the box itself
- (VALUES START-BP STOP-BP))
- ((NULL FIRST-BOX)
- (MOVE-BP START-BP (BP-VALUES BP2))
- (MOVE-BP STOP-BP (BOX-SELF-BP-VALUES LAST-BOX)) ;point to where the box is
- (SET-BP-CHA-NO STOP-BP (1+ (BP-CHA-NO STOP-BP))) ;include the box itself
- (VALUES START-BP STOP-BP))
- ((AND (NULL LAST-BOX) (EQ FIRST-BP BP1)) ;the trailing BP is at the right level
- (MOVE-BP START-BP (BOX-SELF-BP-VALUES FIRST-BOX))
- (MOVE-BP STOP-BP (BP-VALUES BP2))
- (VALUES START-BP STOP-BP))
- ((NULL LAST-BOX)
- (MOVE-BP START-BP (BOX-SELF-BP-VALUES FIRST-BOX))
- (MOVE-BP STOP-BP (BP-VALUES BP1))
- (VALUES START-BP STOP-BP))
- ;; looks like neither BP was at the right level
- (T
- (MOVE-BP START-BP (BOX-SELF-BP-VALUES FIRST-BOX))
- (MOVE-BP STOP-BP (BOX-SELF-BP-VALUES LAST-BOX))
- (SET-BP-CHA-NO STOP-BP (1+ (BP-CHA-NO STOP-BP)))
- (VALUES START-BP STOP-BP))))))
-
- ;;;move-point moves the *POINT* BP
-
- (DEFUN MOVE-POINT-1 (NEW-ROW NEW-CHA-NO &OPTIONAL(NEW-SCREEN-BOX NIL))
- (UNLESS (NULL NEW-SCREEN-BOX)
- (SET-BP-SCREEN-BOX *POINT* NEW-SCREEN-BOX))
- (SET-BP-ROW *POINT* NEW-ROW)
- (SET-BP-CHA-NO *POINT* NEW-CHA-NO))
-
- (DEFUN MOVE-BP-1 (BP NEW-ROW NEW-CHA-NO &OPTIONAL (NEW-SCREEN-BOX NIL))
- (UNLESS (NULL NEW-SCREEN-BOX)
- (SET-BP-SCREEN-BOX BP NEW-SCREEN-BOX))
- (SET-BP-ROW BP NEW-ROW)
- (SET-BP-CHA-NO BP NEW-CHA-NO))
-
- (DEFUN POINT-SCREEN-BOX ()
- (BP-SCREEN-BOX *POINT*))
-
- (DEFF BP-COMPUTE-NEW-SCREEN-BOX 'IGNORE)
-
- (DEFUN BP-COMPUTE-NEW-SCREEN-BOX-OUT (OLD-BOX NEW-BOX OLD-SCREEN-BOX)
- (LET ((LEVEL (LEVEL-OF-SUPERIORITY NEW-BOX OLD-BOX))
- (NEW-SCREEN-BOX OLD-SCREEN-BOX))
- (DOTIMES (I LEVEL)
- (SETQ NEW-SCREEN-BOX (TELL NEW-SCREEN-BOX :SCREEN-BOX)))
- NEW-SCREEN-BOX))
-
- (DEFUN BP-COMPUTE-NEW-SCREEN-BOX-IN (OLD-BOX NEW-BOX OLD-SCREEN-BOX)
- (COND ((EQ NEW-BOX OLD-BOX) OLD-SCREEN-BOX)
- (T
- (TELL NEW-BOX
- :ALLOCATE-SCREEN-OBJ-FOR-USE-IN
- (BP-COMPUTE-NEW-SCREEN-BOX-IN
- OLD-BOX (TELL NEW-BOX :SUPERIOR-BOX) OLD-SCREEN-BOX)))))
-
- (DEFUN VISIBLE-SCREEN-OBJ-OF-INFERIOR-ACTUAL-OBJ (INFERIOR-ACTUAL-OBJ SUPERIOR-SCREEN-OBJ)
- (CAR (MEM #'(LAMBDA (SB SR) (TELL SR :SUPERIOR? SB)) SUPERIOR-SCREEN-OBJ
- (TELL INFERIOR-ACTUAL-OBJ :DISPLAYED-SCREEN-OBJS))))
-
- (DEFUN LOWEST-VISIBLE-BOX (SUPERIOR-SCREEN-BOX BOXES)
- (LOOP FOR N FROM 0 TO (1- (LENGTH BOXES))
- FOR BOX = (NTH N BOXES)
- FOR SCREEN-BOX = (VISIBLE-SCREEN-OBJ-OF-INFERIOR-ACTUAL-OBJ BOX SUPERIOR-SCREEN-BOX)
- WHEN (NULL SCREEN-BOX)
- RETURN (WHEN (> N 0) (NTH (1- N) BOXES))
- FINALLY (RETURN (CAR (LAST BOXES)))))
-
-
-
-
- (DEFUN BP-FORWARD-CHA-VALUES (BP &OPTIONAL (TIMES 1) (NO-OF-TIMES-TO-COUNT-CRLF 1))
- (CHECK-BP-ARG BP)
- (BP-FORWARD-CHA-VALUES-1 (BP-ROW BP) (BP-CHA-NO BP) TIMES NO-OF-TIMES-TO-COUNT-CRLF))
-
- (DEFUN BP-FORWARD-CHA-VALUES-1 (OLD-ROW OLD-CHA-NO TIMES NO-OF-TIMES-TO-COUNT-CRLF)
- (LET ((OLD-ROW-LENGTH-IN-CHAS (TELL OLD-ROW :LENGTH-IN-CHAS)))
- (COND ((<= (+ OLD-CHA-NO TIMES) OLD-ROW-LENGTH-IN-CHAS)
- ;; The destination is is this row. Our job easy.
- (VALUES OLD-ROW (+ OLD-CHA-NO TIMES)))
- ((NULL (TELL OLD-ROW :NEXT-ROW))
- ;; The destination isn't in this row, and there
- ;; is no next row. Just go the the end of this
- ;; row.
- (VALUES OLD-ROW OLD-ROW-LENGTH-IN-CHAS))
- (T
- ;; The destination isn't in this row, and there
- ;; is a next row to go to. Move the BP to the
- ;; beginning of the next row and call ourselves
- ;; recursively.
- (BP-FORWARD-CHA-VALUES-1 (TELL OLD-ROW :NEXT-ROW)
- 0
- (- TIMES
- (- OLD-ROW-LENGTH-IN-CHAS OLD-CHA-NO)
- NO-OF-TIMES-TO-COUNT-CRLF)
- NO-OF-TIMES-TO-COUNT-CRLF)))))
-
- (DEFUN BP-BACKWARD-CHA-VALUES (BP &OPTIONAL (TIMES 1) (NO-OF-TIMES-TO-COUNT-CRLF 1))
- (CHECK-BP-ARG BP)
- (BP-BACKWARD-CHA-VALUES-1 (BP-ROW BP) (BP-CHA-NO BP) TIMES NO-OF-TIMES-TO-COUNT-CRLF))
-
- (DEFUN BP-BACKWARD-CHA-VALUES-1 (OLD-ROW OLD-CHA-NO TIMES NO-OF-TIMES-TO-COUNT-CRLF)
- (COND ((<= TIMES OLD-CHA-NO)
- ;; The destination is in this row. Our job is easy.
- (VALUES OLD-ROW (- OLD-CHA-NO TIMES)))
- ((NULL (TELL OLD-ROW :PREVIOUS-ROW))
- ;; The destination isn't in this row, and there
- ;; is no previous row to go to. Just go to the
- ;; beginning of this row.
- (VALUES OLD-ROW 0))
- (T
- ;; The destination isn't in this row, and there
- ;; is a previous row to go to. Go to the end of
- ;; the previous row and call ourselves recursivley.
- (LET ((OLD-PREVIOUS-ROW (TELL OLD-ROW :PREVIOUS-ROW)))
- (BP-BACKWARD-CHA-VALUES-1 OLD-PREVIOUS-ROW
- (TELL OLD-PREVIOUS-ROW :LENGTH-IN-CHAS)
- (- TIMES
- OLD-CHA-NO
- NO-OF-TIMES-TO-COUNT-CRLF)
- NO-OF-TIMES-TO-COUNT-CRLF)))))
-
-
-
- (DEFUN CHA-BP-VALUES (CHA)
- (LET ((ROW (TELL CHA :SUPERIOR-ROW)))
- (VALUES ROW (TELL ROW :CHA-CHA-NO CHA))))
-
- (DEFUN CHA-NEXT-BP-VALUES (CHA)
- (LET ((ROW (TELL CHA :SUPERIOR-ROW)))
- (VALUES ROW (+ (TELL ROW :CHA-CHA-NO CHA) 1))))
-
- (DEFUN ROW-FIRST-BP-VALUES (ROW)
- (CHECK-ROW-ARG ROW)
- (VALUES ROW 0))
-
- (DEFUN ROW-LAST-BP-VALUES (ROW)
- (CHECK-ROW-ARG ROW)
- (VALUES ROW (TELL ROW :LENGTH-IN-CHAS)))
-
- (DEFUN BOX-FIRST-BP-VALUES (BOX)
- (CHECK-BOX-ARG BOX)
- (VALUES (TELL BOX :ROW-AT-ROW-NO 0) 0))
-
- ;; this handles boxes that may be partially scrolled
- (defun box-first-visible-bp-values (box
- &optional
- (screen-box (car (tell box :displayed-screen-objs))))
- (check-box-arg box)
- (values (or (and (screen-box? screen-box)
- (tell screen-box :scroll-to-actual-row))
- (tell box :row-at-row-no 0))
- 0))
-
- (DEFUN BOX-LAST-BP-VALUES (BOX)
- (CHECK-BOX-ARG BOX)
- (LET* ((BOX-LENGTH-IN-ROWS (TELL BOX :LENGTH-IN-ROWS))
- (LAST-ROW (TELL BOX :ROW-AT-ROW-NO (- BOX-LENGTH-IN-ROWS 1)))
- (LAST-ROW-LENGTH-IN-CHAS (TELL LAST-ROW :LENGTH-IN-CHAS)))
- (VALUES LAST-ROW LAST-ROW-LENGTH-IN-CHAS)))
-
- (DEFUN BOX-SELF-BP-VALUES (BOX)
- (CHECK-BOX-ARG BOX)
- (LET ((SUPERIOR-ROW (TELL BOX :SUPERIOR-ROW)))
- (VALUES SUPERIOR-ROW (TELL SUPERIOR-ROW :CHA-CHA-NO BOX))))
-
- (DEFUN BP-VALUES (BP)
- (CHECK-BP-ARG BP)
- (VALUES (BP-ROW BP) (BP-CHA-NO BP) (BP-SCREEN-BOX BP)))
-
- (COMPILER:MAKE-OBSOLETE SET-BP-FROM-BP "Use BP-VALUES with MOVE-BP instead")
-
-
-
- ;;; Interaction between the editor and the programming environment
- ;;; Utilities for Prompting, Documentation, Help among other things
-
- ;; start from *POINT* and move backwards until we get to a DOIT-BOX. If we are looking at
- ;; a symbol instead, then return a starting CHA-NO for the symbol in the row.
- ;; if we run into something obviously NOT a function (like a DATA-BOX) then return NIL
- (DEFUN FIND-BOX-OR-SYMBOL-START-NO (BP)
- (LET ((ROW (BP-ROW BP)))
- (IF (= 0 (BP-CHA-NO BP)) ;BP is at beginning of row
- (FIRST-CHA-FUNCTION-OR-START-NO ROW)
- (LOOP WITH INSIDE-SYMBOL-P = NIL ;set this flag after any initial whitespace ends
- FOR CHA-NO = (1- (BP-CHA-NO BP)) THEN (1- CHA-NO)
- FOR CHA = (TELL ROW :CHA-AT-CHA-NO CHA-NO)
- UNTIL (AND INSIDE-SYMBOL-P
- (MEMQ (CHA-CODE CHA) *FUNCTION-DELIMITERS*))
- WHEN (NOT (MEMQ (CHA-CODE CHA) *FUNCTION-DELIMITERS*))
- DO (SETQ INSIDE-SYMBOL-P T)
- WHEN (DOIT-BOX? CHA)
- RETURN CHA
- WHEN (= CHA-NO 0)
- RETURN CHA-NO
- WHEN (DATA-BOX? CHA)
- RETURN NIL
- WHEN (PORT-BOX? CHA)
- RETURN (WHEN (DOIT-BOX? (TELL CHA :PORTS)) (TELL CHA :PORTS))
- FINALLY
- (RETURN CHA-NO)))))
-
- (DEFUN FIRST-CHA-FUNCTION-OR-START-NO (ROW)
- (LET ((FIRST-CHA (TELL ROW :CHA-AT-CHA-NO 0)))
- (COND ((DOIT-BOX? FIRST-CHA) FIRST-CHA)
- ((DATA-BOX? FIRST-CHA) NIL)
- ((PORT-BOX? FIRST-CHA)
- (WHEN (DOIT-BOX? (TELL FIRST-CHA :PORTS)) (TELL FIRST-CHA :PORTS)))
- (T 0))))
-
- (DEFUN FIND-SYMBOL-END-NO (BP)
- (LOOP WITH ROW = (BP-ROW BP)
- FOR CHA-NO = (IF (= 0 (BP-CHA-NO BP)) 0 (1- (BP-CHA-NO BP))) THEN (1+ CHA-NO)
- FOR CHA = (TELL ROW :CHA-AT-CHA-NO CHA-NO)
- UNTIL (OR (NULL CHA) (MEMQ (CHA-CODE CHA) *FUNCTION-DELIMITERS*))
- FINALLY
- (RETURN CHA-NO)))
-
- ;; If it's not a BOX, then we have to do some work in finding the end point of the symbol
- ;; remember, we already have the starting point from the function above
- (DEFUN FIND-SYMBOL-FROM-START-NO (START-NO BP)
- (LET* ((END-NO (FIND-SYMBOL-END-NO BP))
- (ROW (BP-ROW BP))
- (START-BP (MAKE-INITIALIZED-BP :FIXED ROW START-NO))
- (END-BP (MAKE-INITIALIZED-BP :FIXED ROW END-NO))
- (STREAM (MAKE-BOXER-STREAM START-BP END-BP))
- ;;should instead, make editor streams handle :ENTRIES
- (STUFF (PARSE-LIST-FOR-EVAL (BOXER-READ STREAM NIL))))
- (TELL ROW :DELETE-BP START-BP) ;cleanup time
- (TELL ROW :DELETE-BP END-BP)
- (WHEN (SYMBOLP (CAR STUFF)) (CAR STUFF))))
-
- (DEFUN FUNCTION-AT-BP (BP)
- (LET ((FUNCTION-OR-START-NO (FIND-BOX-OR-SYMBOL-START-NO BP)))
- (COND ((NULL FUNCTION-OR-START-NO) NIL)
- ((DOIT-BOX? FUNCTION-OR-START-NO) FUNCTION-OR-START-NO)
- ((NUMBERP FUNCTION-OR-START-NO)
- (FIND-SYMBOL-FROM-START-NO FUNCTION-OR-START-NO BP))
- (T (FERROR "Can't find anything around the BP ~A" BP)))))
-
- (DEFUN FUNCTION-AT-POINT ()
- (FUNCTION-AT-BP *POINT*))
-
-
-
- ;;;;CURSOR-TRACKER
-
- ;;Given the fact that there is a variable *POINT* , we can define
- ;;these simple functions.
-
- (DEFUN POINT-BOX ()
- (BP-BOX *POINT*))
-
- (DEFUN POINT-ROW ()
- (BP-ROW *POINT*))
-
- (DEFUN POINT-CHA-NO ()
- (BP-CHA-NO *POINT*))
-
- (DEFUN POINT-SCREEN-BOX ()
- (BP-SCREEN-BOX *POINT*))
-
- (DEFUN SET-POINT-SCREEN-BOX (NEW-SCREEN-BOX)
- (SET-BP-SCREEN-BOX *POINT* NEW-SCREEN-BOX))
-
- (DEFUN POINT-CHA-AFTER-POINT ()
- (TELL (POINT-ROW) :CHA-AT-CHA-NO (POINT-CHA-NO)))
-
- (DEFF POINT-CHA 'POINT-CHA-AFTER-POINT)
-
- (DEFUN SETUP-EDITOR (&OPTIONAL (LOAD-INIT-FILE-P NIL))
- (SETQ *INITIAL-BOX* (MAKE-INITIALIZED-BOX ':TYPE ':DATA-BOX))
- (TELL *INITIAL-BOX* :SET-NAME "WORLD")
- (SET-OUTERMOST-BOX *INITIAL-BOX*) ;this calls redisplay !
- (TELL (CAR (TELL *INITIAL-BOX* :SCREEN-OBJS)) :SET-SCREEN-ROW *BOXER-PANE*)
- (TELL (CAR (TELL *INITIAL-BOX* :SCREEN-OBJS))
- :SET-SUPERIOR-SCREEN-BOX *BOXER-PANE*)
- ;; no one seems to use this an it isn't robust enough yet anyway
- ; (WHEN LOAD-INIT-FILE-P
- ; (INITIALIZE-BOXER-WORLD))
- (SETQ *POINT* (MAKE-BP ':MOVING))
- (MULTIPLE-VALUE-BIND (ROW CHA-NO)
- (BOX-FIRST-BP-VALUES *INITIAL-BOX*)
- (MOVE-POINT-1 ROW CHA-NO (CAR (TELL *INITIAL-BOX* :SCREEN-OBJS)))))
-
-
-
- ;;;; Support for scrolling (after a c-N from the bottom of a box for example)
-
- ;; Estimate the size of a row from the actual structure
- ;; we are assuming that boxes are ALWAYS bigger than chas
- ;; this assumes that the font map is already bound
- ;; it is used by ASSURE-HEAD-ROOM-IN-BOX which bind the font map
- (DEFUN ESTIMATE-ROW-HEIGHT (ROW)
- (LET ((BOXES (TELL ROW :BOXES-IN-ROW)))
- (IF (NULL BOXES)
- (LOOP FOR FONT FROM 0 TO (1- (ARRAY-LENGTH %DRAWING-FONT-MAP))
- MAXIMIZE (FONT-CHAR-HEIGHT (AREF %DRAWING-FONT-MAP FONT)))
- (LOOP FOR BOX IN BOXES
- MAXIMIZE (ESTIMATE-BOX-HEIGHT BOX)))))
-
- ;; this assumes that the font map is already bound
- ;; it is used by ASSURE-HEAD-ROOM-IN-BOX which bind the font map
- (DEFUN ESTIMATE-BOX-HEIGHT (BOX)
- (COND ((EQ (TELL BOX :DISPLAY-STYLE) ':SHRUNK)
- 27.)
- ((NUMBERP (CADDR (TELL BOX :DISPLAY-STYLE-LIST)))
- (CADDR (TELL BOX :DISPLAY-STYLE-LIST)))
- (T
- (MULTIPLE-VALUE-BIND (IGNORE TOP IGNORE BOT)
- (BOX-BORDERS-FN ':BORDER-WIDS (TELL BOX :TYPE) NIL)
- (+ TOP BOT (LOOP FOR ROW IN (TELL BOX :ROWS)
- SUMMING (ESTIMATE-ROW-HEIGHT ROW)))))))
-
- (DEFUN ASSURE-HEAD-ROOM-IN-BOX (LAST-ROW SCREEN-BOX &OPTIONAL (WINDOW *BOXER-PANE*))
- "This starts at LAST-ROW and returns the highest up row that can be the 1st row and still
- have LAST-ROW be displayed based on the current size of SCREEN-BOX. "
- (WITH-FONT-MAP-BOUND (WINDOW)
- (LET ((AVAILABLE-ROOM (MULTIPLE-VALUE-BIND (IGNORE TOP IGNORE BOT)
- (BOX-BORDERS-FN ':BORDER-WIDS
- (TELL (TELL SCREEN-BOX :ACTUAL-OBJ) :TYPE)
- NIL)
- (- (TELL SCREEN-BOX :HEI) TOP BOT))))
- (LOOP FOR ROW = LAST-ROW THEN (TELL ROW :PREVIOUS-ROW)
- FOR ROOM = (- AVAILABLE-ROOM (ESTIMATE-ROW-HEIGHT ROW))
- THEN (- ROOM (ESTIMATE-ROW-HEIGHT ROW))
- WHEN (NULL ROW)
- RETURN (TELL (TELL LAST-ROW :SUPERIOR-BOX) :FIRST-INFERIOR-ROW)
- UNTIL ( ROOM 0)
- FINALLY
- (RETURN ROW)))))
-
- (DEFUN ASSURE-LEG-ROOM-IN-BOX (ROW SCREEN-BOX)
- SCREEN-BOX ;bound but never used...
- ROW)
-
- ;; does the row have screen structure within the screen box
- (DEFMETHOD (ROW :ROW-HAS-SCREEN-STRUCTURE?)(&OPTIONAL (CURRENT-SCREEN-BOX (POINT-SCREEN-BOX)))
- (CDR (ASSQ CURRENT-SCREEN-BOX SCREEN-OBJS)))
-
- (DEFUN ENSURE-ROW-IS-DISPLAYED (ROW SCREEN-BOX &OPTIONAL (DIRECTION -1) SCROLL-ANYWAY)
- "Make sure that the screen box's scroll to actual row is such that ROW will be seen.
- a DIRECTION of 1 specifies that we are moving downward, -1 upward. "
- (WHEN (OR SCROLL-ANYWAY
- (NULL (TELL ROW :ROW-HAS-SCREEN-STRUCTURE? SCREEN-BOX))
- (TELL (TELL ROW :ALLOCATE-SCREEN-OBJ-FOR-USE-IN SCREEN-BOX) :Y-GOT-CLIPPED?))
- (TELL SCREEN-BOX :SET-SCROLL-TO-ACTUAL-ROW (IF (MINUSP DIRECTION)
- (ASSURE-HEAD-ROOM-IN-BOX ROW SCREEN-BOX)
- ;; sounds like a box is a luxury car
- (ASSURE-LEG-ROOM-IN-BOX ROW SCREEN-BOX)))))
-
-
-
- ;;;; Input Boxes
- ;;; input boxes usurp the point and recursively call the boxer editing command loop
- ;;; when the desired configuration of the input box is achieved, then the USER exits
- ;;; the box at which point the recursive command loop is THROWN out of and the desired value
- ;;; is CATCHed
-
- ;;; this will have to be moved elsewhere. Also, is there any situation in which we would need
- ;;; a REAL box to be created....
-
- (DEFUN PARSE-SELF-FOR-INPUT (BOX)
- "Make a Evdata Box from an input box without the prompt string. "
- (LOOP FOR ROW IN (GET-BOX-ROWS BOX)
- UNLESS (NULL ROW)
- COLLECT (MAKE-EVROW-FROM-ENTRIES ROW) INTO RETURN-ROWS
- FINALLY (RETURN (MAKE-EVDATA ROWS RETURN-ROWS))))
-
- (DEFMETHOD (INPUT-BOX :AFTER :EXIT) (&REST IGNORE)
- ;; return out of the inferior command-loop
- (*THROW 'BOXER-IO (PARSE-SELF-FOR-INPUT SELF)))
-
- (DEFUN MAKE-INPUT-BOX (PROMPT)
- (COND ((NULL PROMPT) (MAKE-BOX '(()) 'INPUT-BOX))
- ((EVAL-BOX? PROMPT)
- (LET ((BOX (MAKE-BOX (NCONS (LIST ";" PROMPT)) 'INPUT-BOX)))
- (TELL BOX :APPEND-ROW (MAKE-ROW '()))
- BOX))
- ((LISTP PROMPT)
- (LET ((BOX (MAKE-BOX (NCONS (APPEND '(";") PROMPT)) ':INPUT-BOX)))
- (TELL BOX :APPEND-ROW (MAKE-ROW '()))
- BOX))
- ((STRINGP PROMPT)
- (LET ((BOX (MAKE-BOX (NCONS (LIST ";" PROMPT)) ':INPUT-BOX)))
- (TELL BOX :APPEND-ROW (MAKE-ROW '()))
- BOX))
- (T (FERROR "Don't know how to make an input box from ~A" PROMPT))))
-
- (DEFUN GET-BOXER-INPUT (PROMPT)
- (LET ((INPUT-BOX (MAKE-INPUT-BOX PROMPT)))
- (UNWIND-PROTECT
- (*CATCH 'BOXER-IO
- (INSERT-CHA *POINT* INPUT-BOX)
- (REDISPLAY)
- (MOVE-POINT (BOX-LAST-BP-VALUES INPUT-BOX))
- (SET-POINT-SCREEN-BOX (CAR (TELL INPUT-BOX :SCREEN-OBJS)))
- (MINI-BOXER-COMMAND-LOOP))
- (WHEN (TELL (POINT-BOX) :SUPERIOR? INPUT-BOX)
- ;; if we are inside the input box when an ABORT hits...
- ;; we'd better get rid of it
- (SET-POINT-SCREEN-BOX (BP-COMPUTE-NEW-SCREEN-BOX-OUT (POINT-BOX)
- (TELL INPUT-BOX :SUPERIOR-BOX)
- (POINT-SCREEN-BOX)))
- (MOVE-POINT (BOX-SELF-BP-VALUES INPUT-BOX))
- (TELL (TELL INPUT-BOX :SUPERIOR-ROW) :DELETE-CHA INPUT-BOX)))))
-
-
-
- ;;;; The Boxer Status Line
- ;;; We are currently using ONE line of the *NAME-PANE*. In the future, we might want to
- ;;; expand this to several lines and make it like an EMACS typein window
-
- (DEFUN GET-BOXER-VERSION-STRING ()
- "Special versions of BOXER are indicated by SETQing *BOXER-VERSION-INFO*
- to a descriptive string. Otherwise, the release status, major and minor version numbers
- of the currently loaded system are used. "
- (MULTIPLE-VALUE-BIND (MAJOR MINOR STATUS)
- (SI:GET-SYSTEM-VERSION "Boxer")
- (IF (NULL *BOXER-VERSION-INFO*)
- (FORMAT NIL "~A BOXER ~D.~D" STATUS MAJOR MINOR)
- *BOXER-VERSION-INFO*)))
-
- (DEFUN GET-BOXER-STATUS-STRING (&OPTIONAL (OUTERMOST-BOX-NAME (TELL (OUTERMOST-BOX) :NAME)))
- (IF (NULL *EDITOR-NUMERIC-ARGUMENT*)
- (FORMAT NIL "~A | Outermost Box: ~A" (GET-BOXER-VERSION-STRING) OUTERMOST-BOX-NAME)
- (FORMAT NIL "~A | Outermost Box: ~A | Arg: ~D" (GET-BOXER-VERSION-STRING)
- OUTERMOST-BOX-NAME
- *EDITOR-NUMERIC-ARGUMENT*)))
-
- (DEFUN REQUIRED-STATUS-LINE-LENGTH (&OPTIONAL (OUTERMOST-BOX-NAME
- (TELL (OUTERMOST-BOX) :NAME)))
- (TELL *NAME-PANE* :STRING-LENGTH (FORMAT NIL "~A | Outermost Box: ~A"
- (GET-BOXER-VERSION-STRING)
- OUTERMOST-BOX-NAME)))
-
- (DEFUN REDRAW-STATUS-LINE (&OPTIONAL NEW-NAME)
- (COND ((NULL NEW-NAME)
- (TELL *NAME-PANE* :SET-CURSORPOS (REQUIRED-STATUS-LINE-LENGTH) 0)
- (TELL *NAME-PANE* #+SYMBOLICS :CLEAR-REST-OF-LINE #-SYMBOLICS :CLEAR-EOL)
- (UNLESS (NULL *EDITOR-NUMERIC-ARGUMENT*)
- (TELL *NAME-PANE* :STRING-OUT
- (FORMAT NIL " | Arg: ~D" *EDITOR-NUMERIC-ARGUMENT*))))
- (T (TELL *NAME-PANE* #+SYMBOLICS :CLEAR-WINDOW #-SYMBOLICS :CLEAR-SCREEN)
- (TELL *NAME-PANE* :STRING-OUT (GET-BOXER-STATUS-STRING NEW-NAME)))))
-
-
-
- (COMMENT
- (DEFVAR *HISTORY-LIST* NIL)
-
- (DEFUN HISTORY-RECORD-USER-ENTERED-BOX (BOX)
- (HISTORY-LIST-ADD-BOX-TO-HISTORY BOX))
-
- (DEFUN HISTORY-LIST-ADD-BOX-TO-HISTORY (BOX)
- (PUSH BOX *HISTORY-LIST*))
-
-
- (DEFUN HISTORY-RECORD-USER-CHANGED-OUTERMOST-BOX (OLD-OUTERMOST-BOX)
- (HISTORY-PANE-ADD-BOX-TO-HISTORY OLD-OUTERMOST-BOX))
-
- (DEFVAR *HISTORY-PANE-NO-OF-HISTORY-PORTS* 5.)
-
- (DEFUN SETUP-HISTORY-PANE ()
- (LET* ((NEW-BOX (MAKE-INITIALIZED-BOX ':TYPE ':DATA-BOX))
- (NEW-SCREEN-BOX (TELL NEW-BOX :ALLOCATE-SCREEN-OBJ-FOR-USE-IN
- *HISTORY-PANE*)))
- (SET-OUTERMOST-BOX NEW-BOX NEW-SCREEN-BOX *HISTORY-PANE*)))
-
- (DEFUN HISTORY-PANE-SCREEN-BOX ()
- (TELL *HISTORY-PANE* :OUTERMOST-SCREEN-BOX))
-
- (DEFUN HISTORY-PANE-SCREEN-ROW ()
- (TELL (HISTORY-PANE-SCREEN-BOX) :FIRST-SCREEN-ROW))
-
- (DEFUN HISTORY-PANE-BOX ()
- (SCREEN-OBJ-ACTUAL-OBJ (HISTORY-PANE-SCREEN-BOX)))
-
- (DEFUN HISTORY-PANE-ROW ()
- (SCREEN-OBJ-ACTUAL-OBJ (HISTORY-PANE-SCREEN-ROW)))
-
- (DEFUN HISTORY-PANE-SCREEN-HISTORY-PORT-BOX-SIZE ()
- (REDISPLAYING-WINDOW (*HISTORY-PANE*)
- (MULTIPLE-VALUE-BIND (IL IT IR IB)
- (BOX-BORDERS-FN ':BORDER-WIDS ':PORT-BOX)
- (LET ((INSIDE-WID (- (SCREEN-OBJ-WID (HISTORY-PANE-SCREEN-BOX)) IL IR))
- (INSIDE-HEI (- (SCREEN-OBJ-HEI (HISTORY-PANE-SCREEN-BOX)) IT IB)))
- (VALUES (// INSIDE-WID (+ *HISTORY-PANE-NO-OF-HISTORY-PORTS* 1))
- INSIDE-HEI)))))
-
- (DEFUN HISTORY-PANE-ADD-BOX-TO-HISTORY (BOX)
- (LET ((PORT-BOX (MAKE-INITIALIZED-BOX ':TYPE ':PORT-BOX)))
- (TELL PORT-BOX :SET-PORT-TO-BOX BOX)
- (IF (>= (TELL (HISTORY-PANE-ROW) :LENGTH-IN-CHAS)
- *HISTORY-PANE-NO-OF-HISTORY-PORTS*)
- (TELL (HISTORY-PANE-ROW) :DELETE-CHA-AT-CHA-NO 0))
- (TELL (HISTORY-PANE-ROW) :APPEND-CHA PORT-BOX)
- (MULTIPLE-VALUE-BIND (SCREEN-PORT-BOX-WID SCREEN-PORT-BOX-HEI)
- (HISTORY-PANE-SCREEN-HISTORY-PORT-BOX-SIZE)
- (LET ((SCREEN-PORT-BOX
- (TELL PORT-BOX :ALLOCATE-SCREEN-OBJ-FOR-USE-IN (HISTORY-PANE-SCREEN-BOX))))
- (TELL SCREEN-PORT-BOX :SET-DISPLAY-STYLE
- (CONS SCREEN-PORT-BOX-WID SCREEN-PORT-BOX-HEI))))))
-
- )
-