53 lines
1.5 KiB
Racket
53 lines
1.5 KiB
Racket
#lang racket/base
|
|
|
|
(provide read-pre-prompt
|
|
read-actual-prompt
|
|
skip-newline
|
|
peek-read-length
|
|
narrow-next-read
|
|
peak-until-prompt-length
|
|
narrow-until-prompt
|
|
silent-prompt-read)
|
|
|
|
(require racket/syntax
|
|
racket/port)
|
|
|
|
(define (read-pre-prompt in)
|
|
(regexp-try-match #px"^\\s*" in))
|
|
|
|
(define (read-actual-prompt in)
|
|
(regexp-try-match #px"^> " in))
|
|
|
|
(define (skip-newline in)
|
|
(regexp-try-match #px"^\n" in))
|
|
|
|
(define (peek-read-length in)
|
|
(let* ([pk (peeking-input-port in)]
|
|
[start (file-position pk)]
|
|
[r (read pk)]
|
|
[end (file-position pk)])
|
|
(- end start)))
|
|
|
|
(define (narrow-next-read in)
|
|
(make-limited-input-port in (peek-read-length in)))
|
|
|
|
(define (peak-until-prompt-length in)
|
|
(let* ([pk (peeking-input-port in)]
|
|
[start (file-position pk)]
|
|
[end (let loop ()
|
|
(let* ([pre (read-pre-prompt pk)]
|
|
[pos (file-position pk)]
|
|
[pr (read-actual-prompt pk)])
|
|
(if (or pr (eof-object? (read pk)))
|
|
pos
|
|
(loop))))])
|
|
(- end start)))
|
|
|
|
(define (narrow-until-prompt in)
|
|
(make-limited-input-port in (peak-until-prompt-length in)))
|
|
|
|
;; Just like the default `current-prompt-read`, but without showing the prompt.
|
|
(define silent-prompt-read
|
|
(λ ()
|
|
(let ([in ((current-get-interaction-input-port))])
|
|
((current-read-interaction) (object-name in) in)))) |