Skip to content

Commit

Permalink
Add track-state middleware
Browse files Browse the repository at this point in the history
This middleware keeps the client notified of what the current repl type
is.
  • Loading branch information
Malabarba committed Aug 31, 2015
1 parent 2f72b68 commit 4c1b3d4
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 1 deletion.
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
41 changes: 41 additions & 0 deletions src/cider/nrepl/middleware/track_state.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
(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))

(defn assoc-state
"Return response with a :state entry assoc'ed."
[response msg]
(assoc response :state {:repl-type (if (cljs/grab-cljs-env msg) :cljs :clj)}))

(defn make-transport
"Return a Transport that defers to `transport` and possibly notifies
about the state."
[{:keys [^Transport transport] :as msg}]
(reify Transport
(recv [this] (.recv transport))
(recv [this timeout] (.recv transport timeout))
(send [this {:keys [status] :as response}]
(.send transport (cond-> response
(contains? status :done) (assoc-state msg))))))

(defn wrap-tracker
"Middleware that tracks relevant server info and notifies the client."
[handler]
(fn [{:keys [op] :as msg}]
(cond
(#{"eval" "load-file"} op) (handler (assoc msg :transport (make-transport msg)))
:else (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."}}}))
2 changes: 1 addition & 1 deletion test/clj/cider/nrepl/middleware/pprint_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
:code "[1 2 3] [4 5 6]"
:pprint "true"}
responses (->> (session/message message false)
(map #(dissoc % :id :session :ns))
(map #(dissoc % :id :session :ns :state))
(filter not-empty))]
(is (= responses [{:pprint-out "[1 2 3]\n"}
{:pprint-sentinel {}}
Expand Down
19 changes: 19 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,19 @@
(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))

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

(deftest assoc-state
(is (= (s/assoc-state {} {})
{:state {:repl-type :clj}}))
(with-redefs [cljs/grab-cljs-env identity]
(is (= (s/assoc-state {} {})
{:state {:repl-type :cljs}}))))

0 comments on commit 4c1b3d4

Please sign in to comment.