Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 534 lines (438 sloc) 24.843 kB
b197ced @cemerick Initial spike.
cemerick authored
1 # nREPL
2
2b2b735 @cemerick documentation
cemerick authored
3 [nREPL](http://github.com/clojure/tools.nrepl) is a Clojure *n*etwork REPL that
4 provides a REPL server and client, along with some common APIs
b197ced @cemerick Initial spike.
cemerick authored
5 of use to IDEs and other tools that may need to evaluate Clojure
6 code in remote environments.
7
8 ## Usage
9
2b2b735 @cemerick documentation
cemerick authored
10 ### "Installation" <a name="installing"/>
b197ced @cemerick Initial spike.
cemerick authored
11
e7cd0d4 @cemerick Fix :dependencies misspelling?
cemerick authored
12 nREPL is available in Maven central. Add this to your Leiningen
13 `project.clj` `:dependencies`:
e6d3f52 @cemerick 0.0.4 release notes, docs update
cemerick authored
14
f392614 @cemerick fix coordinates
cemerick authored
15 ```clojure
adf39f3 @cemerick 0.2.10 readme and changes
cemerick authored
16 [org.clojure/tools.nrepl "0.2.10"]
f392614 @cemerick fix coordinates
cemerick authored
17 ```
2b2b735 @cemerick documentation
cemerick authored
18
19 Or, add this to your Maven project's `pom.xml`:
20
f392614 @cemerick fix coordinates
cemerick authored
21 ```xml
22 <dependency>
23 <groupId>org.clojure</groupId>
24 <artifactId>tools.nrepl</artifactId>
adf39f3 @cemerick 0.2.10 readme and changes
cemerick authored
25 <version>0.2.10</version>
f392614 @cemerick fix coordinates
cemerick authored
26 </dependency>
27 ```
e6d3f52 @cemerick 0.0.4 release notes, docs update
cemerick authored
28
2124e13 @cemerick documentation dump
cemerick authored
29 A list of all prior releases are available
30 [here](http://search.maven.org/#search|gav|1|g%3A%22org.clojure%22%20AND%20a%3A%22tools.nrepl%22).
d9eeafb @cemerick brought README up to spec
cemerick authored
31
f436a4b @cemerick 0.2.4 changelog
cemerick authored
32 Please note the changelog in `CHANGELOG.md`.
e6d3f52 @cemerick 0.0.4 release notes, docs update
cemerick authored
33
f436a4b @cemerick 0.2.4 changelog
cemerick authored
34 nREPL is compatible with Clojure 1.2.0 and higher.
2b2b735 @cemerick documentation
cemerick authored
35
2124e13 @cemerick documentation dump
cemerick authored
36 Please post general questions or discussion on either the
37 [clojure-dev](http://groups.google.com/group/clojure-dev/) or
38 [clojure-tools](http://groups.google.com/group/clojure-tools) mailing lists.
39 Bug reports and such may be filed into [nREPL's
40 JIRA](http://dev.clojure.org/jira/browse/NREPL).
d9eeafb @cemerick brought README up to spec
cemerick authored
41
2124e13 @cemerick documentation dump
cemerick authored
42 nREPL's generated API documentation is available
43 [here](http://clojure.github.com/tools.nrepl/). A [history of nREPL
44 builds](http://build.clojure.org/job/tools.nrepl/) is available, as well as [a
45 compatibility test
46 matrix](http://build.clojure.org/job/tools.nrepl-test-matrix/), verifying
47 nREPL's functionality against multiple versions of Clojure and multiple JVMs.
d9eeafb @cemerick brought README up to spec
cemerick authored
48
2b2b735 @cemerick documentation
cemerick authored
49 ### Connecting to an nREPL server
50
51 Most of the time, you will connect to an nREPL server using an existing
52 client/tool. Tools that support nREPL include:
53
54 * [Leiningen](https://github.com/technomancy/leiningen) (starting with v2)
d3ee1dd @cemerick changelog and README tweaks for 0.2.2
cemerick authored
55 * [Counterclockwise](http://code.google.com/p/counterclockwise/) (Clojure
56 plugin for Eclipse)
dd5218e @andrewhr NREPL-70: Add monroe to the list of nrepl clients
andrewhr authored
57 * [cider](https://github.com/clojure-emacs/cider) (Clojure IDE and REPL
58 for Emacs)
59 * [monroe](https://github.com/sanel/monroe) (nREPL client for Emacs)
ddadae8 @cemerick fix nrepl.el => cider, vim-foreplay => vim-fireplace links
cemerick authored
60 * [fireplace.vim](https://github.com/tpope/vim-fireplace) (Clojure + nREPL
d3ee1dd @cemerick changelog and README tweaks for 0.2.2
cemerick authored
61 support for vim)
2b2b735 @cemerick documentation
cemerick authored
62 * [Reply](https://github.com/trptcolin/reply/)
6edfd03 @cemerick 0.2.8 README, ops listing
cemerick authored
63 * [Atom](https://atom.io/packages/search?q=nrepl)
2b2b735 @cemerick documentation
cemerick authored
64
2124e13 @cemerick documentation dump
cemerick authored
65 If your preferred Clojure development environment supports nREPL, you're done.
66 Use it or connect to an existing nREPL endpoint, and you're done.
67
68 #### Talking to an nREPL endpoint programmatically
69
2b2b735 @cemerick documentation
cemerick authored
70 If you want to connect to an nREPL server using the default transport, something
71 like this will work:
72
73 ```clojure
74 => (require '[clojure.tools.nrepl :as repl])
75 nil
76 => (with-open [conn (repl/connect :port 59258)]
77 (-> (repl/client conn 1000) ; message receive timeout required
2124e13 @cemerick documentation dump
cemerick authored
78 (repl/message {:op "eval" :code "(+ 2 3)"})
2b2b735 @cemerick documentation
cemerick authored
79 repl/response-values))
80 [5]
81 ```
82
83 `response-values` will return only the values of evaluated expressions, read
84 from their (by default) `pr`-encoded representations via `read`. You can see
85 the full content of message responses easily:
86
87 ```clojure
88 => (with-open [conn (repl/connect :port 59258)]
89 (-> (repl/client conn 1000)
90 (repl/message {:op :eval :code "(time (reduce + (range 1e6)))"})
91 doall ;; `message` and `client-session` all return lazy seqs
92 pprint))
93 nil
94 ({:out "\"Elapsed time: 68.032 msecs\"\n",
95 :session "2ba81681-5093-4262-81c5-edddad573201",
96 :id "3124d886-7a5d-4c1e-9fc3-2946b1b3cfaa"}
97 {:ns "user",
98 :value "499999500000",
99 :session "2ba81681-5093-4262-81c5-edddad573201",
100 :id "3124d886-7a5d-4c1e-9fc3-2946b1b3cfaa"}
101 {:status ["done"],
102 :session "2ba81681-5093-4262-81c5-edddad573201",
103 :id "3124d886-7a5d-4c1e-9fc3-2946b1b3cfaa"})
104 ```
105
498f6b0 @cemerick fns to generate markdown from :describe op results
cemerick authored
106 Each message must contain at least an `:op` (or `"op"`) slot, which specifies
107 the "type" of the operation to be performed. The operations supported by an
108 nREPL endpoint are determined by the handlers and middleware stack used when
109 starting that endpoint; the default middleware stack (described below) supports
110 a particular set of operations, [detailed
222c456 @bbatsov Fix a typo and remove some trailing whitespace
bbatsov authored
111 here](https://github.com/clojure/tools.nrepl/blob/master/doc/ops.md).
2b2b735 @cemerick documentation
cemerick authored
112
113 ### Embedding nREPL, starting a server
114
115 If your project uses Leiningen (v2 or higher), you already have access to an
2124e13 @cemerick documentation dump
cemerick authored
116 nREPL server for your project via `lein repl` (or, `lein repl :headless` if you
117 don't need the Reply terminal-based nREPL client to connect to the resulting
118 nREPL server).
2b2b735 @cemerick documentation
cemerick authored
119
120 Otherwise, it can be extremely useful to have your application host a REPL
121 server whereever it might be deployed; this can greatly simplify debugging,
2124e13 @cemerick documentation dump
cemerick authored
122 sanity-checking, panicked code patching, and so on.
2b2b735 @cemerick documentation
cemerick authored
123
124 nREPL provides a socket-based server that you can trivially start from your
125 application. [Add it to your project's dependencies](#installing), and add code
126 like this to your app:
127
128 ```clojure
129 => (use '[clojure.tools.nrepl.server :only (start-server stop-server)])
130 nil
131 => (defonce server (start-server :port 7888))
132 #'user/server
133 ```
134
135 Depending on what the lifecycle of your application is, whether you want to be
136 able to easily restart the server, etc., you might want to put the value
137 `start-server` returns into an atom or somesuch. Anyway, once your app is
138 running an nREPL server, you can connect to it from a tool like Leiningen or
139 Counterclockwise or Reply, or from another Clojure process:
140
141 ```clojure
142 => (with-open [conn (repl/connect :port 7888)]
143 (-> (repl/client conn 1000)
144 (repl/message {:op :eval :code "(+ 1 1)"})
145 repl/response-values))
146 [2]
147 ```
148
149 You can stop the server with `(stop-server server)`.
150
151 #### Server options
152
2124e13 @cemerick documentation dump
cemerick authored
153 Note that nREPL is not limited to its default messaging protocol, nor to its
154 default use of sockets. nREPL provides a _transport_ abstraction for
155 implementing support for alternative protocols and connection methods.
156 Alternative transport implementations are available, and implementing your own
157 is not difficult; read more about transports [here](#transports).
b197ced @cemerick Initial spike.
cemerick authored
158
1905501 @cemerick big documentation update
cemerick authored
159 ### Building nREPL
160
2124e13 @cemerick documentation dump
cemerick authored
161 Releases are available from Maven Central, and SNAPSHOT builds from master's
162 HEAD are automatically deployed to Sonatype's OSS repository (see
163 [this](http://dev.clojure.org/display/doc/Maven+Settings+and+Repositories) for
164 how to configure Leiningen or Maven to use OSS-snapshots), so building nREPL
165 shouldn't ever be necessary. But, if you insist:
2b2b735 @cemerick documentation
cemerick authored
166
1905501 @cemerick big documentation update
cemerick authored
167 0. Clone the repo
168 1. Make sure you have maven installed
2124e13 @cemerick documentation dump
cemerick authored
169 2. Run the maven build, either:
1905501 @cemerick big documentation update
cemerick authored
170 1. `mvn package`: This will produce an nREPL jar file in the `target`
2b2b735 @cemerick documentation
cemerick authored
171 directory, and run all tests against Clojure 1.2.0.
1905501 @cemerick big documentation update
cemerick authored
172 2. `mvn verify`: This does the same, but also runs the tests with
222c456 @bbatsov Fix a typo and remove some trailing whitespace
bbatsov authored
173 other Clojure "profiles" (one for each supported version of Clojure).
b197ced @cemerick Initial spike.
cemerick authored
174
2b2b735 @cemerick documentation
cemerick authored
175 ## Why nREPL?
1905501 @cemerick big documentation update
cemerick authored
176
2b2b735 @cemerick documentation
cemerick authored
177 nREPL has been designed with the aim of ensuring that it satisfies the
1905501 @cemerick big documentation update
cemerick authored
178 requirements of both application developers (in support of activities ranging
179 from interactive remote debugging and experimentation in development
180 contexts through to more advanced use cases such as updating deployed
2b2b735 @cemerick documentation
cemerick authored
181 applications) as well as toolmakers (providing a standard way to connect to and
182 introspect running environments as a way of informing user interfaces of all
183 kinds, including "standard" interactive, text-based REPLs).
1905501 @cemerick big documentation update
cemerick authored
184
2124e13 @cemerick documentation dump
cemerick authored
185 The default network protocol used is simple, depending neither
1905501 @cemerick big documentation update
cemerick authored
186 on JVM or Clojure specifics, thereby allowing (encouraging?) the development
187 of non-Clojure REPL clients. The REPLs operational semantics are such
2124e13 @cemerick documentation dump
cemerick authored
188 that essentially any non-JVM Clojure implementation should be able to
2b2b735 @cemerick documentation
cemerick authored
189 implement it, with allowances for hosts that lack the concurrency primitives to
190 support e.g. asynchronous evaluation, interrupts, etc.
1905501 @cemerick big documentation update
cemerick authored
191
192 For more information about the motivation, architecture, use cases, and
2124e13 @cemerick documentation dump
cemerick authored
193 discussion related to nREPL, see the see the original design notes,
222c456 @bbatsov Fix a typo and remove some trailing whitespace
bbatsov authored
194 available [here](https://docs.google.com/document/edit?id=1dnb1ONTpK9ttO5W4thxiXkU5Ki89gK62anRqKEK4YZI&authkey=CMuszuMI&hl=en#),
2b2b735 @cemerick documentation
cemerick authored
195 and the [notes](https://github.com/clojure/tools.nrepl/wiki/nREPL.Next) and
2124e13 @cemerick documentation dump
cemerick authored
196 [discussion](http://groups.google.com/group/clojure-dev/browse_frm/thread/6e366c1d0eaeec59)
2b2b735 @cemerick documentation
cemerick authored
197 around its recent redesign.
198
199 ### Design
200
201 nREPL largely consists of three abstractions: handlers, middleware, and
2124e13 @cemerick documentation dump
cemerick authored
202 transports. These are roughly analogous to the handlers, middleware, and
203 adapters of [Ring](https://github.com/ring-clojure/ring), though there are some
204 important semantic differences. Finally, nREPL is fundamentally message-oriented
205 and asynchronous (in contrast to most REPLs that build on top of streams
206 provided by e.g. terminals).
2b2b735 @cemerick documentation
cemerick authored
207
2124e13 @cemerick documentation dump
cemerick authored
208 #### Messages
2b2b735 @cemerick documentation
cemerick authored
209
2124e13 @cemerick documentation dump
cemerick authored
210 nREPL messages are maps. The keys and values that may be included in messages
211 depends upon the transport being used; different transports may encode messages
212 differently, and therefore may or may not be able to represent certain data
213 types.
2b2b735 @cemerick documentation
cemerick authored
214
2124e13 @cemerick documentation dump
cemerick authored
215 Each message sent to an nREPL endpoint constitutes a "request" to perform a
216 particular operation, which is indicated by a `"op"` entry. Each operation may
217 further require the incoming message to contain other data. Which data an
218 operation requires or may accept varies; for example, a message to evaluate
219 some code might look like this:
2b2b735 @cemerick documentation
cemerick authored
220
2124e13 @cemerick documentation dump
cemerick authored
221 ```clojure
222 {"op" "eval" "code" "(+ 1 2 3)"}
223 ```
2b2b735 @cemerick documentation
cemerick authored
224
2124e13 @cemerick documentation dump
cemerick authored
225 The result(s) of performing each operation may be sent back to the nREPL client
226 in one or more response messages, the contents of which again depend upon the
227 operation.
2b2b735 @cemerick documentation
cemerick authored
228
2124e13 @cemerick documentation dump
cemerick authored
229 #### Transports <a name="transports"/>
230
231 <!-- talk about strings vs. bytestrings, the encoding thereof, etc when we
232 figure that out -->
233
234 _Transports_ are roughly analogous to Ring's adapters: they provide an
235 implementation of a common protocol (`clojure.tools.nrepl.transport.Transport`)
236 to enable nREPL clients and servers to send and receive messages without regard
237 for the underlying channel or particulars of message encoding.
238
239 nREPL includes two transports, both of which are socket-based: a "tty"
240 transport that allows one to connect to an nREPL endpoint using e.g. `telnet`
241 (which therefore supports only the most simplistic interactive evaluation of
242 expressions), and one that uses
243 [bencode](http://wiki.theory.org/BitTorrentSpecification#Bencoding) to encode
244 nREPL messages over sockets. It is the latter that is used by default by
245 `clojure.tools.nrepl.server/start-server` and `clojure.tools.nrepl/connect`.
246
9b1fc68 @cemerick link to community-editable wiki for lists of community-authored trans…
cemerick authored
247 [Other nREPL transports are provided by the community]
248 (https://github.com/clojure/tools.nrepl/wiki/Extensions).
2124e13 @cemerick documentation dump
cemerick authored
249
250 #### Handlers
251
252 _Handlers_ are functions that accept a single incoming message as an argument.
253 An nREPL server is started with a single handler function, which will be used
254 to process messages for the lifetime of the server. Note that handler return
255 values are _ignored_; results of performing operations should be sent back to
256 the client via the transport in use (which will be explained shortly). This
257 may seem peculiar, but is motivated by two factors:
258
259 * Many operations — including something as simple as code evaluation — is
260 fundamentally asynchronous with respect to the nREPL server
261 * Many operations can produce multiple results (e.g. evaluating a snippet of
262 code like `"(+ 1 2) (def a 6)`).
263
264 Thus, messages provided to nREPL handlers are guaranteed to contain a
265 `:transport` entry containing the [transport](#transports) that should be used
266 to send all responses precipitated by a given message. (This slot is added by
267 the nREPL server itself, thus, if a client sends any message containing a
268 `"transport"` entry, it will be bashed out by the `Transport` that was the
269 source of the message.) Further, all messages provided to nREPL handlers have
270 keyword keys (as per `clojure.walk/keywordize-keys`).
271
272 Depending on its `:op`, a message might be required to contain other slots, and
273 might optionally contain others. It is generally the case that request
274 messages should contain a globally-unique `:id`.
2b2b735 @cemerick documentation
cemerick authored
275 Every request must provoke at least one and potentially many response messages,
276 each of which should contain an `:id` slot echoing that of the provoking
2124e13 @cemerick documentation dump
cemerick authored
277 request.
278
279 Once a handler has completely processed a message, a response
2b2b735 @cemerick documentation
cemerick authored
280 containing a `:status` of `:done` must be sent. Some operations necessitate
281 that additional responses related to the processing of a request are sent after
282 a `:done` `:status` is reported (e.g. delivering content written to `*out*` by
283 evaluated code that started a `future`).
284 Other statuses are possible, depending upon the semantics of the `:op` being
285 handled; in particular, if the message is malformed or incomplete for a
286 particular `:op`, then a response with an `:error` `:status` should be sent,
222c456 @bbatsov Fix a typo and remove some trailing whitespace
bbatsov authored
287 potentially with additional information about the nature of the problem.
2b2b735 @cemerick documentation
cemerick authored
288
2124e13 @cemerick documentation dump
cemerick authored
289 It is possible for an nREPL server to send messages to a client that are not a
290 direct response to a request (e.g. streaming content written to `System/out`
291 might be started/stopped by requests, but messages containing such content
292 can't be considered responses to those requests).
2b2b735 @cemerick documentation
cemerick authored
293
2124e13 @cemerick documentation dump
cemerick authored
294 If the handler being used by an nREPL server does not recognize or cannot
295 perform the operation indicated by a request message's `:op`, then it should
2b2b735 @cemerick documentation
cemerick authored
296 respond with a message containing a `:status` of `"unknown-op"`.
297
2124e13 @cemerick documentation dump
cemerick authored
298 It is currently the case that the handler provided as the `:handler` to
299 `clojure.tools.nrepl.server/start-server` is generally built up as a result of
300 composing multiple pieces of middleware.
2b2b735 @cemerick documentation
cemerick authored
301
302 #### Middleware
303
2124e13 @cemerick documentation dump
cemerick authored
304 _Middleware_ are higher-order functions that accept a handler and return a new
305 handler that may compose additional functionality onto or around the original.
306 For example, some middleware that handles a hypothetical `"time?"` `:op` by
307 replying with the local time on the server:
2b2b735 @cemerick documentation
cemerick authored
308
309 ```clojure
310 (require '[clojure.tools.nrepl.transport :as t])
311 (use '[clojure.tools.nrepl.misc :only (response-for)])
312
313 (defn current-time
314 [h]
315 (fn [{:keys [op transport] :as msg}]
316 (if (= "time?" op)
317 (t/send transport (response-for msg :status :done :time (System/currentTimeMillis)))
318 (h msg))))
319 ```
320
2124e13 @cemerick documentation dump
cemerick authored
321 A little silly, but this pattern should be familiar to you if you have
322 implemented Ring middleware before. Nearly all of the same patterns and
323 expectations associated with Ring middleware should be applicable to nREPL
324 middleware.
325
326 All of nREPL's provided default functionality is implemented in terms of
327 middleware, even foundational bits like session and eval support. This default
328 middleware "stack" aims to match and exceed the functionality offered by the
329 standard Clojure REPL, and is available at
330 `clojure.tools.nrepl.server/default-middlewares`. Concretely, it consists of a
331 number of middleware functions' vars that are implicitly merged with any
332 user-specified middleware provided to
333 `clojure.tools.nrepl.server/default-handler`. To understand how that implicit
334 merge works, we'll first need to talk about middleware "descriptors".
335
9b1fc68 @cemerick link to community-editable wiki for lists of community-authored trans…
cemerick authored
336 [Other nREPL middlewares are provided by the community]
337 (https://github.com/clojure/tools.nrepl/wiki/Extensions).
338
2124e13 @cemerick documentation dump
cemerick authored
339 (See [this documentation
340 listing](https://github.com/clojure/tools.nrepl/blob/master/doc/ops.md) for
341 details as to the operations implemented by nREPL's default middleware stack,
342 what each operation expects in request messages, and what they emit for
343 responses.)
344
345 ##### Middleware descriptors and nREPL server configuration
346
347 It is generally the case that most users of nREPL will expect some minimal REPL
348 functionality to always be available: evaluation (and the ability to interrupt
349 evaluations), sessions, file loading, and so on. However, as with all
350 middleware, the order in which nREPL middleware is applied to a base handler is
351 significant; e.g., the session middleware's handler must look up a user's
352 session and add it to the message map before delegating to the handler it wraps
353 (so that e.g. evaluation middleware can use that session data to stand up the
354 user's dynamic evaluation context). If middleware were "just" functions, then
355 any customization of an nREPL middleware stack would need to explicitly repeat
356 all of the defaults, except for the edge cases where middleware is to be
357 appended or prepended to the default stack.
358
359 To eliminate this tedium, the vars holding nREPL middleware functions may have
360 a descriptor applied to them to specify certain constraints in how that
361 middleware is applied. For example, the descriptor for the
362 `clojure.tools.nrepl.middleware.session/add-stdin` middleware is set thusly:
2b2b735 @cemerick documentation
cemerick authored
363
364 ```clojure
2124e13 @cemerick documentation dump
cemerick authored
365 (set-descriptor! #'add-stdin
366 {:requires #{#'session}
367 :expects #{"eval"}
368 :handles {"stdin"
369 {:doc "Add content from the value of \"stdin\" to *in* in the current session."
370 :requires {"stdin" "Content to add to *in*."}
371 :optional {}
372 :returns {"status" "A status of \"need-input\" will be sent if a session's *in* requires content in order to satisfy an attempted read operation."}}}})
2b2b735 @cemerick documentation
cemerick authored
373 ```
374
2124e13 @cemerick documentation dump
cemerick authored
375 Middleware descriptors are implemented as a map in var metadata under a
376 `:clojure.tools.nrepl.middleware/descriptor` key. Each descriptor can contain
377 any of three entries:
378
379 * `:requires`, a set containing strings or vars identifying other middleware
380 that must be applied at a higher level than the middleware being described.
381 Var references indicate an implementation detail dependency; string values
382 indicate a dependency on _any_ middleware that handles the specified `:op`.
383 * `:expects`, the same as `:requires`, except the referenced middleware must
384 exist in the final stack at a lower level than the middleware being
385 described.
386 * `:handles`, a map that documents the operations implemented by the
387 middleware. Each entry in this map must have as its key the string value of
388 the handled `:op` and a value that contains any of four entries:
389 * `:doc`, a human-readable docstring for the middleware
390 * `:requires`, a map of slots that the handled operation must find in request
391 messages with the indicated `:op`
392 * `:optional`, a map of slots that the handled operation may utilize from the
393 request messages with the indicated `:op`
394 * `:returns`, a map of slots that may be found in messages sent in response
395 to handling the indicated `:op`
396
397 The values in the `:handles` map is used to support the `"describe"` operation,
398 which provides "a machine- and human-readable directory and documentation for
399 the operations supported by an nREPL endpoint" (see
400 `clojure.tools.nrepl.middleware/describe-markdown`, and the results of
401 `"describe"` and `describe-markdown`
402 [here](https://github.com/clojure/tools.nrepl/blob/master/doc/ops.md)).
403
404 The `:requires` and `:expects` entries control the order in which
405 middleware is applied to a base handler. In the `add-stdin` example above,
406 that middleware will be applied after any middleware that handles the `"eval"`
407 operation, but before the `clojure.tools.nrepl.middleware.session/session`
408 middleware. In the case of `add-stdin`, this ensures that incoming messages
409 hit the session middleware (thus ensuring that the user's dynamic scope —
410 including `*in*` — has been added to the message) before the `add-stdin`'s
411 handler sees them, so that it may append the provided `stdin` content to the
412 buffer underlying `*in*`. Additionally, `add-stdin` must be "above" any `eval`
413 middleware, as it takes responsibility for calling `clojure.main/skip-if-eol`
414 on `*in*` prior to each evaluation (in order to ensure functional parity with
415 Clojure's default stream-based REPL implementation).
416
417 The specific contents of a middleware's descriptor depends entirely on its
418 objectives: which operations it is to implement/define, how it is to modify
419 incoming request messages, and which higher- and lower-level middlewares are to
420 aid in accomplishing its aims.
421
422 nREPL uses the dependency information in descriptors in order to produce a
423 linearization of a set of middleware; this linearization is exposed by
424 `clojure.tools.nrepl.middleware/linearize-middleware-stack`, which is
425 implicitly used by `clojure.tools.nrepl.server/default-handler` to combine the
426 default stack of middleware with any additional provided middleware vars. The
427 primary contribution of `default-handler` is to use
428 `clojure.tools.nrepl.server/unknown-op` as the base handler; this ensures that
429 unhandled messages will always produce a response message with an `:unknown-op`
430 `:status`. Any handlers otherwise created (e.g. via direct usage of
431 `linearize-middleware-stack` to obtain a ordered sequence of middleware vars)
432 should do the same, or use a similar alternative base handler.
2b2b735 @cemerick documentation
cemerick authored
433
434 <!--
32e5f28 @cemerick add support for defining *in*
cemerick authored
435
1905501 @cemerick big documentation update
cemerick authored
436 #### Server Responses
437
d3ee1dd @cemerick changelog and README tweaks for 0.2.2
cemerick authored
438 The server will produce multiple messages in response to each client request,
439 each of which can have the following slots:
04849ee @cemerick braindump of protocol & message spec
cemerick authored
440
32e5f28 @cemerick add support for defining *in*
cemerick authored
441 - `id` The ID of the request for which the response was generated.
d3ee1dd @cemerick changelog and README tweaks for 0.2.2
cemerick authored
442 - `ns` The stringified value of `*ns*` at the time of the response message's
443 generation.
444 - `out` Contains content written to `*out*` while the request's code was being
445 evaluated. Messages containing `*out*` content may be sent at the discretion
446 of the server, though at minimum corresponding with flushes of the underlying
447 stream/writer.
1905501 @cemerick big documentation update
cemerick authored
448 - `err` Same as `out`, but for `*err*`.
2b2b735 @cemerick documentation
cemerick authored
449 - `value` The result of printing a result of evaluating a form in the code sent
450 in the corresponding request. More than one value may be sent, if more than
451 one form can be read from the request's code string. In contrast to the output
452 written to `*out*` and `*err*`, this may be usefully/reliably read and utilized
453 by the client, e.g. in tooling contexts, assuming the evaluated code returns a
454 printable and readable value. Interactive clients will likely want to simply
d3ee1dd @cemerick changelog and README tweaks for 0.2.2
cemerick authored
455 stream `value`'s content to their UI's primary output / log. Values are
456 printed with `prn` by default; alternatively, if all of the following
457 conditions hold at the time of printing, a pretty-printer will be used instead:
1905501 @cemerick big documentation update
cemerick authored
458 1. One of the following is available:
459 1. Clojure [1.2.0) (and therefore `clojure.pprint`)
460 2. Clojure Contrib (and therefore `clojure.contrib.pprint`)
d3ee1dd @cemerick changelog and README tweaks for 0.2.2
cemerick authored
461 2. `clojure.tools.nrepl/*pretty-print*` is `set!`'ed to true (which
462 persists for the duration of the client connection)
32e5f28 @cemerick add support for defining *in*
cemerick authored
463 - `status` One of:
2b2b735 @cemerick documentation
cemerick authored
464 - `error` Indicates an error occurred evaluating the requested code. The
465 related exception is bound to `*e` per usual, and printed to `*err*`,
466 which will be delivered via a later message. The caught exception is printed
d3ee1dd @cemerick changelog and README tweaks for 0.2.2
cemerick authored
467 using `prn` by default; if `clojure.tools.nrepl/*print-stack-trace-on-error*`
468 is `set!`'ed to true (which persists for the duration of the client
469 connection), then exception stack traces are automatically printed to `*err*`
222c456 @bbatsov Fix a typo and remove some trailing whitespace
bbatsov authored
470 instead.
04849ee @cemerick braindump of protocol & message spec
cemerick authored
471 - `timeout` Indicates that the timeout specified by the requesting message
2b2b735 @cemerick documentation
cemerick authored
472 expired before the code was fully evaluated.
473 - `interrupted` Indicates that the evaluation of the request's code was
474 interrupted.
475 - `server-failure` An unrecoverable error occurred in conjunction with the
476 processing of the request's code. This probably indicates a bug or fatal
222c456 @bbatsov Fix a typo and remove some trailing whitespace
bbatsov authored
477 system fault in the server itself.
2b2b735 @cemerick documentation
cemerick authored
478 - `done` Indicates that the request associated with the specified ID has
479 been completely processed, and no further messages related to it will be
d3ee1dd @cemerick changelog and README tweaks for 0.2.2
cemerick authored
480 sent. This does not imply "success", only that a timeout or interrupt
481 condition was not encountered.
1905501 @cemerick big documentation update
cemerick authored
482
d3ee1dd @cemerick changelog and README tweaks for 0.2.2
cemerick authored
483 Only the `id` and `ns` slots will always be defined. Other slots are only
484 defined when new related data is available (e.g. `err` when new content has
485 been written to `*err*`, etc).
04849ee @cemerick braindump of protocol & message spec
cemerick authored
486
d3ee1dd @cemerick changelog and README tweaks for 0.2.2
cemerick authored
487 Note that evaluations that timeout or are interrupted may nevertheless result
488 in multiple response messages being sent prior to the timeout or interrupt
489 occurring.
04849ee @cemerick braindump of protocol & message spec
cemerick authored
490
b197ced @cemerick Initial spike.
cemerick authored
491 ### Timeouts and Interrupts
492
d3ee1dd @cemerick changelog and README tweaks for 0.2.2
cemerick authored
493 Each message has a timeout associated with it, which controls the maximum time
494 that a message's code will be allowed to run before being interrupted and a
495 response message being sent indicating a status of `timeout`.
04849ee @cemerick braindump of protocol & message spec
cemerick authored
496
d3ee1dd @cemerick changelog and README tweaks for 0.2.2
cemerick authored
497 The processing of a message may be interrupted by a client by sending another
498 message containing code that invokes the `clojure.tools.nrepl/interrupt`
499 function, providing it with the string ID of the message to be interrupted.
500 The interrupt will be responded to separately as with any other message. (The
501 provided client implementation provides a simple abstraction for handling
502 responses that makes issuing interrupts very straightforward.)
e0895b0 @cemerick add link to original design notes
cemerick authored
503
d3ee1dd @cemerick changelog and README tweaks for 0.2.2
cemerick authored
504 *Note that interrupts are performed on a “best-effort” basis, and are subject
505 to the limitations of Java’s threading model. For more read
1905501 @cemerick big documentation update
cemerick authored
506 [here](http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#interrupt%28%29)
2b2b735 @cemerick documentation
cemerick authored
507 and
508 [here](http://download.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html).*
509 -->
e0895b0 @cemerick add link to original design notes
cemerick authored
510
e6d3f52 @cemerick 0.0.4 release notes, docs update
cemerick authored
511
b197ced @cemerick Initial spike.
cemerick authored
512 ## Thanks
513
d3ee1dd @cemerick changelog and README tweaks for 0.2.2
cemerick authored
514 Thanks to the following Clojure masters for their helpful feedback during the
515 initial design phases of nREPL:
1905501 @cemerick big documentation update
cemerick authored
516
2b2b735 @cemerick documentation
cemerick authored
517 * Justin Balthrop
518 * Meikel Brandmeyer
519 * Hugo Duncan
520 * Christophe Grand
521 * Anthony Grimes
522 * Phil Hagelberg
523 * Rich Hickey
524 * Chris Houser
525 * Colin Jones
526 * Laurent Petit
1905501 @cemerick big documentation update
cemerick authored
527 * Eric Thorsen
b197ced @cemerick Initial spike.
cemerick authored
528
529 ## License
530
d3ee1dd @cemerick changelog and README tweaks for 0.2.2
cemerick authored
531 Copyright © 2010 - 2013 Chas Emerick and contributors.
b197ced @cemerick Initial spike.
cemerick authored
532
533 Licensed under the EPL. (See the file epl.html.)
Something went wrong with that request. Please try again.