1 PROMPTFORWORD PROMPTFORWORD is a function that reads in a sequence of characters, generally from the keyboard, without involving READ-like syntax or Process-related problems, and generally echoing the characters being typed-in to a specified stream (e.g., (TTYDISPLAYSTREAM) or PROMPTWINDOW). The intent is to mimic the prompted-READ used by the Alto Exec when asking for login names, passwords etc. Thus a user can supply a prompting string, as well as a "candidate" string, which will be printed and used if the user types only a word terminator character (or doesn't type anything before a given time limit). As soon as any characters are typed the "candidate" string is erased and the new input takes its place. PROMPTFORWORD accepts user type-in until one of the "word terminator" characters is typed. Normally, the word terminator characters are EOL, ESCAPE, LF, SPACE, or TAB. This list can be changed using the TERMINCHAR.LST argument to PROMPTFORWORD, for example if it is desirable to allow the user to input lines including spaces. PROMPTFORWORD also recognizes the following special characters: Control-A, BS, or DELAny of these characters will delete the last character typed and appropriately erase it from the echo stream if it is a displaystream. Control-W or Control-QWill erase all the type-in so far. Control-RReprints the accumulated string. When echoing to display streams, it reprints "in place". ?Calls up a "help" facility. The action taken is defined by the GENERATE?LIST.FN argument to PROMPTFORWORD (see below). Normally, this will print a list of possible candidates. Control-VAfter typing Control-V, the next character typed will be added to the accumulated string, regardless of any special meaning it has. Allows the user to include editing characters and word terminator characters in the accumulated string. (PROMPTFORWORD PROMPT.STR CANDIDATE.STR GENERATE?LIST.FN ECHO.CHANNEL DONTECHOTYPEIN.FLG TIMELIMIT.secs TERMINCHARS.LST KEYBD.CHANNEL OLDSTRING) PROMPTFORWORD has a multiplicity of features, which are specified through a rather large number of input arguments, but the default settings for them (i.e., when they aren't given, or are given as NIL) is such to minimize the number needed in the average case, and an attempt has been made to order the more frequently non-defaulted arguments at the first of the argument list. When the default input channel is taken (NIL, meaning the keyboard) then the various system buffers (linbuf and sysbuf) are saved-and-restored so as not to interact with the "word" being read in; the terminal table in effect during input allows most control characters to be INDICATE'd, and all terminal interrupt characters are temporarily disabled. PROMPTFORWORD returns NIL if a null string is typed; this would occur when no candidate is given and only a terminator is typed, or when the candidate is erased and a terminator is typed with no other input still un-erased. In all other cases, PROMPTFORWORD returns a string. PROMPTFORWORD uses a MONITORLOCK (see page X.XX) so that a second call cannot be started before the first one finished; primarily this is to limit confusion between multiple processes that might try to access the keyboard at the same time, or print in the prompt window "at the same time" PROMPTFORWORD is controlled through the following arguments: PROMPT.STRIf non-NIL, this is coerced to a string and used for prompting; an additional space will be output after this string. CANDIDATE.STRIf non-NIL, this is coerced to a string and offered as initial contents of the input buffer. GENERATE?LIST.FNIf non-NIL, this is either a string to be printed out for help, or a function to be applied to PROMPT.STR and CANDIDATE.STR (after both have been coerced to strings), and which should return a list of potential candidates. The help string or list of potential candidates will then be printed on a separate line, the prompt will be restarted, and any type-in will be re-echoed. Note: If GENERATE?LIST.FN is a function, its value list will be "cached" so that it will be run at most once per call to PROMPTFORWORD. ECHO.CHANNELCoerced to an output stream; NIL and T both mean the current (TTYDISPLAYSTREAM). To achieve echoing to the "current output file", use (GETSTREAM NIL 'OUTPUT). Any display stream will also have a flashing caret showing where the next input is to be echoed. DONTECHOTYPEIN.FLGIf non-NIL, there wil be no echoing of the input characters. However, a non-NIL prompt will still be visible. TIMELIMIT.secsIf non-NIL, this is the number of seconds (as an integer) that the caller is is willing to wait with no input from KEYBD.CHANNEL (see below); if timeout is reached, then CANDIDATE.WORD is returned, regardless of any other type-in activity. TERMINCHAR.LSTThis is list of "word terminators". If NIL, this defaults to (CHARCODE (EOL ESCAPE LF SPACE TAB)). KEYBD.CHANNELIf non-NIL, this will be coerced to a stream, and the input bytes will be taken from that stream. If this is NIL, the default is to take in characters typed on the real keyboard, with any "typeahead" saved-and-restored. Note that supplying T for this arg will generally not do what you want -- it will turn into the LINEBUFFER stream which has an entirely independent input buffering mechanism, and which will probably be at the "end of file" anyway, thereby forcing the candidate result to be returned. Use the (global) variable \KEYBOARD.STREAM to supply a stream which reads from the keyboard, but with no special processing or cognizance of that fact (e.g, it "eats" typeahead rather than saving it). OLDSTRINGIf non-NIL, this must be a string, which will be destructively used to return the answer. Examples: (PROMPTFORWORD "What is your FOO word?" 'Mumble (FUNCTION (LAMBDA () '(Grumble Bletch))) PROMPTWINDOW NIL 30) This will first prompt the user for input by printing the first argument as a prompt into PROMPTWINDOW; then the proffered default answer, "Mumble", will be printed out and the caret will be flashing just after it to indicate that the upcoming input will be echoed there. If the user fails to complete a word within 30 seconds, then the result will be the string "Mumble". (FRESHLINE T) (LIST (PROMPTFORWORD (CONCAT "{" HOST "} Login:") (USERNAME NIL NIL T)) (PROMPTFORWORD " (password)" NIL NIL NIL 'DONTECHO)) This will first prompt in whatever window is currently (TTYDISPLAYSTREAM), and then take in a username; the second call will take in another word (the password) without proffering a candidate, without echoing any of the typed-in characters, and without re-adjusting the caret to the left edge of the window. However, the second call will still issue the prompt " (password)" into the (TTYDISPLAYSTREAM), for the fourth argument designates the echostream, and both NIL and T default to (TTYDISPLAYSTREAM). Caution: because of the dynamics of multiple processes, and the above-mentioned input-buffer saving, a multiple use of PROMPTFORWORD is not quite as simple as this "motivating" example. See discussion of KEYBD.CHANNEL above.