Skip to content

Commit

Permalink
Merge d24159d into 2f72b68
Browse files Browse the repository at this point in the history
  • Loading branch information
Malabarba committed Aug 31, 2015
2 parents 2f72b68 + d24159d commit 25a2348
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 0 deletions.
1 change: 1 addition & 0 deletions project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
cider.nrepl.middleware.stacktrace/wrap-stacktrace
cider.nrepl.middleware.test/wrap-test
cider.nrepl.middleware.trace/wrap-trace
cider.nrepl.middleware.track-state/wrap-tracker
cider.nrepl.middleware.undef/wrap-undef]}
;; The "sources" jar should be the same version as Clojure,
;; but bad sources jars were deployed to the Maven Central
Expand Down
2 changes: 2 additions & 0 deletions src/cider/nrepl.clj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
[cider.nrepl.middleware.stacktrace]
[cider.nrepl.middleware.test]
[cider.nrepl.middleware.trace]
[cider.nrepl.middleware.track-state]
[cider.nrepl.middleware.undef]))

(def cider-middleware
Expand All @@ -34,6 +35,7 @@
cider.nrepl.middleware.stacktrace/wrap-stacktrace
cider.nrepl.middleware.test/wrap-test
cider.nrepl.middleware.trace/wrap-trace
cider.nrepl.middleware.track-state/wrap-tracker
cider.nrepl.middleware.undef/wrap-undef])

(def cider-nrepl-handler
Expand Down
59 changes: 59 additions & 0 deletions src/cider/nrepl/middleware/track_state.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
(ns cider.nrepl.middleware.track-state
"State tracker for client sessions."
{:author "Artur Malabarba"}
(:require [cider.nrepl.middleware.util.cljs :as cljs]
[clojure.tools.nrepl.middleware :refer [set-descriptor!]]
[clojure.tools.nrepl.middleware.interruptible-eval :refer [*msg*]]
[clojure.tools.nrepl.misc :refer [response-for]]
[clojure.tools.nrepl.transport :as transport])
(:import clojure.tools.nrepl.transport.Transport))

(def messages
"Holds a map from sessions to messages.
Whenever an eval request is received through a know session, the
resulting state is reported via the stored message."
(atom {}))

(defn notify-state
"Reply to the message associated with `session`."
[session]
(when-let [msg (@messages session)]
(->> (if (cljs/grab-cljs-env *msg*) :cljs :clj)
(response-for msg :repl-type)
(transport/send (:transport msg)))))

(defn make-transport
"Return a Transport that defers to `transport` and possibly notifies
about the state."
[{:keys [^Transport transport session]}]
(reify Transport
(recv [this] (.recv transport))
(recv [this timeout] (.recv transport timeout))
(send [this response]
(.send transport response)
(when (:done (:status response))
(notify-state session)))))

(defn initialize
"Setup `session` for tracking.
Changes will be notified to `msg`."
[{:keys [session] :as msg}]
(swap! messages assoc session msg)
(notify-state session))

(defn wrap-tracker
"Middleware that tracks relevant server info and notifies the client."
[handler]
(fn [{:keys [op] :as msg}]
(case op
"eval" (handler (assoc msg :transport (make-transport msg)))
"init-tracker" (initialize msg)
(handler msg))))

(set-descriptor!
#'wrap-tracker
(cljs/requires-piggieback
{:expects #{"eval"}
:handles
{"track-state-middleware"
{:doc "Enhances the `eval` op by notifying the client of the current REPL state. Currently, only the REPL type (Clojure or ClojureScript) is informed."}}}))
35 changes: 35 additions & 0 deletions test/clj/cider/nrepl/middleware/track_state_test.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
(ns cider.nrepl.middleware.track-state-test
(:require [cider.nrepl.middleware.track-state :as s]
[cider.nrepl.middleware.util.cljs :as cljs]
[clojure.test :refer :all]
[clojure.tools.nrepl.transport :as t])
(:import clojure.tools.nrepl.transport.Transport))

(def ^:const msg {:session :dummy
:transport :t})

(deftest initialize []
(with-redefs [s/notify-state vector
s/messages (atom {})]
(is (= (s/initialize msg)
[:dummy]))
(is (= @s/messages {:dummy msg}))))

(deftest notify-state []
(with-redefs [s/make-transport vector
t/send vector
s/messages (atom {(:session msg) msg})]
(is (= (s/notify-state :dummy)
[:t {:repl-type :clj, :session :dummy}]))
(is (not (s/notify-state :unknown-session)))
(with-redefs [cljs/grab-cljs-env vector]
(is (= (s/notify-state :dummy)
[:t {:repl-type :cljs, :session :dummy}]))
(is (not (s/notify-state :unknown-session))))))

(deftest make-transport []
(is (instance? Transport (s/make-transport nil)))
(is (try (send (s/make-transport nil) 10)
nil
(catch Exception e true))))

0 comments on commit 25a2348

Please sign in to comment.