-
Notifications
You must be signed in to change notification settings - Fork 175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rewrite the debugger #220
Rewrite the debugger #220
Conversation
(not (seq @debugger-message)) (do (println "Debugger not initialized") | ||
(skip-breaks! true) | ||
val#) | ||
true (read-debug-command |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's customary to use :else
to denote the default branch in clojure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
I've just given this a cursory glance because I was curious but this looks like a sound approach! |
@expez I think it would be possible. We would essentially have to use debugger's "eval in lexical scope" functionality where the code would be like |
Tests passing. |
(nhex [n] (apply str (repeatedly n hex)))] | ||
(let [rhex (format "%x" (bit-or 0x8 (bit-and 0x3 (rand-int 14))))] | ||
(str (nhex 8) "-" (nhex 4) "-4" (nhex 3) | ||
"-" rhex (nhex 3) "-" (nhex 12))))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cljfmt
indented this line like this, but it looks like a bug to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely a bug. You should probably report it upstream.
FIled weavejester/cljfmt#42 |
This is the clojure counterpart to clojure-emacs/cider#1149
This completely rewrites the debugger (again) to be simpler and (I believe) more reliable.
The big complication with the previous debugger were macros.
The previous debugger took a lesson from Edebug and tried to fix the first option by instrumenting the macro arguments according to a specification. This worked surprisingly well, but:
letfn
).The version proposed here goes with the second option instead, by using something that's not available in emacs-lisp, metadata.
instrument-special-form
).Looking at the diffs, it should go without saying that this is much simpler. About half the original code was dedicated to parsing macros.
Notable differences
instrument
on a top-level sexp, and this would instrument everything. Now, we callinstrument-tagged-code
on a top-level sexp, and it will only instrument objects with a:cider-breakfunction
metadata. In particular, this means that if you callinstrument-tagged-code
on a clean sexp, it won't do anything. You have to calldebug-reader
orbreakpoint-reader
on the sexp first, but this is stomething that already happened if the sexp was read with a#dbg
or#bp
reader macro.instrument-and-eval
), thewrap-debug
middleware now hooks cleanly into the “eval” op. If neither one of the reader macros (#dbg
or#bp
) are present in the received code, the message just falls through for regular evaluation. If one of the macros was present,wrap-debug
just adds its own evaluator to the message before letting it fall through.