mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-22 07:09:18 +02:00
line editor now waits for complete sexps
This commit is contained in:
parent
3b14c5ae7b
commit
6cd9654701
3 changed files with 51 additions and 32 deletions
|
@ -1,17 +1,8 @@
|
||||||
;;;; repl.scm - friendlier repl with line editing and signal handling
|
;;;; repl.scm - friendlier repl with line editing and signal handling
|
||||||
;;
|
;;
|
||||||
;; Copyright (c) 2010 Alex Shinn. All rights reserved.
|
;; Copyright (c) 2011 Alex Shinn. All rights reserved.
|
||||||
;; BSD-style license: http://synthcode.com/license.txt
|
;; BSD-style license: http://synthcode.com/license.txt
|
||||||
|
|
||||||
(define-syntax handle-exceptions
|
|
||||||
(syntax-rules ()
|
|
||||||
((handle-exceptions exn handle-expr expr)
|
|
||||||
(call-with-current-continuation
|
|
||||||
(lambda (return)
|
|
||||||
(with-exception-handler
|
|
||||||
(lambda (exn) (return handle-expr))
|
|
||||||
(lambda () expr)))))))
|
|
||||||
|
|
||||||
(define (with-signal-handler sig handler thunk)
|
(define (with-signal-handler sig handler thunk)
|
||||||
(let ((old-handler #f))
|
(let ((old-handler #f))
|
||||||
(dynamic-wind
|
(dynamic-wind
|
||||||
|
@ -19,27 +10,34 @@
|
||||||
thunk
|
thunk
|
||||||
(lambda () (set-signal-action! sig old-handler)))))
|
(lambda () (set-signal-action! sig old-handler)))))
|
||||||
|
|
||||||
|
(define (buffer-complete-sexp? buf)
|
||||||
|
(guard (exn (else #f))
|
||||||
|
(call-with-input-string (buffer->string buf) read)
|
||||||
|
#t))
|
||||||
|
|
||||||
(define (run-repl module env . o)
|
(define (run-repl module env . o)
|
||||||
(let ((history (make-history)))
|
(let ((history (make-history)))
|
||||||
(let lp ((module module) (env env))
|
(let lp ((module module) (env env))
|
||||||
(let ((line
|
(let ((line
|
||||||
(edit-line
|
(edit-line
|
||||||
(string-append (if module (symbol->string module) "") "> ")
|
(string-append (if module (symbol->string module) "") "> ")
|
||||||
'history: history)))
|
'history: history
|
||||||
|
'complete?: buffer-complete-sexp?)))
|
||||||
(cond
|
(cond
|
||||||
((or (not line) (eof-object? line)))
|
((or (not line) (eof-object? line)))
|
||||||
((equal? line "") (lp module env))
|
((equal? line "") (lp module env))
|
||||||
(else
|
(else
|
||||||
(history-commit! history line)
|
(history-commit! history line)
|
||||||
(handle-exceptions
|
(guard
|
||||||
exn
|
(exn
|
||||||
(print-exception exn (current-error-port))
|
(else (print-exception exn (current-error-port))))
|
||||||
(let* ((expr (call-with-input-string line read/ss))
|
(let* ((expr (call-with-input-string line read/ss))
|
||||||
(thread (make-thread
|
(thread
|
||||||
|
(make-thread
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(handle-exceptions
|
(guard
|
||||||
exn
|
(exn
|
||||||
(print-exception exn (current-error-port))
|
(else (print-exception exn (current-error-port))))
|
||||||
(let ((res (eval expr env)))
|
(let ((res (eval expr env)))
|
||||||
(cond
|
(cond
|
||||||
((not (eq? res (if #f #f)))
|
((not (eq? res (if #f #f)))
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
(define-module (chibi term edit-line)
|
(define-module (chibi term edit-line)
|
||||||
(export edit-line edit-line-repl make-history history-insert! history-commit!)
|
(export edit-line edit-line-repl make-history history-insert! history-commit!
|
||||||
|
buffer->string)
|
||||||
(import-immutable (scheme) (chibi stty) (srfi 9))
|
(import-immutable (scheme) (chibi stty) (srfi 9))
|
||||||
(include "edit-line.scm"))
|
(include "edit-line.scm"))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;;; edit-line.scm - pure scheme line editing tool
|
;;;; edit-line.scm - pure scheme line editor
|
||||||
;;
|
;;
|
||||||
;; Copyright (c) 2010 Alex Shinn. All rights reserved.
|
;; Copyright (c) 2011 Alex Shinn. All rights reserved.
|
||||||
;; BSD-style license: http://synthcode.com/license.txt
|
;; BSD-style license: http://synthcode.com/license.txt
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
@ -104,6 +104,13 @@
|
||||||
((< i start))
|
((< i start))
|
||||||
(string-set! dst j (string-ref src i)))))
|
(string-set! dst j (string-ref src i)))))
|
||||||
|
|
||||||
|
(define (string-index ch x)
|
||||||
|
(let ((len (string-length x)))
|
||||||
|
(let lp ((i 0))
|
||||||
|
(cond ((>= i len) #f)
|
||||||
|
((eqv? ch (string-ref x i)))
|
||||||
|
(else (lp (+ i 1)))))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; buffers
|
;; buffers
|
||||||
|
|
||||||
|
@ -120,7 +127,8 @@
|
||||||
(width buffer-width buffer-width-set!)
|
(width buffer-width buffer-width-set!)
|
||||||
(string buffer-string buffer-string-set!)
|
(string buffer-string buffer-string-set!)
|
||||||
(kill-ring buffer-kill-ring buffer-kill-ring-set!)
|
(kill-ring buffer-kill-ring buffer-kill-ring-set!)
|
||||||
(history buffer-history buffer-history-set!))
|
(history buffer-history buffer-history-set!)
|
||||||
|
(complete? buffer-complete? buffer-complete?-set!))
|
||||||
|
|
||||||
(define default-buffer-size 256)
|
(define default-buffer-size 256)
|
||||||
(define default-buffer-width 80)
|
(define default-buffer-width 80)
|
||||||
|
@ -159,6 +167,7 @@
|
||||||
(define (buffer-update-position! buf)
|
(define (buffer-update-position! buf)
|
||||||
(let ((pos (buffer-pos buf))
|
(let ((pos (buffer-pos buf))
|
||||||
(gap (buffer-gap buf))
|
(gap (buffer-gap buf))
|
||||||
|
(str (buffer-string buf))
|
||||||
(end (string-length (buffer-string buf)))
|
(end (string-length (buffer-string buf)))
|
||||||
(width (buffer-width buf)))
|
(width (buffer-width buf)))
|
||||||
(let lp ((i 0) (row 0) (col 0)) ;; update row/col
|
(let lp ((i 0) (row 0) (col 0)) ;; update row/col
|
||||||
|
@ -169,6 +178,8 @@
|
||||||
((>= i end)
|
((>= i end)
|
||||||
(buffer-max-row-set!
|
(buffer-max-row-set!
|
||||||
buf (if (and (zero? col) (> row 0)) (- row 1) row)))
|
buf (if (and (zero? col) (> row 0)) (- row 1) row)))
|
||||||
|
((eqv? #\newline (string-ref str i))
|
||||||
|
(lp (+ i 1) (+ row 1) 0))
|
||||||
((= (+ col 1) width)
|
((= (+ col 1) width)
|
||||||
(lp (+ i 1) (+ row 1) 0))
|
(lp (+ i 1) (+ row 1) 0))
|
||||||
(else
|
(else
|
||||||
|
@ -234,7 +245,10 @@
|
||||||
(cond
|
(cond
|
||||||
((buffer-refresh? buf))
|
((buffer-refresh? buf))
|
||||||
((and (= (buffer-gap buf) (string-length (buffer-string buf)))
|
((and (= (buffer-gap buf) (string-length (buffer-string buf)))
|
||||||
(< (+ (buffer-col buf) len) (buffer-width buf)))
|
(< (+ (buffer-col buf) len) (buffer-width buf))
|
||||||
|
(if (char? x)
|
||||||
|
(not (eqv? x #\newline))
|
||||||
|
(not (string-index #\newline x))))
|
||||||
;; fast path - append to end of buffer w/o wrapping to next line
|
;; fast path - append to end of buffer w/o wrapping to next line
|
||||||
(display x out)
|
(display x out)
|
||||||
(buffer-col-set! buf (+ (buffer-col buf) len)))
|
(buffer-col-set! buf (+ (buffer-col buf) len)))
|
||||||
|
@ -344,9 +358,13 @@
|
||||||
(buffer-insert! buf out ch))
|
(buffer-insert! buf out ch))
|
||||||
|
|
||||||
(define (command/enter ch buf out return)
|
(define (command/enter ch buf out return)
|
||||||
|
(cond
|
||||||
|
(((buffer-complete? buf) buf)
|
||||||
(command/end-of-line ch buf out return)
|
(command/end-of-line ch buf out return)
|
||||||
(newline out)
|
(newline out)
|
||||||
(return))
|
(return))
|
||||||
|
(else
|
||||||
|
(command/self-insert ch buf out return))))
|
||||||
|
|
||||||
(define (command/beep ch buf out return)
|
(define (command/beep ch buf out return)
|
||||||
(write-char (integer->char 7) out))
|
(write-char (integer->char 7) out))
|
||||||
|
@ -442,6 +460,7 @@
|
||||||
(define (make-line-editor . args)
|
(define (make-line-editor . args)
|
||||||
(let* ((prompt (get-key args 'prompt: "> "))
|
(let* ((prompt (get-key args 'prompt: "> "))
|
||||||
(history (get-key args 'history:))
|
(history (get-key args 'history:))
|
||||||
|
(complete? (get-key args 'complete?: (lambda (buf) #t)))
|
||||||
(terminal-width (get-key args 'terminal-width:))
|
(terminal-width (get-key args 'terminal-width:))
|
||||||
(keymap (get-key args 'keymap: standard-keymap)))
|
(keymap (get-key args 'keymap: standard-keymap)))
|
||||||
(lambda (in out)
|
(lambda (in out)
|
||||||
|
@ -454,6 +473,7 @@
|
||||||
(buffer-insert! buf out prompt)
|
(buffer-insert! buf out prompt)
|
||||||
(buffer-min-set! buf (string-length prompt))
|
(buffer-min-set! buf (string-length prompt))
|
||||||
(buffer-history-set! buf history)
|
(buffer-history-set! buf history)
|
||||||
|
(buffer-complete?-set! buf complete?)
|
||||||
(buffer-refresh buf out)
|
(buffer-refresh buf out)
|
||||||
(flush-output out)
|
(flush-output out)
|
||||||
((if (get-key args 'no-stty?:) (lambda (out f) (f)) with-raw-io)
|
((if (get-key args 'no-stty?:) (lambda (out f) (f)) with-raw-io)
|
||||||
|
|
Loading…
Add table
Reference in a new issue