Created
June 15, 2016 23:36
-
-
Save emidln/f2ee7ec7753bb83de1b974c919e1eb0b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns fnk-sourcery | |
(:require clojure.string | |
taoensso.encore | |
plumbing.core) | |
(:import clojure.lang.RT | |
clojure.lang.Reflector | |
java.io.LineNumberReader | |
java.io.InputStreamReader | |
java.io.PushbackReader)) | |
(defn filepath-from-fnk | |
[fnk] | |
(some-> (->> fnk meta :plumbing.fnk.impl/positional-info first pr-str | |
(re-matches #"#.*\[([A-z.\-]*).*\]") | |
second) | |
(clojure.string/replace #"\." "/") | |
(str ".clj"))) | |
(defn fnk-source | |
"Gets the source of a plumbing.core/fnk (or plumbing.core/defnk) object. | |
Does so in a way that is almost certainly guaranteed to break if you look at it wrong. | |
Can we please annotate fnk's with the :file they came from? Please?" | |
[afnk] | |
(with-local-vars [*text* (StringBuilder.)] | |
(taoensso.encore/when-lets | |
[afnk-meta (meta afnk) | |
filepath (filepath-from-fnk afnk) | |
strm (.getResourceAsStream (RT/baseLoader) filepath)] | |
(with-open [rdr (LineNumberReader. (InputStreamReader. strm))] | |
;; move the reader up to our line | |
(dotimes [_ (dec (:line afnk-meta))] (.readLine rdr)) | |
(let [pbr (proxy [PushbackReader] [rdr] | |
(read [] (let [i (proxy-super read)] | |
(.append (var-get *text*) (char i)) | |
i))) | |
read-opts {}] | |
(loop [tries 2] | |
(var-set *text* (StringBuilder.)) | |
(read read-opts (PushbackReader. pbr)) | |
(let [text (str (var-get *text*)) | |
code (read-string text)] | |
(if (and (list? code) (#{'defnk 'fnk} (first code))) | |
(clojure.string/trim text) | |
(when (> tries 0) | |
(recur (dec tries))))))))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment