From e01120a46a6f74c5b71a5dc3c477f518a2073f51 Mon Sep 17 00:00:00 2001 From: Colin Jones Date: Sat, 28 Apr 2012 13:11:46 -0500 Subject: [PATCH] Flush output after session/*out-limit* characters Defaults to 1024, but can easily be rebound on a per-evaluation basis, e.g. (binding [session/*out-limit* Long/MAX_VALUE] ...) --- .../clojure/tools/nrepl/middleware/session.clj | 6 +++++- .../java/clojure/tools/nrepl/StdOutBuffer.java | 10 +++++++--- .../clojure/clojure/tools/nrepl/sanity_test.clj | 20 +++++++++++++------- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/main/clojure/clojure/tools/nrepl/middleware/session.clj b/src/main/clojure/clojure/tools/nrepl/middleware/session.clj index 9081c90..b129a0e 100644 --- a/src/main/clojure/clojure/tools/nrepl/middleware/session.clj +++ b/src/main/clojure/clojure/tools/nrepl/middleware/session.clj @@ -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 @@ -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) diff --git a/src/main/java/clojure/tools/nrepl/StdOutBuffer.java b/src/main/java/clojure/tools/nrepl/StdOutBuffer.java index d85f519..4a66a06 100644 --- a/src/main/java/clojure/tools/nrepl/StdOutBuffer.java +++ b/src/main/java/clojure/tools/nrepl/StdOutBuffer.java @@ -3,9 +3,9 @@ package clojure.tools.nrepl; /** * 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 @@ -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); } diff --git a/src/test/clojure/clojure/tools/nrepl/sanity_test.clj b/src/test/clojure/clojure/tools/nrepl/sanity_test.clj index a28d6cc..0edb1be 100644 --- a/src/test/clojure/clojure/tools/nrepl/sanity_test.clj +++ b/src/test/clojure/clojure/tools/nrepl/sanity_test.clj @@ -46,11 +46,11 @@ (try (are [result expr] (= result (internal-eval expr)) ["" 3] '(+ 1 2) - + ["" nil] '*1 ["" nil] '(do (def ^{:dynamic true} ++ +) nil) ["" 5] '(binding [++ -] (++ 8 3)) - + ["" 42] '(set! *print-length* 42) ["" nil] '*print-length*) (finally (ns-unmap *ns* '++)))) @@ -60,12 +60,12 @@ (are [ns result expr] (= result (internal-eval ns expr)) (ns-name *ns*) ["" [(str (ns-name *ns*)) 3]] '(+ 1 2) - + 'user ["" ["user" '("user" "++")]] '(do (def ^{:dynamic true} ++ +) (map #(-> #'++ meta % str) [:ns :name])) - + (ns-name *ns*) ["" [(str (ns-name *ns*)) 5]] '(binding [user/++ -] (user/++ 8 3))) @@ -104,11 +104,17 @@ (binding [*out* out] (newline) (prn #{}) + (flush) + (binding [session/*out-limit* 10] + (print (range 11))) (flush))) - + (is (= ["abcdefghij " "no writes\nkeyed on linebreaks" - "\n#{}\n"] + "\n#{}\n" + "(0 1 2 3 4" + " 5 6 7 8 9" + " 10)"] (->> (repl/response-seq local 0) (map :out)))))) @@ -133,4 +139,4 @@ (throw (Exception. "foo"))) full-response :err)))) -) \ No newline at end of file +) -- 1.7.1.1