Cider REPL

Bozhidar Batsov edited this page May 23, 2018 · 20 revisions

When using CIDER, you'll have access to CIDER's advanced functionality like interactive debugging, doc/code lookup, etc.

Recent boot versions support this smoothly but note that for CIDER >= 0.11.0 what follows is only necessary when calling boot from the command line: C-c M-j or cider-jack-in automatically inject the necessary dependencies.

Another thing to notice is that recent versions of CIDER and clj-refactor take advantage of Clojure's reader conditionals and therefore won't work unless you set BOOT_CLOJURE_VERSION=1.7.0.

Here's how to do this:

  1. Make sure your version of Boot is recent by running boot -u.**

  2. Make your $BOOT_HOME/profile.boot or build.boot look like the following. $BOOT_HOME/profile.boot is preferred so that you don't force other people to default to Cider, even though they really should.

    (require 'boot.repl)
    (swap! boot.repl/*default-dependencies*
           concat '[[cider/cider-nrepl "0.15.0"]
                    [refactor-nrepl "2.3.1"]])
    
    (swap! boot.repl/*default-middleware*
           concat '[cider.nrepl/cider-middleware
                    refactor-nrepl.middleware/wrap-refactor])

    NOTE: Make sure to have an ' (apostrophe) before [[cider/cider-nrepl "0.10.0"]]. (If it's not shown here that means Github's syntax highlighting is still broken.)

  3. Run REPL as usual with boot repl.

Adding clj-refactor works the same way, just add [refactor-nrepl "VERSION-HERE"] and refactor-nrepl.middleware/wrap-refactor respectively.

A better way

cider-nrepl 0.16 switched to lazy loading of all its middlewares, so the approach suggested in this section won't change anything in terms of startup time anymore

Following the above instructions will make your Boot work with CIDER, but will be slightly inconvenient if you still launch boot repl from the terminal sometimes. REPL load time is greatly influenced by cider-nrepl and refactor-nrepl dependencies. To separate regular REPL from CIDER REPL you can do this:

  1. Put this code into ~/.boot/profile.boot:

    (deftask cider "CIDER profile"
       []
       (require 'boot.repl)
       (swap! @(resolve 'boot.repl/*default-dependencies*)
              concat '[[org.clojure/tools.nrepl "0.2.12"]
                       [cider/cider-nrepl "0.15.0"]
                       [refactor-nrepl "2.3.1"]])
       (swap! @(resolve 'boot.repl/*default-middleware*)
              concat '[cider.nrepl/cider-middleware
                       refactor-nrepl.middleware/wrap-refactor])
       identity)
  2. In Emacs do M-x customize-variable cider-boot-parameters and set it to cider repl -s wait. For project specific settings you can create a .dir-locals.el file with the following content:

    ((nil . ((cider-boot-parameters . "cider repl -s ...others... wait"))))
    
  3. That's all! Your regular REPL should no longer be so slow to load:

    $ time boot cider repl -s
    ...
    boot cider repl -s  32.92s user 1.20s system 210% cpu 16.182 total
    
    $ time boot repl -s
    ...
    boot repl -s  12.71s user 0.37s system 242% cpu 5.385 total
    

You can find more documentation in commit 1a765793:

Expose REPL task dependencies

The REPL task is special because it can't run in a pod. It needs to run in the project context and have access to the environment of the build.boot script.

In order to keep the project classpath pristine when the REPL is not in use, the nREPL dependencies are not loaded until the REPL task actually needs to run. This presents difficulties with middleware, since most of these are in namespaces that assume tools.nrepl is available.

To support middlware in this environment we expose two atoms:

  • boot.repl/*default-dependencies* atom containing a vector of Maven coordinates in the (set-env! :dependencies '[...]) format. These dependencies will be added only when the REPL task is run, and only if the project does not already have explicit dependencies for the deps it would otherwise load.

  • boot.repl/*default-middleware* atom containing a vector of namespace qualified symbols corresponding to desired middleware. The REPL task will resolve them at runtime as necessary, so they don't need to be resolvable from the build.boot.

Modify these to change dependencies or middleware loaded by default by the REPL task. The middleware option to the REPL task adds middleware in addition to these defaults. The handler option will override these.

Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.