(local lume (require :plugins.fennel-xl.lume)) (local util (require :plugins.fennel-xl.util)) (local core (require :core)) (local command (require :core.command)) (local keymap (require :core.keymap)) (local common (require :core.common)) (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)] {: 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 1)) (values i-target i-target))) (local symbol-pattern "[a-zA-Z%!%@%#%$%%%^%&%*%<%>%?%/%~%-%_%=%+][a-zA-Z%!%@%#%$%%%^%&%*%<%>%?%/%~%-%_%=%+0-9%.%:]*") (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 selected-symbol [] (: (place-to-symbol (get-selection)) :get-text)) (fn inline-eval [eval] (: (to-place (get-selection)) :replace-text (eval (selected-form)))) (local {: show : submit} (util.require :plugins.fennel-xl.debug)) (local replsession (require :plugins.fennel-xl.replsession)) (local mm (util.require :plugins.fennel-xl.multimethod)) (local nrepl (require :plugins.fennel-xl.nrepl)) (command.add :plugins.fennel-xl.replview { "repl:submit" #(core.active_view:submit) "repl:restart" #(replsession.restart core.active_view.conn.session) }) (command.add nil { "repl:create" #(show) "repl:switch-connection" #(core.command_view:enter "Connection Type" {:submit #(when $2.text (set replsession.default-repl $2.text)) :suggest #(mm.keys replsession.submit)}) }) (command.add #(nrepl:connected?) { "nrepl:disconnect" #(nrepl:disconnect) }) (command.add #(not (nrepl:connected?)) { "nrepl:connect" #(nrepl:connect) }) (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)) ldoc (when (> (length filename) 0) (core.open_doc filename))] (when ldoc (core.root_view:open_doc ldoc) (ldoc:set_selection line 1 line 1) true)))) (core.log (.. "Unable to find symbol " symbol)))) (: (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 symbols []) (: (replsession.session) :submit (.. ",complete " text) #(set symbols (or $1.vals [])) true) (icollect [_ symbol (ipairs symbols)] (let [item {:text symbol}] (: (replsession.session) :submit (.. ",doc " symbol) #(when $1.vals (set item.info (. $1.vals 1)))) item))) (fn autocomplete-symbol [callback ?starting-text] (fn fixup-result [text item] (callback (or (and item item.text) text))) (core.command_view:enter "Symbol" {:submit fixup-result :suggest autocomplete-results}) (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 (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}