|
2 | 2 | (:require [lighttable.nrepl.core :as core] |
3 | 3 | [lighttable.nrepl.eval :as eval] |
4 | 4 | [lighttable.nrepl.cljs :as cljs] |
| 5 | + [clojure.java.io :as io] |
| 6 | + [clojure.string :as string] |
5 | 7 | [cljs.env :as env] |
6 | 8 | [cljs.compiler :as comp] |
7 | | - [cljs.analyzer :as ana])) |
| 9 | + [cljs.analyzer :as ana]) |
| 10 | + (:import java.net.URL java.io.File)) |
8 | 11 |
|
9 | 12 | (defn clean-meta [m] |
10 | 13 | (when m |
|
42 | 45 | (str-contains? (str (:name m)) search)))] |
43 | 46 | (format-result (clean-meta m))))) |
44 | 47 |
|
| 48 | +(def jar-temp-files |
| 49 | + "Maps jar-url paths to temp files" |
| 50 | + (atom {})) |
| 51 | + |
| 52 | +(defn jar-url->file |
| 53 | + "Given a jar-url, retrieve its cached tempfile or copy its contents to a |
| 54 | + tempfile and return it." |
| 55 | + [^URL jar-url] |
| 56 | + (or |
| 57 | + (get @jar-temp-files (.getPath jar-url)) |
| 58 | + (let [[_ relative-name ext] (re-find #"!/(.*)(\.[^.]+)$" (.getPath jar-url)) |
| 59 | + new-file (.getPath (File/createTempFile relative-name ext)) |
| 60 | + body (-> jar-url .getContent slurp)] |
| 61 | + (swap! jar-temp-files assoc (.getPath jar-url) new-file) |
| 62 | + (spit new-file body) |
| 63 | + new-file))) |
| 64 | + |
| 65 | +(defn resolve-file |
| 66 | + "Resolves a file to its full path. Jar paths are unpacked to a tempfile." |
| 67 | + [file] |
| 68 | + (when file |
| 69 | + (let [url (or (io/resource file) |
| 70 | + (URL. |
| 71 | + ;; cljs files don't have jar:file: or file: prefix off of metadata |
| 72 | + (if (.contains file ".jar!/") |
| 73 | + (string/replace-first file #"^file:" "jar:file:") |
| 74 | + (string/replace-first file #"^/" "file:/"))))] |
| 75 | + (if (= "jar" (.getProtocol url)) |
| 76 | + (jar-url->file url) |
| 77 | + (-> url io/file .getPath))))) |
| 78 | + |
45 | 79 | (defn dmeta [nsp sym] |
46 | 80 | (-> (ns-resolve (symbol nsp) sym) |
47 | 81 | (meta) |
|
77 | 111 | (defmethod core/handle "editor.clj.doc" [{:keys [ns sym loc session path result-type] :as msg}] |
78 | 112 | (let [ns (eval/normalize-ns ns path) |
79 | 113 | _ (eval/require|create-ns (symbol ns)) |
80 | | - res (get-doc ns sym) |
81 | | - res (when res (assoc res :loc loc :result-type result-type))] |
| 114 | + res (some-> (get-doc ns sym) |
| 115 | + (assoc :loc loc :result-type result-type) |
| 116 | + (update-in [:file] resolve-file))] |
82 | 117 | (core/respond msg "editor.clj.doc" res)) |
83 | 118 | @session) |
84 | 119 |
|
|
91 | 126 | res (if (:macro clj) |
92 | 127 | clj |
93 | 128 | (get-cljs-doc ns sym)) |
94 | | - res (when res (assoc res :loc loc :result-type result-type))] |
| 129 | + res (some-> res |
| 130 | + (assoc :loc loc :result-type result-type) |
| 131 | + (update-in [:file] resolve-file))] |
95 | 132 | (core/respond msg "editor.cljs.doc" res)))) |
96 | 133 | @session) |
97 | 134 |
|
|
0 commit comments