|
66 | 66 | (declare ops)
|
67 | 67 |
|
68 | 68 | (defn- handle-describe [request send-fn]
|
69 |
| - (send-fn request |
70 |
| - {"versions" {"basilisp" (let [version basilisp.lang.runtime/BASILISP-VERSION-STRING] |
71 |
| - (assoc (zipmap ["major" "minor" "incremental"] |
72 |
| - version) |
73 |
| - "version-string" (str/join "." version))) |
74 |
| - "python" (let [version (get (.split sys/version " ") 0)] |
75 |
| - (assoc (zipmap ["major" "minor" "incremental"] |
76 |
| - (py->lisp (.split version "."))) |
77 |
| - "version-string" (py->lisp sys/version)))} |
78 |
| - "ops" (zipmap (map name (keys ops)) (repeat {})) |
79 |
| - "status" ["done"]})) |
| 69 | + (let [basilisp-version (-> (zipmap ["major" "minor" "incremental"] *basilisp-version*) |
| 70 | + (assoc "version-string" (str/join "." *basilisp-version*))) |
| 71 | + python-version (-> (zipmap ["major" "minor" "incremental"] *python-version*) |
| 72 | + (assoc "version-string" (str/join "." *python-version*)))] |
| 73 | + (send-fn request |
| 74 | + {"versions" {"basilisp" basilisp-version |
| 75 | + "python" python-version} |
| 76 | + "ops" (zipmap (map name (keys ops)) (repeat {})) |
| 77 | + "status" ["done"]}))) |
80 | 78 |
|
81 | 79 | (defn- format-value [_nrepl-pprint _pprint-options value]
|
82 | 80 | (pr-str value))
|
83 | 81 |
|
84 | 82 | (defn- send-value [request send-fn v]
|
85 |
| - (let [{:keys [client*]} request |
86 |
| - {:keys [*1 *2]} @client* |
87 |
| - [v opts] v |
88 |
| - ns (:ns opts)] |
| 83 | + (let [{:keys [client*]} request |
| 84 | + {:keys [*1 *2]} @client* |
| 85 | + [v opts] v |
| 86 | + ns (:ns opts)] |
89 | 87 | (swap! client* assoc :*1 v :*2 *1 :*3 *2)
|
90 | 88 | (let [v (format-value (:nrepl.middleware.print/print request)
|
91 | 89 | (:nrepl.middleware.print/options request)
|
92 | 90 | v)]
|
93 | 91 | (send-fn request {"value" (str v)
|
94 |
| - "ns" (str ns)})))) |
| 92 | + "ns" (str ns)})))) |
95 | 93 |
|
96 | 94 | (defn- handle-error [send-fn request e]
|
97 | 95 | (let [{:keys [client* ns]} request
|
98 | 96 | data (ex-data e)
|
99 | 97 | message (or (:message data) (str e))]
|
100 | 98 | (swap! client* assoc :*e e)
|
101 | 99 | (send-fn request {"err" (str message)})
|
102 |
| - (send-fn request {"ex" (traceback/format-exc) |
| 100 | + (send-fn request {"ex" (traceback/format-exc) |
103 | 101 | "status" ["eval-error"]
|
104 |
| - "ns" ns}))) |
| 102 | + "ns" ns}))) |
105 | 103 |
|
106 | 104 | (defn- do-handle-eval
|
107 | 105 | "Evaluate the ``request`` ``code`` of ``file`` in the ``ns`` namespace according
|
|
125 | 123 | eval-ns (if ns
|
126 | 124 | (create-ns (symbol ns))
|
127 | 125 | eval-ns)]
|
128 |
| - (binding [*ns* eval-ns |
| 126 | + (binding [*ns* eval-ns |
129 | 127 | *out* out-stream
|
130 |
| - *1 *1 *2 *2 *3 *3 *e *e] |
| 128 | + *1 *1 |
| 129 | + *2 *2 |
| 130 | + *3 *3 |
| 131 | + *e *e] |
131 | 132 | (try
|
132 | 133 | (let [results (for [form (seq (basilisp.lang.reader/read reader
|
133 | 134 | *resolver*
|
|
142 | 143 | (handle-error send-fn (assoc request :ns (str *ns*)) e))
|
143 | 144 | (finally
|
144 | 145 | (swap! client* assoc :eval-ns *ns*)
|
145 |
| - (send-fn request {"ns" (str *ns*) |
| 146 | + (send-fn request {"ns" (str *ns*) |
146 | 147 | "status" ["done"]}))))))
|
147 | 148 |
|
148 | 149 | (defn- handle-eval [request send-fn]
|
|
179 | 180 | (first (seq (basilisp.lang.reader/read reader
|
180 | 181 | *resolver*
|
181 | 182 | *data-readers*))))}
|
182 |
| - (catch python/Exception e |
183 |
| - (info :symbol-identify-reader-error :input symbol-str :exception e) |
184 |
| - {:error (str e)}))] |
| 183 | + (catch python/Exception e |
| 184 | + (info :symbol-identify-reader-error :input symbol-str :exception e) |
| 185 | + {:error (str e)}))] |
185 | 186 |
|
186 | 187 | (cond
|
187 | 188 | error
|
|
201 | 202 | (catch python/Exception e
|
202 | 203 | {:error (str e)}))]
|
203 | 204 | (cond
|
204 |
| - var |
205 |
| - [:var var] |
206 |
| - error |
207 |
| - [:error error] |
208 |
| - :else |
209 |
| - [:other form]))))) |
| 205 | + var [:var var] |
| 206 | + error [:error error] |
| 207 | + :else [:other form]))))) |
210 | 208 |
|
211 | 209 | (defn- forms-join [forms]
|
212 | 210 | (->> (map pr-str forms)
|
|
221 | 219 | (let [mapping-type (-> request :op)
|
222 | 220 | {:keys [eval-ns]} @client*]
|
223 | 221 | (try
|
224 |
| - (let [lookup-ns (if ns |
225 |
| - (create-ns (symbol ns)) |
226 |
| - eval-ns) |
227 |
| - sym-str (or (:sym request) ;; cider |
228 |
| - (:symbol request) ;; calva |
229 |
| - ) |
| 222 | + (let [lookup-ns (if ns |
| 223 | + (create-ns (symbol ns)) |
| 224 | + eval-ns) |
| 225 | + sym-str (or (:sym request) ;; cider |
| 226 | + (:symbol request) ;; calva |
| 227 | + ) |
| 228 | + |
230 | 229 | [tp var-maybe] (symbol-identify lookup-ns sym-str)
|
231 | 230 | var-meta (when (= tp :var) (meta var-maybe))
|
| 231 | + |
232 | 232 | {:keys [arglists doc file ns line] symname :name} var-meta
|
233 |
| - ref (when (= tp :var) (var-get var-maybe)) |
234 |
| - response (when symname (case mapping-type |
235 |
| - :eldoc (cond-> |
236 |
| - {"eldoc" (mapv #(mapv str %) arglists) |
237 |
| - "ns" (str ns) |
238 |
| - "type" (if (fn? ref) |
239 |
| - "function" |
240 |
| - "variable") |
241 |
| - "name" (str symname) |
242 |
| - "status" ["done"]} |
243 |
| - doc (assoc "docstring" doc)) |
244 |
| - :info {"doc" doc |
245 |
| - "ns" (str ns) |
246 |
| - "name" (str symname) |
247 |
| - "file" file |
248 |
| - "line" line |
249 |
| - "arglists-str" (forms-join arglists) |
250 |
| - "status" ["done"]})) |
251 |
| - status (if (and (nil? symname) (= mapping-type :eldoc) ) |
252 |
| - ["done" "no-eldoc"] |
253 |
| - ["done"])] |
| 233 | + |
| 234 | + ref (when (= tp :var) (var-get var-maybe)) |
| 235 | + response (when symname |
| 236 | + (case mapping-type |
| 237 | + :eldoc (cond-> |
| 238 | + {"eldoc" (mapv #(mapv str %) arglists) |
| 239 | + "ns" (str ns) |
| 240 | + "type" (if (fn? ref) |
| 241 | + "function" |
| 242 | + "variable") |
| 243 | + "name" (str symname) |
| 244 | + "status" ["done"]} |
| 245 | + doc (assoc "docstring" doc)) |
| 246 | + :info {"doc" doc |
| 247 | + "ns" (str ns) |
| 248 | + "name" (str symname) |
| 249 | + "file" file |
| 250 | + "line" line |
| 251 | + "arglists-str" (forms-join arglists) |
| 252 | + "status" ["done"]})) |
| 253 | + status (if (and (nil? symname) (= mapping-type :eldoc) ) |
| 254 | + ["done" "no-eldoc"] |
| 255 | + ["done"])] |
254 | 256 | (debug :lookup :sym sym-str :doc doc :args arglists)
|
255 | 257 | (send-fn request (assoc response :status status)))
|
256 | 258 | (catch python/Exception e
|
|
308 | 310 | "status" ["done"]})))
|
309 | 311 |
|
310 | 312 | (def ops
|
311 |
| - "A list of operations supported by the nREPL server." |
| 313 | + "A map of operations supported by the nREPL server (as keywords) to function |
| 314 | + handlers for those operations." |
312 | 315 | {:eval handle-eval
|
313 | 316 | :describe handle-describe
|
314 | 317 | :info handle-lookup
|
|
353 | 356 |
|
354 | 357 | - ``:recv-buffer-size`` The buffer size to using for incoming nREPL messages."
|
355 | 358 | (let [{:keys [recv-buffer-size]
|
356 |
| - :or {recv-buffer-size 1024}} opts |
357 |
| - socket (.-request tcp-req-handler) |
358 |
| - handler (make-request-handler opts) |
359 |
| - response-handler (make-reponse-handler socket) |
360 |
| - pending (atom nil) |
361 |
| - zero-bytes #b "" |
362 |
| - client-info (py->lisp (.getsockname socket)) |
363 |
| - client* (atom {:*1 nil :*2 nil ;; keeps track of the latest |
364 |
| - :*3 nil :*e nil ;; evaluation results |
365 |
| - :eval-ns nil ;; the last eval ns |
366 |
| - })] |
| 359 | + :or {recv-buffer-size 1024}} opts |
| 360 | + socket (.-request tcp-req-handler) |
| 361 | + handler (make-request-handler opts) |
| 362 | + response-handler (make-reponse-handler socket) |
| 363 | + pending (atom nil) |
| 364 | + zero-bytes #b "" |
| 365 | + client-info (py->lisp (.getsockname socket)) |
| 366 | + client* (atom {;; keeps track of latest evaluation results |
| 367 | + :*1 nil |
| 368 | + :*2 nil |
| 369 | + :*3 nil |
| 370 | + :*e nil |
| 371 | + ;; the last eval ns |
| 372 | + :eval-ns nil |
| 373 | + })] |
367 | 374 | (try
|
368 | 375 | (info "Connection accepted" :info client-info)
|
369 | 376 | ;; Need to load the `clojure.core` alias because cider uses it
|
370 | 377 | ;; to test for availability of features.
|
371 |
| - (eval (read-string "(ns user (:require clojure.core))")) |
| 378 | + (eval '(ns user (:require clojure.core))) |
372 | 379 | (swap! client* assoc :eval-ns *ns*)
|
373 | 380 | (loop [data (.recv socket recv-buffer-size)]
|
374 | 381 | (if (= data zero-bytes)
|
|
380 | 387 | b)
|
381 | 388 | data)
|
382 | 389 | [requests unprocessed] (bc/decode-all data {:keywordize-keys true
|
383 |
| - :string-fn #(.decode % "utf-8")})] |
| 390 | + :string-fn #(.decode % "utf-8")})] |
384 | 391 | (debug :requests requests)
|
385 | 392 | (when (not (str/blank? unprocessed))
|
386 | 393 | (reset! pending unprocessed))
|
|
423 | 430 | The session UUIDs are ignored and only created to satisfy the initial clone op."
|
424 | 431 | [opts]
|
425 | 432 | (let [{:keys [host port] :or {host "127.0.0.1" port 0}} opts
|
426 |
| - handler (python/type (name (gensym "nREPLTCPHandler")) (python/tuple [socketserver/StreamRequestHandler]) |
| 433 | + handler (python/type (name (gensym "nREPLTCPHandler")) |
| 434 | + #py (socketserver/StreamRequestHandler) |
427 | 435 | #py {"handle" #(on-connect % opts)})]
|
428 | 436 | (socketserver/ThreadingTCPServer (python/tuple [host port]) handler)))
|
429 | 437 |
|
|
0 commit comments