diff options
author | Jim Blandy <jimb@red-bean.com> | 1997-10-22 20:18:02 +0000 |
---|---|---|
committer | Jim Blandy <jimb@red-bean.com> | 1997-10-22 20:18:02 +0000 |
commit | 4f33c6cd619749d2bb1365b205403e219579a03c (patch) | |
tree | 192b8742967591984a7d580246b3526d64ed62a4 | |
parent | b0880257363873ba8b92e6bebcc2f6c344d32d50 (diff) | |
download | guile-4f33c6cd619749d2bb1365b205403e219579a03c.tar.gz |
Add support for readline function.
* readline.scm: New module.
* boot-9.scm (repl-reader): New function.
(scm-style-repl): Call repl-reader, instead of doing the reading
ourselves. Remove repl-report-reset; it was never used for
anything.
(top-repl): If we've got the readline primitives, then redefine
repl-reader to use them.
If we've got the readline primitives, import the readline module.
-rw-r--r-- | ice-9/boot-9.scm | 51 | ||||
-rw-r--r-- | ice-9/readline.scm | 72 |
2 files changed, 112 insertions, 11 deletions
diff --git a/ice-9/boot-9.scm b/ice-9/boot-9.scm index c1e27ab0d..34f603251 100644 --- a/ice-9/boot-9.scm +++ b/ice-9/boot-9.scm @@ -2424,11 +2424,18 @@ (define before-read-hook '()) (define after-read-hook '()) +;;; The default repl-reader function. We may override this if we've +;;; the readline library. +(define repl-reader + (lambda (prompt) + (display prompt) + (force-output) + (read (current-input-port)))) + (define (scm-style-repl) (letrec ( (start-gc-rt #f) (start-rt #f) - (repl-report-reset (lambda () #f)) (repl-report-start-timing (lambda () (set! start-gc-rt (gc-run-time)) (set! start-rt (get-internal-run-time)))) @@ -2454,17 +2461,19 @@ ((char=? ch #\newline) (read-char)))))) (-read (lambda () - (if scm-repl-prompt - (begin - (display (cond ((string? scm-repl-prompt) - scm-repl-prompt) - ((thunk? scm-repl-prompt) - (scm-repl-prompt)) - (else "> "))) - (force-output) - (repl-report-reset))) + ;; It would be nice if we could run this after the + ;; first prompt was printed, but with readline + ;; that's not possible, so we punt. (run-hooks before-read-hook) - (let ((val (read (current-input-port)))) + (let ((val + (let ((prompt (cond ((string? scm-repl-prompt) + scm-repl-prompt) + ((thunk? scm-repl-prompt) + (scm-repl-prompt)) + (scm-repl-prompt "> ") + (else "")))) + (repl-reader prompt)))) + ;; As described in R4RS, the READ procedure updates the ;; port to point to the first characetr past the end of ;; the external representation of the object. This @@ -2747,6 +2756,17 @@ ;; the protected thunk. (lambda () + + ;; If we've got readline, use it to prompt the user. This is a + ;; kludge, but we'll fix it soon. At least we only get + ;; readline involved when we're actually running the repl. + (if (memq 'readline *features*) + (begin + (set-current-input-port (readline-port)) + (set! repl-reader + (lambda (prompt) + (set-readline-prompt! prompt) + (read))))) (scm-style-repl)) ;; call at exit. @@ -2811,6 +2831,15 @@ (define-module (guile) :use-module (ice-9 regex))) +;;; Load readline code if rreadline primitives are available. +;;; +;;; Ideally, we wouldn't do this until we were sure we were actually +;;; going to enter the repl, but autoloading individual functions is +;;; clumsy at the moment. +(if (memq 'readline *features*) + (define-module (guile) :use-module (ice-9 readline))) + + ;;; {Check that the interpreter and scheme code match up.} (let ((show-line diff --git a/ice-9/readline.scm b/ice-9/readline.scm new file mode 100644 index 000000000..cb47d6522 --- /dev/null +++ b/ice-9/readline.scm @@ -0,0 +1,72 @@ +;;;; readline.scm --- support functions for command-line editing +;;;; +;;;; Copyright (C) 1997 Free Software Foundation, Inc. +;;;; +;;;; This program is free software; you can redistribute it and/or modify +;;;; it under the terms of the GNU General Public License as published by +;;;; the Free Software Foundation; either version 2, or (at your option) +;;;; any later version. +;;;; +;;;; This program is distributed in the hope that it will be useful, +;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;;; GNU General Public License for more details. +;;;; +;;;; You should have received a copy of the GNU General Public License +;;;; along with this software; see the file COPYING. If not, write to +;;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +;;;; +;;;; Contributed by Daniel Risacher <risacher@worldnet.att.net>. + +(define-module (ice-9 readline)) + +(define prompt "") + +(define (make-readline-port) + (let ((read-string "") + (string-index -1)) + (letrec ((get-character + (lambda () + (cond + ((eof-object? read-string) + read-string) + ((>= string-index (string-length read-string)) + (begin + (set! string-index -1) + #\nl)) + ((= string-index -1) + (begin + (set! read-string (readline prompt)) + (set! string-index 0) + (if (not (eof-object? read-string)) + (begin + (or (string=? read-string "") + (add-history read-string)) + (get-character)) + read-string))) + (else + (let ((res (string-ref read-string string-index))) + (set! string-index (+ 1 string-index)) + res)))))) + (make-soft-port + (vector write-char display #f get-character #f) + "rw")))) + +;;; We only create one readline port. There's no point in having +;;; more, since they would all share the tty and history --- +;;; everything except the prompt. And don't forget the +;;; compile/load/run phase distinctions. +(define the-readline-port #f) + +(define-public (readline-port) + (if (not the-readline-port) + (set! the-readline-port (make-readline-port))) + the-readline-port) + +(define-public (set-readline-prompt! p) + (set! prompt p)) + + +;(define myport (make-readline-port)) +;(define (doit) +; (set-current-input-port myport)) |