Skip to content

Commit

Permalink
Add compatibility with nREPL 0.4 (#540)
Browse files Browse the repository at this point in the history
Support with tools.nrepl is kept for now with the assumption
that tools.nrepl namespaces would be loaded automatically by
`lein repl` or `boot repl`.

Support for tools.nrepl will likely be removed after a couple of
releases (once mainstream Lein and Boot switch to nREPL 0.4).
  • Loading branch information
bbatsov authored Aug 4, 2018
1 parent 270400f commit 15d8774
Show file tree
Hide file tree
Showing 28 changed files with 219 additions and 95 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ You can easily boot an nREPL server with the CIDER middleware loaded
with the following "magic" incantation:

```
clj -Sdeps '{:deps {cider/cider-nrepl {:mvn/version "0.18.0-SNAPSHOT"} }}' -e '(require (quote cider-nrepl.main)) (cider-nrepl.main/init ["cider.nrepl/cider-middleware"])'
clj -Sdeps '{:deps {cider/cider-nrepl {:mvn/version "0.19.0-SNAPSHOT"} }}' -e '(require (quote cider-nrepl.main)) (cider-nrepl.main/init ["cider.nrepl/cider-middleware"])'
```

Note that `clj` was introduced in Clojure 1.9.
Expand All @@ -194,7 +194,7 @@ server with CIDER's own nREPL handler.

```clojure
(ns my-app
(:require [clojure.tools.nrepl.server :as nrepl-server]))
(:require [nrepl.server :as nrepl-server]))

(defn nrepl-handler []
(require 'cider.nrepl)
Expand Down
2 changes: 1 addition & 1 deletion project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}

:dependencies [[org.clojure/tools.nrepl "0.2.13"]
:dependencies [[nrepl "0.4.4"]
^:source-dep [cider/orchard "0.3.0"]
^:source-dep [thunknyc/profile "0.5.2"]
^:source-dep [mvxcvi/puget "1.0.2"]
Expand Down
21 changes: 16 additions & 5 deletions src/cider/nrepl.clj
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
(ns cider.nrepl
(:require [clojure.tools.nrepl.middleware :refer [set-descriptor!]]
[clojure.tools.nrepl.middleware.session :refer [session]]
[clojure.tools.nrepl.middleware.pr-values :refer [pr-values]]
[clojure.tools.nrepl.server :as nrepl-server]
[cider.nrepl.version :as version]
(:require [cider.nrepl.version :as version]
[cider.nrepl.middleware.util.cljs :as cljs]
[cider.nrepl.middleware.pprint :as pprint]
[cider.nrepl.print-method]))

;; Compatibility with the legacy tools.nrepl and the new nREPL 0.4.x.
;; The assumption is that if someone is using old lein repl or boot repl
;; they'll end up using the tools.nrepl, otherwise the modern one.
(if (find-ns 'clojure.tools.nrepl)
(require
'[clojure.tools.nrepl.middleware :refer [set-descriptor!]]
'[clojure.tools.nrepl.middleware.session :refer [session]]
'[clojure.tools.nrepl.middleware.pr-values :refer [pr-values]]
'[clojure.tools.nrepl.server :as nrepl-server])
(require
'[nrepl.middleware :refer [set-descriptor!]]
'[nrepl.middleware.session :refer [session]]
'[nrepl.middleware.pr-values :refer [pr-values]]
'[nrepl.server :as nrepl-server]))

(def delayed-handlers
"Map of `delay`s holding deferred middleware handlers."
(atom {}))
Expand Down
14 changes: 10 additions & 4 deletions src/cider/nrepl/middleware/content_type.clj
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,19 @@
[4] https://tools.ietf.org/html/rfc2017"
{:authors ["Reid 'arrdem' McKenzie <[email protected]>"]}
(:require [cider.nrepl.middleware.slurp :refer [slurp-reply]])
(:import clojure.tools.nrepl.transport.Transport
java.awt.Image
(:import java.awt.Image
[java.io ByteArrayOutputStream File OutputStream]
[java.net URI URL]
java.nio.file.Path
javax.imageio.ImageIO))

;; Compatibility with the legacy tools.nrepl and the new nREPL 0.4.x.
;; The assumption is that if someone is using old lein repl or boot repl
;; they'll end up using the tools.nrepl, otherwise the modern one.
(if (find-ns 'clojure.tools.nrepl)
(import 'clojure.tools.nrepl.transport.Transport)
(import 'nrepl.transport.Transport))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defprotocol URLCoercable
Expand Down Expand Up @@ -80,7 +86,7 @@
[{:keys [session value] :as response}]
(cond
;; FIXME (arrdem 2018-04-03):
;;
;;
;; This could be more generic in terms of tolerating more
;; protocols / schemes

Expand All @@ -96,7 +102,7 @@
:body "")

;; FIXME (arrdem 2018-04-03):
;;
;;
;; This is super snowflakey in terms of only supporting base64
;; coding this one kind of object. This could definitely be
;; more generic / open to extension but hey at least it's
Expand Down
21 changes: 16 additions & 5 deletions src/cider/nrepl/middleware/debug.clj
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,24 @@
[cider.nrepl.middleware.util.instrument :as ins]
[orchard.misc :as misc]
[orchard.meta :as m]
[clojure.java.io :as io]
[clojure.tools.nrepl.middleware.interruptible-eval :refer [*msg*]]
[clojure.tools.nrepl.misc :refer [response-for]]
[clojure.tools.nrepl.middleware.session :as session]
[clojure.tools.nrepl.transport :as transport])
[clojure.java.io :as io])
(:import [clojure.lang Compiler$LocalBinding]))

;; Compatibility with the legacy tools.nrepl and the new nREPL 0.4.x.
;; The assumption is that if someone is using old lein repl or boot repl
;; they'll end up using the tools.nrepl, otherwise the modern one.
(if (find-ns 'clojure.tools.nrepl)
(require
'[clojure.tools.nrepl.middleware.interruptible-eval :refer [*msg*]]
'[clojure.tools.nrepl.middleware.session :as session]
'[clojure.tools.nrepl.misc :refer (response-for)]
'[clojure.tools.nrepl.transport :as transport])
(require
'[nrepl.middleware.interruptible-eval :refer [*msg*]]
'[nrepl.middleware.session :as session]
'[nrepl.misc :refer (response-for)]
'[nrepl.transport :as transport]))

;;;; # The Debugger
;;;
;;; The debugger is divided into two parts, instrument.clj and
Expand Down
21 changes: 18 additions & 3 deletions src/cider/nrepl/middleware/inspect.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,24 @@
[cider.nrepl.middleware.util.error-handling :refer [base-error-response]]
[orchard.inspect :as inspect]
[orchard.misc :as u]
[clojure.tools.nrepl.misc :refer [response-for]]
[clojure.tools.nrepl.transport :as transport])
(:import clojure.tools.nrepl.transport.Transport))
[nrepl.misc :refer [response-for]]
[nrepl.transport :as transport])
(:import nrepl.transport.Transport))

;; Compatibility with the legacy tools.nrepl and the new nREPL 0.4.x.
;; The assumption is that if someone is using old lein repl or boot repl
;; they'll end up using the tools.nrepl, otherwise the modern one.
(if (find-ns 'clojure.tools.nrepl)
(do
(require
'[clojure.tools.nrepl.misc :refer [response-for]]
'[clojure.tools.nrepl.transport :as transport])
(import 'clojure.tools.nrepl.transport.Transport))
(do
(require
'[nrepl.misc :refer [response-for]]
'[nrepl.transport :as transport])
(import 'nrepl.transport.Transport)))

(def ^:dynamic *inspector* (inspect/fresh))

Expand Down
11 changes: 8 additions & 3 deletions src/cider/nrepl/middleware/out.clj
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@
We use an eval message, instead of the clone op, because there's no
guarantee that the channel that sent the clone message will properly
handle output replies."
(:require [cider.nrepl.middleware.util.error-handling :refer [with-safe-transport]]
[clojure.tools.nrepl.middleware.interruptible-eval :as ie])
(:require [cider.nrepl.middleware.util.error-handling :refer [with-safe-transport]])
(:import [java.io PrintWriter Writer PrintStream OutputStream]))

(if (find-ns 'clojure.tools.nrepl)
(require
'[clojure.tools.nrepl.middleware.interruptible-eval :as ieval])
(require
'[nrepl.middleware.interruptible-eval :as ieval]))

(declare unsubscribe-session)

(def original-output
Expand All @@ -29,7 +34,7 @@
(case ~type
:out #'*out*
:err #'*err*))]
(try (binding [ie/*msg* ~'msg]
(try (binding [ieval/*msg* ~'msg]
~@body)
;; If a channel is faulty, dissoc it.
(catch Exception ~'e
Expand Down
26 changes: 19 additions & 7 deletions src/cider/nrepl/middleware/pprint.clj
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
(ns cider.nrepl.middleware.pprint
(:require [cider.nrepl.middleware.util.cljs :as cljs]
[orchard.misc :as u]
[clojure.pprint :refer [pprint *print-right-margin*]]
[clojure.tools.nrepl.middleware.interruptible-eval :refer [*msg*]]
[clojure.tools.nrepl.middleware.pr-values :refer [pr-values]]
[clojure.tools.nrepl.middleware.session :as session]
[clojure.tools.nrepl.misc :refer [response-for]]
[clojure.tools.nrepl.transport :as transport])
(:import clojure.tools.nrepl.transport.Transport))
[clojure.pprint :refer [pprint *print-right-margin*]]))

(if (find-ns 'clojure.tools.nrepl)
(do
(require
'[clojure.tools.nrepl.middleware.interruptible-eval :refer [*msg*]]
'[clojure.tools.nrepl.middleware.pr-values :refer [pr-values]]
'[clojure.tools.nrepl.middleware.session :as session]
'[clojure.tools.nrepl.misc :refer [response-for]]
'[clojure.tools.nrepl.transport :as transport])
(import 'clojure.tools.nrepl.transport.Transport))
(do
(require
'[nrepl.middleware.interruptible-eval :refer [*msg*]]
'[nrepl.middleware.pr-values :refer [pr-values]]
'[nrepl.middleware.session :as session]
'[nrepl.misc :refer [response-for]]
'[nrepl.transport :as transport])
(import 'nrepl.transport.Transport)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Expand Down
13 changes: 9 additions & 4 deletions src/cider/nrepl/middleware/profile.clj
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,15 @@
Based on older middleware (nrepl-profile) that's not actively
maintained anymore."
{:author "Edwin Watkeys"}
(:require [clojure.string :as s]
[profile.core :as p]
[clojure.tools.nrepl.transport :as t]
[clojure.tools.nrepl.misc :refer [response-for]]))
(:require [profile.core :as p]))

(if (find-ns 'clojure.tools.nrepl)
(require
'[clojure.tools.nrepl.misc :refer [response-for]]
'[clojure.tools.nrepl.transport :as t])
(require
'[nrepl.misc :refer [response-for]]
'[nrepl.transport :as t]))

(defn send-exception
[e msg transport]
Expand Down
15 changes: 11 additions & 4 deletions src/cider/nrepl/middleware/refresh.clj
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,17 @@
[clojure.tools.namespace.dir :as dir]
[clojure.tools.namespace.find :as find]
[clojure.tools.namespace.reload :as reload]
[clojure.tools.namespace.track :as track]
[clojure.tools.nrepl.middleware.interruptible-eval :refer [*msg*]]
[clojure.tools.nrepl.misc :refer [response-for]]
[clojure.tools.nrepl.transport :as transport]))
[clojure.tools.namespace.track :as track]))

(if (find-ns 'clojure.tools.nrepl)
(require
'[clojure.tools.nrepl.middleware.interruptible-eval :refer [*msg*]]
'[clojure.tools.nrepl.misc :refer (response-for)]
'[clojure.tools.nrepl.transport :as transport])
(require
'[nrepl.middleware.interruptible-eval :refer [*msg*]]
'[nrepl.misc :refer (response-for)]
'[nrepl.transport :as transport]))

(defonce ^:private refresh-tracker (agent (track/tracker)))

Expand Down
14 changes: 10 additions & 4 deletions src/cider/nrepl/middleware/slurp.clj
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
(ns cider.nrepl.middleware.slurp
"Rich reading & handling for CIDER.
Goes with middleware.content-types, providing the capability to
convert URLs to values which can be handled nicely."
{:authors ["Reid 'arrdem' McKenzie <[email protected]>"]}
(:require [clojure.edn :as edn]
[clojure.java.io :as io]
[clojure.string :as str]
[clojure.tools.nrepl.transport :as transport]
[clojure.tools.nrepl.misc :refer [response-for]])
[clojure.string :as str])
(:import [java.net MalformedURLException URL]
java.io.ByteArrayOutputStream
[java.nio.file Files Path Paths]))

(if (find-ns 'clojure.tools.nrepl)
(require
'[clojure.tools.nrepl.misc :refer (response-for)]
'[clojure.tools.nrepl.transport :as transport])
(require
'[nrepl.misc :refer (response-for)]
'[nrepl.transport :as transport]))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defmacro if-class
Expand Down
17 changes: 12 additions & 5 deletions src/cider/nrepl/middleware/stacktrace.clj
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,23 @@
[orchard.namespace :as namespace]
[clojure.repl :as repl]
[clojure.string :as str]
[clojure.tools.nrepl.middleware.session :refer [session]]
[clojure.tools.nrepl.misc :refer [response-for]]
[clojure.tools.nrepl.transport :as t]
[orchard.misc :as u]
[orchard.java :as java]
[clojure.java.io :as io]
[clojure.set :as set]
[clojure.tools.namespace.find :as nsfind])
(:import (clojure.lang Compiler$CompilerException)))

(if (find-ns 'clojure.tools.nrepl)
(require
'[clojure.tools.nrepl.middleware.session :refer (session)]
'[clojure.tools.nrepl.misc :refer (response-for)]
'[clojure.tools.nrepl.transport :as t])
(require
'[nrepl.middleware.session :refer (session)]
'[nrepl.misc :refer (response-for)]
'[nrepl.transport :as t]))

;;; ## Stacktraces

;; Java stacktraces don't expose column number.
Expand Down Expand Up @@ -110,10 +117,10 @@

(defn flag-tooling
"Walk the call stack from top to bottom, flagging frames below the first call
to `clojure.lang.Compiler` or `clojure.tools.nrepl.*` as `:tooling` to
to `clojure.lang.Compiler` or `(clojure.tools.)nrepl.*` as `:tooling` to
distinguish compilation and nREPL middleware frames from user code."
[frames]
(let [tool-regex #"^clojure\.lang\.Compiler|^clojure\.tools\.nrepl|^cider\."
(let [tool-regex #"^clojure\.lang\.Compiler|^clojure\.tools\.nrepl\.|^nrepl\.|^cider\."
tool? #(re-find tool-regex (or (:name %) ""))
flag #(if (tool? %)
(flag-frame % :tooling)
Expand Down
18 changes: 13 additions & 5 deletions src/cider/nrepl/middleware/test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,19 @@
[orchard.namespace :as ns]
[orchard.query :as query]
[clojure.pprint :as pp]
[clojure.test :as test]
[clojure.tools.nrepl.middleware.interruptible-eval :as ie]
[clojure.tools.nrepl.middleware.pr-values :refer [pr-values]]
[clojure.tools.nrepl.misc :refer [response-for]]
[clojure.tools.nrepl.transport :as t]))
[clojure.test :as test]))

(if (find-ns 'clojure.tools.nrepl)
(require
'[clojure.tools.nrepl.middleware.interruptible-eval :as ie]
'[clojure.tools.nrepl.middleware.pr-values :refer [pr-values]]
'[clojure.tools.nrepl.misc :refer (response-for)]
'[clojure.tools.nrepl.transport :as t])
(require
'[nrepl.middleware.interruptible-eval :as ie]
'[nrepl.middleware.pr-values :refer [pr-values]]
'[nrepl.misc :refer (response-for)]
'[nrepl.transport :as t]))

;;; ## Overview
;;
Expand Down
17 changes: 13 additions & 4 deletions src/cider/nrepl/middleware/track_state.clj
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,22 @@
[orchard.meta :as m]
[orchard.namespace :as namespace]
[cljs-tooling.util.analysis :as cljs-ana]
[clojure.tools.namespace.find :as ns-find]
[clojure.tools.nrepl.misc :refer [response-for]]
[clojure.tools.nrepl.transport :as transport])
[clojure.tools.namespace.find :as ns-find])
(:import (clojure.lang Namespace MultiFn)
clojure.tools.nrepl.transport.Transport
java.net.SocketException))

(if (find-ns 'clojure.tools.nrepl)
(do
(require
'[clojure.tools.nrepl.misc :refer [response-for]]
'[clojure.tools.nrepl.transport :as transport])
(import 'clojure.tools.nrepl.transport.Transport))
(do
(require
'[nrepl.misc :refer [response-for]]
'[nrepl.transport :as transport])
(import 'nrepl.transport.Transport)))

(def clojure-core (try (find-ns 'clojure.core)
(catch Exception e nil)))

Expand Down
Loading

0 comments on commit 15d8774

Please sign in to comment.