Implement go to definition, REPL restart on crash

This commit is contained in:
Jeremy Penner 2022-04-10 12:03:16 -04:00
parent 0914090ed4
commit c0ae50fba0
4 changed files with 69 additions and 20 deletions

View file

@ -11,6 +11,24 @@
(ldoc:get_text aline 1 aline 10000000) (ldoc:get_text aline 1 aline 10000000)
(ldoc:get_text aline acol bline bcol)))) (ldoc:get_text aline acol bline bcol))))
(fn find-closest [s pattern i-target]
(var (start end) nil)
(set (start end) (s:find pattern))
(while (and start (< end (- i-target 1)))
(set (start end) (s:find pattern (+ end 1))))
(if (<= start i-target) (values start end)
(values 1 0)))
(local symbol-pattern "[a-zA-Z%!%@%#%$%%%^%&%*%<%>%?%/%~%-%_%=%+][a-zA-Z%!%@%#%$%%%^%&%*%<%>%?%/%~%-%_%=%+0-9%.%:]*")
(fn selected-symbol []
(let [ldoc core.active_view.doc
(aline acol bline bcol) (ldoc:get_selection)]
(if (and (= aline bline) (= acol bcol))
(let [line (ldoc:get_text aline 1 aline 10000000)
(start end) (find-closest line symbol-pattern acol)]
(ldoc:get_text aline start aline (+ end 1)))
(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)]
@ -23,15 +41,37 @@
}) })
(local {: show : submit} (util.require :inspector.debug)) (local {: show : submit} (util.require :inspector.debug))
(local replsession (require :editor.replsession))
(command.add nil { (command.add nil {
"repl:create" #(show) "repl:create" #(show)
}) })
(fn go-to-definition [symbol]
(fn jump-to-find-result [result]
(when (not (match result
{:vals [loc]}
(let [(filename line) (when loc (loc:match "(.*):([0-9]+)"))
filename (or filename "")
filename (if (filename:find "^%.%.%.") "" (or (filename:match "^%./(.*)") filename))
line (tonumber (or line 0))
doc (when (> (length filename) 0) (core.open_doc filename))]
(when doc
(core.root_view:open_doc doc)
(doc:set_selection line 1 line 1)
true))))
(core.log (.. "Unable to find symbol " symbol))))
(: (replsession.session) :submit (.. ",find " symbol) jump-to-find-result))
(command.add :core.docview { (command.add :core.docview {
"repl:eval" #(submit nil (selected-form)) "repl:eval" #(submit nil (selected-form))
"repl:go-to-definition" #(go-to-definition (selected-symbol))
}) })
(keymap.add { (keymap.add {
:return "repl:submit" :return "repl:submit"
"alt+e" "repl:eval" "alt+e" "repl:eval"
"alt+d" "repl:go-to-definition"
}) })
{: inline-eval} {: inline-eval : symbol-pattern}

View file

@ -1,25 +1,32 @@
(local util (require :lib.util)) (local util (require :lib.util))
(local fennel (require :lib.fennel)) (local fennel (require :lib.fennel))
(local core (require :core))
(local replsession (util.hot-table ...)) (local replsession (util.hot-table ...))
(set replsession.sessions {}) (set replsession.sessions {})
(fn replsession.new-session [] (fn replsession.session-run [session]
(let [run (fn [session]
(fennel.repl {:readChunk coroutine.yield (fennel.repl {:readChunk coroutine.yield
:onValues #(session.callback {:vals $1}) ; todo: log errors?
:onError #(session.callback {:errType $1 :err $2 :luaSource $3 :traceback (fennel.traceback)}) :onValues #(pcall session.callback {:vals $1})
:onError #(pcall session.callback {:errType $1 :err $2 :luaSource $3 :traceback (fennel.traceback)})
:pp #$1 :pp #$1
:env (lume.clone _G)})) :env (lume.clone _G)}))
session {:coro (coroutine.create run) :submit replsession.submit}]
(fn replsession.restart-session [session]
(set session.coro (coroutine.create replsession.session-run))
(coroutine.resume session.coro session) (coroutine.resume session.coro session)
session)) session)
(fn replsession.new-session [] (replsession.restart-session {:submit replsession.submit}))
(fn replsession.submit [session chunk callback] (fn replsession.submit [session chunk callback]
(assert (= session.callback nil)) (assert (= session.callback nil))
(set session.callback callback) (set session.callback callback)
(coroutine.resume session.coro (.. chunk "\n")) (match (pcall coroutine.resume session.coro (.. chunk "\n"))
(false err) (do (core.log (.. "REPL crashed: " err))
(replsession.restart-session session)))
(assert (= session.callback callback)) (assert (= session.callback callback))
(set session.callback nil)) (set session.callback nil))

View file

@ -7,12 +7,14 @@ pp = function(x) print(fv(x)) end
lume = require("lib.lume") lume = require("lib.lume")
_coroutine_resume = coroutine.resume _coroutine_resume = coroutine.resume
function coroutine.resume(...) function handle_error(ok, ...)
local state,result = _coroutine_resume(...) if not ok then
if not state then error(...)
error( tostring(result), 2 ) -- Output error message
end end
return state,result return ok, ...
end
function coroutine.resume(...)
return handle_error(_coroutine_resume(...))
end end
require("vendor.lite.main") require("vendor.lite.main")

View file

@ -1,6 +1,6 @@
; [q X] -> q(X) ; [q X] -> q(X) -> [:literal :q [:var :X]]
; [q :x] -> q(x) ; [q :x] -> q(x) -> [:literal :q [:const :x]]
; [q #(+ 1 2)] -> q(3) ; [q #(+ 1 2)] -> q(3) -> [:literal q [:const (+ 1 2)]]
(fn clause [c] (fn clause [c]
(match c (match c