48 lines
1.5 KiB
Clojure
48 lines
1.5 KiB
Clojure
(ns scittle.nrepl
|
|
(:require
|
|
[clojure.edn :as edn]
|
|
[sci.nrepl.completions :refer [completions]]
|
|
[scittle.core :refer [!last-ns eval-string !sci-ctx]]))
|
|
|
|
(defn nrepl-websocket []
|
|
(.-ws_nrepl js/window))
|
|
|
|
(defn nrepl-reply [{:keys [id session]} payload]
|
|
(.send (nrepl-websocket)
|
|
(str (assoc payload :id id :session session :ns (str @!last-ns)))))
|
|
|
|
(defn handle-nrepl-eval [{:keys [code] :as msg}]
|
|
(let [[kind val] (try [::success (eval-string code)]
|
|
(catch :default e
|
|
[::error (str e)]))]
|
|
(case kind
|
|
::success
|
|
(do (nrepl-reply msg {:value (pr-str val)})
|
|
(nrepl-reply msg {:status ["done"]}))
|
|
::error
|
|
(do
|
|
(nrepl-reply msg {:err (pr-str val)})
|
|
(nrepl-reply msg {:ex (pr-str val)
|
|
:status ["error" "done"]})))))
|
|
|
|
(defn handle-nrepl-message [msg]
|
|
(case (:op msg)
|
|
:eval (handle-nrepl-eval msg)
|
|
:complete (let [completions (completions (assoc msg :ctx @!sci-ctx))]
|
|
(nrepl-reply msg completions))))
|
|
|
|
(defn ws-url [host port path]
|
|
(str "ws://" host ":" port "/" path))
|
|
|
|
(let [ws-port (or (.-SCITTLE_NREPL_WEBSOCKET_PORT js/window) 1340)]
|
|
(set! (.-ws_nrepl js/window)
|
|
(new js/WebSocket (ws-url "localhost" ws-port "_nrepl"))))
|
|
|
|
(when-let [ws (nrepl-websocket)]
|
|
(prn :ws ws)
|
|
(set! (.-onmessage ws)
|
|
(fn [event]
|
|
(handle-nrepl-message (edn/read-string (.-data event)))))
|
|
(set! (.-onerror ws)
|
|
(fn [event]
|
|
(js/console.log event))))
|