I'm experimenting with multiple connections for every client 👀 thanks to the #105 issue forcing me to think about the concept and how I could slot it in seamlessly.
Adding a dynamic var system to handle binding things other than the current client in call stacks too! So small! And tested!
(module conjure.dynamic
{require {a conjure.aniseed.core}})
(def- stack-key :conjure.dynamic/stack)
(defn new [base-value]
(let [stack [base-value]]
(fn [x ...]
(if (= stack-key x)
stack
((a.last stack) x ...)))))
(defn- run-binds! [f binds]
(a.map-indexed
(fn [[dyn new-value]]
(f (dyn stack-key) new-value))
binds))
(defn bind [binds f ...]
(run-binds! table.insert binds)
(let [(ok? result) (pcall f ...)]
(run-binds! #(table.remove $1) binds)
(if ok?
result
(error result))))
Really happy with it, it means I can replace the current conjure.client/with-filetype
implementation with something robust, nestable and generic.
These are all internal things but really good progress towards having as many connections as you want per client with easy ways to switch between them 😄
This allows me to do (def filetype (dyn.new #(<http://nvim.bo|nvim.bo>.filetype))
for example, then (filetype)
to get the current filetype. Then I can use (dyn.bind {filetype #(do :something-else)} some-body-function)
to override it in a call stack local way!
This is basically a poor imitation of Clojure's dynamic vars and binding but still, it's useful.