{Begin SubSec Changing The Programmer's Assistant}
{Title Changing The Programmer's Assistant}
{Text

{FnDef {FnName CHANGESLICE} {FnArgs N HISTORY {anonarg}}
{Text
Changes the time-slice of the history list {arg HISTORY} to {arg N} (see {PageRef Tag TimeSlice}).{index time-slice (of history list)}  If {arg HISTORY} is {lisp NIL}, changes both the top level history list {var LISPXHISTORY} and the edit history list {var EDITHISTORY}.


Note:  The effect of {it increasing} the time-slice is gradual: the history list is simply allowed to grow to the corresponding length before any events are forgotten.  {it Decreasing} the time-slice will immediately remove a sufficient number of the older events to bring the history list down to the proper size.
However, {index CHANGESLICE FN}{fn CHANGESLICE} is undoable, so that these events are (temporarily) recoverable.  Therefore, if the user wants to recover the storage associated with these events without waiting {arg N} more events until the {fn CHANGESLICE} event drops off the history list, he must perform a {index FORGET PACom}{pacom FORGET} command ({PageRef PACom FORGET}).
}}



{VarDef {Name PROMPT#FLG}
{Text
When this variable is set to {lisp T}, the current event number{index event number} to be printed before each prompt character.{index prompt character}  See {index PROMPTCHAR FN}{fn PROMPTCHAR}, {PageRef Fn PROMPTCHAR}.  {var PROMPT#FLG} is initially {lisp T}.
}}


{VarDef {Name PROMPTCHARFORMS}
{Text
The value of {var PROMPTCHARFORMS} is a list of expression which are evaluated each time {index PROMPTCHAR FN}{fn PROMPTCHAR} ({PageRef Fn PROMPTCHAR}) is called to print the prompt character.  If {fn PROMPTCHAR} is going to print something, it first maps down {var PROMPTCHARFORMS} evaluating each expression under an {fn ERRORSET}.  

These expressions can access the special variables {var HISTORY}{index HISTORY Var} (the current history list), {var ID}{index ID Var} (the prompt character to be printed), and {var PROMPTSTR},{index PROMPTSTR Var} which is what {fn PROMPTCHAR} will print before {var ID}, if anything.  When {var PROMPT#FLG} is {lisp T}, {var PROMPTSTR} will be the event number.  The expressions on {var PROMPTCHARFORMS} can change the shape of a cursor, update a clock, check for mail, etc. or change what {fn PROMPTCHAR} is about to print by resetting {var ID} and/or {var PROMPTSTR}.  After the expressions on {var PROMPTCHARFORMS} have been evaluated, {var PROMPTSTR} is printed if it is (still) non-{lisp NIL}, and then {var ID} is printed, if it is (still) non-{lisp NIL}.
}}



{VarDef {Name HISTORYSAVEFORMS}
{Text
The value of {var HISTORYSAVEFORMS} is a list of expressions that are evaluated under errorset protection each time {fn HISTORYSAVE} ({PageRef Fn HISTORYSAVE}) creates a new event.  This happens each time there is an interaction with the user, but not when performing an operation that is being redone.

The expressions on {var HISTORYSAVEFORMS} are presumably executed for effect, and can access the special variables {var HISTORY}{index HISTORY Var} (the current history list), {var ID}{index ID Var} (the current prompt character), and {var EVENT}{index EVENT Var} (the current event which {fn HISTORYSAVE} is going to return).
}}



Note that {var PROMPTCHARFORMS} and {var HISTORYSAVEFORMS} together enable bracketing each interaction with the user.  These can be used to measure how long the user takes to respond, to use a different readtable or terminal table, etc.


{VarDef {Name RESETFORMS}
{Text
The value of {var RESETFORMS} is a list of forms that are evaluated at each {lisp RESET}, i.e. when user types control-D, calls function {fn RESET}, or types control-C followed by {lisp START}.
}}



{VarDef {Name ARCHIVEFN}
{Text
If the {it value} of {var ARCHIVEFN} is {lisp T}, and an event is about to drop off the end of the history list and be forgotten, {var ARCHIVEFN} is called as a function with two arguments: the input portion of the event, and the entire event (see {PageRef Tag HistoryListFormat} for the format of events).  If {var ARCHIVEFN} returns {lisp T}, the event is archived on a permanent history list (see {PageRef PAcom ARCHIVE}).  Note that {var ARCHIVEFN} must be {it both} set and defined.  {var ARCHIVEFN} is initially {lisp NIL} and undefined.

For example, defining {var ARCHIVEFN} as {lisp (LAMBDA (X Y) (EQ (CAR X) 'LOAD))} will keep a record of all calls to {fn LOAD}.
}}


{VarDef {Name ARCHIVEFLG}
{Text
If the value of {var ARCHIVEFLG} is non-{lisp NIL}, the system automatically marks all events that are referenced by history commands so that they will be archived when they drop off the history list.  {var ARCHIVEFLG} is initially {lisp T}, so once an event is redone, it is guaranteed to be saved.  

An event is "marked for archiving" by putting the property {prop *ARCHIVE*}, value {lisp T}, on the event (see {PageRef Tag HistoryListFormat}).  The user could do this by means of an appropriately defined {var LISPXUSERFN} (see below).
}}



{VarDef {Name LISPXMACROS}
{Text
{var LISPXMACROS} provides a macro facility that allows the user to define his own programmer's assistant commands.  It is a list of elements of the form {lisp ({arg COMMAND} {arg DEF})}.  Whenever {arg COMMAND} appears as the first expression on a line in a {fn LISPX} input, the variable {index LISPXLINE Var}{var LISPXLINE} is bound to the rest of the line, the event is recorded on the history list, {arg DEF} is evaluated, and {arg DEF}'s value is stored as the value of the event.
Similarly, whenever {arg COMMAND} appears as {fn CAR} of a form in a {fn LISPX} input, the variable {var LISPXLINE} is bound to {fn CDR} of the form, the event is recorded, and {arg DEF} is evaluated.

An element of the form {lisp ({arg COMMAND} NIL {arg DEF})} is interpreted to mean bind {var LISPXLINE} and evaluate {arg DEF} as described above, except do {it not} save the event on the history list.
}}


{VarDef {Name LISPXHISTORYMACROS}
{Text
{var LISPXHISTORYMACROS} allows the user to define programmer's assistant commands that re-execute other events.  {var LISPXHISTORYMACROS} is interpreted the same as {var LISPXMACROS}, except that the result of evaluating {arg DEF} is treated as a list of expressions to be {it unread}, exactly as though the expressions had been retrieved by a {pacom REDO} command, or computed by a {pacom USE} command.  Note that returning {lisp NIL} means nothing else is done.  This provides a mechanism for defining {fn LISPX} commands which are executed for effect only.
}}



Many programmer's assistant commands, such as {pacom RETRIEVE}{index RETRIEVE PACom}, {pacom BEFORE}{index BEFORE PACom}, {pacom AFTER}{index AFTER PACom}, etc. are implemented through {var LISPXMACROS} or {var LISPXHISTORYMACROS}.


Note:  Definitions of commands on {var LISPXMACROS} or {var LISPXHISTORYMACROS} can be saved on files with the file package command {filecom LISPXMACROS} (see {PageRef FileCom LISPXMACROS}).


{VarDef {Name LISPXUSERFN}
{Text
When {var LISPXUSERFN} is set to {lisp T}, it is applied as a function to all inputs not recognized as a programmer's assistant command, or on {var LISPXMACROS} or {var LISPXHISTORYMACROS}.  If {var LISPXUSERFN} decides to handle this input, it simply processes it (the event was already stored on the history list before {var LISPXUSERFN} was called), sets {var LISPXVALUE}{index LISPXVALUE Var} to the value for the event, and returns {lisp T}.  The programmer's assistant will then know not to call {fn EVAL} or {fn APPLY}, and will simply store {var LISPXVALUE} into the value slot for the event, and print it.  If {var LISPXUSERFN} returns {lisp NIL}, {fn EVAL} or {fn APPLY} is called in the usual way.  Note that {var LISPXUSERFN} must be both set and defined.

{var LISPXUSERFN} is given two arguments: {arg X} and {arg LINE}.  {arg X} is the first expression typed, and {arg LINE} is the rest of the line, as read by {index READLINE FN}{fn READLINE} ({PageRef Fn READLINE}).  For example, if the user typed {lisp FOO(A B C)}, {arg X}={lisp FOO}, and {arg LINE}={lisp ((A B C))}; if the user typed {lisp (FOO A B C)}, {arg X}={lisp (FOO A B C)}, and {arg LINE}={lisp NIL}; and if the user typed {lisp FOO A B C}, {arg X}={lisp FOO} and {arg LINE}={lisp (A B C)}.

By appropriately defining (and setting) {var LISPXUSERFN}, the user can with a minimum of effort incorporate the features of the programmer's assistant into his own executive (actually it is the other way around).  For example, {var LISPXUSERFN} could be defined to parse all input (other than p.a. commands) in an alternative way.  Note that since {index LISPXUSERFN Var}{var LISPXUSERFN} is called for each input (except for p.a. commands), it can also be used to monitor some condition or gather statistics.


{note bad example from "Lunar Sciences Natural Language Information System" deleted (saved on Stuff.Lunar)  ---mjs}
}}







{FnDef {Name LISPXPRINT} {Args X Y Z NODOFLG}
}
{FnDef {Name LISPXPRIN1} {Args X Y Z NODOFLG}
}
{FnDef {Name LISPXPRIN2} {Args X Y Z NODOFLG}
}
{FnDef {Name LISPXSPACES} {Args X Y Z NODOFLG}
}
{FnDef {Name LISPXTERPRI} {Args X Y Z NODOFLG}
}
{FnDef {Name LISPXTAB} {Args X Y Z NODOFLG}
}
{FnDef {Name LISPXPRINTDEF} {Args EXPR FILE LEFT DEF TAIL NODOFLG}
{Text
In addition to saving inputs and values, the programmer's assistant saves most system messages on the history list.  For example, {lisp FILE CREATED {ellipsis}}, {lisp ({arg FN} REDEFINED)}, {lisp ({arg VAR} RESET)}, output of {fn TIME}, {fn BREAKDOWN}, {fn STORAGE}, DWIM messages, etc.  When {pacom ??} prints the event, the output is also printed.  This facility is implemented via these functions.

{indexX {Name LISPX Printing Functions}
{Text {lisp LISPX} Printing Functions} }

These functions print exactly the same as their non-{lisp LISPX} counterparts.  Then, they put the output on the history list under the property {index *PRIMARY* *LISPXPRINT* Prop}{lisp *LISPXPRINT*} (see {PageRef Tag HistoryListFormat}).

If {arg NODOFLG} is non-{lisp NIL}, these fuctions do not print, but only put their output on the history list.

To perform output operations from user programs so that the output will appear on the history list, the program needs simply to call the corresponding {lisp LISPX} printing function.
}}


{note to be consistant with non-lispx printing functions, these functions should have arg lists:
(LISPXPRINT X FILE RRDTBL NODOFLG)
(LISPXPRIN1 X FILE NODOFLG)
(LISPXPRIN2 X FILE RRDTBL NODOFLG)
(LISPXSPACES X FILE NODOFLG)
(LISPXTERPRI FILE NODOFLG)
(LISPXTAB POS MINSPACES FILE NODOFLG)
there is a problem with number of arguments....
NOT TO MENTION HOW MUCH CODE WOULD HAVE TO BE EDITTED.}


{FnDef {Name USERLISPXPRINT} {Args X FILE Z NODOFLG}
{Text
The function {fn USERLISPXPRINT}{index USERLISPXPRINT FN} is available to permit the user to define additional {lisp LISPX} printing functions.  If the user has a function {arg FN} that takes three or fewer arguments, and the second argument is the file name, he can define a {lisp LISPX} printing function by simply giving {lisp LISPX{arg FN}} the definition of {fn USERLISPXPRINT}, for example, with {lisp MOVD(USERLISPXPRINT LISPX{arg FN})}.  {fn USERLISPXPRINT} is defined to look back on the stack, find the name of the calling function, strip off the leading "{lisp LISPX}", perform the appropriate saving information, and then call the function to do the actual printing.
}}



{VarDef {Name LISPXPRINTFLG}
{Text
If {var LISPXPRINTFLG}={lisp NIL}, the {lisp LISPX} printing functions will not store their output on the history list.  {var LISPXPRINTFLG} is initially {lisp T}.
}}


}{End SubSec Changing The Programmer's Assistant}



{Begin SubSec Statistics}
{Title Statistics}
{Text

{index statistics}

The programmer's assistant keeps various statistics about system usage, e.g., number of user inputs, number of undo saves, number of calls to editor, number of edit commands, number of p.a. commands, cpu time, console time, etc.  These can be viewed via the function {fn LISPXSTATS}.  The user can define add new statistics to the p.a. statistics via the function {fn ADDSTATS}, and increment them with {fn LISPXWATCH}.


Note:  The collection of programmer's assistant statistics is not supported in Interlisp-D.  {fn ADDSTATS} and {fn LISPXWATCH} are defined with null definitions, so programs can be transferred.


{FnDef {FnName LISPXSTATS} {FnArgs RETURNVALUESFLG}
{Text
Prints programmer's assistant statistics.  If {arg RETURNVALUESFLG}={lisp T}, returns the statistics as a list of elements of the form {lisp ({arg VALUE} . {arg EXPLANATION})}.
}}


{FnDef {FnName ADDSTATS} {FnArgs STAT{sub 1} {ellipsis} STAT{sub N}}
{Type NOSPREAD NLAMBDA}
{Text
Each {arg STAT{sub i}} is a list of the form {lisp ({arg STAT-NAME} . {arg MESSAGE})}.  Each {arg STAT-NAME} is defined as the name of a new statistic.


For example, {lisp (ADDSTATS (EDITCALLS CALLS TO EDITOR) (UNDOSTATS CHANGES UNDONE)} will define two new statistics, named {lisp EDITCALLS} and {lisp UNDOSTATS}.
}}



{FnDef {FnName LISPXWATCH} {FnArgs STAT N}
{Text
Increments the statistic with name {arg STAT} by {arg N} (or 1 if {arg N}={lisp NIL}).

{fn LISPXWATCH} has a {index BLKLIBRARYDEF Prop}{prop BLKLIBRARYDEF} (see {PageRef Prop BLKLIBRARYDEF}).
}}


The user can save his statistics for loading into a new system by performing {lisp MAKEFILE(DUMPSTATS)}.  After the file {lisp DUMPSTATS} is loaded, the statistics printed by {fn LISPXSTATS} will be the same as those that would be printed following the {fn MAKEFILE}.

}{End SubSec Statistics}