From 9f2da61b88ceabf3d1516619213d145fe39df2cf Mon Sep 17 00:00:00 2001 From: Jeremy Penner Date: Sun, 10 Apr 2022 15:31:34 -0400 Subject: [PATCH] Refactor selection expansion, implement autocomplete --- editor/init.fnl | 71 ++++++++++++++++++++++++++++-------------- editor/replsession.fnl | 4 +-- 2 files changed, 49 insertions(+), 26 deletions(-) diff --git a/editor/init.fnl b/editor/init.fnl index 68a661d..2f5d5b9 100644 --- a/editor/init.fnl +++ b/editor/init.fnl @@ -1,38 +1,56 @@ (local util (require :lib.util)) +(local lume (require :lib.lume)) (local core (require :core)) (local command (require :core.command)) (local keymap (require :core.keymap)) (local common (require :core.common)) -(fn selected-form [] +(fn place-to-line [selection] + (let [selection (lume.clone selection)] + (when (selection:place?) + (set selection.acol 1) + (set selection.bcol math.huge)) + selection)) + +(fn get-selection [] (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 math.huge) - (ldoc:get_text aline acol bline bcol)))) + {: ldoc : aline : acol : bline : bcol + :place? (fn [self] (and (= self.aline self.bline) (= self.acol self.bcol))) + :rtl? (fn [self] (or (and (= self.aline self.bline) (< self.bcol self.acol)) (< self.bline self.aline))) + :get-text (fn [self] (self.ldoc:get_text self.aline self.acol self.bline self.bcol)) + :replace-text (fn [self text] + (self.ldoc:set_selection self.aline self.acol self.bline self.bcol) + (self.ldoc:text_input text))})) + +(fn to-place [selection ?beginning] + (let [selection (lume.clone selection)] + (if (or (and ?beginning (not (selection:rtl?))) (and (not ?beginning) (selection:rtl?))) + (set (selection.bline selection.bcol) (values selection.aline selection.acol)) + (set (selection.aline selection.acol) (values selection.bline selection.bcol))) + selection)) + +(fn selected-form [] (: (place-to-line (get-selection)) :get-text)) (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 (and start (<= start i-target)) (values start end) - (values 1 0))) + (if (and start (<= start i-target)) (values start (+ end 1)) + (values i-target i-target))) (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 math.huge) - (start end) (find-closest line symbol-pattern acol)] - (ldoc:get_text aline start aline (+ end 1))) - (ldoc:get_text aline acol bline bcol)))) +(fn place-to-symbol [selection] + (let [selection (lume.clone selection)] + (when (selection:place?) + (let [line (: (place-to-line selection) :get-text)] + (set (selection.acol selection.bcol) (find-closest line symbol-pattern selection.acol)))) + selection)) -(fn inline-eval [eval] - (let [ldoc core.active_view.doc - (aline acol bline bcol) (ldoc:get_selection)] - (ldoc:insert bline bcol (eval (selected-form))))) +(fn selected-symbol [] (: (place-to-symbol (get-selection)) :get-text)) + +(fn inline-eval [eval] (: (to-place (get-selection)) :replace-text (eval (selected-form)))) (require :editor.editmode) @@ -60,30 +78,35 @@ (ldoc:set_selection line 1 line 1) true)))) (core.log (.. "Unable to find symbol " symbol)))) - (: (replsession.session) :submit (.. ",find " symbol) jump-to-find-result)) + (: (replsession.session) :submit (.. ",find " symbol) jump-to-find-result) true) + +(fn replace-selected-symbol [text] (: (place-to-symbol (get-selection)) :replace-text text)) (fn autocomplete-results [text] (var result []) - (: (replsession.session) :submit (.. ",complete " text) #(set result (or $1.vals []))) + (: (replsession.session) :submit (.. ",complete " text) #(set result (or $1.vals [])) true) result) (fn autocomplete-symbol [callback ?starting-text] - (fn fixup-result [text] - (let [[completed-result] (autocomplete-results text)] - (callback (or completed-result text)))) + (fn fixup-result [text item] (callback (or (and item item.text) text))) (core.command_view:enter "Symbol" fixup-result autocomplete-results) - (when ?starting-text (core.command_view:set_text ?starting-text))) + (print "start-text" ?starting-text) + (when ?starting-text + (core.command_view:set_text ?starting-text) + (core.command_view:update_suggestions))) (command.add :core.docview { "fennel:eval" #(submit nil (selected-form)) "fennel:go-to-definition-under-cursor" #(go-to-definition (selected-symbol)) "fennel:go-to-definition" #(autocomplete-symbol #(go-to-definition $1) (selected-symbol)) + "fennel:autocomplete" #(autocomplete-symbol #(replace-selected-symbol $1) (selected-symbol)) }) (keymap.add { :return "repl:submit" "alt+e" "fennel:eval" "alt+d" "fennel:go-to-definition-under-cursor" + "ctrl+space" "fennel:autocomplete" }) {: inline-eval : symbol-pattern} diff --git a/editor/replsession.fnl b/editor/replsession.fnl index 1cf725f..b0f3733 100644 --- a/editor/replsession.fnl +++ b/editor/replsession.fnl @@ -21,11 +21,11 @@ (fn replsession.new-session [] (replsession.restart-session {:submit replsession.submit})) -(fn replsession.submit [session chunk callback] +(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 (core.log (.. "REPL crashed: " err)) + (false err) (do (when (not ?suppress-crash) (core.log (.. "REPL crashed: " err))) (replsession.restart-session session))) (assert (= session.callback callback)) (set session.callback nil))