1 ;;; user.rkt -- global bindings visible to geiser users
3 ;; Copyright (C) 2010, 2011, 2012, 2013 Jose Antonio Ortega Ruiz
5 ;; This program is free software; you can redistribute it and/or
6 ;; modify it under the terms of the Modified BSD License. You should
7 ;; have received a copy of the license along with this program. If
8 ;; not, see <http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5>.
10 ;; Start date: Wed Mar 31, 2010 22:24
14 (provide init-geiser-repl run-geiser-server start-geiser)
16 (require (for-syntax racket/base)
27 (define top-namespace (current-namespace))
28 (define last-entered (make-parameter ""))
30 (define (do-enter mod name)
32 (current-namespace (module->namespace mod))
35 (define (submod-path mod)
37 (eq? 'submod (car mod))
39 (let ([parent (cadr mod)])
40 (cond [(path-string? parent) `(submod (file ,parent) ,@(cddr mod))]
41 [(symbol? parent) mod]
44 (define (enter! mod stx)
46 (current-namespace top-namespace)
48 [(symbol? mod) (do-enter mod (symbol->string mod))]
49 [(path-string? mod) (do-enter `(file ,mod) mod)]
53 (path-string? (cadr mod))) (do-enter mod (cadr mod))]
54 [(submod-path mod) => (lambda (m) (do-enter m m))]
55 [else (raise-syntax-error #f "Invalid module path" stx mod)]))
57 (define orig-loader (current-load/use-compiled))
58 (define geiser-loader (module-loader orig-loader))
61 (define geiser-main (module->namespace 'geiser))
62 (define (eval-here form) (eval form geiser-main))
68 (cond [(equal? form '(unquote apply))
69 (let* ([proc (eval-here (read))]
70 [args (map eval-here (read))]
71 [ev (lambda () (apply proc args))])
72 (eval-in `(,ev) mod lang))]
73 [else ((geiser:eval lang) form mod)])))))
75 (define ((geiser-read prompt))
77 (flush-output (current-error-port))
78 (flush-output (current-output-port))
79 (let* ([in ((current-get-interaction-input-port))]
80 [form ((current-read-interaction) (object-name in) in)])
82 [(uq cmd) (eq? 'unquote (syntax-e #'uq))
83 (case (syntax-e #'cmd)
84 [(start-geiser) (datum->syntax #f `(list 'port ,(start-geiser)))]
85 [(enter) (enter! (read) #'cmd)]
86 [(geiser-eval) (geiser-eval)]
87 [(geiser-no-values) (datum->syntax #f (void))]
88 [(add-to-load-path) (add-to-load-path (read))]
89 [(set-image-cache) (image-cache (read))]
90 [(help) (get-help (read) (read))]
91 [(image-cache) (image-cache)]
92 [(gcd) (current-directory)]
93 [(cd) (current-directory (read))]
99 (let ([m (namespace->module-name (current-namespace) (last-entered))])
100 (printf "racket@~a> " (regexp-replace* " " m "_")))))
102 (define (geiser-prompt-read prompt)
103 (make-repl-reader (geiser-read prompt)))
105 (define (init-geiser-repl)
106 (compile-enforce-module-constants #f)
107 (current-load/use-compiled geiser-loader)
109 (current-prompt-read (geiser-prompt-read geiser-prompt))
110 (current-print maybe-print-image))
112 (define (run-geiser-repl in out enforce-module-constants)
113 (parameterize [(compile-enforce-module-constants enforce-module-constants)
114 (current-input-port in)
115 (current-output-port out)
116 (current-error-port out)
117 (current-load/use-compiled geiser-loader)
118 (current-prompt-read (geiser-prompt-read geiser-prompt))
119 (current-print maybe-print-image)]
121 (read-eval-print-loop)))
123 (define server-channel (make-channel))
125 (define (run-geiser-server port enforce-module-constants (hostname #f))
128 (run-geiser-repl in out enforce-module-constants))
132 (let ([lsner (tcp-listen p 4 #f hostname)])
133 (let-values ([(_ p __ ___) (tcp-addresses lsner #t)])
134 (channel-put server-channel p)
137 (define (start-geiser (port 0) (hostname #f) (enforce-module-constants #f))
139 (run-geiser-server port enforce-module-constants hostname)))
140 (channel-get server-channel))