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 clojure@googlegroups.com 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 -~----------~----~----~----~------~----~------~--~---