Skip to content
Browse files

Factor out :repl-options handling into its own function.

  • Loading branch information...
1 parent b5002a2 commit 4b994497ee277d28b9058d3def95622f57c2573a @technomancy committed Feb 28, 2011
Showing with 64 additions and 58 deletions.
  1. +64 −58 src/leiningen/repl.clj
View
122 src/leiningen/repl.clj
@@ -10,62 +10,69 @@
(def *retry-limit* 100)
-(defn repl-server [project host port & repl-options]
- (let [init-form [:init `#(let [is# ~(:repl-init-script project)
- in# ~(:repl-init project)
- mn# '~(:main project)]
- (when (and is# (.exists (File. (str is#))))
- (println (str "Warning: :repl-init-script is "
- "deprecated; use :repl-init."))
- (load-file is#))
- (when in#
- (doto in# require in-ns))
- (if mn#
- (doto mn# require in-ns)
- (in-ns '~'user)))]
- repl-options (concat init-form repl-options)]
- `(do (try ;; transitive requires don't work for stuff on bootclasspath
- (require '~'clojure.java.shell)
- (require '~'clojure.java.browse)
- ;; these are new in clojure 1.2, so swallow exceptions for 1.1
- (catch Exception _#))
- (let [server# (ServerSocket. ~port 0 (InetAddress/getByName ~host))
- acc# (fn [s#]
- (let [ins# (.getInputStream s#)
- outs# (.getOutputStream s#)
- skip-whitespace# @(ns-resolve '~'clojure.main
- '~'skip-whitespace)
- ;; Suppress socket closed exceptions since
- ;; they are part of normal operation
- caught# (fn [t#]
- (when-not (instance? SocketException t#)
- (throw t#)))]
- (doto (Thread.
- #(binding [*in* (-> ins# InputStreamReader.
- LineNumberingPushbackReader.)
- *out* (OutputStreamWriter. outs#)
- *err* *err*
- ;; TODO: bugger; can't rebind in 1.3
- ;; clojure.main/repl has no way
- ;; to exit without signalling EOF,
- ;; which we can't do with a socket.
- clojure.main/skip-whitespace
- (fn [s#]
- (try (skip-whitespace# s#)
- (catch java.io.IOException _#
- :stream-end)))]
- (clojure.main/repl :caught caught#
- ~@repl-options)))
- .start)))]
- (doto (Thread. #(when-not (.isClosed server#)
- (try
- (acc# (.accept server#))
- (catch SocketException e#
- (.printStackTrace e#)))
- (recur)))
- .start)
- (symbol (format "REPL started; server listening on %s:%s."
- ~host ~port))))))
+;; TODO: test custom options, repl in interactive
+(defn repl-options [project options]
+ (let [options (apply hash-map options)
+ init `#(let [is# ~(:repl-init-script project)
+ in# ~(:repl-init project)
+ mn# '~(:main project)]
+ ~(:init options)
+ (when (and is# (.exists (File. (str is#))))
+ (println (str "Warning: :repl-init-script is "
+ "deprecated; use :repl-init."))
+ (load-file is#))
+ (when in#
+ (doto in# require in-ns))
+ (if mn#
+ (doto mn# require in-ns)
+ (in-ns '~'user)))
+ ;; Suppress socket closed since it's part of normal operation
+ caught `(fn [t#]
+ (when-not (instance? SocketException t#)
+ (~(:caught options 'clojure.main/repl-caught) t#)))
+ ;; clojure.main/repl has no way to exit without signalling EOF,
+ ;; which we can't do with a socket. We can't rebind skip-whitespace
+ ;; in Clojure 1.3, so we have to duplicate the function
+ read `(fn [request-prompt# request-exit#]
+ (or ({:line-start request-prompt# :stream-end request-exit#}
+ (try (clojure.main/skip-whitespace *in*)
+ (catch java.io.IOException _#
+ :stream-end)))
+ (let [input# (read)]
+ (clojure.main/skip-if-eol *in*)
+ input#)))]
+ (concat [:init init :caught caught :read read]
+ (flatten (seq (dissoc options :caught :init :read))))))
+
+(defn repl-server [project host port & options]
+ `(do (try ;; transitive requires don't work for stuff on bootclasspath
+ (require '~'clojure.java.shell)
+ (require '~'clojure.java.browse)
+ ;; these are new in clojure 1.2, so swallow exceptions for 1.1
+ (catch Exception _#))
+ (let [server# (ServerSocket. ~port 0 (InetAddress/getByName ~host))
+ acc# (fn [s#]
+ (let [ins# (.getInputStream s#)
+ outs# (.getOutputStream s#)
+ skip-whitespace# @(ns-resolve '~'clojure.main
+ '~'skip-whitespace)]
+ (doto (Thread.
+ #(binding [*in* (-> ins# InputStreamReader.
+ LineNumberingPushbackReader.)
+ *out* (OutputStreamWriter. outs#)
+ *err* *err*]
+ (clojure.main/repl
+ ~@(repl-options project options))))
+ .start)))]
+ (doto (Thread. #(when-not (.isClosed server#)
+ (try
+ (acc# (.accept server#))
+ (catch SocketException e#
+ (.printStackTrace e#)))
+ (recur)))
+ .start)
+ (symbol (format "REPL started; server listening on %s:%s."
+ ~host ~port)))))
(defn copy-out-loop [reader]
(let [buffer (make-array Character/TYPE 1000)]
@@ -126,5 +133,4 @@ Running outside a project directory will start a standalone repl session."
(clojure.main/with-bindings (println (eval server-form)))
(eval-in-project project server-form)))
(poll-repl-connection port retries repl-client)
- (exit))))
-
+ 0)))

0 comments on commit 4b99449

Please sign in to comment.
Something went wrong with that request. Please try again.