Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Initial commit.

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

0 notes on commit 15bc54e

Please sign in to comment.
Something went wrong with that request. Please try again.