Refactor REPL - eval hotkey now pipes to active REPL session

This commit is contained in:
Jeremy Penner 2022-04-10 00:20:18 -04:00
parent 35d9fc10e7
commit 0914090ed4
5 changed files with 70 additions and 36 deletions

View file

@ -4,13 +4,17 @@
(local keymap (require :core.keymap)) (local keymap (require :core.keymap))
(local common (require :core.common)) (local common (require :core.common))
(fn selected-form []
(let [ldoc core.active_view.doc
(aline acol bline bcol) (ldoc:get_selection)]
(if (and (= aline bline) (= acol bcol))
(ldoc:get_text aline 1 aline 10000000)
(ldoc:get_text aline acol bline bcol))))
(fn inline-eval [eval] (fn inline-eval [eval]
(let [ldoc core.active_view.doc (let [ldoc core.active_view.doc
(aline acol bline bcol) (ldoc:get_selection) (aline acol bline bcol) (ldoc:get_selection)]
inject #(ldoc:insert bline bcol (eval $1))] (ldoc:insert bline bcol (eval (selected-form)))))
(if (and (= aline bline) (= acol bcol))
(inject (ldoc:get_text aline 1 aline 10000000))
(inject (ldoc:get_text aline acol bline bcol)))))
(require :editor.editmode) (require :editor.editmode)
@ -18,16 +22,16 @@
"repl:submit" #(core.active_view:submit) "repl:submit" #(core.active_view:submit)
}) })
(local ReplView (require :editor.replview)) (local {: show : submit} (util.require :inspector.debug))
(local repl (require :editor.repl))
(command.add nil { (command.add nil {
"repl:create" (fn [] "repl:create" #(show)
(local node (core.root_view:get_active_node)) })
(node:add_view (ReplView (repl.new))) (command.add :core.docview {
) "repl:eval" #(submit nil (selected-form))
}) })
(keymap.add { (keymap.add {
:return "repl:submit" :return "repl:submit"
"alt+e" "repl:eval"
}) })
{: inline-eval} {: inline-eval}

View file

@ -4,6 +4,8 @@
(local lume (require :lib.lume)) (local lume (require :lib.lume))
(local {: textbutton : under : group-wrapper} (util.require :editor.imgui)) (local {: textbutton : under : group-wrapper} (util.require :editor.imgui))
(local {: inspect} (util.require :inspector)) (local {: inspect} (util.require :inspector))
(local replsession (require :editor.replsession))
(local repl (util.hot-table ...)) (local repl (util.hot-table ...))
(fn repl.inspector [{: w &as form} {: vals : states}] (fn repl.inspector [{: w &as form} {: vals : states}]
@ -19,30 +21,20 @@
(fn repl.mk-result [vals] (fn repl.mk-result [vals]
{:draw repl.inspector : vals :states (icollect [_ (ipairs vals)] {})}) {:draw repl.inspector : vals :states (icollect [_ (ipairs vals)] {})})
(fn repl.run [{: listeners}]
(fennel.repl {:readChunk coroutine.yield
:onValues #(repl.notify listeners (repl.mk-result $1))
:onError (fn [errType err luaSource] (repl.notify listeners (repl.mk-result [err])))
:pp #$1
:env (lume.clone _G)}))
(fn repl.listen [{: listeners} listener] (fn repl.listen [{: listeners} listener]
(table.insert listeners listener)) (table.insert listeners listener))
(fn repl.unlisten [{: listeners} listener] (fn repl.unlisten [{: listeners} listener]
(lume.remove listeners listener)) (lume.remove listeners listener))
(fn repl.submit [{: coro} chunk] (fn repl.submit [{: session : listeners} chunk]
(coroutine.resume coro (.. chunk "\n"))) (session:submit chunk (fn [{: vals : err : traceback}] (repl.notify listeners (repl.mk-result (or vals [err traceback]))))))
(fn repl.new [] (fn repl.new [?id]
(local result
{:listeners [] {:listeners []
:listen #(repl.listen $...) :listen #(repl.listen $...)
:unlisten #(repl.unlisten $...) :unlisten #(repl.unlisten $...)
:submit #(repl.submit $...) :submit #(repl.submit $...)
:coro (coroutine.create repl.run)}) :session (replsession.session ?id)})
(coroutine.resume result.coro result)
result)
repl.hot repl.hot

35
editor/replsession.fnl Normal file
View file

@ -0,0 +1,35 @@
(local util (require :lib.util))
(local fennel (require :lib.fennel))
(local replsession (util.hot-table ...))
(set replsession.sessions {})
(fn replsession.new-session []
(let [run (fn [session]
(fennel.repl {:readChunk coroutine.yield
:onValues #(session.callback {:vals $1})
:onError #(session.callback {:errType $1 :err $2 :luaSource $3 :traceback (fennel.traceback)})
:pp #$1
:env (lume.clone _G)}))
session {:coro (coroutine.create run) :submit replsession.submit}]
(coroutine.resume session.coro session)
session))
(fn replsession.submit [session chunk callback]
(assert (= session.callback nil))
(set session.callback callback)
(coroutine.resume session.coro (.. chunk "\n"))
(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

View file

@ -3,6 +3,7 @@
(local util (require :lib.util)) (local util (require :lib.util))
(local repl (require :editor.repl)) (local repl (require :editor.repl))
(local ReplView (require :editor.replview)) (local ReplView (require :editor.replview))
(local replsession (require :editor.replsession))
(local module (util.hot-table ...)) (local module (util.hot-table ...))
@ -15,16 +16,20 @@
(fn create-inspector-window [name ?value] (fn create-inspector-window [name ?value]
(let [node (core.root_view:get_active_node) (let [node (core.root_view:get_active_node)
conn (repl.new) conn (repl.new name)
view (ReplView conn)] view (ReplView conn)]
(set view.inspector-name name) (set view.inspector-name name)
(set view.title name) (set view.title name)
(view:append {:draw (fn [_ _ x y] (renderer.draw_text style.font name x y style.text) (+ (style.font:get_height) style.padding.y))}) (view:append {:draw (fn [_ _ x y] (renderer.draw_text style.font name x y style.text) (+ (style.font:get_height) style.padding.y))})
(view:append (repl.mk-result [?value])) (view:append (repl.mk-result [?value]))
(node:add_view view))) (node:add_view view)
view))
(lambda module.show [name ?value] (lambda module.show [?name ?value]
(when (= (find-existing-inspector-window name) nil) (let [name (replsession.session-id ?name)]
(create-inspector-window name ?value))) (or (find-existing-inspector-window name) (create-inspector-window name ?value))))
(lambda module.submit [?name chunk]
(: (module.show ?name) :submit chunk))
module.hot module.hot

View file

@ -15,7 +15,6 @@
(: :gsub "%.init$" ""))) (: :gsub "%.init$" "")))
(command.add "core.docview" { (command.add "core.docview" {
"fennel:eval" #(editor.inline-eval #(fv (fennel.eval $1 {:env _G :compiler-env _G}) {}))
"lume:hotswap" (fn [] "lume:hotswap" (fn []
(local modname (get-modname)) (local modname (get-modname))
(core.log (.. "Hotswapping " modname)) (core.log (.. "Hotswapping " modname))
@ -29,7 +28,6 @@
(core.log (.. modname " was not a loaded macro module"))))) (core.log (.. modname " was not a loaded macro module")))))
}) })
(keymap.add { (keymap.add {
"alt+e" "fennel:eval"
"alt+r" "lume:hotswap" "alt+r" "lume:hotswap"
"alt+u" "fennel:unload-macro" "alt+u" "fennel:unload-macro"
}) })