From 72838e060b21e9be4c92cb3c7eb91dd01b207e5b Mon Sep 17 00:00:00 2001 From: Bobby Towers Date: Sun, 16 Apr 2023 04:30:45 -0700 Subject: [PATCH] eval top-level --- .calva/output-window/output.calva-repl | 520 +++++++++++++++++++++++++ resources/public/cljs/codemirror.cljs | 68 ++-- 2 files changed, 559 insertions(+), 29 deletions(-) diff --git a/.calva/output-window/output.calva-repl b/.calva/output-window/output.calva-repl index 0c37a69..4c94606 100644 --- a/.calva/output-window/output.calva-repl +++ b/.calva/output-window/output.calva-repl @@ -488,3 +488,523 @@ clj꞉user꞉>  "(def u 7)\n\n(defn t []\n (map inc (range 8)))" clj꞉user꞉>  +# + +clj꞉user꞉>  +(def n 7) + +clj꞉user꞉>  +(def n 7) + +clj꞉user꞉>  +(def n 7) + +clj꞉user꞉>  +; : count not supported on this type: Character user +clj꞉user꞉>  +(def n 7) + +clj꞉user꞉>  +"(def n 7)" + +clj꞉user꞉>  +"\n\n(defn t []\n (map inc (range n)))" + +clj꞉user꞉>  +"(defn t []\n (map inc (range n)))" + +clj꞉user꞉>  +# + +clj꞉user꞉>  +"(defn t []\n (map inc (range n)))" + +clj꞉user꞉>  +# + +clj꞉user꞉>  +"(def n 7)\n\n(defn t []\n (map inc (range n)))" + +clj꞉user꞉>  +# + +clj꞉user꞉>  +3 + +clj꞉user꞉>  +# + +clj꞉user꞉>  +# + +clj꞉user꞉>  +(do (def n 7) (defn t [] (map inc (range n)))) + +clj꞉user꞉>  +do + +clj꞉user꞉>  +(def n 7) + +clj꞉user꞉>  +3 + +clj꞉user꞉>  +((def n 7) (defn t [] (map inc (range n)))) + +clj꞉user꞉>  +\f + +clj꞉user꞉>  +\n + +clj꞉user꞉>  +\d + +clj꞉user꞉>  +\space + +clj꞉user꞉>  +\t + +clj꞉user꞉>  +\t + +clj꞉user꞉>  +((def n 7) (defn t [] (map inc (range n)))) + +clj꞉user꞉>  +\t + +clj꞉user꞉>  +# + +clj꞉user꞉>  +((def n 7) (defn t [] (map inc (range n)))) + +clj꞉user꞉>  +"" + +clj꞉user꞉>  +" t" + +clj꞉user꞉>  +"(def n 7)\n\n(defn t []\n (map inc (range n)))" + +clj꞉user꞉>  +" t" + +clj꞉user꞉>  +() + +clj꞉user꞉>  +() + +clj꞉user꞉>  +" t" + +clj꞉user꞉>  +; : Don't know how to create ISeq from: java.lang.Character user +clj꞉user꞉>  +() + +clj꞉user꞉>  +(\space \t) + +clj꞉user꞉>  +"(def n 7)\n\n(defn t []\n (map inc (range n)))" + +clj꞉user꞉>  +((def n 7) (defn t [] (map inc (range n)))) + +clj꞉user꞉>  +(def n 7) + +clj꞉user꞉>  +0 + +clj꞉user꞉>  +((def n 7) (defn t [] (map inc (range n)))) + +clj꞉user꞉>  +nil + +clj꞉user꞉>  +nil + +clj꞉user꞉>  +"(def n 7)\n\n(defn t []\n (map inc (range n)))" + +clj꞉user꞉>  +() + +clj꞉user꞉>  +(\( \d \e \f \space \n \space \7 \) \newline) + +clj꞉user꞉>  +(\n + \space + \7 + \) + \newline + \newline + \( + \d + \e + \f + \n + \space + \t + \space + \[ + \] + \newline + \space + \space + \( + \m + \a + \p + \space + \i + \n + \c + \space + \( + \r + \a + \n + \g + \e + \space + \n + \) + \) + \)) + +clj꞉user꞉>  +(\) + \newline + \newline + \( + \d + \e + \f + \n + \space + \t + \space + \[ + \] + \newline + \space + \space + \( + \m + \a + \p + \space + \i + \n + \c + \space + \( + \r + \a + \n + \g + \e + \space + \n + \) + \) + \)) + +clj꞉user꞉>  +(\( + \d + \e + \f + \space + \n + \space + \7 + \) + \newline + \newline + \( + \d + \e + \f + \n + \space + \t + \space + \[ + \] + \newline + \space + \space + \( + \m + \a + \p + \space + \i + \n + \c + \space + \( + \r + \a + \n + \g + \e + \space + \n + \) + \) + \)) + +clj꞉user꞉>  +(\( + \d + \e + \f + \space + \n + \space + \7 + \) + \newline + \newline + \( + \d + \e + \f + \n + \space + \t + \space + \[ + \] + \newline + \space + \space + \( + \m + \a + \p + \space + \i + \n + \c + \space + \( + \r + \a + \n + \g + \e + \space + \n + \) + \) + \)) + +clj꞉user꞉>  +(\) + \newline + \newline + \( + \d + \e + \f + \n + \space + \t + \space + \[ + \] + \newline + \space + \space + \( + \m + \a + \p + \space + \i + \n + \c + \space + \( + \r + \a + \n + \g + \e + \space + \n + \) + \) + \)) + +clj꞉user꞉>  +(\) \) \)) + +clj꞉user꞉>  +nil + +clj꞉user꞉>  +"(def n 7)\n\n(defn t []\n (map inc (range n)))" + +clj꞉user꞉>  +((def n 7) (defn t [] (map inc (range n)))) + +clj꞉user꞉>  +"((def n 7) (defn t [] (map inc (range n))))" + +clj꞉user꞉>  +# + +clj꞉user꞉>  +1 + +clj꞉user꞉>  +"(def n 7)" + +clj꞉user꞉>  +"((def n 7) (defn t [] (map inc (range n))))" + +clj꞉user꞉>  +((def n 7) (defn t [] (map inc (range n)))) + +clj꞉user꞉>  +(defn t [] (map inc (range n))) + +clj꞉user꞉>  +("(def n 7)" "(defn t [] (map inc (range n)))") + +clj꞉user꞉>  +# + +clj꞉user꞉>  +("(def n 7)" "(defn t [] (map inc (range n)))") + +clj꞉user꞉>  +"(defn t [] (map inc (range n)))" + +clj꞉user꞉>  +11 + +clj꞉user꞉>  +(1 11) + +clj꞉user꞉>  +{"(def n 7)" 1, "(defn t [] (map inc (range n)))" 11} + +clj꞉user꞉>  +{1 "(def n 7)", 11 "(defn t [] (map inc (range n)))"} + +clj꞉user꞉>  +([1 "(def n 7)"] [11 "(defn t [] (map inc (range n)))"]) + +clj꞉user꞉>  +; : Could not resolve symbol: s user +clj꞉user꞉>  +10/9 + +clj꞉user꞉>  +1 + +clj꞉user꞉>  +5 + +clj꞉user꞉>  +26 + +clj꞉user꞉>  +# + +clj꞉user꞉>  +(5 26) + +clj꞉user꞉>  +# + +clj꞉user꞉>  +([5 "(def n 7)"] [26 "(defn t [] (map inc (range n)))"]) + +clj꞉user꞉>  +# + +clj꞉user꞉>  +([26 "(defn t [] (map inc (range n)))"] [5 "(def n 7)"]) + +clj꞉user꞉>  +([26 "(defn t [] (map inc (range n)))"] [5 "(def n 7)"]) + +clj꞉user꞉>  +([26 "(defn t [] (map inc (range n)))"] [5 "(def n 7)"]) + +clj꞉user꞉>  +([26 "(defn t [] (map inc (range n)))"] [5 "(def n 7)"]) + +clj꞉user꞉>  +-25 + +clj꞉user꞉>  +25 + +clj꞉user꞉>  +# + +clj꞉user꞉>  +([26 "(defn t [] (map inc (range n)))"] [5 "(def n 7)"]) + +clj꞉user꞉>  +([5 "(def n 7)"] [26 "(defn t [] (map inc (range n)))"]) + +clj꞉user꞉>  +# + +clj꞉user꞉>  +[5 "(def n 7)"] + +clj꞉user꞉>  +# + +clj꞉user꞉>  +("(def n 7)") + +clj꞉user꞉>  +# + +clj꞉user꞉>  +"(def n 7)" + +clj꞉user꞉>  +# + +clj꞉user꞉>  +# + +clj꞉user꞉>  +"(def n 7)" + +clj꞉user꞉>  +"(defn t [] (map inc (range n)))" + +clj꞉user꞉>  diff --git a/resources/public/cljs/codemirror.cljs b/resources/public/cljs/codemirror.cljs index b422d85..ff8d3a3 100644 --- a/resources/public/cljs/codemirror.cljs +++ b/resources/public/cljs/codemirror.cljs @@ -14,7 +14,7 @@ (defn update-editor! [text cursor-pos] (let [end (count (some-> cm .-state .-doc str))] (.dispatch cm #js{:changes #js{:from 0 :to end :insert text} - :selection #js{:anchor cursor-pos :head cursor-pos}}))) + :selection #js{:anchor cursor-pos :head cursor-pos}}))) (defn parse-char [level pos] (case pos @@ -45,10 +45,40 @@ (.dispatch cm #js{:selection #js{:anchor cursor-pos :head cursor-pos}})) true) +(defn code-str [s] + (str (rest (read-string (str "(do " s ")"))))) + +(defn code-seq [s] + (map str (rest (read-string (str "(do " s ")"))))) + +;; but we really want to find the center points, not the start points. + +(defn find-center [[start s]] + [(+ start (int (/ (count s) 2))) s]) + +;; then just pick the one with the closest center point to the cursor, +;; and evaluate it! + +(defn abs [v] + (if (neg? v) (- v) v)) + +(defn top-level [s pos] + (first (nfirst + (sort-by #(abs (- pos (first %))) + (map find-center + (map vector + (map #(str/last-index-of (code-str s) %) (code-seq s)) + (code-seq s))))))) + (defn eval-top-level [viewer] - (let [region (str "(do " (.-doc (.-state viewer)) " )") - region (if (nil? region) nil (eval-string region))] - (if (nil? region) nil (reset! last-result region))) + (let [code (some-> cm .-state .-doc str) + cursor-pos (some-> cm .-state .-selection .-main .-head) + result (reset! last-result (eval-string (top-level code cursor-pos)))] + (update-editor! (str (subs code 0 cursor-pos) + (when-not (= "" (:result @last-result)) " => ") + (:result result) + (subs code cursor-pos)) + cursor-pos)) true) (defn eval-cell [viewer] @@ -65,11 +95,11 @@ cursor-pos (some-> cm .-state .-selection .-main .-head) result @last-result splits (str/split code #" => ")] - (when (not= "" @last-result) - (update-editor! (str (first splits) (subs (last splits) (count (str (:result result))))) + (when (not= "" @last-result) + (update-editor! (str (first splits) (subs (last splits) (count (str (:result result))))) cursor-pos) - (reset! last-result "") - (reset! eval-tail "")))) + (reset! last-result "") + (reset! eval-tail "")))) (def extension (.of js/cv.keymap @@ -86,30 +116,10 @@ (def cm (let [doc "(def n 7) -(defn t [] +(defn r [] (map inc (range n)))"] (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) - -;; what is top-level, anyway? - -(def u 7) - -(defn t [] - (map inc (range 8))) - -;; ah, Peter from Calva to the rescue! -;; > Calva does not check the contents of the form in order to -;; determine it as a top-level forms: -;; *all forms not enclosed in any other form are top level forms*. - -;; so there we have it! -;; we parse until we are not enclosed in a form. - -;; pretty simple, actually. -;; the contents of the cell are a series of forms. -;; evaluate the last one! -;; that is, before the cursor \ No newline at end of file