{Begin SubSec Terminal Tables} {Title Terminal Tables} {Text {Tag TerminalTables} {index *BEGIN* terminal tables} A readtable contains input/output information that is {it media-independent}. For example, the action of parentheses is the same regardless of the device from which the input is being performed. A terminal table is an object that contains information that pertains to {it terminal} input/output operations only, such as the character to type to delete the last character or to delete the last line. In addition, terminal tables contain such information as how line-buffering is to be performed, how control characters are to be echoed/printed, whether lower case input is to be converted to upper case, etc. Using the functions below, the user may change, reset, or copy terminal tables, or create a new terminal table and install it as the primary terminal table{index primary terminal table} via {fn SETTERMTABLE}. However, unlike readtables, terminal tables cannot be passed as arguments to input/output functions. {Begin SubSec Terminal Table Functions} {Title Terminal Table Functions} {Text {FnDef {FnName TERMTABLEP} {FnArgs TTBL} {Text Returns {arg TTBL}, if {arg TTBL} is a real terminal table, {lisp NIL} otherwise. }} {FnDef {FnName GETTERMTABLE} {FnArgs TTBL} {Text If {arg TTBL}={lisp NIL}, returns the primary (i.e., current) terminal table. If {arg TTBL} is a real terminal table, return {arg TTBL}. Otherwise, generates an {lisp ILLEGAL TERMINAL TABLE}{index ILLEGAL TERMINAL TABLE Error} error. }} {FnDef {FnName SETTERMTABLE} {FnArgs TTBL} {Text Sets the primary terminal table to be {arg TTBL}. Returns the previous {arg TTBL}. Generates an {lisp ILLEGAL TERMINAL TABLE}{index ILLEGAL TERMINAL TABLE Error} error if {arg TTBL} is not a real terminal table. }} {FnDef {FnName COPYTERMTABLE} {FnArgs TTBL} {Text Returns a copy of {arg TTBL}. {arg TTBL} can be a real terminal table, {lisp NIL}, or {lisp ORIG}, in which case it returns a copy of the {it original} system terminal table. Note that {fn COPYTERMTABLE} is the only function that {it creates} a terminal table. }} {FnDef {FnName RESETTERMTABLE} {FnArgs TTBL FROM} {Text Copies (smashes) {arg FROM} into {arg TTBL}. {arg FROM} and {arg TTBL} can be {lisp NIL} or a real terminal table. In addition, {arg FROM} can be {lisp ORIG}, meaning to use the system's original terminal table. }} }{End SubSec Terminal Table Functions} {Begin SubSec Terminal Syntax Classes} {Title Terminal Syntax Classes} {Text {index terminal syntax classes} A terminal table associates with each character a single "terminal syntax class", one of {lisp CHARDELETE}, {lisp LINEDELETE}, {lisp WORDDELETE} (Interlisp-D only), {lisp RETYPE}, {lisp CTRLV}, {lisp EOL}, and {lisp NONE}. Unlike readtable classes, only one character in a particular terminal table can belong to each of the classes (except for the default class {lisp NONE}). When a new character is assigned one of these syntax classes by {fn SETSYNTAX}, the previous character is disabled (i.e., reassigned the syntax class {lisp NONE}), and the value of {fn SETSYNTAX} is the code for the previous character of that class, if any, otherwise {lisp NIL}. The terminal syntax classes are interpreted as follows: {Begin LabeledList terminal syntax classes} {Name {lisp CHARDELETE} or {lisp DELETECHAR}{index CHARDELETE (syntax class)}{index DELETECHAR (syntax class)}} {Text (Initially control-A{index control-A} under Tenex, del{index del} under Tops20, BackSpace{index BackSpace} in Interlisp-D) Typing this character deletes the previous character typed. Repeated use of this character deletes successive characters back to the beginning of the line. } {Name {lisp LINEDELETE} or {lisp DELETELINE}{index LINEDELETE (syntax class)}{index DELETELINE (syntax class)}} {Text (Initially control-Q{index control-Q} in Interlisp-10 under Tenex and in Interlisp-D, control-U{index control-U} under Tops20) Typing this character deletes the whole line; it cannot be used repeatedly. } {Name {lisp WORDDELETE}{index WORDDELETE (syntax class)}} {Text (Interlisp-D only; initially control-W){index control-W} Typing this character deletes the previous "word", i.e., sequence of non-separator characters. } {Name {lisp RETYPE}{index RETYPE (syntax class)}} {Text (Initially control-R){index control-R} Causes the line to be retyped as Interlisp sees it (useful when repeated deletions make it difficult to see what remains). } {Name {lisp CTRLV} or {lisp CNTRLV}{index CTRLV (syntax class)}{index CNTRLV (syntax class)}} {Text (Initially control-V){index control-V} When followed by {lisp A}, {lisp B}, {ellipsis} {lisp Z}, inputs the corresponding control character control-A, control-B, {ellipsis} control-Z. This allows interrupt characters to be input without causing an interrupt. } {Name {lisp EOL}{index EOL (syntax class)}} {Text On input from a terminal, the {lisp EOL} character signals to the line buffering routine to pass the input back to the calling function. It also is used to terminate inputs to {fn READLINE} ({PageRef Fn READLINE}). In general, whenever the phrase carriage-return linefeed is used, what is meant is the character with terminal syntax class {lisp EOL}. } {Name {lisp NONE}{index NONE (syntax class)}} {Text The terminal syntax class of all other characters. } {End LabeledList terminal syntax classes} {note currently, DELETECHAR and DELETELINE are not accepted by Interlisp-D as valid terminal syntax classes, but CNTRLV is.} {fn GETSYNTAX}, {fn SETSYNTAX}, and {fn SYNTAXP} all work on terminal tables as well as readtables (see {PageRef Fn GETSYNTAX}). When given {lisp NIL} as a {arg TABLE} argument, {fn GETSYNTAX} and {fn SYNTAXP} use the primary readtable{index primary readtable} or primary terminal table{index primary terminal table} depending on which table contains the indicated {arg CLASS} argument. For example, {lisp (SETSYNTAX {arg CH} 'BREAK)} refers to the primary readtable, and {lisp (SETSYNTAX {arg CH} 'CHARDELETE)} refers to the primary terminal table. In the absence of such information, all three functions default to the primary readtable; e.g., {lisp (SETSYNTAX '{lbracket} '%[)} refers to the primary read table. If given incompatible {arg CLASS} and table arguments, all three functions generate errors. For example, {lisp (SETSYNTAX {arg CH} 'BREAK {arg TTBL})}, where {arg TTBL} is a terminal table, generates an {lisp ILLEGAL READTABLE}{index ILLEGAL READTABLE Error} error, and {lisp (GETSYNTAX 'CHARDELETE {arg RDTBL})} generates an {lisp ILLEGAL TERMINAL TABLE}{index ILLEGAL TERMINAL TABLE Error} error. {Note currently, WORDDELETE is not in Interlisp-10. Will it ever get put in??} {Note WORDDELETE doesn't show up in Interlisp-D when inspecting a termtable. --mjs} {index *END* syntax classes} }{End SubSec Terminal Syntax Classes} {Begin SubSec Terminal Control Functions} {Title Terminal Control Functions} {Text {index echoing} {index control character echoing} {FnDef {FnName ECHOCONTROL} {FnArgs CHAR MODE TTBL} {Text Used to indicate how control characters are to be echoed or printed. {arg CHAR} is a character or character code. {arg MODE} may be one of the atoms {lisp IGNORE}, {lisp REAL}, {lisp SIMULATE}, or {lisp INDICATE},{foot {lisp UPARROW} is an obsolete synonym of {lisp INDICATE}. }{comment endfootnote} which specify how the control character should be printed: {Begin LabeledList ECHOCONTROL MODE argument} {Name {lisp IGNORE}} {Text {arg CHAR} is never printed.} {Name {lisp REAL}} {Text {arg CHAR} itself is printed; i.e., the raw control character is sent to the terminal. Some terminals, particularly displays, respond to certain control characters in interesting ways.} {Name {lisp SIMULATE}} {Text Output of {arg CHAR} is simulated. For example, control-I (tab) may be simulated by printing spaces. The simulation is machine-specific and beyond the control of the user.} {Name {lisp INDICATE}} {Text {arg CHAR} is printed as {lisp ^} followed by the corresponding alphabetic character.} {End LabeledList ECHOCONTROL MODE argument} The value of {fn ECHOCONTROL} is the previous output mode for {arg CHAR}. If {arg MODE}={lisp NIL}, {fn ECHOCONTROL} returns the current output mode without changing it. Note that although the name of this function suggests echoing only, it affects {it all} output of the control character, both echoing of input and printing of output. The two cannot be specified independently, which can lead to some trickiness in {fn DELETECONTROL} messages (below). In Interlisp-10, echoing information can be specified only for control characters (although {it all} echoing can be disabled using {fn ECHOMODE}, below). Therefore, if {arg CHAR} is an alphabetic character (or code), it refers to the corresponding control character, e.g., {lisp (ECHOCONTROL 'Z 'INDICATE)} makes control-Z echo as {lisp ^Z}. All other values of {arg CHAR} generate {lisp ILLEGAL ARG} errors.{index ILLEGAL ARG Error} In Interlisp-D and Interlisp-VAX, it is possible to specify echoing information for {it all} characters, using the function {fn ECHOCHAR}. }} {FnDef {FnName ECHOCHAR} {FnArgs CHARCODE MODE TTBL} {Text (Interlisp-D, Interlisp-VAX only) Like {fn ECHOCONTROL}, but {arg CHARCODE} must be a character code, and can specify {it any} character{emdash}no coercions are performed. The {lisp INDICATE} mode for "meta" characters, i.e., characters whose codes are in the range 200Q through 377Q, causes the character to be printed following a {lisp #}. For example, meta-A would print as {lisp #A}, meta-control-B as {lisp #^B}. {arg CHARCODE} can also be a list of characters, in which case {fn ECHOCHAR} is applied to each of them with arguments {arg MODE} and {arg TTBL}. }} {FnDef {FnName ECHOMODE} {FnArgs FLG TTBL} {Text If {arg FLG}={lisp T}, turns echoing for terminal table {arg TTBL} on. If {arg FLG}={lisp NIL}, turns echoing off. Returns the previous setting. }} {FnDef {FnName GETECHOMODE} {FnArgs TTBL} {Text Returns the current echo mode for {arg TTBL}. }} {FnDef {FnName DELETECONTROL} {FnArgs TYPE MESSAGE TTBL} {Text Specifies the output protocol when a {lisp CHARDELETE}{index CHARDELETE (syntax class)} or {lisp LINEDELETE}{index LINEDELETE (syntax class)} is typed. In the case of character deletion, Interlisp-10 is initially set up for hardcopy terminals: it echos the characters being deleted, preceding the first by a {lisp \} and following the last by a {lisp \}, so that it is easy to see exactly what was deleted, viz., the characters between the {lisp \}'s. Interlisp-D and Interlisp-VAX are initially set up to physically erase the deleted characters from the display, backing up over them. The various values of {arg TYPE} specify different phases of the deletion, as follows:{index control-A}{index control-Q} {Begin LabeledList interpretations of TYPE} {Label {lisp 1STCHDEL}} {Text {arg MESSAGE} is the message printed the first time {lisp CHARDELETE} is typed. Initially "{lisp \}" in Interlisp-10.{index \ (Printed by System)} } {Label {lisp NTHCHDEL}} {Text {arg MESSAGE} is the message printed on subsequent {lisp CHARDELETE}'s (without intervening characters). Initially "" in Interlisp-10. } {Label {lisp POSTCHDEL}} {Text {arg MESSAGE} is the message printed when input is resumed following a sequence of one or more {lisp CHARDELETE'}s. Initially "{lisp \}" in Interlisp-10.{index \ (Printed by System)} } {Label {lisp EMPTYCHDEL}} {Text {arg MESSAGE} is the message printed when a {lisp CHARDELETE} is typed and there are no characters in the buffer. Initially "{lisp ##{CRsymbol}}" in Interlisp-10.{index ## (Printed by System)} } {Label {lisp ECHO}} {Text The characters deleted by {lisp CHARDELETE} are echoed. {arg MESSAGE} is ignored. } {Label {lisp NOECHO}} {Text The characters deleted by {lisp CHARDELETE} are not echoed {arg MESSAGE} is ignored. } {Label {lisp LINEDELETE}} {Text {arg MESSAGE} is the message printed when {lisp LINEDELETE} character is typed. Initially "{lisp ##{CRsymbol}}".{index ## (Printed by System)} } {End LabeledList interpretations of TYPE} Note: In Interlisp-10, the {lisp LINEDELETE}, {lisp 1STCHDEL}, {lisp NTHCHDEL}, {lisp POSTCHDEL}, and {lisp EMPTYCHDEL} messages must be 4 characters or fewer in length. {fn DELETECONTROL} returns the previous message as a string. If {arg MESSAGE}={lisp NIL}, the value returned is the previous message without changing it. For {lisp ECHO} and {lisp NOECHO}, the value of {fn DELETECONTROL} is the previous echo mode, i.e., {lisp ECHO} or {lisp NOECHO}. {note which is lousy, because it means you can't do (RESETSAVE NIL (LIST 'DELETECONTROL type (DELETECONTROL type newvalue))) without regard to TYPE.} }} {FnDef {FnName GETDELETECONTROL} {FnArgs TYPE TTBL} {Text Returns the current {fn DELETECONTROL} mode for {arg TYPE} in {arg TTBL}. }} If the user's terminal is a display, {fn DELETECONTROL} and {fn ECHOCONTROL} can be used to make it really delete the last character by performing the following: {Begin LabeledList Backspace kludge} {Label {lisp (ECHOCONTROL 8 'REAL)}} {Item 8 is the code for control-H, which is backspace; we want the terminal to really backspace when we send {lisp ^H}. } {Label {lisp (DELETECONTROL 'NOECHO)}} {Item Do not echo the deleted characters.} {Label {lisp (DELETECONTROL '1STCHDEL "^H ^H")}} {Label {lisp (DELETECONTROL 'NTHCHDEL "^H ^H")}} {Item Erase each character by backspacing over it, printing a space, then backspacing again to put the carriage in the right place.} {End LabeledList Backspace kludge} The following functions manipulate the {fn RAISE} mode, which determines whether lower case characters are converted to upper case when input from the terminal. (There currently is no "raise" mode for input from files.) {index lower case input} {FnDef {FnName RAISE} {FnArgs FLG TTBL} {Text Sets the {fn RAISE} mode for terminal table {arg TTBL}. If {arg FLG}={lisp NIL}, all characters are passed as typed. If {arg FLG}={lisp T}, input is echoed as typed, but lowercase letters are converted to upper case. If {arg FLG}={lisp 0}, input is converted to upper case {it before} it is echoed. Returns the previous setting. }} {FnDef {FnName GETRAISE} {FnArgs TTBL} {Text Returns the current {fn RAISE} mode for {arg TTBL}. }} }{End SubSec Terminal Control Functions} {Begin SubSec Line-Buffering} {Title Line-Buffering} {Text {index *BEGIN* line-buffering} {index *PRIMARY* line-buffering} Characters typed at the terminal are stored in two buffers before they are passed to an input function. All characters typed in are put into the low-level "system buffer",{index *PRIMARY* system buffer} which allows type-ahead. When an input function is entered, characters are transferred to the "line buffer"{index *PRIMARY* line buffer} until a character with terminal syntax class {lisp EOL} appears (or, for calls from {fn READ}, when the count of unbalanced open parentheses{index parentheses counting by READ} reaches 0).{foot {fn PEEKC} is an exception; it returns the character immediately when its second argument is {lisp NIL}. }{comment endfootnote} Until this time, the user can delete characters one at a time from the line buffer by typing the current {lisp CHARDELETE} character, or delete the entire line buffer back to the last carriage-return by typing the current {lisp LINEDELETE}. Note that this line editing is {it not} performed by {fn READ} or {fn RATOM}, but by Interlisp, i.e., it does not matter (nor is it necessarily known) which function will ultimately process the characters, only that they are still in the Interlisp line buffer. However, the function that is requesting input at the time the buffering starts does determine whether parentheses counting{index parentheses counting by READ} is observed. For example, if a program performs {lisp (PROGN (RATOM) (READ))} and the user types in "{lisp A (B C D)}", the user must type in the carriage-return following the right parenthesis before any action is taken, because the line buffering is happening under {fn RATOM}. If the program had performed {lisp (PROGN (READ) (READ))}, the line-buffering would be under {fn READ}, so that the right parenthesis would terminate line buffering, and no terminating carriage-return would be required. Once a carriage-return has been typed, the entire line is "available" even if not all of it is processed by the function initiating the request for input. If any characters are "left over", they are returned immediately on the next request for input. For example, {lisp (LIST (RATOM) (READC) (RATOM))} when the input is "{lisp A B{CRsymbol}}" returns the three-element list {lisp (A % B)} and leaves the carriage-return in the buffer. If a carriage-return is typed when the input under {fn READ} is not "complete" (the parentheses are not balanced or a string is in progress), line buffering continues, but the lines completed so far are not available for editing with {lisp CHARDELETE} or {lisp LINEDELETE}. The function {fn CONTROL} is available to defeat line-buffering: {FnDef {FnName CONTROL} {FnArgs MODE TTBL} {Text If {arg MODE}={lisp T}, eliminates Interlisp's normal line-buffering for the terminal table {arg TTBL}. If {arg MODE}={lisp NIL}, restores line-buffering (normal). When operating with a terminal table in which {lisp (CONTROL T)} has been performed, characters are returned to the calling function without line-buffering as described below. {fn CONTROL} returns its previous setting. }} {FnDef {FnName GETCONTROL} {FnArgs TTBL} {Text Returns the current control mode for {arg TTBL}. }} The function that initiates the request for input determines how the line is treated when {lisp (CONTROL T)} is in effect: {Begin LabeledList function that initiates the request} {Label {fn READ}} {Text {index READ FN}If the expression being typed is a list, the effect is the same as though done with {lisp (CONTROL NIL)}, i.e., line-buffering continues until a carriage-return or matching parentheses. If the expression being typed is not a list, it is returned as soon as a break or separator character{index break characters}{index separator characters} is encountered, e.g., {lisp (READ)} when the input is "{lisp ABC}" immediately returns {lisp ABC}. {lisp CHARDELETE} and {lisp LINEDELETE} are available on those characters still in the buffer. Thus, if a program is performing several reads under {lisp (CONTROL T)}, and the user types "{lisp NOW IS THE TIME}" followed by control-Q, only {lisp TIME} is deleted, since the rest of the line has already been transmitted to {fn READ} and processed. An exception to the above occurs when the break or separator character is an opening parenthesis, bracket or double-quote, since returning at this point would leave the line buffer in a "funny" state. Thus if the input to {lisp (READ)} is "{lisp ABC(}", the {lisp ABC} is not read until a carriage-return or matching parentheses is encountered. In this case the user could {lisp LINEDELETE} the entire line, since all of the characters are still in the buffer. } {Label {fn RATOM}} {Text {index RATOM FN}Characters are returned as soon as a break or separator character is encountered. Until then, {lisp LINEDELETE} and {lisp CHARDELETE} may be used as with {fn READ}. For example, {lisp (RATOM)} followed by "{lisp ABC}" returns {lisp AB}. {lisp (RATOM)} followed by "{lisp (}" returns {lisp (} and types {lisp ##}{index ## (Printed by System)} indicating that control-A was attempted with nothing in the buffer, since the {lisp (} is a break character and would therefore already have been read. } {Label {fn READC} or {fn PEEKC}} {Text {index READC FN}{index PEEKC FN}The character is returned immediately; no line editing is possible. In particular, {lisp (READC)} is perfectly happy to return the {lisp CHARDELETE} or {lisp LINEDELETE} characters, or the {fn ESCAPE} character ({lisp %}){index % (escape character)}. } {End LabeledList function that initiates the request} The system buffer and line buffer can be directly manipulated using the following functions. {FnDef {FnName CLEARBUF} {FnArgs FILE FLG} {Text Clears the input buffer{index input buffer} for {arg FILE}. If {arg FILE} is {lisp T} and {arg FLG} is {lisp T}, the contents of Interlisp's system buffer{index system buffer} and line buffer{index line buffer} are saved (and can be obtained via {index SYSBUF FN}{fn SYSBUF} and {index LINBUF FN}{fn LINBUF} described below). When {index control-D}control-D or {index control-E}control-E is typed, or any of the interrupt characters that require terminal interaction is typed ({index control-H}control-H, {index control-P}control-P, or {index control-S}control-S), Interlisp automatically performs {lisp (CLEARBUF T T)}. For control-P, control-S, and, when the break is exited normally, control-H, Interlisp restores the buffer after the interaction. The action of {lisp (CLEARBUF T)}, i.e., clearing of typeahead, is also available as the {lisp RUBOUT} interrupt character, initially assigned to the del key{index del} in Interlisp-D and in Interlisp-10 under Tenex, control-Z under Tops20{index control-Z (TOPS-20) Term}. Note that this interrupt clears both buffers at the time it is {it typed}, whereas the action of the {lisp CHARDELETE} and {lisp LINEDELETE} character occur at the time they are {it read}. }} {FnDef {FnName SYSBUF} {FnArgs FLG} {Text If {arg FLG}={lisp T}, returns the contents of the system buffer{index system buffer} (as a string) that was saved at the last {lisp (CLEARBUF T T)}. If {arg FLG}={lisp NIL}, clears this internal buffer. }} {FnDef {FnName LINBUF} {FnArgs FLG} {Text Same as {fn SYSBUF} for the line buffer{index line buffer}. }} If both the system buffer and Interlisp's line buffer are empty, the internal buffers associated with {fn LINBUF} and {fn SYSBUF} are not changed by a {lisp (CLEARBUF T T)}. {FnDef {FnName BKSYSBUF} {FnArgs X FLG RDTBL} {Text {fn BKSYSBUF} sets the system buffer to the {fn PRIN1}-name of {arg X}. The effect is the same as though the user typed {arg X}. Some implementations have a limit on the length of {arg X}, in which case characters in {arg X} beyond the limit are ignored. Returns {arg X}. If {arg FLG} is {arg T}, then the {fn PRIN2}-name of {arg X} is used, computed with respect to the readtable {arg RDTBL}. Note that if the user is typing at the same time as the {fn BKSYSBUF} is being performed, the relative order of the type-in and the characters of {arg X} is unpredictable. Compatibility note: Some implementations of {fn BKSYSBUF} (Interlisp-10) use a "system" buffer, from which keyboard interrupts are also processed. In this case, {fn BKSYSBUF} of an interrupt character actually invokes the interrupt at some (asynchronous) time after the {fn BKSYSBUF} is initiated. In other implementations (Interlisp-D), the characters are not processed for interrupts, and it is possible to {fn BKSYSBUF} characters which would otherwise be impossible to type. }} {Begin Note} Date: 12 AUG 83 00:24 PDT From: MASINTER.PA Subject: FLG and RDTBL args for MKSTRING and BKSYSBUF I have fixed Interlisp-10 also to allow FLG and RDTBL arguments for MKSTRING and BKSYSBUF. This is a slightly incompatible change for BKSYSBUF: it used to be that BKSYSBUF((A)) didn't do ANYTHING and now it actually bksysbuf's the PRIN1-pname of (A). {End Note} {FnDef {FnName BKLINBUF} {FnArgs STR} {Text {arg STR} is a string. {fn BKLINBUF} sets Interlisp's line buffer to {arg STR}. Some implementations have a limit on the length of {arg STR}, in which case characters in {arg STR} beyond the limit are ignored. Returns {arg STR}. }} {index BKLINBUF FN}{fn BKLINBUF}, {index BKSYSBUF FN}{fn BKSYSBUF}, {index LINBUF FN}{fn LINBUF}, and {index SYSBUF FN}{fn SYSBUF} provide a way of "undoing" a {index CLEARBUF FN}{fn CLEARBUF}. Thus to "peek" at various characters in the buffer, one could perform {lisp (CLEARBUF T T)}, examine the buffers via {fn LINBUF} and {fn SYSBUF}, and then put them back. The more common use of these functions is in saving and restoring typeahead when a program requires some unanticipated (from the user's standpoint) input. The function {fn RESETBUFS} provides a convenient way of simply clearing the input buffer, performing an interaction with the user, and then restoring the input buffer. {FnDef {FnName RESETBUFS} {FnArgs FORM{SUB 1} FORM{SUB 2} {ellipsis} FORM{SUB N}} {Type NOSPREAD NLAMBDA} {Text Clears any typeahead (ringing the terminal's bell if there was, indeed, typeahead), evaluates {arg FORM{sub 1}}, {arg FORM{sub 2}},{ellipsis} {arg FORM{sub N}}, then restores the typeahead. Returns the value of {arg FORM{sub N}}. Compiles open. }} {index *END* line-buffering} }{End SubSec Line-Buffering} {index *END* terminal tables} }{End SubSec Terminal Tables} a»GACHA a»z¸