On Nov 3, 7:03 pm, Chouser <[EMAIL PROTECTED]> wrote:
> [...] It's not pretty, and it only works on functions defined in the clojure
> namespace. [...]
The variation below works in a more general setting: it will look for
the source file anywhere in the classpath (including jar files) or in
user.dir
I just combined your get-source function with functionality from swank-
clojure (in swank/commands/basic/basic.clj). I didn't test it much,
there might be a bug or two.
Carlos
(import '(java.io File FileInputStream LineNumberReader
InputStreamReader PushbackReader)
'(java.util.zip ZipFile)
'(clojure.lang RT))
(defn- namespace-to-path [ns]
(-> (name (ns-name ns))
(.replace \- \_)
(.replace \. \/)))
(defn- get-path-prop
"Returns a coll of the paths represented in a system property"
([prop]
(seq (-> (System/getProperty prop)
(.split File/pathSeparator))))
([prop & props]
(lazy-cat (get-path-prop prop) (mapcat get-path-prop props))))
(defn- search-paths []
(concat (get-path-prop "user.dir" "java.class.path"
"sun.boot.class.path")
(map #(.getPath %) (.getURLs clojure.lang.RT/
ROOT_CLASSLOADER))))
(defn- find-file-in-dir [#^File file #^String dir]
(let [file-name (. file (getPath))
child (File. (File. dir) file-name)]
(or (when (.exists child)
(FileInputStream. child))
(try
(let [zipfile (ZipFile. dir)]
(when (.getEntry zipfile file-name)
(.getInputStream zipfile (.getEntry zipfile file-name))))
(catch Throwable e false)))))
(defn- find-file-in-paths [#^String file paths]
(let [f (File. file)]
(if (.isAbsolute f)
(FileInputStream. f)
(first (filter identity (map #(find-file-in-dir f %) paths))))))
(defn get-source [vn]
(let [m ^(resolve vn)
strm (when (:file m)
(or (find-file-in-paths (str (namespace-to-path (:ns m))
(.separator File)
(:file m)) (search-paths))
(find-file-in-paths (:file m) (search-paths))))]
(if strm
(with-open rdr (LineNumberReader. (InputStreamReader. strm))
(dotimes _ (dec (:line m)) (.readLine rdr))
(.mark rdr 2000)
(read (PushbackReader. rdr))
(let [cnt (- (.getLineNumber rdr) (:line m))]
(.reset rdr)
(dotimes _ cnt (println (.readLine rdr)))
true))
(println "Source not found for" vn))))
(defmacro source [n]
`(get-source '~n))
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---