Walking Dream – single-participant crawl game for the Oculus Quest

On this put up, I am going to be sharing a irascible, no appropriate hack for the Emacs Cider Clojure REPL that it is top to unexcited surely never direct your self.

When debugging or executing a Clojure/Clojurescript program, I most continuously are attempting to originate functions in my program from the Clojure REPL. Nonetheless, as a lot as I admire the Clojure syntax for programming, or no longer it’s pretty inconvenient for continuously executing instructions in a program it’s probably you’ll well bear written.

For occasion, I in truth bear a job monitoring app written in Clojure. Every time I wished to add a brand new todo merchandise by the REPL, I liable to must form one thing admire this:


> (a "iron curtains")

Merchandise added.
NIL

> _

Although I was ready to streamline the enlighten by having the one-letter characteristic identify, this enlighten remains incredibly awkward! What I in truth would preserve to form is that this:


> a iron curtains

Syntax error compiling at (*cider-repl*:0:0).
Unable to procure to the backside of image: iron in this context
Syntax error compiling at (*cider-repl*:0:0).
Unable to procure to the backside of image: curtains in this context

Clearly, since this shorter enlighten does now not obey the parsing principles of the Clojure reader, it appropriate leads to syntax error in the REPL. This raises the place an order to: Is there any formula we can work around this limitation and enter custom instructions into the Clojure REPL, the usage of our admire principles for parsing the enlighten? The retort is… sure, form of.

At this point, some of you will almost definitely be conscious my classic Convey tutorial, named Casting SPELs. On this tutorial, I applied a textual stammer material crawl game in a Unique Convey REPL, letting you enter instructions such as “GET BOTTLE” and “WALK EAST”. Naturally, the academic needed to form compromises to work around REPL boundaries, for the particular similar causes I am outlining in this put up… in insist it’s probably you’ll glance, I’ve already had a decade-lengthy admire-despise relationship with inflexible Convey REPL syntax.

Let’s strive to search out a work-around to this self-discipline once and for all!

Absolutely the Clojure REPL will never, ever settle for “a iron curtains” as reputable syntax in the reader, until we’re sharp to write our admire custom fork of the Clojure programming language. However if we’re the usage of Emacs to whisk our REPL, we can comprise barely somethin’ on the Emacs reside of things, to wrap our enlighten in a capability that the Clojure reader will settle for:


(defun wrap-clojure-enlighten ()
    "takes a enlighten written on the cider instantaneous and executes it as (repl-enlighten "...")"
  (interactive)
  (pass-starting attach-of-line nil)
  (insert "(repl-enlighten "")
  (pass-reside-of-line nil)
  (insert "")")
  (cider-repl-return))

(world-field-key "M-z" 'wrap-clojure-enlighten)

With this enlighten, we can now enter custom instructions into the Cider REPL, then hit the M-z hotkey barely than ENTER to originate these instructions. Then, the Emacs characteristic wraps our REPL enlighten within a standard Clojure string, inner a characteristic call:


> a iron curtains 

           |
      Pressing M+z
           |
           V

> (repl-enlighten "a iron curtains")

To expend inspire of this Emacs hotkey, all my Clojure/Clojurescript applications then bear a characteristic named repl-enlighten that’s then to blame for parsing my REPL string and performing the particular action.

By default, Cider launches new REPL lessons in the user namespace. I admire this default behavior, since it forces me to explicitly uncover any namespaces I am interacting with as I work in the repl. Nonetheless, if I am executing idea to be one of my custom repl instructions, I originate no longer are attempting to must tackle namespacing points. Therefore, I in truth bear the following characteristic declared in my deepest Clojure libraries:


(defn user-repl-enlighten [repl-command]
  (binding [*ns(create-ns 'user)]
    (eval `(def user/repl-enlighten ~enlighten))))

This enlighten takes an arbitrary characteristic and announces it in the user namespace as user/repl-enlighten. So on the backside of the “core” module for every of my Clojure apps I will now uncover my custom REPL enlighten handler, to “register” it for direct in the REPL:


(cl/user-repl-enlighten my-repl-enlighten)


Now I will right away originate arbitrary instructions for my Clojure app handsome in the Clojure REPL, the usage of my admire custom enlighten syntax, even in the default cider REPL namespace!

Absolutely, here’s all very hacky, but I’ve susceptible this workflow all day, daily, for about a year. This, alone, seems admire a appropriate enough reason for sharing my REPL workflow with others.

However indubitably I’d admire to return up with a much less hackish resolution to this order. If any of it’s probably you’ll well bear gotten ideas for cleansing up my worflow, please fragment them on twitter!

Be taught More