scittle 2026-01-15

When using nrepl, is there a way to make println print in the repl instead of the browser console?

@borkdude Did you miss this question? I think it may need solving in Scittle and I can do some work to make it happen, but first I need to know if I am just missing something…

sorry, missed it. I think you just have to set *print-fn* correctly to print to nREPL

👀 1
🙏 1

What is correctly, in this case? 😃

Copilot suggests this:

;; 1. Capture eval message context via onmessage monkeypatch
(def !current-eval-ctx (atom nil))
(let [original-onmessage (.-onmessage js/ws_nrepl)]
  (set! (.-onmessage js/ws_nrepl)
        (fn [event]
          (try
            (let [msg (read-string (.-data event))]
              (when (= :eval (:op msg))
                (reset! !current-eval-ctx
                        {:id (:id msg) :session (:session msg)})))
            (catch :default _))
          (original-onmessage event))))

;; 2. Route *print-fn* through the nREPL transport  
(set! *print-fn*
      (fn [s]
        (let [{:keys [id session]} @!current-eval-ctx]
          (when id
            (.send js/ws_nrepl
                   (pr-str {:id id :session session :out s}))))))

;; 3. Enable newlines (Scittle defaults to false for console.log)
(set! *print-newline* true)
Which works. But seems to be quite a lot, so I think I am missing something.

you need to change the sci print-fn actually

sci.core/print-fn

with sci.core/alter-var-root!

is there already code for this in the scittle nrepl server? I haven't checked. can you?

Doesn’t seem to be anything there for this. This is handle-eval:

(defn- handle-eval [{:keys [code] :as msg}]
  (let [[kind val] (try [::success (nrepl-server/eval-string code)]
                        (catch :default e
                          [::error (str e)]))]
    (case kind
      ::success
      (if (instance? js/Promise val)
        (-> val
            (.then (fn [resolved]
                     (nrepl-server/nrepl-reply msg {:value (str "#<Promise " (pr-str resolved) ">")})
                     (nrepl-server/nrepl-reply msg {:status ["done"]})))
            (.catch (fn [rejected]
                      (nrepl-server/nrepl-reply msg {:err (str rejected)})
                      (nrepl-server/nrepl-reply msg {:ex (str rejected)
                                                      :status ["error" "done"]}))))
        (do (nrepl-server/nrepl-reply msg {:value (pr-str val)})
            (nrepl-server/nrepl-reply msg {:status ["done"]})))
      ::error
      (do
        (nrepl-server/nrepl-reply msg {:err (pr-str val)})
        (nrepl-server/nrepl-reply msg {:ex (pr-str val)
                                        :status ["error" "done"]})))))

no mention of sci/print-fn at all?

I think we might have fixed this for joyride before

you can check there

No mention of sci/print-fn, it doesn’t even require sci.core.

so then you/we have the same problem in joyride? or no, because it prints via console.log probably and you'll see it anyway?

We have solved it in Joyride. handle-eval accepts a send-fn function that we use like so:

(sci/alter-var-root sci/print-fn (constantly
                                      (fn [s]
                                        (send-fn request {"out" s}))))

And I also solved it in the AI:s repl in Joyride, but there closed over the evaluation and restoring the original afterwards.

Anyway, I take it as this should be solved in the scittle repl server? It’s not obvious to me how right now, but I can hava a look at it.

please hava a look! yes, I think in the scittle nrepl.js

🤘 1