nrepl

onetom 2024-10-31T12:02:25.657319Z

is there a place where i could keep per-nREPL-connection state? i could do

(def ^:dynamic s 1)
(defn f [x] (+ s x))

(binding [s 123]
  (f 1))
but i want something like
(set! s 123)
(f 1))
in other words, i'd like to specify var values on a per nREPL client basis, instead of a per evaluated expression basis. ideally i should be able to set those values at nREPL client start time too via the command line, but i wouldn't mind defining them manually every time after the client connects.

oyakushev 2024-11-01T07:49:38.458629Z

Yeah, that one:)

oyakushev 2024-10-31T14:32:40.035629Z

You can make a global atom with a map keyed by nREPL transports. E.g.

(def per-connection-state (atom {}))

(defn this-conn-transport []
  (:transport nrepl.middleware.interruptible-eval/*msg*))

(swap! per-connection-state assoc-in [(this-conn-transport) :s] 123)

(get-in @per-connection-state [(this-conn-transport) :s])

onetom 2024-10-31T23:53:28.162439Z

thanks for the pointer! i haven't thought about looking into specific nrepl middlewares. for some reason i thought this should be more of a core functionality, since *e, *1, *2 behave this way already. i guess what i want is to extend the list of those dynamic vars, which are bound on a per-eval basis. maybe i can achieve this via a custom nrepl handler too? but is there no off the shelf way to do this?

oyakushev 2024-11-01T06:36:18.447339Z

Nothing 'official". But you can (alter-var-root #'nrepl.middleware.session/gather-var-bindings ...) to append the dynamic vars you want to make settable.

🙏 1
onetom 2024-11-01T06:43:02.850969Z

judging by its name, it sounds exactly what we need 🙂

onetom 2024-11-01T06:51:11.030139Z

i assume u meant gather-initial-bindings, which u added to the code.