94 lines
2.8 KiB
Plaintext
94 lines
2.8 KiB
Plaintext
|
(local Object (require :core.object))
|
||
|
(local nrepl (require :plugins.fennel-xl.nrepl))
|
||
|
(local lume (require :plugins.fennel-xl.lume))
|
||
|
(local {: defmethod} (require :plugins.fennel-xl.multimethod))
|
||
|
(local {: restart : submit} (require :plugins.fennel-xl.replsession))
|
||
|
|
||
|
(local Session (Object:extend))
|
||
|
|
||
|
(fn Session.new [self ?handlers]
|
||
|
(set self.queue [])
|
||
|
(set self.in-progress false)
|
||
|
(set self.handlers ?handlers))
|
||
|
|
||
|
(fn Session.init-session [self]
|
||
|
(when (nrepl:connected?)
|
||
|
(self:do #(nrepl:new-session
|
||
|
#(do (set self.session $2)
|
||
|
(self:done-msg))
|
||
|
(self:make-handlers)))))
|
||
|
|
||
|
(fn Session.shutdown-session [self]
|
||
|
(set self.queue [])
|
||
|
(set self.in-progress false)
|
||
|
(set self.session nil))
|
||
|
|
||
|
(fn Session.cleanup-handlers [self]
|
||
|
{:status/done #(self:done-msg)
|
||
|
:status/interrupted #(self:done-msg)})
|
||
|
|
||
|
(fn Session.make-handlers [self]
|
||
|
(lume.merge
|
||
|
(or self.handlers {})
|
||
|
(nrepl:chain-handlers [:status/done :status/interrupted]
|
||
|
(or self.handlers {})
|
||
|
(self:cleanup-handlers))))
|
||
|
|
||
|
(fn Session.coro-handlers [self coro ?handlers]
|
||
|
(lume.merge
|
||
|
(or ?handlers {})
|
||
|
(nrepl:chain-handlers [:status/done :status/interrupted]
|
||
|
(self:cleanup-handlers)
|
||
|
{:status/done #(coroutine.resume coro)
|
||
|
:status/interrupted #(coroutine.resume coro)})))
|
||
|
|
||
|
(fn Session.do [self f]
|
||
|
(if self.in-progress (table.insert self.queue f)
|
||
|
(do (set self.in-progress true)
|
||
|
(f))))
|
||
|
|
||
|
(fn Session.done-msg [self]
|
||
|
(if (> (length self.queue) 0) ((table.remove self.queue 1))
|
||
|
(set self.in-progress false)))
|
||
|
|
||
|
(fn Session.send [self message ?handlers]
|
||
|
(self:do #(nrepl:send message ?handlers self.session)))
|
||
|
|
||
|
(fn Session.send-oob [self message ?handlers]
|
||
|
(local handlers
|
||
|
(lume.merge
|
||
|
(nrepl:chain-handlers [:status/done :status/interrupted]
|
||
|
(or self.handlers {}))
|
||
|
(or ?handlers {})))
|
||
|
(nrepl:send message handlers self.session))
|
||
|
|
||
|
(fn Session.eval [self code ?handlers]
|
||
|
(self:send {:op :eval : code} ?handlers))
|
||
|
|
||
|
(fn Session.input-handler [self input]
|
||
|
{:status/need-input #(self:send-oob {:op :stdin :stdin input})})
|
||
|
|
||
|
(fn Session.eval-input [self code input ?handlers]
|
||
|
(self:send {:op :eval : code}
|
||
|
(lume.merge (or ?handlers {}) (self:input-handler input))))
|
||
|
|
||
|
(local fennel (require :plugins.fennel-xl.fennel))
|
||
|
(fn parse-vals [s]
|
||
|
(let [parser (fennel.parser s)]
|
||
|
(icollect [ok ast (fennel.parser s)] (if ok ast s))))
|
||
|
|
||
|
(defmethod restart :nrepl (fn [session]
|
||
|
(when (not (nrepl:connected?)) (error "Must connect nrepl"))
|
||
|
(when session.conn (session.conn:shutdown-session))
|
||
|
(set session.conn (Session))
|
||
|
(session.conn:init-session)
|
||
|
session))
|
||
|
|
||
|
(defmethod submit :nrepl (fn [session chunk callback ?suppress-crash]
|
||
|
(session.conn:eval chunk
|
||
|
{:out #(callback {:vals [$2]})
|
||
|
:value #(callback {:vals (parse-vals $2)})
|
||
|
:ex #(callback {:err $2})})))
|
||
|
|
||
|
Session
|