ClojureScript integration with Emacs/Cider ?

2,122 views
Skip to first unread message

Alexandru Nedelcu

unread,
Jan 5, 2014, 3:30:44 PM1/5/14
to clo...@googlegroups.com

Hi,

I can’t get auto-completion or jumping to the definition of a function in Emacs, while working with ClojureScript. Is this a limitation of Emacs’ Cider plugin?

I managed to get nRepl working by using the awesome com.cemerick/austin plugin for lein (besides including the plugin in project.clj I’ve got no other special configuration). So to work with ClojureScript, from inside an nRepl session, I execute the following (not sure if this is right):

(cemerick.austin.repls/exec :exec-cmds ["google-chrome"])

In Emacs I do the same thing, by first starting the repl with cider-jack-in and then I execute the above command. Compiling the current buffer works (C-c C-k), I can also send expressions for evaluation to the repl (C-x C-e).

However, as I said, auto-completion doesn’t work and neither does jumping to the definition of a function. Is there any way to get these features while working with ClojureScript in Emacs? Or maybe in another IDE?

Thanks,

--
Alexandru Nedelcu
www.bionicspirit.com

PGP Public Key:
https://bionicspirit.com/key.aexpk

Tim Visher

unread,
Jan 6, 2014, 2:56:39 PM1/6/14
to Clojure
Hi Alexandru,

On Sun, Jan 5, 2014 at 3:30 PM, Alexandru Nedelcu <al...@bionicspirit.com> wrote:
> I can’t get auto-completion or jumping to the definition of a function in
> Emacs, while working with ClojureScript. Is this a limitation of Emacs’
> Cider plugin?

IIUC, completing et al does not work for ClojureScript because
ClojureScript, not because of tooling. I have no idea how or if
development towards that end is going, but I believe it has something
to do with limitations of the host language which does not get my
hopes up.

If someone else knows better, please correct me, because I miss it too!

--

In Christ,

Timmy V.

http://blog.twonegatives.com/
http://five.sentenc.es/ -- Spend less time on mail

David Nolen

unread,
Jan 6, 2014, 3:01:40 PM1/6/14
to clo...@googlegroups.com
Limitation of tooling. ClojureScript analyzer exposes the necessary information.
--
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Tim Visher

unread,
Jan 6, 2014, 3:02:34 PM1/6/14
to Clojure
On Mon, Jan 6, 2014 at 3:01 PM, David Nolen <dnolen...@gmail.com> wrote:
> Limitation of tooling. ClojureScript analyzer exposes the necessary
> information.

That is seriously great to hear. I had no idea we were that far along.

Colin Fleming

