{Begin SubSec Using the Loops System}
{Title Using the Loops System}
{Text


Loops is integrated with Interlisp-D, and makes use of many of its advanced features.  In order to run Loops one must have the appropriate version of the Interlisp-D system and the corresponding versions of a set of LispUsers packages.  The instructions for building the system as of February 1, 1983 are contained in a document of export instructions, currently filed on: {lisp {MAXC}<LOOPS>EXPORTINSTRUCTIONS.TXT}. 


{Begin SubSec Starting up the System}
{Title Starting up the System}
{Text

At PARC, we maintain two version of Loops most of the time, a current system which is a released version, an another which is the system under development. There are two command files: {lisp loops.cm} and {lisp newLoops.cm} which start up a Lisp and fetch the appropriate sysout from a server.

In the version of the system as loaded at PARC, we include the following Lispusers packages: {lisp TTY}, {lisp TMENU}, {lisp GRAPHER}, {lisp HISTMENU}, {lisp SINGLEFILEINDEX}, {lisp PATCHUP}

The first four packages must be included in any loadup of Loops; the second are ones we find useful.  Documentation of these facilities are to be found on {lisp <LISPUSERS>} directories on various servers.


}{End SubSec Starting up the System}



{Begin SubSec The Loops Screen Setup}
{Title The Loops Screen Setup}
{Text

The screen as one sees it set up contains the following windows(top to bottom, left to right):

{it Prompt Window} --- Small black window in upper left.  Prompts for what will happen in various mouse interactions appear here.  Also various notifications of directory attachment changes.  Labelled with the date of the Lisp system loadup and of the Loops system loadup.

{it Top Level Window} --- Normal interaction window.  Labelled with the currently connected directory.

{it User Exec -- PPDefault Window} --- Below the EditCommands menu is a title icon of the UserExec window.  When this is expanded it fills the bottom half of the screen.  It can be used for TTY interactions.  It can be made the primary window for such interactions by calling the function {fn UE}.{index UE Fn}  Typing {lisp OK} when in that window returns you to the previous {lisp TTYDIPLAYSTREAM}.   This window is also used as the default place to prettyprint class and instance descriptions.

There are three icons on the right half of the screen.

{it Loops Icon} --- This circular icon is active and if buttoned gives the user the option of setting up the screen again (useful if it has been cluttered with many windows), and of producing a graph browser of the current classes in the system.

{it History Icon} --- This icon will expand to give a History menu list.  See the write up on {lisp <LISPUSERS>HISTMENU.TTY}.

{it Edit Work Area} --- This window is shown only by a title icon in the upper right.  It expands when necessary, and takes up the entire right half of the screen.  It shrinks automatically when {lisp DoneEdit} is selected from the EditCommand menu.  It can be expanded to allow you to look at the last expression being edited.

}{End SubSec The Loops Screen Setup}



{Begin SubSec Using the Browser}
{Title Using the Browser}
{Text

{Tag LOOPSbrowser}


{note this whole section needs to be updated}


Two special classes in the system are used to build browsers based on the grapher package.  The general class is called {lisp LatticeBrowser}, and the particular subClass that is used by the system is called {lisp ClassBrowser}.  We will first describe how to use the class browser which appears when requested by buttoning in the Loops icon.  We then describe how to build your own browser.



{Begin SubSec Using the Class Browser}
{Title Using the Class Browser}
{Text

The items in the class browser can be buttoned with either the left or middle button.  When buttoned a pop up menu will appear, and the user can make a selection of one of these.

If a browser menu selection is followed by an asterisk (i.e., {lisp Print*}), this means that it has a number of sub-commands.  Selecting such a selection with the middle mouse button will present another pop-up menu of sub-commands.  Selecting a "starred" selection with the left mouse button will execute the "default" sub-command.  The left and middle mouse buttons act the same when selecting an un-starred selection.

The left button menu selections are:

{Begin LabeledList left button menu selections}

{Label {lisp Print*}{index Print* (Browser Command)}}
{Text
Prints a summary of information about the selected class in the "User Exec -- PPDefault Window".  If selected with the middle mouse button, another pop-up menu gives a choice of what to print:

{Begin LabeledList middle button Print* menu selections}

{Label {lisp PP}{index PP (Browser Command)}}
{Text PrettyPrint Class definition.}

{Label {lisp PP!}{index PP! (Browser Command)}}
{Text PrettyPrint Class definition including inherited information.}

{Label {lisp PPV!}{index PPV! (Browser Command)}}
{Text Same as {lisp PP!} without seeing methods.}

{Label {lisp PPM}{index PPM (Browser Command)}}
{Text Puts up a pop-up menu of all of the methods defined in the class, and prettyprints the definition of the selected one.}

{Label {lisp PrintSummary}{index PrintSummary (Browser Command)}}
{Text Prints a summary of all of the information (instance variables, class variables, and methods) for the selected class}

{End LabeledList middle button Print* menu selections}

If {lisp Print*} is selected with the left button, {lisp PrintSummary} is the default sub-command that is executed.
}


{Label {lisp Doc*}{index Doc* (Browser Command)}}
{Text
Prints documentation for Classes, IVs, CVs, or Methods.  If selected with the middle mouse button, another pop-up menu gives a choice of what to print:

{Begin LabeledList middle button Doc* menu selections}

{Label {lisp ClassDoc}{index ClassDoc (Browser Command)}}
{Text Prints Class doc information for selected class.}

{Label {lisp MethodDoc}{index MethodDoc (Browser Command)}}
{Text Puts up a pop-up menu of all of the methods defined in the class, and prints the doc information of the selected one.  This pop-up menu is redisplayed until the user buttons outside the menu, so that the user can see the doc information from multiple methods.}

{Label {lisp IVDoc}{index IVDoc (Browser Command)}}
{Text Same as {lisp MethodDoc}, except that it prints the doc information for instance variables of the class.}

{Label {lisp CVDoc}{index CVDoc (Browser Command)}}
{Text Same as {lisp MethodDoc}, except that it prints the doc information for class variables of the class.}

{End LabeledList middle button Doc* menu selections}

If {lisp Doc*} is selected with the left button, {lisp ClassDoc} is the default sub-command that is executed.
}

{Label {lisp WhereIs}{index WhereIs (Browser Command)}}
{Text This command is used to find out which super class of the selected class a particular IV, CV, or Method was inherited from.  When selected with the left or middle mouse button, a pop-up menu is displayed with the elements {lisp IVS}, {lisp CVS}, {lisp Methods}.  Whichever element is selected, a pop-up menu of the class' instance variables (or class variables or methods) is displayed.  When one of these is selected, the super class from which that IV, CV or Method was inherited is flashed, and its nameis printed in the Prompt Window.  This final pop-up menu is redisplayed until the user buttons outside the menu, so that the user select multiple IVs (or CVs or methods).
}

{Label {lisp Unread}{index Unread (Browser Command)}}
{Text
Unreads {lisp ${arg className}} into the typein buffer.  This is useful when typing messages to particular classes.
}

{End LabeledList left button menu selections}



The middle button menu selections are:

{Begin LabeledList middle button menu selections}


{Label {lisp EM*}{index EM* (Browser Command)}}
{Text
Edit a method in the selected class.  If selected with the middle mouse button, puts up another pop-up menu:

{Begin LabeledList middle button EM* menu selections}

{Label {lisp EM}{index EM (Browser Command)}}
{Text Puts up a pop-up menu of all of the methods defined in the class, and envokes the editor on the selected method.}

{Label {lisp EM!}{index EM! (Browser Command)}}
{Text Same as {lisp EM}, except that includes all inherited methods in the list.}

{End LabeledList middle button EM* menu selections}

If {lisp EM*} is selected with the left button, {lisp EM} is the default sub-command that is executed.
}

{Label {lisp Add*}{index Add* (Browser Command)}}
{Text
Add a new method, a specialized class, an IV, or a CV to the selected class, or make a new instance.  If selected with the middle mouse button, puts up another pop-up menu:

{Begin LabeledList middle button Add* menu selections}

{Label {lisp Specialize}{index Specialize (Browser Command)}}
{Text Creates a new subclass of the selected class, giving it a name typed by the user.}

{Label {lisp DefMethod}{index DefMethod (Browser Command)}}
{Text Define a new method to the selected class.  Asks the user (in the prompt window) to type the name of a selector, and envokes the editor on a dummy definition for that new method.}

{Label {lisp DefRSM}{index DefRSM (Browser Command)}}
{Text Installs a RuleSet as a method in a class.  Asks the user (in the prompt window) to type the name of a selector, and invokes the RuleSet editor.  When the user exits the RuleSet editor, the RuleSet is compiled and installed as the method in the class.}

{Label {lisp AddIV}{index AddIV (Browser Command)}}
{Text Asks the user to type an instance variable name, and adds it to the selected class.}

{Label {lisp AddCV}{index AddCV (Browser Command)}}
{Text Asks the user to type a class variable name, and adds it to the selected class.}

{Label {lisp New}{index New (Browser Command)}}
{Text Sets the Interlisp variable {var IT}{index IT Var} to a new instance of the selected class.}


{End LabeledList middle button Add* menu selections}

If {lisp Add*} is selected with the left button, {lisp DefMethod} is the default sub-command that is executed.
}

{Label {lisp Delete}{index Delete (Browser Command)}}
{Text
Delete a method, IV, or CV from the selected, or the whole selected class.  Puts up a pop-up menu with elements {lisp IVs}, {lisp CVs}, {lisp Methods}, and {lisp Class}.  If one of the first three is selected, a menu of the selected class' instance variables, class variables, or methods is given, and the selected one is deleted from the class.  If {lisp Class} is selected, the whole class is deleted.
}

{Label {lisp Move*}{index Move* (Browser Command)}}
{Text
Move or copy an IV, CV, method, or super from the selected class to another class.  The destination class is specified by using the {lisp BoxNode} command, described below.  If selected with the middle mouse button, puts up another pop-up menu:

{Begin LabeledList middle button Move* menu selections}

{Label {lisp MoveTo}{index MoveTo (Browser Command)}}
{Text Puts up a pop-up menu with elements {lisp IVS}, {lisp CVS}, {lisp Methods}, and {lisp Supers}.  Selecting one of these will put up still another menu, listing the items of that type.  Selecting one of these items will cause it to be moved to the destination class specified with {lisp BoxNode}. 
}

{Label {lisp CopyTo}{index CopyTo (Browser Command)}}
{Text The same as {lisp MoveTo}, except that the selected item is copied to the destination class.}

{End LabeledList middle button Move* menu selections}

If {lisp Move*} is selected with the left button, {lisp MoveTo} is the default sub-command that is executed.
}

{Label {lisp BoxNode}{index BoxNode (Browser Command)}}
{Text Draws a box around the selected class node.  If the selected class is already boxed, the box is removed.  If any other class node has been boxed, that box is removed.  This command is used in conjunction with the {lisp Move*} command to specify a "destination class", as described above.}

{Label {lisp Rename*}{index Rename* (Browser Command)}}
{Text
Renames some part of the selected class.  Puts up a pop-up menu with elements {lisp IVS}, {lisp CVS}, {lisp Methods}, and {lisp Class}.  Selecting one of these will put up still another menu, listing the items of that type.  Selecting one of these items will cause it to be renamed to a name typed in by the user.

{note why note "Rename" rather than "Rename*"?}
}

{Label {lisp Edit*}{index Edit* (Browser Command)}}
{Text
Edit some part of the selected class.    If selected with the middle mouse button, puts up another pop-up menu:

{Begin LabeledList middle button Edit* menu selections}

{Label {lisp EditObject}{index EditObject (Browser Command)}}
{Text Calls the editor to edit the selected class.}

{Label {lisp EditIVs}{index EditIVs (Browser Command)}}
{Text Calls the editor to edit the instance variables of the selected class.}

{Label {lisp EditCVs}{index EditCVs (Browser Command)}}
{Text Calls the editor to edit the class variables of the selected class.}

{Label {lisp Inspect}{index Inspect (Browser Command)}}
{Text Call the Interlisp inspector to inspect the selected class.}

{End LabeledList middle button Edit* menu selections}

If {lisp Edit*} is selected with the left button, {lisp EditObject} is the default sub-command that is executed.
}

{End LabeledList middle button menu selections}


Pressing either the left or middle mouse button in the title region at the top of the class browser brings up another pop-menu, containing commands which deal with the entire browser.  The commands are:

{Begin LabeledList title menu commands}

{Label {lisp Recompute}}
{Text
Recompute class lattice from the "starting list" of objects (described below).
}

{Label {lisp AddRoot}}
{Text
Add named item to starting list for browser.
}

{Label {lisp DeleteRoot}}
{Text
Delete named item from starting list for browser.
}

{Label {lisp SaveInIT}}
{Text
Store this browser object in the Interlisp variable {lisp IT}.
}

{End LabeledList title menu commands}



To create a Class Browser for a small set of classes, send the message {lisp Show} to the class {lisp ClassBrowser}:

{lispcode (←New ($ ClassBrowser) Show {arg browseList} {arg window})}

This displays the class inheritance lattice starting with the "starting list" of objects {arg browseList}.  {arg browseList} can be a single className or class, or a list of these.  A new browse window will be created which contains nodes for each class mentioned, and (recursively) all subclasses of those classes in the current environment which have been accessed.  If {arg window} is given, then it will be used as the display window.

{note If goodList is given, then only subclasses which are on goodList should be shown.  Not implemented yet.}


}{End SubSec Using the Class Browser}



{Begin SubSec Building Your Own Browser}
{Title Building Your Own Browser}
{Text


* * * The following information is incorrect.  If you want to build your own browser, try poking around the class {lisp LatticeBrowser}.  Good Luck. * * *


The general class which supports browsing is {lisp LatticeBrowser}.{index LatticeBrowser (Class)}  The specialization {lisp ClassBrowser}{index ClassBrowser (Class)} is used to generate the Class Inheritance Lattice Browser that we all use.  {lisp ClassBrowser} provides an example of how to specialize {lisp LatticeBrowser} for your own use.  The following is a brief description of the {lisp LatticeBrowser} messages.

If {lisp ($ Lb)} is an instance of (any subclass of) {lisp ($ LatticeBrowser)} then:

{lispcode (← ($ Lb) Show {arg browseList})}

will create a graph of elements starting with those in {arg browseList}.  {arg browseList} should be a list of objectNames or objects.  If {arg browseList} is single item, it will be treated as list of that item. The browser will show a lattice of elements determined by a sub relation implemented by the {lisp LatticeBrowser} message {lisp GetSub}.  For each object, {lisp (← ($ Lb) GetSubs {arg object})} should produce a list of objects which are the "subs" of {arg object}, and {lisp (← ($ Lb) GetLabel {arg object})} should produce a string to be used in the graph as a label.  The {lisp GetSubs} method in {lisp LatticeBrowser} just obtains the value of the instance variable {lisp sub}, if it exists in that object (no error otherwise).  The {lisp GetLabel} method in {lisp LatticeBrowser} finds the name of the object. 

Each node in the browser graph has actions associated with the left and middle mouse buttons.  When either button is clicked over a node, a menu of actions is brought up.  The items on the action menu are determined by the class variables {lisp LeftButtonItems}{index LeftButtonItems (CV of LatticeBrowser)} and {lisp MiddleButtonItems}.{index MiddleButtonItems (CV of LatticeBrowser)}  

The value obtained by selecting the menu item will be used as a message selector for an action.  The message will be sent either to the browser or to the object itself.  Selectors on the class variable {lisp LocalCommands},{index LocalCommands (CV of LatticeBrowser)} or those not understood by the object will be sent in a message to the browser, with arguments of the object and objectName.  Otherwise, the object will be sent that selector as a unary message (no arguments).

For example, assume that the value of {lisp LeftButtonItems} was {lisp (PP PP! EditObject)} and the value of {lisp LocalCommands} was {lisp NIL}, and {lisp EditObject} is not understood by {arg obj1} selected in the browser.  By buttoning {lisp PP} (or {lisp PP!}) in the action menu, {arg obj1} would be sent the message {lisp PP} (or {lisp PP!}).  Selecting {lisp EditObject} would result in sending the message {lisp (← ($ Lb) EditObject {arg obj1} (GetName {arg obj1}))}.

A {lisp LatticeBrowser} responds to {lisp EditObject} by sending the object the message {lisp Edit} {it in a TTY process}.  The latter is necessary to allow the mouse to continue to work in the process world.  If {arg obj1} might have understood the message {lisp EditObject}, then that atom should appear on the list {lisp LocalCommands} to ensure that the browser is sent the message rather than {arg obj1}.

As usual with menus, items need not be atoms.  If an item is a list, EVAL of the second element is returned.  Thus one might have the element {lisp ("Edit With EE" 'EEObject )} on a menu item list, so the string {lisp "Edit With EE"} will be displayed in the Menu, and the message {lisp EEObject} sent when that item is selected.

If the result of selecting an item returns a list, the {fn CAR} of the list is treated as the selector, and {fn CDR} is an extra argument to send.  For example, in the class browser {lisp MiddleButtonItems} contains an item {lisp (EditIVs '(EditObject -2 EE))}.  Selecting {lisp EditIVs} in the menu causes the following message to be sent: {lisp (← ($ Lb EditObject {arg object} (-2 EE))}

{it Shifted Selections} --- If one selects a node with the {lisp LEFT} or {lisp MIDDLE} mouse button while holding down the left shift key, then a message is sent to the browser:

{lispcode
(← ($ Lb) LeftShiftSelect {arg object} {arg objName})
(← ($ Lb) MiddleShiftSelect {arg object} {arg objName})}

The default behavior for {lisp LeftShiftSelect}{index LeftShiftSelect (Method of LatticeBrowser)} is to send {lisp PP!} to the object, and for {lisp MiddleShiftSelect}{index MiddleShiftSelect (Method of LatticeBrowser)} to send {lisp EEObject} to the browser.


{it Moving Nodes} --- Holding the {lisp CTRL} key down when selecting allows one to move the selected node in the browser window.  This does not affect the underlying structure, just the display.

{it Format of the Browser Window} --- One can obtain a browser display with a specified title or in an existing window.  If one specifies {arg windowOrTitle} in

{lispcode (← ($ Lb) Show {arg browseList} {arg windowOrTitle})}

then if {arg windowOrTitle} is a string, it will be used as the title of a new window for the browser.  If {arg windowOrTitle} is a window, then that window will be used as is.  If {arg windowOrTitle}={lisp NIL}, then the title is obtained from the instance variable {lisp title},{index title (IV of LatticeBrowser)} and a new window is created and stored in the instance variable {lisp window}.{index window (IV of LatticeBrowser)}  If the instance variable {lisp topAlign}={lisp T}{index topAlign (IV of LatticeBrowser)} (the default) then GRAPHER will align the graph to the top of the window.  The font used for labels is found in the instance variable {lisp browseFont}.{index browseFont (IV of LatticeBrowser)}  At any time, the last object selected is found in {lisp lastSelectedObject}.{index lastSelectedObject (IV of LatticeBrowser)}


{it SUMMARY:}  To specialize a browser, define the method for {lisp GetSubs}.  If the browser is not using object names for its labels, specialize {lisp GetLabel}.  Set up the class variables {lisp LeftButtonItems}, {lisp MiddleButtonItems} and {lisp LocalCommands}.  Specialize {lisp LeftShiftSelect} and {lisp MiddleShiftSelect} if desired.


{Def {Type (Class)} {Name LatticeBrowser} {Text}}

IV's:

{Def {Type (IV of LatticeBrowser)} {Name boxedNode}
{Text
The last object boxed, if any.
}}

{Def {Type (IV of LatticeBrowser)} {Name browseFont}
{Text
The font used for labels.
}}

{Def {Type (IV of LatticeBrowser)} {Name lastSelectedObject}
{Text
Last object selected.
}}

{Def {Type (IV of LatticeBrowser)} {Name startingList}
{Text
List of objects used to compute this browser.
}}

{Def {Type (IV of LatticeBrowser)} {Name title}
{Text
Title passed to GRAPHER package.
}}

{Def {Type (IV of LatticeBrowser)} {Name topAlign}
{Text
Flag used to indicate whether graph should be aligned with the top or bottom of the window.  If {lisp topAlign}={lisp T} (the default) then GRAPHER will align the graph to the top of the window.
}}

{Def {Type (IV of LatticeBrowser)} {Name window}
{Text
Window for browsing.
}}

CVs:

{Def {Type (CV of LatticeBrowser)} {Name LeftButtonItems}
{Text
Items for left button menu.  Value sent as message to object or browser.
}}

{Def {Type (CV of LatticeBrowser)} {Name LocalCommands}
{Text
List of messages that should be sent to browser when item is selected in menu, even if object does understand them.
}}

{Def {Type (CV of LatticeBrowser)} {Name MiddleButtonItems}
{Text
Items for middle button menu.  Value sent as message to object or browser.
}}

{Def {Type (CV of LatticeBrowser)} {Name TitleItems}
{Text
Items for menu in title of window.
}}

Methods:

{Def {Type (Method of LatticeBrowser)} {Name BoxNode} {Args browser object}
{PrintName {lisp (← {arg browser} BoxNode {arg object})}}
{Text
Draws a box around the node in the graph representing the object.
}}

{Def {Type (Method of LatticeBrowser)} {Name DoSelectedCommand} {Args browser command obj objName}
{PrintName {lisp (← {arg browser} DoSelectedCommand {arg command} {arg obj} {arg objName})}}
{Text
Does the selected command or forwards it to the object.
}}


{Def {Type (Method of LatticeBrowser)} {Name EEObject} {Args browser object objName}
{PrintName {lisp (← {arg browser} EEObject {arg object} {arg objName})}}
{Text
Edit {arg object}, using the TTYIN editor (in a {lisp TTYPROCESS}).
}}

{Def {Type (Method of LatticeBrowser)} {Name EditObject} {Args browser object objName args}
{PrintName {lisp (← {arg browser} EditObject {arg object} {arg objName} {arg args})}}
{Text
Edit {arg object} using Lisp editor (in a {lisp TTYPROCESS}), passing the commands {arg args}.
}}

{Def {Type (Method of LatticeBrowser)} {Name FlashNode} {Args browser node N flashTime}
{PrintName {lisp (← {arg browser} FlashNode {arg node} {arg N} {arg flashTime})}}
{Text
Call {lisp FlipNode} 2{arg N} times, delaying for {arg flashTime} milliseconds between flips.  Default values: {arg N}=3, {arg flashTime}=300.
}}

{Def {Type (Method of LatticeBrowser)} {Name FlipNode} {Args browser object}
{PrintName {lisp (← {arg browser} FlashNode {arg object})}}
{Text
Inverts the video around the node in the graph representing {arg object}.
}}

{Def {Type (Method of LatticeBrowser)} {Name GetLabel} {Args browser object}
{PrintName {lisp (← {arg browser} GetLabel {arg object})}}
{Text
Returns the label for {arg object} displayed in the browser.
}}

{Def {Type (Method of LatticeBrowser)} {Name GetNodeList} {Args browser browseList goodList}
{PrintName {lisp (← {arg browser} GetNodeList {arg browseList} {arg goodList})}}
{Text
Returns the node data structures of the tree starting at {arg browseList}.  If {arg goodList} is given, only include elements of it.  If {arg goodList}={lisp T}, this is the same as {arg goodList}={arg browseList}.
}}

{Def {Type (Method of LatticeBrowser)} {Name GetSubs} {Args browser object}
{PrintName {lisp (← {arg browser} GetSubs {arg object})}}
{Text
Returns a list of the subs from {arg object}.
}}

{Def {Type (Method of LatticeBrowser)} {Name LeftShiftSelect} {Args browser object objname}
{PrintName {lisp (← {arg browser} LeftShiftSelect {arg object} {arg objname})}}
{Text
Called when {arg object} is selected with the {lisp LEFT} mouse button while the shift key is down.
}}

{Def {Type (Method of LatticeBrowser)} {Name MiddleShiftSelect} {Args browser object objname}
{PrintName {lisp (← {arg browser} MiddleShiftSelect {arg object} {arg objname})}}
{Text
Called when {arg object} is selected with the {lisp MIDDLE} mouse button while the shift key is down.
}}

{Def {Type (Method of LatticeBrowser)} {Name ObjNamePair} {Args browser objOrName}
{PrintName {lisp (← {arg browser} ObjNamePair {arg objOrName})}}
{Text
{arg objOrName} may be either an object or a name used to label an object in the browser.  Returns the pair {lisp ({arg object} . {arg objName})}.
}}

{Def {Type (Method of LatticeBrowser)} {Name Recompute} {Args browser}
{PrintName {lisp (← {arg browser} Recompute)}}
{Text
Recompute the browser display using same window and {arg browseList}
}}

{Def {Type (Method of LatticeBrowser)} {Name Show} {Args browser browseList windowOrTitle goodList}
{PrintName {lisp (← {arg browser} Show {arg browseList} {arg windowOrTitle} {arg goodList})}}
{Text
Show the items and their subs on a browse window.
}}

{Def {Type (Method of LatticeBrowser)} {Name Unread} {Args browser object objName}
{PrintName {lisp (← {arg browser} Unread {arg object} {arg objName})}}
{Text
Put {lisp ${arg objName}} into the tty buffer
}}

}{End SubSec Building Your Own Browser}


}{End SubSec Using the Browser}




{Begin SubSec Editing in Loops}
{Title Editing in Loops}
{Text

{Tag LOOPSediting}


This section is about editing in Loops.  It describes the Loops interface to the standard Interlisp editors.  In addition to the usual teletype oriented editor, Interlisp-D, provides a variety of other editing programs that make available the benefits of a bitmap display and a mouse.  We will describe some of the interfaces to these editors, but leave the instruction on editing to the appropriate other documents


{Begin SubSec Editing a Class}
{Title Editing a Class}
{Text


The editor for classes is invoked by sending the message {lisp Edit}{index Edit (Message)} to the class to be edited.  The message {lisp Edit} allows an optional argument, a list of editing commands, as do all the usual Lisp editing functions.

Example:  To edit {lisp StudentEmployee}:

{lispcode (← ($ StudentEmployee) Edit)}

An alternative way to edit a class is provided by the LISP function {fn EC}{index EC Fn} (for "edit class").  {fn EC} takes the class name as its argument.  For this example, the form is:

{lisp (EC ($ StudentEmployee))}

At this point, if you prettyprint the expression you will see:

{lispcode
[DEFCLASS StudentEmployee
   (MetaClass Class)
   (Supers Student Employee)
   (InstanceVariables)
   (ClassVariables)
   (Methods)]}

Suppose now you edit this structure to the one shown below:

{lispcode
[DEFCLASS StudentEmployee
   (MetaClass Class)
   (Supers Student Employee)
   (InstanceVariables   (name) 
                     (project "KBE"))
   (ClassVariables   (numberEmployees 0))
   (Methods         (Work StudentEmployee.Work))}

This specifies that each instance will have two instance variables, {lisp name} and {lisp project}, with default values of {lisp NIL} and {lisp "KBE"}, respectively.  The class has a class variable {lisp numberEmployees}, initialized to {lisp 0}.   If we have an instance of this class bound to the Lisp variable {lisp worker}, the following expression causes this instance to respond to the message {lisp Work}: 

{lispcode (← worker Work 3)}

The result of evaluating this expression is to call the Lisp function {lisp StudentEmployee.Work} with arguments (the value of) {lisp worker} and 3.  This is described in more detail in the section on methods.

The normal way to terminate editing is with {lisp OK}.  This causes the revised definition to be installed.  If you exit from this editing session with {lisp STOP} or ↑D, all the changes of this session will be lost, since the list structure is not saved; it is only used to build the new class structure.  If you have made any syntax errors in editing, warning messages will be printed when you type {lisp OK}, and you will be returned to the editor.

}{End SubSec Editing a Class}



{Begin SubSec Editing an Instance}
{Title Editing an Instance}
{Text

To edit an instance, send it the message {lisp Edit}.{index Edit (Message)}  

{lispcode (← {arg object} Edit)}

This will put you in the Interlisp editor editing a source for the instance.  When you end with {lisp OK}, the new values will be inserted in the instance.  

An equivalent way to edit an instance is

{lispcode (EI {arg object})}{index EI Fn}

where {arg object} is an instance.  (If one has an Interlisp variable, say {lisp X1}, bound to an instance then to edit one should type {lisp (EI X1)}. 

When instances refer to other instances, they are printed out in the form {lisp #"UI&DII"}, that is as a hash mark ({lisp #}) followed by a string which is a unique identifier.  When this is read back in from the string editing buffer of TTYIN, a readmacro for {lisp #} converts it back into a pointer to an instance with that unique identifier.  When a class is printed out for TTYIN it prints as {lisp #$ClassName}, and the {lisp #} readmacro converts it bvack into a pointer to the class.

}{End SubSec Editing an Instance}


{Begin SubSec Editing a Method}
{Title Editing a Method}
{Text


Often it is convenient to type to enter only a skeletal definition for a method, and then finish making the specifications by using an editor.  To edit the function for a particular method:

{lispcode (EM {arg className} {arg selector})}{index EM Fn}

This puts you in the Lisp editor, editing whatever function is associated with the selector specified. The name of the actual function is printed out as you enter the editing process.  Aside from the syntactic convention of having the first argument to a function implementing a method be {lisp self}, these methods are perfectly normal Lisp functions.  However, special compilations can be done on these using the GLISP compiler for Loops.  This is documented in the section on Lisp interactions.

{note Methods should be documented.  DefaultComment is inserted   Loops will complain if you don't comment the methods....******}

}{End SubSec Editing a Method}

}{End SubSec Editing in Loops}



{Begin SubSec Inspecting in Loops}
{Title Inspecting in Loops}
{Text


Loops is integrated into the Lisp system so that one can invoke the Inspector on Loops objects.  This uses the Loops inspect package, which allows a specialized way of viewing the objects in Loops terms as described in the two sections below. 

{Begin SubSec Inspecting Classes}
{Title Inspecting Classes}
{Text

To inspect a class, send the message {lisp Inspect}:{index Inspect (Message)}

{lispcode (← ($ {arg className}) Inspect)}

}{End SubSec Inspecting Classes}


{Begin SubSec Inspecting Instances}
{Title Inspecting Instances}
{Text

An alternative way to modify an instance is to inspect it:

{lispcode (← {arg object} Inspect)}

and then you can set any values and properties, and add or delete any IVs.

}{End SubSec Inspecting Instances}


{note <to be completed>}

}{End SubSec Inspecting in Loops}



{Begin SubSec Errors in Loops}
{Title Errors in Loops}
{Text

Most errors in Loops which are not errors in Lisp call the function {fn HELPCHECK},{index HELPCHECK Fn} which prints out a message, and goes into a Lisp break.  The appropriate response to some errors is described below.


{Begin SubSec When the Object is Not Recognized}
{Title When the Object is Not Recognized}
{Text

When the value of {arg object} in the form

{lispcode (← {arg object} {arg selector} {arg arg{sub 1}} {ellipsis} {arg arg{sub N}})}

is not a Loops object, Loops activates the {lisp NoObjectForMsg}{index NoObjectForMsg (Method of Object)} method in the kernel class {lisp Object}. 

The response to this condition can be changed as described below.

This condition can arise if the filler refers to an object that is not in the current environment.  For example,

{lispcode (← ($ FOO) {arg selector} {arg arg{sub 1}} {ellipsis} {arg arg{sub N}})}

will cause the condition if there is no class named {lisp FOO} in the current environment.  In the default case, this causes an error.  A user can return from the error by typing

{lispcode RETURN {arg MyValue}}

to let the process continue, returning {arg MyValue} as the value that should have been returned had the method been applied successfully.

Alternatively it is possible to create user-specific responses to this condition by creating a class with a {lisp NoObjectForMsg}{index NoObjectForMsg (Message)} method and setting the global LISP variable {var DefaultObject}{index DefaultObject Var} to that class.  The arguments to the {lisp NoObjectForMsg} method are {arg object} and {arg Selector}.  This method should carry out whatever response is appropriate, apply the method that was intended, and return the value of that application.    

}{End SubSec When the Object is Not Recognized}



{Begin SubSec When the Selector is Not Recognized}
{Title When the Selector is Not Recognized}
{Text

If the object is recognized but the selector is not, then the object is sent a {lisp MessageNotUnderstood}{index MessageNotUnderstood (Message)} message as follows:

{lispcode (← {arg object} MessageNotUnderstood {arg selector})}

In most cases, this invokes the default method on the kernel class {lisp Object} which attempts to perform spelling correction.  If the correction fails, then a break is caused.  If the user then types

{lispcode RETURN {arg selector}}

to the Lisp Break Package, the selector so named will be used.

Alternatively it is possible to create user-specific responses to this condition by providing a {lisp MessageNotUnderstood} method in some super of the object.  This method should return a Lisp atom other than {lisp NIL}, which is then used as the selector as the {lisp SEND} is tried again.{note any way to simply return the value of the SEND?}  

}{End SubSec When the Selector is Not Recognized}

}{End SubSec Errors in Loops}



{Begin SubSec Breaking and Tracing Methods}
{Title Breaking and Tracing Methods}
{Text

{FnDef {Name BreakMethod} {Args className selector}
{Text
This function will break the method called by {arg selector} in the specified class.  It will find the function name and break it, even if the selector is only found in a superclass.  All calls to that function will be broken, even ones that do not come from className.
}}

{FnDef {Name TraceMethod} {Args className selector}
{Text
Similar to {fn BreakMethod}, except that it traces the appropriate method.
}}


The Lisp function {fn UNBREAK} will unbreak the function which was broken.

}{End SubSec Breaking and Tracing Methods}



{Begin SubSec Monitoring Variable Access}
{Title Monitoring Variable Access}
{Text


{FnDef {Name BreakIt} {Args self varName propName type breakOnGetAlsoFlg}
{Text
This function is used for causing an Interlisp break when the value of a variable or property is set or fetched.  The {arg type} argument is one of {lisp IV}, {lisp CV}, {lisp METHOD}, or {lisp CLASS} for instance variables, class variables, method properties, or class properties respectively.  If it is {lisp NIL}, then {lisp IV} is assumed.  If {arg propName} is {lisp NIL}, then type must be {lisp IV} or {lisp CV} and {fn BreakIt} refers to the value of a variable.

If {arg breakOnGetAlsoFLg} is {lisp NIL} then the break is only entered when an attempt is made to store into the value.  If {arg breakOnGetAlsoFLg} is {lisp T}, then breaks will also occur on attempts to fetch the value.  
}}


{FnDef {Name TraceIt} {Args self varName propName type traceOnGetAlsoFlg}
{Text
Similar to {fn BreakIt}, except that it will trace the value of a variable or property, printing the old and new values when the variable or property is accessed.
}}


{FnDef {Name UnBreakIt} {Args self varName propName type}
{Text
This function is used to remove monitoring (breaking or tracing) for the specified variable or property.  If {arg self}={lisp NIL}, then all known breaks and traces are removed.
}}


}{End SubSec Monitoring Variable Access}



}{End SubSec Using the Loops System}