Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Initial commit.

  • Loading branch information...
commit 15bc54ea835fad838cc9bff18fa76d179ce25ef1 0 parents
@technomancy authored
10 .gitignore
@@ -0,0 +1,10 @@
+/target
+/lib
+/classes
+/checkouts
+pom.xml
+*.jar
+*.class
+.lein-deps-sum
+.lein-failures
+.lein-plugins
21 README.md
@@ -0,0 +1,21 @@
+# Limit Break
+
+<img src="http://p.hagelb.org/limit-break.jpg" alt="omnislash" />
+
+Modernized version of George Jahad's debug-repl.
+
+## Usage
+
+Require `limit` and add `(limit/break)` to the body of a function to
+inject a REPL.
+
+Currently only works with a direct stdin REPL; planning support for
+nREPL. Try `lein trampoline run -m clojure.main/main`.
+
+## License
+
+Copyright © 2009-2012 George Jahad, Alex Osborne, and Phil Hagelberg.
+
+Image above © 1997 Square Enix.
+
+Distributed under the Eclipse Public License, the same as Clojure.
6 project.clj
@@ -0,0 +1,6 @@
+(defproject limit-break "0.1.0-SNAPSHOT"
+ :description "Inject a REPL into the middle of your functions for debugging."
+ :url "https://github.com/technomancy/limit-break"
+ :license {:name "Eclipse Public License"
+ :url "http://www.eclipse.org/legal/epl-v10.html"}
+ :profiles {:dev {:dependencies [[org.clojure/clojure "1.4.0"]]}})
7 src/limit.clj
@@ -0,0 +1,7 @@
+(ns limit
+ (:require limit.break))
+
+;; I know, I know: single-segment namespaces are evil. So don't use
+;; this out of dev-time. But the shorter name is nice.
+
+(defmacro break [] `(limit.break/break))
32 src/limit/break.clj
@@ -0,0 +1,32 @@
+(ns limit.break
+ (:require [clojure.main]))
+
+(def ^:dynamic *level* 0)
+
+(defmacro local-bindings
+ "Produces a map of the names of local bindings to their values."
+ []
+ (let [symbols (keys &env)]
+ (zipmap (map (fn [sym] `(quote ~sym)) symbols) symbols)))
+
+(def ^:dynamic *locals*)
+
+(defn eval-with-locals
+ "Evals a form with given locals. The locals should be a map of symbols to
+values."
+ [locals form]
+ (binding [*locals* locals]
+ (eval
+ `(let ~(vec (mapcat #(list % `(*locals* '~%)) (keys locals)))
+ ~form))))
+
+(defn prompt []
+ (print (if (= 1 *level*) ; get fancy only if we're nesting
+ "break> "
+ (str "break-" *level* "> "))))
+
+(defmacro break []
+ `(let [eval-fn# (partial eval-with-locals (local-bindings))]
+ (binding [*level* (inc *level*)]
+ ;; TODO: nrepl-friendly :read function
+ (clojure.main/repl :prompt prompt :eval eval-fn#))))
Please sign in to comment.
Something went wrong with that request. Please try again.