;;; -*- Mode:gate; Fonts:(HL12 HL12I HL12B CPTFONTB HL12BI HL12B HL12I ) -*- =Node: 4Rubout Handling* =Text: 3RUBOUT HANDLING* The rubout handler is a feature of all interactive streams, that is, streams that connect to terminals. Its purpose is to allow the user to edit minor mistakes made during type-in. At the same time, it is not supposed to get in the way; input is to be seen by Lisp as soon as a syntactically complete form has been typed. The definition of `syntactically complete form' depends on the function that is reading from the stream; for 2read*, it is a Lisp expression. Some interactive streams (`editing Lisp listeners') have a rubout handler that allows input to be edited with the full power of the ZWEI editor. (ZWEI is the general editor implementation on which Zmacs and ZMail are based.) Most windows have a rubout handler that apes ZWEI, implementing about twenty common ZWEI commands. The cold load stream has a simple rubout handler that allows just rubbing out of single characters, and a few simple commands like clearing the screen and erasing the entire input typed so far. All three kinds of rubout handler use the same protocol, which is described in this section. We also say a little about the most common of the three rubout handlers. [Eventually some version of ZWEI will be used for all streams except the cold load stream] The tricky thing about the rubout handler is the need for it to figure out when you are all done. The idea of a rubout handler is that you can type in characters, and they are saved up in a buffer so that if you change your mind, you can rub them out and type different characters. However, at some point, the rubout handler has to decide that the time has come to stop putting characters into the buffer and to let the function parsing the input, such as 2read*, return. This is called 1activation*. The right time to activate depends on the function calling the rubout handler, and may be very complicated (if the function is 2read*, figuring out when one Lisp expression has been typed requires knowledge of all the various printed representations, what all currently-defined reader macros do, and so on). Rubout handlers should not have to know how to parse the characters in the buffer to figure out what the caller is reading and when to activate; only the caller should have to know this. The rubout handler interface is organized so that the calling function can do all the parsing, while the rubout handler does all the handling of editing commands, and the two are kept completely separate. The basic way that the rubout handler works is as follows. When an input function that reads characters from a stream, such as 2read* or 2readline* (but not 2tyi*), is invoked with a stream which has 2:rubout-handler* in its 2:which-operations* list, that function ``enters'' the rubout handler. It then goes ahead 2:tyi*'ing characters from the stream. Because control is inside the rubout handler, the stream echoes these characters so the user can see what he is typing. (Normally echoing is considered to be a higher-level function outside of the province of streams, but when the higher-level function tells the stream to enter the rubout handler it is also handing it the responsibility for echoing.) The rubout handler is also saving all these characters in a buffer, for reasons disclosed in the following paragraph. When the parsing function decides it has enough input, it returns and control ``leaves'' the rubout handler. This is the easy case. If the user types a rubout, a 2throw* is done out of all recursive levels of 2read*, reader macros, and so forth, back to the point where the rubout handler was entered. Also the rubout is echoed by erasing from the screen the character which was rubbed out. Now the 2read* is tried over again, re-reading all the characters that have not been rubbed out, not echoing them this time. When the saved characters have been exhausted, additional input is read from the user in the usual fashion. The effect of this is a complete separation of the functions of rubout handling and parsing, while at the same time mingling the execution of these two functions in such a way that input is always activated at just the right time. It does mean that the parsing function (in the usual case, 2read* and all macro-character definitions) must be prepared to be thrown through at any time and should not have non-trivial side-effects, since it may be called multiple times. If an error occurs while inside the rubout handler, the error message is printed and then additional characters are read. When the user types a rubout, it rubs out the error message as well as the character that caused the error. The user can then proceed to type the corrected expression; the input will be reparsed from the beginning in the usual fashion. The rubout handler based on the ZWEI editor interprets control characters in the usual ZWEI way: as editing commands, allowing you to edit your buffered input. The common rubout handler also recognizes a subset of the editor commands, including 2Rubout*, 2Control-F* and 2Meta-F* and others. Typing 2Help* while in the rubout handler displays a list of the commands. The kill and yank commands in the rubout handler use the same kill ring as the editor, so you can kill an expression in the editor and yank it back into a rubout handler with 2Control-Y*, or kill an expression in the rubout handler with 2Control-K* or 2Clear-input* and yank it back in the editor. The rubout processor also keeps a ring buffer of most recent input strings (a separate ring for each stream), and the commands 2Control-C* and 2Meta-C* retrieve from this ring just as 2Control-Y* and 2Meta-Y* do from the kill ring. When not inside the rubout handler, and when typing at a program that uses control characters for its own purposes, control characters are treated the same as ordinary characters. Some programs such as the debugger allow the user to type either a control character or an expression. In such programs, you are really not inside the rubout handler unless you have typed the beginning of an expression. When the input buffer is empty, a control character is treated as a command for the program (such as, 2Control-C* to continue in the debugger); when there is text in the rubout handler buffer, the same character is treated as a rubout handler command. Another consequence of this is that the message you get by typing 2Help* varies, being either the rubout handler's documentation or the debugger's documentation. To write a parsing function that reads with rubout handling, use 2with-input-editing*. 3with-input-editing* 1(stream* 1options)* 1body...* 1Macro* Invokes the rubout handler on 1stream*, if 1stream* supports it, and then executes 1body*. 1body* is executed in any case, within the rubout handler if possible. 2rubout-handler* is non-2nil* while in 1body* if rubout handling is in use. 1options* are used as the rubout handler options. If already within an invocation of the rubout handler, 1options* are appended to the front of the options already in effect. This happens if a function which reads input using 2with-input-editing*, such as 2read* or 2readline*, is called from the body of another 2with-input-editing*. The 2:norecursive* option can be used to cause the outer set of options to be completely ignored even when not overridden by new ones. 1body*'s values are returned by 2with-input-editing*. 1body* ought to read input from 1stream* and return a Lisp object that represents the input. It should have no nontrivial side effects aside from reading input from 1stream* structure, as it may be aborted at any time it reads input and may be executed over and over. If the 2:full-rubout* option is specified, and the user types some input and rubs it all out, the 2with-input-editing* form returns immediately. See 2:full-rubout*, below. If a preemptive command is input by the user, 2with-input-editing* returns immediately with the values being as specified below under the 2:command* and 2:preemptable* options. 1body* is aborted from its call to the 2:tyi* operation, and the input read so far remains in the rubout handler editing buffer to be read later. 3rubout-handler* 1Variable* If control is inside the rubout handler in this process, the value is the stream on which rubout handling is being done. Otherwise, the value is 2nil*. 3:rubout-handler* 1options* 1function* &rest 1args* 1Operation on streams* Invokes the rubout handler on the stream, with 1options* as the options, and parses by applying 1function* to 1args*. 2with-input-editing* uses this operation. 3:read-bp* 1Operation on streams* This operation may be used only from within the code for parsing input from this stream inside the rubout handler. It returns the index within the rubout handler buffer which parsing has reached. 3:force-rescan* 1Operation on streams* This operation may be used only from within the code for parsing input from this stream inside the rubout handler. It causes parsing to start again immediately from the beginning of the buffer. 3:rescanning-p* 1Operation on streams* This operation may be used only from within the code for parsing input from this stream inside the rubout handler. It returns 2t* if parsing is now being done on input already in the buffer, 2nil* if parsing has used up all the buffered input and the next character parsed will come from the keyboard. Each option in the list of rubout handler options consists of a list whose first element is a keyword and whose remaining elements are the arguments of that keyword. Note that this is not the same format as the arguments to a typical function that takes keyword arguments; rather this is an alist of options. The standard options are: 2(:activation 1fn* 1args*...) * Activate if certain characters are typed in. When the user types an activation character, the rubout handler moves the editing pointer immediately to the end of the buffer and inserts the activation character. This immediately causes the parsing function to begin rescanning the input. 1fn* is used to test characters for being activators. It is called with an input character as the first arg (possibly a fixnum, possibly a character object) and 1args* as additional args. If 1fn* returns non-2nil*, the character is an activation. 1fn* is not called for blips. After the parsing function has read the entire contents of the buffer, it sees the activation character as a blip 2(:activation 1char* 1numeric-arg*)* where 1char* is the character that activated and 1numeric-arg* is the numeric arg that was pending for the next rubout handler command. Normally the parsing function will return at this point. Then the activation character does not echo. But if the parsing function continues to read input, the activation character echoes and is inserted in the buffer. 2(:do-not-echo 1chars*...) * Poor man's activation characters. Like 2:activation* except that the characters that should activate are listed explicitly, and the character itself is returned to the parsing function rather than a blip. 2(:full-rubout 1val*)* If the user rubs out all the characters he typed, then control is returned from the rubout handler immediately. Two values are returned; the first is 2nil* and the second is 1val*. (If the user doesn't rub out all the characters, then the rubout handler propagates multiple values back from the function that it calls, as usual.) In the absence of this option, the rubout handler would simply wait for more characters to be typed in and would ignore any additional rubouts. This is how the debugger knows to remove 2Eval:* from the screen if you type the beginning of a form and rub it all out. 2(:pass-through 1char1* 1char2*...)* The characters 1char1*, 1char2*, etc. are not to be treated as special by the rubout handler. They are read as input by the parsing function. If the parsing function does not return, they can be rubbed out. This works only for characters with no modifier bits. 2(:preemptable 1value*) * Makes all blips read as input by the rubout handler act as preemptive commands. If this option is specified, the rubout handler returns immediately when it reads a blip. It returns two values: the blip that was read, and 1value*. The parsing function is not allowed to finish parsing up to a delimiter; instead, any buffered input remains in the buffer for the next time input is done. In the mean time, the preemptive command character can be processed by the command loop. While this applies to all blips, the blips which it is probably intended for are mouse blips. 2(:command 1fn* 1args*...) * Makes certain characters preemptive commands. A preemptive command returns instantly to the caller of the 2:rubout-handler* operation, regardless of the input in the buffer. It returns two values: a list 2(:command 1char* 1numeric-arg*)* and the keyword 2:command*. The parsing function is not allowed to finish parsing up to a delimiter; instead, any buffered input remains in the buffer for the next time input is done. In the mean time, the preemptive command character can be processed by the command loop. The test for whether a character should be a preemptive command is done using 1fn* and 1args* just as in 2:activation*. 2(:editing-command (1char* 1doc*)...) * Defines editing commands to be executed by the parsing function itself. This is how 2qsend* implements the 2Control-Meta-Y* command. Each 1char* is such a command, and 1doc* says what it does. (1doc* is printed out by the rubout handler's 2Help* command.) If any of these characters is read by the rubout handler, it is returned immediately to the parsing function regardless of where the editing pointer is in the buffer. (Normal inserted text is not returned immediately when read unless the editing pointer is at the end of the buffer.) The parsing function should not regard these characters as part of the input. There are two reasonable things that the parsing function can do when it receives one of the editing command characters: print some output, or force some input. If it prints output, it should invoke the 2:refresh-rubout-handler* operation afterward before the next 2:tyi*. This causes the rubout handler to redisplay so that the input being edited appears after the output that was done. If the parsing function forces input, the input is read by the rubout handler. This can be used to modify the buffered input. 2qsend*'s 2Control-Meta-Y* command works by forcing the yanked text as input. There is no way to act directly on the buffered input because different implementations of the rubout handler store it in different ways. 2(:prompt 1function*)* 2(:reprompt 1function*)*When it is time for the user to be prompted, 1function* is called with two arguments. The first is a stream it may print on; the second is the character which caused the need for prompting, e.g. 2#\clear-input* or 2#\clear-screen*, or 2nil* if the rubout handler was just entered. The difference between 2:prompt* and 2:reprompt* is that the latter does not call the prompt function when the rubout handler is first entered, but only when the input is redisplayed (e.g. after a screen clear). If both options are specified then 2:reprompt* overrides 2:prompt* except when the rubout handler is first entered. 1function* may also be a string. Then it is simply printed. If the rubout handler is exited with an empty buffer due to the 2:full-rubout* option, whatever prompt was printed is erased. 2(:initial-input 1string*)* Pretends that the user typed 1string*. When the rubout handler is entered, 1string* is typed out. The user can input more characters or rub out characters from it. 2(:initial-input-index 1index*)* Positions the editing pointer initially 1index* characters into the initial input string. Used only in company with with 2:initial-input*. 2(:no-input-save t) * Don't save this batch of input in the input history when it is done. For example, 2yes-or-no-p* specifies this option. 2(:norecursive t)* If this invocation of the rubout handler is within another one, the options specified in the previous call should be completely ignored during this one. Normally, individual options specified this time override the previous settings for the same options, but any of the previous options not individually overridden are still in effect. Rubout handlers handle the condition 2sys:parse-error* if it is signaled by the parsing function. The handling consists of printing the error message, waiting for the user to rub out, erasing the error message, and parsing the input again. All errors signaled by a parsing function that signify that the user's input was syntactically invalid should have this condition name. For example, the errors 2read* signals have condition name 2sys:parse-error* since it is is a consequence of 2sys:read-error*. 3sys:parse-error* (error) 1Condition* The condition name for syntax errors in input being parsed. The compiler handles 2sys:parse-error* by proceeding with proceed-type 2:no-action*. All signalers of 2sys:parse-error* should offer this proceed type, and respond to its use by continuing to parse, ignoring the invalid input. 3sys:parse-ferror* 1format-string* &rest 1args* Signals a 2sys:parse-error* error, using 1format-string* and 1args* to print the error message. The proceed-type 2:no-action* is provided, and if a handler uses it, this function returns 2nil*.