From ceac29690fd403af64925e58fb3c408beb76d1fa Mon Sep 17 00:00:00 2001 From: Bobby Towers Date: Sat, 15 Apr 2023 15:10:09 -0700 Subject: [PATCH] eval at cursor --- .calva/output-window/output.calva-repl | 415 +++++++++++++++++++++++++ resources/public/cljs/codemirror.cljs | 63 +++- resources/public/codemirror.html | 1 + 3 files changed, 472 insertions(+), 7 deletions(-) create mode 100644 .calva/output-window/output.calva-repl diff --git a/.calva/output-window/output.calva-repl b/.calva/output-window/output.calva-repl new file mode 100644 index 0000000..e2b0b74 --- /dev/null +++ b/.calva/output-window/output.calva-repl @@ -0,0 +1,415 @@ +; This is the Calva evaluation results output window. +; TIPS: The keyboard shortcut `ctrl+alt+o o` shows and focuses this window +; when connected to a REPL session. +; Please see https://calva.io/output/ for more info. +; Happy coding! ♥️ + +; Jacking in... +; Connecting using "Babashka" project type. +; You can make Calva auto-select this. +; - See https://calva.io/connect-sequences/ +; +; Starting Jack-in Terminal: pushd c:\Users\porko\Documents\GitHub\scittle & bb --nrepl-server 54728 & popd +; Using host:port 127.0.0.1:54728 ... +; Hooking up nREPL sessions ... +; Connected session: clj +; TIPS: +; - You can edit the contents here. Use it as a REPL if you like. +; - `alt+enter` evaluates the current top level form. +; - `ctrl+enter` evaluates the current form. +; - `alt+up` and `alt+down` traverse up and down the REPL command history +; when the cursor is after the last contents at the prompt +; - Clojure lines in stack traces are peekable and clickable. +clj꞉user꞉>  ; Use `alt+enter` to evaluate +; Jack-in done. +clj꞉user꞉>  +"(map inc (range 8))" + +clj꞉user꞉>  +19 + +clj꞉user꞉>  +(0) + +clj꞉user꞉>  +; : Could not resolve symbol: cm user +clj꞉user꞉>  +"here is a string with newlines" + +clj꞉user꞉>  +"here\n is a string\n with newlines" + +clj꞉user꞉>  +"here is a string with newlines" + +clj꞉user꞉>  +"(map inc (range 8))" + +clj꞉user꞉>  +(\) \) \8 \space \e \g \n \a \r \( \space \c \n \i \space \p \a \m \() + +clj꞉user꞉>  +(\) \8 \space \e \g \n \a \r \( \space \c \n \i \space \p \a \m \() + +clj꞉user꞉>  +(\( \m \a \p \space \i \n \c \space \( \r \a \n \g \e \space \8 \) \)) + +clj꞉user꞉>  +; : Could not resolve symbol: open-parens user +clj꞉user꞉>  +false + +clj꞉user꞉>  +true + +clj꞉user꞉>  +(\8 \space \e \g \n \a \r \( \space \c \n \i \space \p \a \m \() + +clj꞉user꞉>  +false + +clj꞉user꞉>  +true + +clj꞉user꞉>  +2 + +clj꞉user꞉>  +[(\8 \space \e \g \n \a \r \( \space \c \n \i \space \p \a \m \() 0 2] + +clj꞉user꞉>  +[(\8 \space \e \g \n \a \r \( \space \c \n \i \space \p \a \m \() 0 2] + +clj꞉user꞉>  +nil + +clj꞉user꞉>  +[(\8 \space \e \g \n \a \r \( \space \c \n \i \space \p \a \m \() 0 2] + +clj꞉user꞉>  +false + +clj꞉user꞉>  +false + +clj꞉user꞉>  +[(\space \e \g \n \a \r \( \space \c \n \i \space \p \a \m \() 0 2] + +clj꞉user꞉>  +[(\e \g \n \a \r \( \space \c \n \i \space \p \a \m \() 0 2] + +clj꞉user꞉>  +() + +clj꞉user꞉>  +[(\e \g \n \a \r \( \space \c \n \i \space \p \a \m \() 0 2] + +clj꞉user꞉>  +[(\8 \space \e \g \n \a \r \( \space \c \n \i \space \p \a \m \() 0 0] + +clj꞉user꞉>  +true + +clj꞉user꞉>  +true + +clj꞉user꞉>  +[(\8 \space \e \g \n \a \r \( \space \c \n \i \space \p \a \m \() 0 1] + +clj꞉user꞉>  +[(\space \e \g \n \a \r \( \space \c \n \i \space \p \a \m \() 0 2] + +clj꞉user꞉>  +[(\e \g \n \a \r \( \space \c \n \i \space \p \a \m \() 0 3] + +clj꞉user꞉>  +[(\g \n \a \r \( \space \c \n \i \space \p \a \m \() 0 4] + +clj꞉user꞉>  +[(\8 \space \e \g \n \a \r \( \space \c \n \i \space \p \a \m \() 0 1] + +clj꞉user꞉>  +[(\space \e \g \n \a \r \( \space \c \n \i \space \p \a \m \() 0 2] + +clj꞉user꞉>  +[(\space \e \g \n \a \r \( \space \c \n \i \space \p \a \m \() 0 1] + +clj꞉user꞉>  +[(\e \g \n \a \r \( \space \c \n \i \space \p \a \m \() 0 1] + +clj꞉user꞉>  +[(\g \n \a \r \( \space \c \n \i \space \p \a \m \() 0 1] + +clj꞉user꞉>  +[(\n \a \r \( \space \c \n \i \space \p \a \m \() 0 1] + +clj꞉user꞉>  +[(\a \r \( \space \c \n \i \space \p \a \m \() 0 1] + +clj꞉user꞉>  +true + +clj꞉user꞉>  +false + +clj꞉user꞉>  +false + +clj꞉user꞉>  +[(\space \c \n \i \space \p \a \m \() 1 1] + +clj꞉user꞉>  +true + +clj꞉user꞉>  +(\( \r \a \n \g \e \space \8 \)) + +clj꞉user꞉>  +() + +clj꞉user꞉>  +"fart" + +clj꞉user꞉>  +(\) \8 \space \e \g \n \a \r \( \space \c \n \i \space \p \a \m \() + +clj꞉user꞉>  +18 + +clj꞉user꞉>  +(\) \8 \space \e \g \n \a \r \( \space \c \n \i \space \p \a \m \() + +clj꞉user꞉>  +true + +clj꞉user꞉>  +(\) \8 \space \e \g \n \a \r \( \space \c \n \i \space \p \a \m \() + +clj꞉user꞉>  +() + +clj꞉user꞉>  +(\( \r \a \n \g \e \space \8 \)) + +clj꞉user꞉>  +# + +clj꞉user꞉>  +# + +clj꞉user꞉>  +1 + +clj꞉user꞉>  +(0 -1 -1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1) + +clj꞉user꞉>  +(\) \8 \space \e \g \n \a \r \( \space \c \n \i \space \p \a \m \() + +clj꞉user꞉>  +# + +clj꞉user꞉>  +; : java.lang.Character cannot be cast to java.lang.Number user +clj꞉user꞉>  +# + +clj꞉user꞉>  +1 + +clj꞉user꞉>  +(0 -1 -1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1) + +clj꞉user꞉>  +; : java.lang.Character cannot be cast to java.lang.Number user +clj꞉user꞉>  +(0 -1 -1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1) + +clj꞉user꞉>  +(\( \m \a \p \space \i \n \c \space \( \r \a \n \g \e \space \8 \)) + +clj꞉user꞉>  +(\) \8 \space \e \g \n \a \r \( \space \c \n \i \space \p \a \m \() + +clj꞉user꞉>  +(0 -1 -1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1) + +clj꞉user꞉>  +# + +clj꞉user꞉>  +; : clojure.lang.PersistentVector cannot be cast to java.lang.Number user +clj꞉user꞉>  +# + +clj꞉user꞉>  +; : clojure.lang.PersistentVector cannot be cast to java.lang.Number user +clj꞉user꞉>  +# + +clj꞉user꞉>  +; : Wrong number of args (2) passed to: sci.impl.fns/fun/arity-1--7879 user +clj꞉user꞉>  +; : Wrong number of args (2) passed to: sci.impl.fns/fun/arity-1--7879 user +clj꞉user꞉>  +# + +clj꞉user꞉>  +; : Wrong number of args (2) passed to: sci.impl.fns/fun/arity-1--7879 user +clj꞉user꞉>  +# + +clj꞉user꞉>  +; : Wrong number of args (2) passed to: sci.impl.fns/fun/arity-1--7879 user +clj꞉user꞉>  +# + +clj꞉user꞉>  +(["(" 0] + [["(" 0] \)] + [[["(" 0] \)] \8] + [[[["(" 0] \)] \8] \space] + [[[[["(" 0] \)] \8] \space] \e] + [[[[[["(" 0] \)] \8] \space] \e] \g] + [[[[[[["(" 0] \)] \8] \space] \e] \g] \n] + [[[[[[[["(" 0] \)] \8] \space] \e] \g] \n] \a] + [[[[[[[[["(" 0] \)] \8] \space] \e] \g] \n] \a] \r] + [[[[[[[[[["(" 0] \)] \8] \space] \e] \g] \n] \a] \r] \(] + [[[[[[[[[[["(" 0] \)] \8] \space] \e] \g] \n] \a] \r] \(] \space] + [[[[[[[[[[[["(" 0] \)] \8] \space] \e] \g] \n] \a] \r] \(] \space] \c] + [[[[[[[[[[[[["(" 0] \)] \8] \space] \e] \g] \n] \a] \r] \(] \space] + \c] + \n] + [[[[[[[[[[[[[["(" 0] \)] \8] \space] \e] \g] \n] \a] \r] \(] \space] + \c] + \n] + \i] + [[[[[[[[[[[[[[["(" 0] \)] \8] \space] \e] \g] \n] \a] \r] \(] \space] + \c] + \n] + \i] + \space] + [[[[[[[[[[[[[[[["(" 0] \)] \8] \space] \e] \g] \n] \a] \r] \(] \space] + \c] + \n] + \i] + \space] + \p] + [[[[[[[[[[[[[[[[["(" 0] \)] \8] \space] \e] \g] \n] \a] \r] \(] + \space] + \c] + \n] + \i] + \space] + \p] + \a] + [[[[[[[[[[[[[[[[[["(" 0] \)] \8] \space] \e] \g] \n] \a] \r] \(] + \space] + \c] + \n] + \i] + \space] + \p] + \a] + \m] + [[[[[[[[[[[[[[[[[[["(" 0] \)] \8] \space] \e] \g] \n] \a] \r] \(] + \space] + \c] + \n] + \i] + \space] + \p] + \a] + \m] + \(]) + +clj꞉user꞉>  +(\) \8 \space \e \g \n \a \r \( \space \c \n \i \space \p \a \m \() + +clj꞉user꞉>  +# + +clj꞉user꞉>  +# + +clj꞉user꞉>  +1 + +clj꞉user꞉>  +(0 -1 -1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1) + +clj꞉user꞉>  +19 + +clj꞉user꞉>  +(-1 -1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1) + +clj꞉user꞉>  +(-1 -1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1) + +clj꞉user꞉>  +(\) \8 \space \e \g \n \a \r \( \space \c \n \i \space \p \a \m \() + +clj꞉user꞉>  +18 + +clj꞉user꞉>  +\) + +clj꞉user꞉>  +-1 + +clj꞉user꞉>  +(-1 -1 -1 -1 -1 -1 -1 -1 0 0 0 0 0 0 0 0 0 1) + +clj꞉user꞉>  +(-1 -1 -1 -1 -1 -1 -1 -1) + +clj꞉user꞉>  +8 + +clj꞉user꞉>  +(\) \8 \space \e \g \n \a \r) + +clj꞉user꞉>  +(\r \a \n \g \e \space \8 \)) + +clj꞉user꞉>  +(\( \r \a \n \g \e \space \8 \)) + +clj꞉user꞉>  +"(range 8)" + +clj꞉user꞉>  +"(range 8)" + +clj꞉user꞉>  +"(range 8)" + +clj꞉user꞉>  +# + +clj꞉user꞉>  +")8 egnar( cni pam(" + +clj꞉user꞉>  +"(range 8)" + +clj꞉user꞉>  +; : No reader function for tag js user +clj꞉user꞉>  +; : No reader function for tag js user +clj꞉user꞉>  diff --git a/resources/public/cljs/codemirror.cljs b/resources/public/cljs/codemirror.cljs index 67d1ec9..1ab1ddd 100644 --- a/resources/public/cljs/codemirror.cljs +++ b/resources/public/cljs/codemirror.cljs @@ -16,10 +16,27 @@ (.dispatch cm #js{:changes #js{:from 0 :to end :insert text} :selection #js{:anchor cursor-pos :head cursor-pos}}))) +(defn parse-char [level pos] + (case pos + \( (inc level) + \) (dec level) + level)) + +(defn form-at-cursor + "Takes the string of characters before cursor pos." + [s] + (let [run (rest (reductions parse-char 0 s))] + (->> s + (take (inc (count (take-while #(not= 0 %) run)))) + reverse + (apply str)))) + +(form-at-cursor (reverse (take 18 "(map inc (range 8)"))) + (defn eval-at-cursor [viewer] (let [cursor-pos (some-> cm .-state .-selection .-main .-head) code (first (str/split (str (some-> cm .-state .-doc str)) #" => "))] - (let [region (str "(do " (.-doc (.-state viewer)) " )") + (let [region (form-at-cursor (reverse (take cursor-pos code))) region (if (nil? region) nil (eval-string region))] (if (nil? region) nil (reset! last-result region))) (update-editor! (str (subs code 0 cursor-pos) @@ -27,9 +44,8 @@ (:result @last-result) (reset! eval-tail (subs code cursor-pos (count code)))) cursor-pos) - (.dispatch cm - #js{:selection #js{:anchor cursor-pos - :head cursor-pos}}))) + (.dispatch cm #js{:selection #js{:anchor cursor-pos :head cursor-pos}})) + true) (defn eval-top-level [viewer] (let [region (str "(do " (.-doc (.-state viewer)) " )") @@ -66,11 +82,44 @@ {:key "ArrowRight" :run clear-eval}]))) (def cm - (let [doc (str/trim " -(map inc (range 8)) -")] + (let [doc "(map inc (range 8))"] (js/cm.EditorView. #js {:doc doc :extensions #js [js/cm.basicSetup, (js/lc.clojure), (.highest js/cs.Prec extension)] :parent (js/document.querySelector "#app")}))) (set! (.-cm_instance js/globalThis) cm) + + + +(let [code "(map inc (range 8)" + cursor-pos 18 + s '(\space \c \n \i \space \p \a \m \() + open-parens 1 + closed-parens 1] + [(rest s) + (inc open-parens) closed-parens] +(drop (count s) code) + ) + +;; god dammit this doesn't work and I have no idea why! +;; I stepped through it (above) and it works - +;; output is `(\( \r \a \n \g \e \space \8 \))` +;; but in the loop (below), it gives the empty list. +;; figure this out tomorrow + +(let [code "(map inc (range 8)" + cursor-pos 18] + (loop [s (reverse (take cursor-pos code)) + open-parens 0 + closed-parens 0] + (cond + (= open-parens closed-parens) + (drop (count s) code) + + (= \) (first s)) (recur (rest s) open-parens (inc closed-parens)) + (= \( (first s)) (recur (rest s) (inc open-parens) closed-parens) + :else (recur (rest s) open-parens closed-parens)) + + + )) + diff --git a/resources/public/codemirror.html b/resources/public/codemirror.html index 205f957..12c9f99 100644 --- a/resources/public/codemirror.html +++ b/resources/public/codemirror.html @@ -48,5 +48,6 @@
+