(local util (require :lib.util)) (local fennel (require :lib.fennel)) (local core (require :core)) (local replsession (util.hot-table ...)) (set replsession.sessions {}) (fn replsession.session-run [session] (fennel.repl {:readChunk coroutine.yield ; todo: log errors? :onValues #(pcall session.callback {:vals $1}) :onError #(pcall session.callback {:errType $1 :err $2 :luaSource $3 :traceback (fennel.traceback)}) :pp #$1 :env (lume.clone _G)})) (fn replsession.restart-session [session] (set session.coro (coroutine.create replsession.session-run)) (coroutine.resume session.coro session) session) (fn replsession.new-session [] (replsession.restart-session {:submit replsession.submit})) (fn replsession.current-session-id [] (var session-id nil) (let [coro (coroutine.running)] (each [id session (pairs replsession.sessions)] (when (= session.coro coro) (set session-id id))) session-id)) (fn replsession.submit [session chunk callback ?suppress-crash] (assert (= session.callback nil)) (set session.callback callback) (match (pcall coroutine.resume session.coro (.. chunk "\n")) (false err) (do (when (not ?suppress-crash) (core.log (.. "REPL crashed: " err))) (replsession.restart-session session))) (assert (= session.callback callback)) (set session.callback nil)) (fn replsession.activate [id] (set replsession.active-session-id id)) (fn replsession.session-id [?id] (or ?id replsession.active-session-id :REPL)) (fn replsession.session [?id] (let [id (replsession.session-id ?id) session (or (. replsession.sessions id) (replsession.new-session))] (tset replsession.sessions id session) session)) replsession.hot