123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 |
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % LISP-Interface.SL - NMODE Lisp Text Execution Interface
- %
- % Author: Alan Snyder
- % Hewlett-Packard/CRC
- % Date: 23 August 1982
- % Revised: 14 February 1983
- %
- % Adapted from Will Galway's EMODE
- %
- % 14-Feb-83 Alan Snyder
- % Added statement to flush output buffer cache.
- % 2-Feb-83 Alan Snyder
- % Added Execute-Defun-Command. Change to supply the free EOL at the end of
- % the input buffer whenever the buffer-modified flag is set, instead of only
- % when currently at the end of the buffer.
- % 25-Jan-83 Alan Snyder
- % Check terminal type after resuming.
- %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- (CompileTime (load objects))
- (fluid '(nmode-current-buffer
- nmode-output-buffer
- nmode-terminal
- nmode-initialized
- *NMODE-RUNNING
- *GC
- LispBanner*
- *RAWIO
- *nmode-init-running
- *nmode-init-has-run
- nmode-terminal-input-buffer
- nmode-default-init-file-name
- nmode-auto-start
- nmode-first-start
- ))
- (setf *NMODE-RUNNING NIL)
- (setf *nmode-init-running NIL)
- (setf *nmode-init-has-run NIL)
- (setf nmode-default-init-file-name "PSL:NMODE.INIT")
- (setf nmode-auto-start NIL)
- (setf nmode-first-start T)
- (fluid '(
- nmode-buffer-channel % Channel used for NMODE I/O.
- nmode-output-start-position % Where most recent "output" started in buffer.
- nmode-output-end-position % Where most recent "output" ended in buffer.
- OldStdIn
- OldStdOut
- OldErrOut
- ))
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- (de yank-last-output-command ()
- % Insert "last output" typed in the OUTPUT buffer. Output is demarked by
- % NMODE-OUTPUT-START-POSITION and NMODE-OUTPUT-END-POSITION.
- (if (not nmode-output-start-position)
- (Ding)
- % Otherwise
- (let ((text (=> nmode-output-buffer
- extract-region
- NIL
- nmode-output-start-position
- (or nmode-output-end-position
- (buffer-position-create (=> nmode-output-buffer size) 0)
- )
- )))
- (=> nmode-current-buffer insert-text (cdr text))
- )))
- (de execute-form-command ()
- % Execute starting at the beginning of the current line.
- (set-mark-from-point) % in case the user wants to come back
- (move-to-start-of-line)
- (execute-from-buffer)
- )
- (de execute-defun-command ()
- % Execute starting at the beginning of the current defun (if the current
- % position is within a defun) or from the current position (otherwise).
- (set-mark-from-point) % in case the user wants to come back
- (move-to-start-of-current-defun)
- (execute-from-buffer)
- )
- (de make-buffer-terminated ()
- % If the current buffer ends with an "unterminated" line, add an EOL to
- % terminate it.
- (let ((old-pos (buffer-get-position)))
- (move-to-buffer-end)
- (when (not (current-line-empty?)) (insert-eol))
- (buffer-set-position old-pos)
- ))
- (de execute-from-buffer ()
- % Causes NMODE to return to the procedure that called it (via
- % nmode-channel-editor) with input redirected to come from the (now) current
- % buffer. We arrange for output to go to the end of the output buffer.
- (if (=> nmode-current-buffer modified?) (make-buffer-terminated))
- (buffer-channel-set-input-buffer nmode-buffer-channel nmode-current-buffer)
- % Output will go to end of the output buffer. Supply a free EOL if the last
- % line is unterminated. Record the current end-of-buffer for later use by
- % Lisp-Y.
- (let ((old-pos (=> nmode-output-buffer position)))
- (=> nmode-output-buffer move-to-buffer-end)
- (if (not (=> nmode-output-buffer current-line-empty?))
- (=> nmode-output-buffer insert-eol))
- (setf nmode-output-start-position (=> nmode-output-buffer position))
- (=> nmode-output-buffer set-position old-pos)
- )
- % Set things up to read from and write to NMODE buffers.
- (nmode-select-buffer-channel)
- (exit-nmode-reader)
- )
- (de nmode-exit-to-superior ()
- (if (not *NMODE-RUNNING)
- (original-quit)
- % else
- (leave-raw-mode) % Turn echoing back on. Next refresh is FULL.
- (original-quit)
- (enter-raw-mode) % Turn echoing off.
- (nmode-set-terminal) % Ensure proper terminal driver is loaded.
- ))
- % Redefine QUIT so that it restores the terminal to echoing before exiting.
- (when (FUnboundP 'original!-quit)
- (CopyD 'original!-quit 'quit)
- (CopyD 'quit 'nmode-exit-to-superior)
- )
- (de emode () (nmode)) % for user convenience
- (de nmode ()
- % Rebind the PSL input channel to the NMODE buffer channel and return. This
- % will cause the next READ to invoke Nmode-Channel-Editor and start running
- % NMODE. Use the function "exit-nmode" to switch back to original channels.
- (nmode-initialize) % does nothing if already initialized
- (when (neq STDIN* nmode-buffer-channel)
- (setf OldStdIn STDIN*)
- (setf OldStdOut STDOUT*)
- (setf OldErrOut ErrOut*)
- )
- (nmode-select-buffer-input-channel)
- )
- (de nmode-run-init-file ()
- (setf *nmode-init-has-run T)
- (let ((fn (namestring (init-file-pathname "NMODE"))))
- (cond ((FileP fn)
- (nmode-execute-init-file fn))
- ((FileP (setf fn nmode-default-init-file-name))
- (nmode-execute-init-file fn))
- )))
- (de nmode-execute-init-file (fn)
- (let ((*nmode-init-running T))
- (nmode-read-and-evaluate-file fn)
- ))
- (de nmode-read-and-evaluate-file (fn)
- (let ((chn (open fn 'INPUT))
- exp
- )
- (while (not (eq (setf exp (ChannelRead chn)) $Eof$))
- (eval exp)
- )
- (close chn)
- )
- )
- (de exit-nmode ()
- % Leave NMODE, return to normal listen loop.
- (nmode-select-old-channels)
- (=> nmode-terminal move-cursor (=> nmode-terminal maxrow) 0)
- (leave-raw-mode)
- (setf *NMODE-RUNNING NIL)
- (setf *GC T)
- (exit-nmode-reader) % Set flag to cause NMODE to exit.
- )
- % The following function is not currently used.
- (de nmode-invoke-lisp-listener ()
- % Invoke a normal listen loop.
- (let* ((*NMODE-RUNNING NIL)
- (OldIN* IN*)
- (OldOUT* OUT*)
- (ERROUT* 1)
- (StdIn* 0)
- (StdOut* 1)
- (old-raw-mode (=> nmode-terminal raw-mode))
- )
- (leave-raw-mode)
- (RDS 0)
- (WRS 1)
- (unwind-protect
- (TopLoop 'Read 'Print 'Eval "Lisp" "Return to NMODE with ^Z")
- (RDS OldIN*)
- (WRS OldOUT*)
- (if old-raw-mode (enter-raw-mode))
- )))
- % (de emode () (throw '$read$ $eof$)) % use with above function
- % (de nmode () (throw '$read$ $eof$)) % use with above function
- (de nmode-select-old-channels ()
- % Select channels that were in effect when "Lisp Interface" was started up.
- % (But don't turn echoing on.) NOTE that the "old channels" are normally
- % selected while NMODE is actually running (this is somewhat counter
- % intuitive). This is so that any error messages created by bugs in NMODE
- % will not be printed into NMODE buffers. (If they were, it might break
- % things recursively!)
- (setf STDIN* OldStdIn)
- (setf STDOUT* OldStdOut)
- (setf ErrOut* OldErrOut)
- (RDS STDIN*) % Select the channels.
- (WRS STDOUT*)
- )
- (de nmode-select-buffer-channel ()
- % Select channels that read from and write to NMODE buffers.
- (nmode-select-buffer-input-channel)
- (setf STDOUT* nmode-buffer-channel)
- (setf ErrOut* nmode-buffer-channel)
- (WRS STDOUT*)
- )
- (de nmode-select-buffer-input-channel ()
- % Select channel that reads from NMODE buffer. "NMODE-Channel-Editor" is
- % called when read routines invoke the "editor routine" for the newly selected
- % channel.
- (if (null nmode-buffer-channel)
- (setf nmode-buffer-channel
- (OpenBufferChannel NIL nmode-output-buffer 'nmode-channel-editor)))
- (setf STDIN* nmode-buffer-channel)
- (RDS STDIN*)
- )
- (de nmode-channel-editor (chn)
- % This procedure is called every time that input is requested from an NMODE
- % buffer. It starts up NMODE (if not already running) and resumes NMODE
- % execution. When the user has decided on what input to give to the channel
- % (by performing Lisp-E), the NMODE-reader will return with I/O bound to the
- % "buffer channel". The reader will also return if the user performs Lisp-L,
- % in which case I/O will remain bound to the "standard" channels.
- % Select "old" channels, so if an error occurs we don't get a bad recursive
- % situation where printing into a buffer causes more trouble!
- (nmode-select-old-channels)
- (cond ((not *NMODE-RUNNING)
- (setf *NMODE-RUNNING T)
- (setf *GC NIL)
- (if (not *nmode-init-has-run)
- (nmode-run-init-file)
- )
- )
- (t
- (buffer-channel-flush nmode-buffer-channel)
- (setf nmode-output-end-position (=> nmode-output-buffer position))
- % compensate for moving to line start on next Lisp-E:
- (if (not (at-line-start?))
- (move-to-next-line))
- )
- )
- (enter-raw-mode)
- (nmode-select-major-window) % just in case
- (NMODE-reader NIL) % NIL => don't exit when a command aborts
- )
- (de nmode-main ()
- (setf CurrentReadMacroIndicator* 'LispReadMacro) % Crock!
- (setf CurrentScanTable* LispScanTable*)
- (when (not toploopread*)
- (setf toploopread* 'read)
- (setf toploopprint* 'print)
- (setf toploopeval* 'eval)
- (setf toploopname* "NMODE Lisp")
- )
- (nmode-initialize) % does nothing if already initialized
- (nmode-set-terminal) % ensure proper terminal driver is loaded
- % Note: RESET may cause echoing to be turned on without clearing *RawIO.
- (when *RawIO
- (setf *RawIO NIL)
- (EchoOff)
- )
- (when nmode-first-start
- (setf nmode-first-start NIL) % never again
- (cond (nmode-auto-start
- (setf *NMODE-RUNNING T) % see below
- (let ((was-modified? (=> nmode-output-buffer modified?)))
- (=> nmode-output-buffer insert-line LispBanner*)
- (if (not was-modified?)
- (=> nmode-output-buffer set-modified? NIL)
- )))
- (t
- (printf "%w%n" LispBanner*)
- ))
- )
- (while T
- (setf nmode-terminal-input-buffer NIL) % flush execution from buffers
- (cond (*NMODE-RUNNING
- (setf *NMODE-RUNNING NIL) % force full start-up
- (nmode) % cause next READ to start up NMODE
- )
- (t
- (RDS 0)
- (WRS 1)
- ))
- (nmode-top-loop)
- ))
- (copyd 'main 'nmode-main)
- (de nmode-top-loop ()
- (TopLoop toploopread* toploopprint* toploopeval* toploopname* "")
- (Printf "End of File read!")
- )
|