62 lines
1.7 KiB
Scheme
62 lines
1.7 KiB
Scheme
|
|
(let*-values ([(.history) "~/.mzrl.history"]
|
|
[(MAX-HISTORY) 100]
|
|
[(readline add-history) (require-library "readline.ss" "readline")]
|
|
[(leftovers) null]
|
|
[(local-history)
|
|
(with-handlers ([void (lambda (exn) null)])
|
|
(with-input-from-file .history
|
|
(lambda () (read))))]
|
|
[(do-readline)
|
|
(lambda (p)
|
|
(let ([s (readline p)])
|
|
(when (string? s)
|
|
(add-history s)
|
|
(if (= (length local-history) MAX-HISTORY)
|
|
(set! local-history (cdr local-history)))
|
|
(set! local-history (append local-history (list s))))
|
|
s))]
|
|
[(save-history)
|
|
(lambda ()
|
|
(with-handlers ([void void])
|
|
(with-output-to-file .history
|
|
(lambda () (write local-history))
|
|
'truncate)))])
|
|
(exit-handler (let ([old (exit-handler)])
|
|
(lambda (v)
|
|
(save-history)
|
|
(old v))))
|
|
(for-each add-history local-history)
|
|
(let ([prompt-read-using-readline
|
|
(lambda (get-prompt)
|
|
(if (pair? leftovers)
|
|
(begin0
|
|
(car leftovers)
|
|
(set! leftovers (cdr leftovers)))
|
|
(let big-loop ()
|
|
(let loop ([s (do-readline (get-prompt 0))][next-pos 1])
|
|
(if (eof-object? s)
|
|
(begin
|
|
(save-history)
|
|
s)
|
|
(with-handlers ([exn:read:eof?
|
|
(lambda (exn)
|
|
(loop (string-append
|
|
s
|
|
(string #\newline)
|
|
(do-readline (get-prompt next-pos)))
|
|
(add1 next-pos)))])
|
|
(let* ([p (open-input-string s)]
|
|
[rs (let loop ()
|
|
(let ([r (read p)])
|
|
(if (eof-object? r)
|
|
null
|
|
(cons r (loop)))))])
|
|
(if (null? rs)
|
|
(big-loop)
|
|
(begin0
|
|
(car rs)
|
|
(set! leftovers (cdr rs)))))))))))])
|
|
prompt-read-using-readline))
|
|
|