Skip to content

Commit

Permalink
add first draft of a repl with expeditor support
Browse files Browse the repository at this point in the history
  • Loading branch information
willghatch committed Apr 21, 2022
1 parent 1165297 commit 1f1d63f
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 19 deletions.
66 changes: 66 additions & 0 deletions rash/repl-expeditor.rkt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#lang racket/base
;; The parameterization doesn't seem to work if I dynamically require expeditor.
;; So I'll just make a dedicated module for the expeditor version of the repl.
;; This may mean that I'm doing something wrong... a quick look at the xrepl
;; implementation shows me that it dynamically requires expeditor... but it
;; doesn't use `call-with-expeditor`. Maybe if I do the open/read/close stuff
;; like xrepl I can get it to work.
;;
;; Anyway, I would like to get expeditor mode working as a flag to the normal
;; repl module.
;;
;; ALSO - this is silently failing in weird ways when my TERM variable is set to
;; something that it doesn't recognize. This definitely isn't ready for prime time.
;; More specifically, it still seems to run the rash-repl function, but without
;; properly parameterizing the read function, which then returns a single syntax
;; object read with racket's default reader instead of a list of syntax objects
;; read with the linea reader. I'm not sure how it's getting to that point and
;; not throwing an exception or something, though.
(require (submod "repl.rkt" _out-for-expeditor)
expeditor
racket/port
racket/string
)

(expeditor-configure)
(call-with-expeditor
(λ (e-read)
(define orig-indenter (current-expeditor-indenter))
(parameterize ([current-expeditor-reader (λ (in) (port->list repl-read in))]
;[current-expeditor-color-enabled #t]
[current-expeditor-ready-checker
(λ (in)
(with-handlers ([(λ (e) #t) (λ (e) #f)])
(define contents (port->string in))
(define stripped (string-trim contents))
(define re-in (open-input-string contents))
(define vals
(with-handlers ([(λ (e) #t) (λ (e) #f)])
(port->list repl-read re-in)))
(and (not (equal? "" stripped)) vals)))]
;; The default indenter crashed on me, so I don't trust it.
[current-expeditor-indenter (λ args
(with-handlers
([(λ (e) #t) (λ (e) #f)])
(apply orig-indenter args)))]
;; Whatever the default expeditor lexer is gives me something
;; useful, while the syntax-color/default-lexer doesn't.
;[current-expeditor-lexer
; (dynamic-require 'syntax-color/default-lexer
; 'default-lexer)]
;; This doesn't seem to do anything.
;[current-expeditor-parentheses
; (map (λ (x) (map string->symbol x))
; '(("(" ")")
; ("[" "]")
; ("{" "}")
; ("«" "»")
; ("“" "”")
; ("◸" "◹")
; ("◺" "◿")
; ("◤" "◥")
; ("◣" "◢")
; ))]
)
;; TODO - the expeditor implementation includes a current-expeditor-completer, but it's not exported.
(rash-repl (void) 0 #f e-read))))
59 changes: 40 additions & 19 deletions rash/repl.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,14 @@
(cleanup!)
(exit))


(define (rash-repl last-ret-val n input-port)
(define (repl-read input-port)
(linea-read-syntax (object-name input-port) input-port))

(define (rash-repl last-ret-val n input-port expeditor-read)
(define read-func
(if expeditor-read
expeditor-read
(λ () (list (repl-read input-port)))))
(with-handlers ([exn:break:hang-up? (λ (e) (clean/exit))]
[exn:break:terminate? (λ (e) (clean/exit))]
[(λ _ #t) (λ (e) (eprintf "error in prompt function: ~a\n" e))])
Expand All @@ -71,22 +77,35 @@
(flush-output (current-output-port))
(flush-output (current-error-port))
(set-box! cwd-hack-box (current-directory))
(let* ([next-input (with-handlers ([exn:break:hang-up? (λ (e) (clean/exit))]
[exn:break:terminate? (λ (e) (clean/exit))]
[exn? (λ (e) (eprintf "~a\n" e)
(let* ([next-inputs (with-handlers ([exn:break:hang-up? (λ (e) (clean/exit))]
[exn:break:terminate? (λ (e) (clean/exit))]
[exn? (λ (e) (eprintf "~a\n" e)
#`(void))])
(linea-read-syntax (object-name input-port)
input-port))]
[exit? (if (equal? next-input eof) (clean/exit) #f)])
(let* ([ret-val-list
(call-with-values
(λ () (with-handlers ([exn:break:hang-up? (λ (e) (clean/exit))]
[exn:break:terminate? (λ (e) (clean/exit))]
[(λ (e) #t) (λ (e) e)])
(repl-eval next-input)))
list)]
[ret-val (if (equal? (length ret-val-list)
1)
(read-func))]
[exit? (if (or (eof-object? next-inputs)
(null? next-inputs))
(clean/exit)
#f)])
(let* ([eval-1
(λ (one-stx)
(call-with-values
(λ () (with-handlers ([exn:break:hang-up? (λ (e) (clean/exit))]
[exn:break:terminate? (λ (e) (clean/exit))]
[(λ (e) #t) (λ (e) e)])
(repl-eval one-stx)))
list))]
[ret-val-list-list
(for/list ([next-input next-inputs])
(if (eof-object? next-input)
(clean/exit)
(eval-1 next-input)))]
[ret-val-list (map (λ (ret-val-list)
(if (equal? (length ret-val-list)
1)
(car ret-val-list)
ret-val-list))
ret-val-list-list)]
[ret-val (if (equal? (length ret-val-list) 1)
(car ret-val-list)
ret-val-list)]
[new-n (add1 n)])
Expand All @@ -96,7 +115,7 @@
;; Sleep just long enough to give any filter ports (eg a highlighted stderr)
;; to be able to output before the next prompt.
(sleep 0.01)
(rash-repl ret-val new-n input-port))))
(rash-repl ret-val new-n input-port expeditor-read))))

(define (repl-eval stx #:splice [splice #f])
(eval-syntax
Expand Down Expand Up @@ -214,10 +233,12 @@
(eval-rash-file eval-rashrc "rashrc")
(eval '(repl-display-startup-hint))

(rash-repl (void) 0 input-port-for-repl)
(rash-repl (void) 0 input-port-for-repl #f)

(printf "and now exiting for some reason\n")
(clean/exit))

(module+ main
(main))
(module+ _out-for-expeditor
(provide rash-repl repl-read))

0 comments on commit 1f1d63f

Please sign in to comment.