debug-repl | George Jahad @georgejahad (with an insight by Alex Osborne @atosborne) |
---|---|
swank-clojure | Phil Hagelburg @technomancy |
CDT | George Jahad @georgejahad |
Started Ritz to provide Clojure debugging in SLIME via SLDB
https://github.com/clojure/tools.nrepl
transport (socket & bencode)
Driven by Chas Emerick / @cemerick
Support for Clojure and ClojureScript
Configure your favourite middleware in ~/.lein/profiles.clj
.
:user
{:repl-options
{:nrepl-middleware
[ritz.nrepl.middleware.doc/wrap-doc]}}
Or add project specific middleware in project.clj
:dev
{:repl-options
{:nrepl-middleware
[ritz.nrepl.middleware.doc/wrap-doc]}}
Colin Jones @trptcolin https://github.com/trptcolin/reply
Laurent Petit @petitlaurent http://code.google.com/p/counterclockwise.
Meikel Brandmeyer @kotarak VimClojure.
and …
https://github.com/kingtim/nrepl.el
An Emacs client for the nREPL protocol, unfettered by support of any other lisp.
Driven by Tim King
nrepl.el is available as an Emacs package in Marmalade
.
(require 'package)
(add-to-list 'package-archives
'("marmalade"
. "http://marmalade-repo.org/packages/"))
(package-initialize)
The git HEAD
is packaged to MELPA
.
(add-to-list 'package-archives
'("melpa"
. "http://melpa.milkbox.net/packages/"))
In either case, to actually install nrepl
:
M-x package-install nrepl
Browse to a file in your clojure project an jack-in:
M-x nrepl-jack-in
Start an nREPL server, possibly with lein
.
lein repl :headless
Connect to the nREPL server. lein
announces the port
the REPL is running on.
M-x nrepl localhost 41045
https://github.com/pallet/ritz
Started life as a fork of swank-clojure, but is now a very different codebase.
Initially was to provide SLDB for Clojure in SLIME.
Now refactored to support nREPL.
Can be used in any nREPL server
Refactored after reading Out of the Tar Pit
, Ben Moseley,
Peter Marks 2006.
Map for each connection, with assoc and update-in functions for different areas within the connection.
Could be used by other (non-emacs) clients.
Emacs package for nrepl.el extensions.
Install the nrepl-ritz.el
Emacs package:
M-x package-install nrepl-ritz
Add lein-ritz
to you :plugins
in
~/.lein/profiles.clj
:user {:plugins [[lein-ritz "0.6.0"]]
Run the ritz nREPL server:
lein ritz-nrepl
Connect to the repl server, specifying the port:
M-x nrepl 4005
Examine stack traces before the stack unwinds. Needs to be turned on:
M-x nrepl-ritz-break-on-exception
user>
(/ 1 0)
Filtering of exceptions is via "restarts" displayed as part of the stacktrace.
Divide by zero java.lang.ArithmeticException Restarts: 0: [CONTINUE] Pass exception to program 1: [ABORT] Abort request. 2: [IGNORE] Do not enter debugger for this exception type 3: [IGNORE-MSG] Do not enter debugger for this exception message 4: [IGNORE-CATCH] Do not enter debugger for exceptions with catch location clojure.lang.Compiler.* 5: [IGNORE-LOC] Do not enter debugger for exceptions with throw location clojure.lang.Numbers.* Stacktrace: 0: clojure.lang.Numbers.divide (Numbers.java:156) 1: clojure.lang.Numbers.divide (Numbers.java:3691) 2: ritz-conj.example/eval2845 (UNKNOWN:-1)
Any (try ... (finally ..))
block means that JPDA
considers an exception within that block as caught
(with-open [f (io/reader f)] ...)
Makes filtering on caught/uncaught meaningless.
Linking source code to stack frames requires that the source is on the classpath.
The Ritz servers arrange this if the source code is in your local repository.
lein pom
mvn dependency:sources
You can evaluate an expression within the context of a frame. Just select the frame, and press:
In ritz-swank, just press Enter
on any local variable to
pop up the SLIME inspector.
Clojure does something called locals clearing, to avoid holding onto the head of lazy sequences. This can result in locals showing up as nil, even when they aren't really.
Can be switched off in 1.4+
Use a prefix argument (C-u
)to the following commands
to disable locals clearing on the code being compiled.
C-c C-c | nrepl-ritz-compile-expression |
C-c C-c | slime-compile-defun |
C-c C-k | slime-compile-file |
To disable locals clearing globally:
(alter-var-root #'*compiler-options*
assoc :disable-locals-clearing true)
SLIME only for now
Press C-c C-x C-b
to set a breakpoint on any line (of
clojure or java).
Restarts for Step, Step Over, and Step Out
Press 'D' on any frame to see the JVM bytecode for the frame
M-x nrepl-ritz-threads
============================================================================================ :id | :name | :status | :at-breakpoint? | :suspended? | :suspend-count ============================================================================================ | system | | | | | main | | | | 1 | main | :wait | false | false | 0 1569 | JDI-VM-Control-Thread | :running | false | true | 1 1782 | msg-pump4905 | :wait | false | false | 0 5228 | Reference Handler | :wait | false | false | 0 5229 | Finalizer | :wait | false | false | 0 5230 | Signal Dispatcher | :running | false | false | 0 ============================================================================================
Reload project to pick up classpath changes.
M-x nrepl-ritz-reload-project
Switch project
M-x nrepl-ritz-load-project
Run lein targets on project
M-x nrepl-ritz-lein
Split out into the nrepl-project
project as an nREPL
middleware.
https://github.com/technomancy/limit-break
A version of debug-repl for nrepl.
The simplest thing that could work and not need any extra setup beyond nrepl.el.
Parity with ritz-swank:
Other Ideas:
http://www.cs.brown.edu/~sk/Publications/Papers/Published/mcskr-dataflow-lang-script-debug-journal/
nREPL middleware provides flexibility.
Make Ritz the goto place for middleware and debugger.