Skip to content

Commit

Permalink
Flush output after *out-limit* characters
Browse files Browse the repository at this point in the history
Defaults to 1024, but can be rebound on any message with :out-limit.
  • Loading branch information
trptcolin committed Jun 21, 2012
1 parent 21d2fe5 commit 5bd3847
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 5 deletions.
10 changes: 8 additions & 2 deletions src/main/clojure/clojure/tools/nrepl/middleware/session.clj
Expand Up @@ -18,6 +18,8 @@
;; depending upon the expectations of the client/user. I'm not sure at the moment
;; how best to make it configurable though...

(def ^{:dynamic true} *out-limit* 1024)

(defn- session-out
"Returns a PrintWriter suitable for binding as *out* or *err*. All of
the content written to that PrintWriter will (when .flush-ed) be sent on the
Expand All @@ -33,7 +35,9 @@
(number? x) (.append buf (char x))
(not off) (.append buf x)
(instance? CharSequence x) (.append buf ^CharSequence x off len)
:else (.append buf ^chars x off len))))
:else (.append buf ^chars x off len))
(when (<= *out-limit* (.length buf))
(.flush ^Writer this))))
(flush []
(let [text (locking buf (let [text (str buf)]
(.setLength buf 0)
Expand Down Expand Up @@ -89,6 +93,7 @@
*err* (session-out :err id transport)
*in* in
*ns* (create-ns 'user)
*out-limit* (or (baseline-bindings #'*out-limit*) 1024)
; clojure.test captures *out* at load-time, so we need to make sure
; runtime output of test status/results is redirected properly
; TODO is this something we need to consider in general, or is this
Expand Down Expand Up @@ -139,13 +144,14 @@
*msg* to the currently-evaluated message so that session-specific *out*
and *err* content can be associated with the originating message)."
[h]
(fn [{:keys [op session transport] :as msg}]
(fn [{:keys [op session transport out-limit] :as msg}]
(let [the-session (if session
(@sessions session)
(create-session transport))]
(if-not the-session
(t/send transport (response-for msg :status #{:error :unknown-session}))
(let [msg (assoc msg :session the-session)]
(when out-limit (swap! the-session assoc #'*out-limit* out-limit))
(case op
"clone" (register-session msg)
"close" (close-session msg)
Expand Down
10 changes: 7 additions & 3 deletions src/main/java/clojure/tools/nrepl/StdOutBuffer.java
Expand Up @@ -3,9 +3,9 @@
/**
* This class exists solely so that the clojure side can call .setLength under JDK 1.5.
* Doing so with a StringBuilder/StringBuffer fails with:
*
*
* Can't call public method of non-public class: public void java.lang.AbstractStringBuilder.setLength(int)
*
*
* ...as documented in these outstanding bugs:
* http://dev.clojure.org/jira/browse/CLJ-126
* http://dev.clojure.org/jira/browse/CLJ-259
Expand All @@ -16,7 +16,11 @@ public class StdOutBuffer {
public void setLength (int x) {
sb.setLength(x);
}


public int length () {
return sb.length();
}

public void append(Object x) {
sb.append(x);
}
Expand Down
15 changes: 15 additions & 0 deletions src/test/clojure/clojure/tools/nrepl_test.clj
Expand Up @@ -94,6 +94,21 @@
(map :out)
(remove nil?)))))

(def-repl-test streaming-out-without-explicit-flushing
(is (= ["(0 1 "
"2 3 4"
" 5 6 "
"7 8 9"
" 10)"]
; new session
(->> (message client {:op :eval :out-limit 5 :code "(print (range 11))"})
(map :out)
(remove nil?))
; existing session
(->> (message session {:op :eval :out-limit 5 :code "(print (range 11))"})
(map :out)
(remove nil?)))))

(def-repl-test ensure-whitespace-prints
(is (= " \t \n \f \n" (->> (repl-eval client "(println \" \t \n \f \")")
combine-responses
Expand Down

0 comments on commit 5bd3847

Please sign in to comment.