1
0
mirror of https://github.com/PDP-10/its.git synced 2026-01-18 17:16:59 +00:00
PDP-10.its/src/libdoc/comrd.kmp1

463 lines
15 KiB
Common Lisp
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;;; -*- LISP -*-
;;; COMRD: A library that implements a completing reader.
;;; Written by KMP some time ago, (obviously before # readmacro
;;; and defmacro were in use in maclisp), moved to LIBDOC by GJC
;;; as this is of general use as a command reader for
;;; interactive programs.
;;; The simplest and most common call will be
;;; (completing-read "prompt-> " '(foo bar baz bomb))
(herald comrd)
(DECLARE (SPECIAL COMPLETING-READER-OBJECT-HEADER)
(*LEXPR *COMPLETING-READ-OPTIONS
*COMPLETING-READ-PROMPT
*COMPLETING-READ-INSTREAM
*COMPLETING-READ-OUTSTREAM
*COMPLETING-READ-AMBIGUITY-ERROR
*COMPLETING-READ-NULL-ERROR
*COMPLETING-READ-COMPLETION-CHARS
*COMPLETING-READ-RETURN-CHARS
*COMPLETING-READ-CASE-CONVERT
*COMPLETING-READ-LAST-CASE
*COMPLETING-READ-OVERRUBOUT-RETURN
*COMPLETING-READ-CHARS-READ))
(SSTATUS TTYINT 23. NIL) ; Turn off ^W as a tty interrupt
(SSTATUS TTYINT 21. NIL) ; Turn off ^U as a tty interrupt
(EVAL-WHEN (EVAL COMPILE)
(OR (GET 'TTY 'VERSION)
(LOAD (CASEQ (STATUS OPSYS)
((ITS) '((DSK LIBLSP) TTY))
(T '((LISP)TTY))))))
(DEFUN LAMBDA MACRO (FORM) (LIST 'FUNCTION FORM))
;;; *COMPLETING-READ and *COMPLETING-READ1
;;;
;;; *COMPLETING-READ prints a newline and a prompt.
;;; *COMPLETING-READ1 starts in cold (this is good for if completion
;;; has been done and user rubs back out into the read)
;;;
;;; Args are:
;;;
;;; PROMPT: What to type out as a prompt if anything.
;;; CHARS-PENDING: What characters have already been read (won't echo).
;;; INSTREAM: Where to read more chars from.
;;; OUTSTREAM: Where to do type-out to.
;;; AMBIGUITY-ERROR: If T, then beep instead of return if result is ambiguous.
;;; NULL-ERROR: If T, then beep instead of return if result is null.
;;; COMPLETION-CHARS: List of fixnums for chars that show completion.
;;; RETURN-CHARS: List of fixnums for chars that return value(s).
;;; CASE-CONVERT: If T, then lowercase stuff input gets canonicalized.
;;; OVER-RUBOUT-RETURN-FLAG: Should form return if over-rubout?
;;; If non-NIL returns OVER-RUBOUT for too many
;;; rubouts, WORD-RUBOUT for ^W, and LINE-RUBOUT
;;; for ^U.
;;;
;;; Returns a list whose CAR is the list of characters read and the
;;; CDR of which is the set of still-possible completions at the end of the
;;; read.
(DEFUN *COMPLETING-READ (PROMPT OPTIONS INSTREAM OUTSTREAM
AMBIGUITY-ERROR NULL-ERROR
COMPLETION-CHARS RETURN-CHARS
CASE-CONVERT OVER-RUBOUT-RETURN-FLAG)
(TERPRI OUTSTREAM)
(PRINC PROMPT OUTSTREAM)
(*COMPLETING-READ1 PROMPT OPTIONS () INSTREAM OUTSTREAM
AMBIGUITY-ERROR NULL-ERROR
COMPLETION-CHARS RETURN-CHARS
CASE-CONVERT OVER-RUBOUT-RETURN-FLAG))
(DEFUN *COMPLETING-READ1 (PROMPT OPTIONS CHARS-PENDING INSTREAM OUTSTREAM
AMBIGUITY-ERROR NULL-ERROR
COMPLETION-CHARS RETURN-CHARS
CASE-CONVERT OVER-RUBOUT-RETURN-FLAG)
(LET ((COMPLETION-OBJECT (*COMPLETING-READ-OBJECT
OPTIONS
PROMPT
INSTREAM
OUTSTREAM
AMBIGUITY-ERROR
NULL-ERROR
COMPLETION-CHARS
RETURN-CHARS
CASE-CONVERT
OVER-RUBOUT-RETURN-FLAG)))
(MAPC (LAMBDA (X) (*COMPLETING-READ-PUSH-COMPLETION
X
COMPLETION-OBJECT))
CHARS-PENDING)
(*CATCH 'COMPLETING-READ-EXIT
(DO-WITH-TTY-OFF
(DO ()
(NIL)
(*COMPLETING-READ-TYI COMPLETION-OBJECT))))))
;;; (COMPLETING-READ <prompt> <options>)
;;; I/O default is to/from tty
;;; ambiguous or null response acceptable
;;; return or space causes return
;;; altmode causes completion
;;; no initial character
;;;
;;; Sample: (COMPLETING-READ '> '(THIS THAT THOSE))
;;;
(DEFUN COMPLETING-READ (PROMPT OPTIONS)
(CDR (*COMPLETING-READ PROMPT OPTIONS TYI TYO
T T
'(27.) '(13. 32.)
T NIL)))
(DEFUN *COMPLETING-READ-SOFT-TYI (COMPLETION CHAR)
(LET ((OUTSTREAM (*COMPLETING-READ-OUTSTREAM COMPLETION)))
(TYO CHAR OUTSTREAM)
(*COMPLETING-READ-PUSH-COMPLETION CHAR COMPLETION)))
(DEFUN *COMPLETING-READ-CASE-FUNCTION (CHAR)
(COND ((AND (> CHAR 96.) (< CHAR 123.))
'*COMPLETING-READ-LOWERCASIFY)
(T
'*COMPLETING-READ-UPPERCASIFY)))
(DEFUN *COMPLETING-READ-TYI (COMPLETION)
(LET ((INSTREAM (*COMPLETING-READ-INSTREAM COMPLETION))
(OUTSTREAM (*COMPLETING-READ-OUTSTREAM COMPLETION)))
(LET ((CHAR (TYI INSTREAM)))
(COND ((= CHAR 12.)
(CURSORPOS 'C OUTSTREAM)
(*COMPLETING-READ-REDISPLAY-LINE COMPLETION))
((= CHAR 18.)
(*COMPLETING-READ-REDISPLAY-LINE COMPLETION))
((MEMBER CHAR '(63. 2120.))
(*COMPLETING-READ-DISPLAY-OPTIONS COMPLETION)
(*COMPLETING-READ-REDISPLAY-LINE COMPLETION))
((MEMBER CHAR (*COMPLETING-READ-COMPLETION-CHARS
COMPLETION))
(*COMPLETING-READ-ATTEMPT-COMPLETION COMPLETION))
((MEMBER CHAR (*COMPLETING-READ-RETURN-CHARS
COMPLETION))
(*COMPLETING-READ-RETURN COMPLETION CHAR))
((= CHAR 23.)
(PRINC '|/| TYO)
(COND
((*COMPLETING-READ-OVERRUBOUT-RETURN COMPLETION)
(*THROW 'COMPLETING-READ-EXIT 'WORD-RUBOUT))
(T
(*COMPLETING-READ-RESET-COMPLETION COMPLETION)
(*COMPLETING-READ-REDISPLAY-LINE COMPLETION))))
((= CHAR 21.)
(PRINC '|/| TYO)
(COND
((*COMPLETING-READ-OVERRUBOUT-RETURN COMPLETION)
(*THROW 'COMPLETING-READ-EXIT 'LINE-RUBOUT))
(T
(*COMPLETING-READ-RESET-COMPLETION COMPLETION)
(*COMPLETING-READ-REDISPLAY-LINE COMPLETION))))
((= CHAR 127.)
(LET ((CHAR
(*COMPLETING-READ-POP-COMPLETION COMPLETION)))
(COND (CHAR
(COND ((MEMQ 'RUBOUT
(STATUS FILEM OUTSTREAM))
(RUBOUT CHAR OUTSTREAM))
(T
(TYO 92. OUTSTREAM)
(TYO CHAR OUTSTREAM))))
((*COMPLETING-READ-OVERRUBOUT-RETURN
COMPLETION)
(*THROW 'COMPLETING-READ-EXIT
'OVER-RUBOUT)))))
(T
(TYO CHAR (*COMPLETING-READ-OUTSTREAM COMPLETION))
(*COMPLETING-READ-LAST-CASE
COMPLETION
(*COMPLETING-READ-CASE-FUNCTION CHAR))
(*COMPLETING-READ-PUSH-COMPLETION CHAR COMPLETION))))))
(DEFUN *COMPLETING-READ-REDISPLAY-LINE (COMPLETION)
(LET ((OUTSTREAM (*COMPLETING-READ-OUTSTREAM COMPLETION)))
(CURSORPOS 'A OUTSTREAM)
(PRINC (*COMPLETING-READ-PROMPT COMPLETION) OUTSTREAM)
(DO ((L (REVERSE (*COMPLETING-READ-CHARS-READ COMPLETION))
(CDR L))
(CASE-FUN (*COMPLETING-READ-LAST-CASE COMPLETION)))
((NULL L))
(TYO (FUNCALL CASE-FUN (CAR L)) OUTSTREAM))))
(DEFUN *COMPLETING-READ-RETURN (COMPLETION CHAR)
(LET ((OPTIONS (CAR (*COMPLETING-READ-OPTIONS COMPLETION)))
(NUMBER-OF-CHARS)
(CHARS))
(COND ((OR (AND (NULL OPTIONS)
(NOT (*COMPLETING-READ-NULL-ERROR COMPLETION)))
(= (LENGTH OPTIONS) 1.)
(NOT (*COMPLETING-READ-AMBIGUITY-ERROR COMPLETION)))
(COND ((AND (NOT (= CHAR 13.))
(= (LENGTH OPTIONS) 1.))
(*COMPLETING-READ-SHOW-COMPLETION COMPLETION)))
(TYO CHAR (*COMPLETING-READ-OUTSTREAM COMPLETION))
(*THROW 'COMPLETING-READ-EXIT
(CONS (CONS
CHAR
(*COMPLETING-READ-CHARS-READ COMPLETION))
OPTIONS))))
(SETQ NUMBER-OF-CHARS
(LENGTH (SETQ CHARS
(*COMPLETING-READ-CHARS-READ COMPLETION))))
(MAPC (LAMBDA (X)
(COND ((= (FLATC X) NUMBER-OF-CHARS)
(TYO CHAR
(*COMPLETING-READ-OUTSTREAM COMPLETION))
(*THROW 'COMPLETING-READ-EXIT
(LIST (CONS CHAR CHARS) X)))))
OPTIONS)
(TYO 7. (*COMPLETING-READ-OUTSTREAM COMPLETION))
(*COMPLETING-READ-ATTEMPT-COMPLETION COMPLETION)))
(DEFUN *COMPLETING-READ-DISPLAY-OPTIONS (COMPLETION)
(LET ((OUTSTREAM (*COMPLETING-READ-OUTSTREAM COMPLETION))
(OPTIONS (CAR (*COMPLETING-READ-OPTIONS COMPLETION))))
(CURSORPOS 'A OUTSTREAM)
(COND ((NOT OPTIONS)
(PRINC '|No options match.| OUTSTREAM))
((= (LENGTH OPTIONS) 1.)
(PRINC '|Unambiguous match: | OUTSTREAM)
(PRINC (CAR OPTIONS) OUTSTREAM))
(T
(PRINC '|Options are: | OUTSTREAM)
(PRINC (CAR OPTIONS) OUTSTREAM)
(DO ((L (CDR OPTIONS) (CDR L)))
((NULL L))
(PRINC '|, | OUTSTREAM)
(COND ((> (+ (FLATC (CAR L)) (CHARPOS OUTSTREAM)) 67.)
(TERPRI OUTSTREAM)
(TYO 9. OUTSTREAM)))
(PRINC (CAR L) OUTSTREAM))))))
(DEFUN *COMPLETING-READ-ATTEMPT-COMPLETION (COMPLETION)
(LET ((OUTSTREAM (*COMPLETING-READ-OUTSTREAM COMPLETION))
(OPTIONS (CAR (*COMPLETING-READ-OPTIONS COMPLETION)))
(LEN (1+ (LENGTH (*COMPLETING-READ-CHARS-READ COMPLETION)))))
(COND ((NULL OPTIONS)
(TYO 7. OUTSTREAM))
(T
(DO ((I LEN (1+ I))
(CASE-FUN (*COMPLETING-READ-LAST-CASE COMPLETION))
(END (FLATC (CAR OPTIONS))))
((OR (> I END)
(NOT (*COMPLETING-READ-MATCH-ALL OPTIONS I)))
(COND ((= I LEN)
(TYO 7. OUTSTREAM))))
(*COMPLETING-READ-SOFT-TYI
COMPLETION
(FUNCALL CASE-FUN (GETCHARN (CAR OPTIONS) I))))))))
(DEFUN *COMPLETING-READ-SHOW-COMPLETION (COMPLETION)
(LET ((OPTION (CAAR (*COMPLETING-READ-OPTIONS COMPLETION)))
(LEN (1+ (LENGTH (*COMPLETING-READ-CHARS-READ COMPLETION)))))
(DO ((I LEN (1+ I))
(CASE-FUN (*COMPLETING-READ-LAST-CASE COMPLETION))
(END (FLATC OPTION)))
((> I END))
(*COMPLETING-READ-SOFT-TYI
COMPLETION
(FUNCALL CASE-FUN (GETCHARN OPTION I))))))
(DEFUN *COMPLETING-READ-MATCH-ALL (OPTIONS I)
(DO ((C (GETCHARN (CAR OPTIONS) I))
(O (CDR OPTIONS) (CDR O)))
((NULL O) T)
(COND ((NOT (= C (GETCHARN (CAR O) I)))
(RETURN NIL)))))
(EVAL-WHEN (EVAL LOAD)
(SETQ COMPLETING-READER-OBJECT-HEADER
(MAKNAM '(/# C O M P L E T I O N))))
(DEFUN *COMPLETING-READ-OBJECT? (X)
(AND (NOT (ATOM X))
(EQ (CAR X) COMPLETING-READER-OBJECT-HEADER)))
(DEFUN *COMPLETING-READ-OBJECT (OPTIONS PROMPT INSTREAM OUTSTREAM
AMBIGUITY-ERROR NULL-ERROR
COMPLETION-CHARS RETURN-CHARS
CASE-CONVERT OVER-RUBOUT-RETURN-FLAG)
(HUNK COMPLETING-READER-OBJECT-HEADER
(NCONS OPTIONS) ; Options stack
PROMPT ; How to prompt
INSTREAM ; Where to get input from
OUTSTREAM ; Where to output echo
AMBIGUITY-ERROR ; Is ambiguity an error?
NULL-ERROR ; Is null choice an error?
COMPLETION-CHARS; Chars that complete
RETURN-CHARS ; Chars that cause a return
CASE-CONVERT ; Should lowercase chars convert?
(LAMBDA (X) X) ; What case to do completions in
OVER-RUBOUT-RETURN-FLAG ; Return if over-rubout occurs?
() ; Stack of chars read
))
(DEFUN *COMPLETING-READ-OPTIONS X
(COND ((= X 1.) (CXR 2. (ARG 1.)))
(T (RPLACX 2. (ARG 1.) (ARG 2.)))))
(DEFUN *COMPLETING-READ-PROMPT X
(COND ((= X 1.) (CXR 3. (ARG 1.)))
(T (RPLACX 3. (ARG 1.) (ARG 2.)))))
(DEFUN *COMPLETING-READ-INSTREAM X
(COND ((= X 1.) (CXR 4. (ARG 1.)))
(T (RPLACX 4. (ARG 1.) (ARG 2.)))))
(DEFUN *COMPLETING-READ-OUTSTREAM X
(COND ((= X 1.) (CXR 5. (ARG 1.)))
(T (RPLACX 5. (ARG 1.) (ARG 2.)))))
(DEFUN *COMPLETING-READ-AMBIGUITY-ERROR X
(COND ((= X 1.) (CXR 6. (ARG 1.)))
(T (RPLACX 6. (ARG 1.) (ARG 2.)))))
(DEFUN *COMPLETING-READ-NULL-ERROR X
(COND ((= X 1.) (CXR 7. (ARG 1.)))
(T (RPLACX 7. (ARG 1.) (ARG 2.)))))
(DEFUN *COMPLETING-READ-COMPLETION-CHARS X
(COND ((= X 1.) (CXR 8. (ARG 1.)))
(T (RPLACX 8. (ARG 1.) (ARG 2.)))))
(DEFUN *COMPLETING-READ-RETURN-CHARS X
(COND ((= X 1.) (CXR 9. (ARG 1.)))
(T (RPLACX 9. (ARG 1.) (ARG 2.)))))
(DEFUN *COMPLETING-READ-CASE-CONVERT X
(COND ((= X 1.) (CXR 10. (ARG 1.)))
(T (RPLACX 10. (ARG 1.) (ARG 2.)))))
(DEFUN *COMPLETING-READ-LAST-CASE X
(COND ((= X 1.) (CXR 11. (ARG 1.)))
(T (RPLACX 11. (ARG 1.) (ARG 2.)))))
(DEFUN *COMPLETING-READ-OVERRUBOUT-RETURN X
(COND ((= X 1.) (CXR 12. (ARG 1.)))
(T (RPLACX 12. (ARG 1.) (ARG 2.)))))
(DEFUN *COMPLETING-READ-CHARS-READ X
(COND ((= X 1.) (CXR 0. (ARG 1.)))
(T (RPLACX 0. (ARG 1.) (ARG 2.)))))
(DEFUN *COMPLETING-READ-RESET-COMPLETION (OBJECT)
(*COMPLETING-READ-OPTIONS OBJECT
(LAST (*COMPLETING-READ-OPTIONS OBJECT)))
(*COMPLETING-READ-CHARS-READ OBJECT ()))
(DEFUN *COMPLETING-READ-PUSH-COMPLETION (CHAR OBJECT)
(LET ((OPTS (*COMPLETING-READ-OPTIONS OBJECT))
(CHARS (*COMPLETING-READ-CHARS-READ OBJECT)))
(COND ((*COMPLETING-READ-CASE-CONVERT OBJECT)
(SETQ CHAR (*COMPLETING-READ-UPPERCASIFY CHAR))))
(*COMPLETING-READ-OPTIONS OBJECT
(CONS
(*COMPLETING-READ-PROCESS-OPTIONS
CHAR
(CAR OPTS)
(1+ (LENGTH CHARS)))
OPTS))
(*COMPLETING-READ-CHARS-READ OBJECT (CONS CHAR CHARS))))
(DEFUN *COMPLETING-READ-UPPERCASIFY (X)
(COND ((AND (> X 96.) (< X 123.)) (- X 32.))
(T X)))
(DEFUN *COMPLETING-READ-LOWERCASIFY (X)
(COND ((AND (> X 64.) (< X 91.)) (+ X 32.))
(T X)))
(DEFUN *COMPLETING-READ-POP-COMPLETION (OBJECT)
(LET ((CHARS (*COMPLETING-READ-CHARS-READ OBJECT)))
(COND (CHARS
(*COMPLETING-READ-OPTIONS
OBJECT
(CDR (*COMPLETING-READ-OPTIONS OBJECT)))
(*COMPLETING-READ-CHARS-READ OBJECT (CDR CHARS))
(CAR CHARS))
(T
NIL))))
(DEFUN *COMPLETING-READ-PROCESS-OPTIONS (CHAR OPTIONS N)
(DO ((L OPTIONS (CDR L))
(NEW-L ()))
((NULL L) (NREVERSE NEW-L))
(COND ((= (GETCHARN (CAR L) N) CHAR)
(PUSH (CAR L) NEW-L)))))
;;; (COMPLETING-READ-LINE (<prompt1> <option1[1]> <option1[2]> ...)
;;; (<prompt2> <option2[1]> <option2[2]> ...) ...)
;;; Prints <prompt1> and reads words on a single line returning NIL if
;;; over-rubout and (<option1-choice> <option2-choice> ... <optionN-choice>)
;;; if sucessful. <prompt2> ... <promptN> are only used if the user types
;;; <CR> to terminate the option before that. If he types <space> instead
;;; he will not be prompted. Ambiguous or null responses are not allowed.
(DEFUN (COMPLETING-READ-LINE MACRO) (X)
`(*COMPLETING-READ-LINE1 ',(CDR X)))
(DEFUN *COMPLETING-READ-LINE1 (PROMPT-ALIST)
(CURSORPOS 'A TYO)
(*CATCH 'COMPLETING-READ-LINE-EXIT
(*COMPLETING-READ-LINE1-AUX (CAAR PROMPT-ALIST)
PROMPT-ALIST
NIL
T)))
(DEFUN *COMPLETING-READ-LINE1-AUX (PROMPT PROMPT-ALIST VALUES PROMPTFLAG)
(COND ((NULL PROMPT-ALIST)
(*THROW 'COMPLETING-READ-LINE-EXIT
(NREVERSE VALUES)))
(T
(COND (PROMPTFLAG (PRINC (CAAR PROMPT-ALIST) TYO)))
(DO ((VAL)
(CHARS NIL))
(NIL)
(SETQ VAL
(*COMPLETING-READ1 PROMPT ; Prompt
(CDAR PROMPT-ALIST) ; Options
CHARS ; Chars read
TYI ; Instream
TYO ; Outstream
T ; Ambiguity
T ; Null
'(27.) ; Completion
'(32. 13.) ; Return chars
T ; Case
T)) ; Over-rubout
(COND ((EQ VAL 'OVER-RUBOUT)
(RETURN NIL))
((EQ VAL 'LINE-RUBOUT)
(*THROW 'COMPLETING-READ-LINE-EXIT NIL))
((EQ VAL 'WORD-RUBOUT)
(CURSORPOS 'A TYO)
(PRINC PROMPT TYO)
(RETURN NIL)))
(SETQ CHARS (REVERSE (CAR VAL)))
(*COMPLETING-READ-LINE1-AUX
(MAKNAM (NCONC (EXPLODEN PROMPT) CHARS))
(CDR PROMPT-ALIST)
(CONS (CADR VAL) VALUES)
(= (CAAR VAL) 13.))
(SETQ CHARS (REVERSE (CDAR VAL)))
(COND ((= (CAAR VAL) 13.)
(CURSORPOS 'A TYO)
(PRINC PROMPT TYO)
(MAPC (LAMBDA (X) (TYO X TYO)) CHARS))
(T
(COND ((MEMQ 'RUBOUT (STATUS FILEM TYO))
(CURSORPOS 'X TYO))
(T
(PRINC '|\ | TYO)))))))))
(SSTATUS FEATURE COMPLETING-READER-PACKAGE)