Backstory:

I modified the cljs.repl/repl to instead of pulling characters from *in*, 
but to use core.async channels, and to <!! on an input-channel. When an 
input is received, a StringReader with the input is created and evaluation 
continues until either an error or printed output occur. Instead of 
printing to *out*, I use with-out-str to put *out* into a string, and then 
put onto an output-channel. I then wrap this whole repl in a 
clojure.core.async/thread. Then I return a helper function that when called 
with a string, sends it to the input channel, and then waits for the 
output, making it behave like a simple cljs-eval function.

The problem is the input is a string instead of cljs forms. Since cljs has 
different meaning behind the literal tags, I have to pass a string. What's 
really desired in the end, however, is how to get a block of clojurescript 
code in emacs, to be sent to this clojurescript repl.

The desired interface would be like so:

Write some clojurescript code in a scratch cider buffer. Then do something 
like C-c C-s, and the toplevel block of code will be sent to the cljs-repl 
function, and the output will be grabbed and sent to a result buffer, just 
like C-c C-f does for vanilla clojure code.

What emacslisp needs to be written and evaluated to get something like this 
to work?

A difficulty: I need to be able to define what function needs to be called 
each time. I can potentially have multiple channel-repls, and thus multiple 
channel-repl-eval functions that would be passed the code-as-a-strings. So 
we can't hardcode the name of a function that will be called each time (its 
possible the function name could be the same, but then something else that 
would be passed to the function, would be changed).

Code for channel-repl:

(in-ns 'cljs.repl)
(defn channel-repl
  "Note - repl will reload core.cljs every time, even if supplied old 
repl-env"
  [repl-env & {:keys [analyze-path verbose warn-on-undeclared special-fns 
static-fns] :as opts
               :or {warn-on-undeclared true}}]
  (let [in-chan (clojure.core.async/chan)
        out-chan (clojure.core.async/chan)]
    (clojure.core.async/thread
     (env/with-compiler-env
       (or (::env/compiler repl-env) (env/default-compiler-env opts))
       (binding [ana/*cljs-ns* 'cljs.user
                 *cljs-verbose* verbose
                 ana/*cljs-warnings* (assoc ana/*cljs-warnings*
                                       :unprovided warn-on-undeclared
                                       :undeclared-var warn-on-undeclared
                                       :undeclared-ns warn-on-undeclared
                                       :undeclared-ns-form 
warn-on-undeclared)
                 ana/*cljs-static-fns* static-fns]
         (when analyze-path
           (analyze-source analyze-path))
         (let [env {:context :expr :locals {}}
               special-fns (merge default-special-fns special-fns)
               is-special-fn? (set (keys special-fns))
               read-error (Object.)]
           (-setup repl-env)
           (loop []
             (let [rdr (readers/source-logging-push-back-reader
                        (java.io.PushbackReader. (java.io.StringReader. 
(clojure.core.async/<!! in-chan)))
                        1
                        "NO_SOURCE_FILE")
                   form (try
                          (binding [*ns* (create-ns ana/*cljs-ns*)
                                    reader/*data-readers* 
tags/*cljs-data-readers*
                                    reader/*alias-map*
                                    (apply merge
                                           ((juxt :requires :require-macros)
                                            (ana/get-namespace 
ana/*cljs-ns*)))]
                            (reader/read rdr nil read-error))
                          (catch Exception e
                            (clojure.core.async/>!! out-chan
                                                    (.getMessage e))
                            read-error))]
               (cond
                (identical? form read-error) (recur)
                (= form :cljs/quit) :quit

                (and (seq? form) (is-special-fn? (first form)))
                (do (apply (get special-fns (first form)) repl-env (rest 
form))
                    (newline)
                    (recur))

                :else
                (do (clojure.core.async/>!! out-chan
                                            (with-out-str (eval-and-print 
repl-env env form)))
                    (recur)))))
           (-tear-down repl-env)))))
    (fn [txt]
      (clojure.core.async/go
       (clojure.core.async/>! in-chan
                              txt))
      (clojure.core.async/<!! out-chan))))

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to