unread,
Jan 6, 2014, 4:10:27 PM1/6/14
to clo...@googlegroups.com
Since Cursive (http://cursiveclojure.com) resolves everything statically from source, ClojureScript completion and navigation works for most symbols. There are still a lot that it doesn't know about since cljs-specific functionality is still pretty low, so js/* symbols have no support, and any functions included from Closure are not found either. But for pure cljs it should work pretty well. There are quite a few people using Cursive for cljs dev now, despite the slightly embarrassing lack of explicit support :-)


--

Bozhidar Batsov

unread,
Jan 7, 2014, 1:54:27 AM1/7/14
to clo...@googlegroups.com
I'm cider's maintainer. The problem with code completion for ClojureScript is that the default mechanism is based on the Clojure-only library https://github.com/ninjudd/clojure-complete. As I don't use ClojureScript I haven't paid much attention to it so far. If there is a similar library for ClojureScript I might add support for it. Btw, cider will also pick up any nREPL middleware that provides a "complete" op - if there is a ClojureScript nREPL completion middleware it can be used with cider even now. Ideally at some point we'll have unified middleware supporting both Clojure & ClojureScript.

Alexandru Nedelcu

unread,
Jan 7, 2014, 6:26:48 AM1/7/14
to clo...@googlegroups.com
On Mon, Jan 6, 2014 at 11:10 PM, Colin Fleming <colin.ma...@gmail.com> wrote:
Since Cursive (http://cursiveclojure.com) resolves everything statically from source, ClojureScript completion and navigation works for most symbols. There are still a lot that it doesn't know about since cljs-specific functionality is still pretty low, so js/* symbols have no support, and any functions included from Closure are not found either. But for pure cljs it should work pretty well. There are quite a few people using Cursive for cljs dev now, despite the slightly embarrassing lack of explicit support :-)


Hi Colin,

I just installed Cursive and looks very promising. I'll try using it.

Do you plan to explicitly support ClojureScript? Do you have an ETA? That would be awesome, because viewing the implementation of Clojure's core libs is very valuable and from what I understand, there are differences between Clojure and ClojureScript (e.g. protocols are at the bottom in ClojureScript) and it would be valuable if I could click on a function and see its ClojureScript specific code and documentation. Also handling the Javascript interop would be awesome too.

Colin Fleming

unread,
Jan 7, 2014, 5:35:34 PM1/7/14
to clo...@googlegroups.com
Great, let me know if you have any questions. I'm definitely planning ClojureScript support sometime soon. I think most of the symbol resolution for core cljs should work (since it's mostly the same as clj) for for pure cljs (including the core libs) everything at http://cursiveclojure.com/userguide/documentation.html should work. If you see anything that's not working either let me know directly or we have an issue tracker at https://github.com/cursiveclojure/cursive/issues.

I'm also planning to handle JS interop but that's tricky because that support is only present in IntelliJ Ultimate. I'm still working out how to handle that but it's definitely on the roadmap.


--

Gary Trakhman

unread,
Jan 11, 2014, 11:03:38 PM1/11/14
to clo...@googlegroups.com
In response to this thread, I've hacked lein-cljsbuild to dump the compiler state, and built a version of autodoc to parse it and generate api docs.

I'm trying to figure out how exactly cider and austin will talk to each other so I can make it happen, and I approach that I'm considering now is to add a 'complete' operation to the piggieback middleware, since Bozhidar says that it should work out of the box.  The information's available, and I've demonstrated how to parse it in my autodoc-cljs port.  Hopefully that's enough.

I've created a lein-cljsbuild issue to possibly integrate this stuff and evoke further discussion.  It has a screenshot of autodoc generated from a compiler dump and links to the implementations.

Gary Trakhman

unread,
Jan 13, 2014, 9:03:11 AM1/13/14
to clo...@googlegroups.com
I've released a cljs port of clojure-complete:

Here's the mailing list announcement, also inlined.

cljs-complete, A Clojure library designed to auto-complete clojurescript based on cljs compiler state.

- With leiningen:
     [cljs-complete "0.1.0"]

- Usage

;; env is pulled from cljs compiler state
=> (completions @cljs.env/*compiler* "al" 'cljs.core)
("alength" "alter-meta!")

This is meant to hook into piggieback, that'll be the next thing I try. I hope I can get some help with the hairy emacs bits :-).

Gary Trakhman

unread,
Jan 13, 2014, 9:55:51 AM1/13/14
to clo...@googlegroups.com
On talking to Chas, 

it seems like the right approach is to reify ac-nrepl's use of eval into a real "complete" op, and reimplement it to use that, then a common middleware can either use clojure's environment (clojure-complete) or piggieback's compiler state to implement the appropriate auto-complete based on the active repl.

The issue here is that clojure's auto-complete takes the JVM state as an implicit parameter, whereas cljs-complete requires an 'env' arg that has to come from somewhere (piggieback has a var that keeps track of repl session state).  Ac-nrepl shouldn't be able to eval code, that means it's being coupled to the JVM state, which won't do for cljs or other sorts of repls-on-repls.
 


--

Bozhidar Batsov

unread,
Jan 13, 2014, 10:10:43 AM1/13/14
to clo...@googlegroups.com
Cider’s completion understands a `complete` op, so the middleware is the best approach if you ask me. The only reason that there’s also an eval based completion mechanism (the one used by default) is that clojure-complete is present as a REPLy (which is used by lein) dependency and many newcomers have absolutely no idea what an nREPL middleware is. Unfortunately it’s hard to balance initial easy of setup and good design decisions. 

-- 
Cheers,
Bozhidar

You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/uXtd--Xv6vU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.

Gary Trakhman

unread,
Jan 13, 2014, 10:21:30 AM1/13/14
to clo...@googlegroups.com
Austin's lein-plugin already manipulates project middlewares, so that's an easy target.  Onward!

Gary Trakhman

unread,
Jan 18, 2014, 1:56:11 PM1/18/14
to clo...@googlegroups.com
Bozhidar, I had to slightly modify cider-interaction.el to make autocomplete work for cljs.

--- cider-interaction.el        2014-01-18 13:51:28.082131609 -0500
+++ /home/gary/.emacs.d/elpa/cider-0.4.0/cider-interaction.el   2014-01-17 19:06:45.872591834 -0500
@@ -469,12 +469,12 @@
   (let ((strlst (plist-get
                  (nrepl-send-request-sync
                   (list "op" "complete"
-                        "session" (nrepl-current-tooling-session)
+                        "session" (nrepl-current-session)
                         "ns" nrepl-buffer-ns
                         "symbol" str))
                  :value)))
     (when strlst
-      (car strlst))))
+      strlst)))


Here's the current implementing code:

Here's a screenshot: http://i.imgur.com/GmBJ6Fj.png

It can't be implemented for cljs on the tooling session without sending the real session id over somehow, it seems this would be wasteful and not a good precedent for other middlewares.

I'd appreciate your thoughts.

I'm also curious what it would take to make the display pretty like ac-nrepl, which I had to disable.

As soon as this stuff is finalized, I'll package everything up nice and make a first release.

Bozhidar Batsov

unread,
Jan 22, 2014, 9:10:28 AM1/22/14
to clo...@googlegroups.com
Sorry about the late response, Gary. Would you mind taking the discussion over to cider’s issue tracker? (I tend to miss emails, but I don’t miss issues :-) ). 

The second change seems totally reasonable. I guess ritz’s complete middleware returns the completion candidates in some odd format. Regarding the tooling-session - why can’t the completions be generated using the tooling session with ClojureScript (my knowledge of it is pretty basic). I guess this was something to do with piggieback, right? 

-- 
Cheers,
Bozhidar

Gary Trakhman

unread,
Jan 24, 2014, 7:29:18 PM1/24/14
to clo...@googlegroups.com
Bozhidar, I created an issue summing up my concerns:
Reply all
Reply to author
Forward
0 new messages