conjure

:neovim:+:clj: https://github.com/Olical/conjure - If you're enjoying Conjure and want to say thanks: https://github.com/users/Olical/sponsorship :smile: (alt https://conjure.fun/discord)
Olical 2020-07-19T16:16:51.484600Z

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.

Olical 2020-07-19T17:45:31.485500Z

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))))

Olical 2020-07-19T17:46:18.486300Z

Really happy with it, it means I can replace the current conjure.client/with-filetype implementation with something robust, nestable and generic.

Olical 2020-07-19T17:46:56.487100Z

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 😄

Olical 2020-07-19T17:48:32.488500Z

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!

Olical 2020-07-19T17:49:15.489300Z

This is basically a poor imitation of Clojure's dynamic vars and binding but still, it's useful.