Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP


Added ClojureScript support. #128

merged 9 commits into from

2 participants


Support for ClojureScript was added by defining a new command under swank.commands.cljs. This command is triggered by an Emacs customization (see clojure-mode).

Note that swank does not automatically run this code, so as to avoid forcing those not using cljs to require it. In order to add repl support to a VM, one has to register a repl explicitly, before starting it:

(require '[swank.commands.cljs :as swank-cljs])
(def env (browser/repl-env))
(swank-cljs/register-repl :cljs-repl env)

Different repls can be supported by registering different keys and using suitable buffer-local variables from Emacs.

@technomancy technomancy merged commit 57844d3 into technomancy:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 55 additions and 1 deletion.
  1. +8 −1 src/swank/commands/basic.clj
  2. +47 −0 src/swank/commands/cljs.clj
9 src/swank/commands/basic.clj
@@ -72,7 +72,14 @@
(defslimefn interactive-eval [string]
- (pr-str (first (eval-region string)))))
+ (pr-str
+ (let [value (first (eval-region string))]
+ ;; If the result is a seq, consume it here instead of getting evaluated
+ ;; from pr-str to allow side-effects to go to the repl.
+ (if (instance? clojure.lang.LazySeq value)
+ (doall value)
+ value)
+ ))))
(defslimefn listener-eval [form]
47 src/swank/commands/cljs.clj
@@ -0,0 +1,47 @@
+(ns ^{:doc "Support for sending evaluation of forms into a ClojureScript repl."}
+ swank.commands.cljs
+ (:use [swank.core :only (with-emacs-package)]
+ [swank.commands :onlny (defslimefn)])
+ (:require [cljs.repl :as repl]
+ [cljs.compiler :as comp])
+ )
+(def cljs-targets "A mapping of registered repl environments which can be used as targets." (atom {}))
+(defn register-repl
+ "Register a new REPL environment for interactive-eval-with-target to dispatch to."
+ [key env]
+ (swap! cljs-targets assoc key env))
+(defn eval-in-cljs
+ "Evaluate the given string in the provided ClojureScript repl environment."
+ [env form-string]
+ (binding [comp/*cljs-ns* comp/*cljs-ns*]
+ (let [form (read-string form-string),
+ ;; Note: the following is lifted from cljs.repl.browser; FIXME: we
+ ;; should add support there to do this without a repl thread.
+ context {:context :statement
+ :locals {}
+ :ns (@comp/namespaces comp/*cljs-ns*)}]
+ (repl/evaluate-form env context "<swank-cljs-repl>" form)
+ )))
+(defslimefn ^{:doc "Evaluate a Clojure form in a ClojureScript environment."}
+ interactive-eval-with-target [target form-string]
+ (let [env (get @cljs-targets target)]
+ (if env
+ (eval-in-cljs env form-string)
+ (throw (Exception.
+ (format "Emacs eval abort; eval target '%s' not found" target)))
+ )))
+;; Notes:
+;; You will need an Emacs customization that overrides
+;; slime-interactive-eval tocall (swank:interactive-eval-with-target) instead of
+;; (swank:interactive-eval), such as is provided in clojure-mode.el.
+;; Also, before you can eval to a target, you will need your VM to have a repl
+;; instance registered via 'register-repl' (e.g. browser repl).
Something went wrong with that request. Please try again.