Fork me on GitHub
#cursive
<
2021-09-01
>
Sam Adams17:09:18

Hey all! I want to interact with IntelliJ APIs from my Cursive REPL, e.g. call (com.intellij.openapi.vfs.VirtualFileManager/getInstance) — [link to method](https://upsource.jetbrains.com/idea-ce/file/idea-ce-178c8565735689ec2663b7ed21a7e817a1e368cf/platform/core-api/src/com/intellij/openapi/vfs/VirtualFileManager.java). (Underlying goal is to programmatically manipulate source file contents at the cursive REPL, and then force a https://upsource.jetbrains.com/idea-ce/file/idea-ce-178c8565735689ec2663b7ed21a7e817a1e368cf/platform/core-api/src/com/intellij/openapi/vfs/VirtualFile.java?nav=26143:26150:focused&amp;line=785&amp;preview=false via the REPL; or, possibly, directly manipulate IntelliJ’s VirtualFile buffer rather than go straight to disk.) The problem, I think, is that my REPL is a different JVM instance than that running IntelliJ itself — so of course the IntelliJ SDK classes aren’t on the classpath, and instances of them are not accessible in this separate process. I think a solution would be to embed a clojure REPL inside the IntelliJ JVM process itself, e.g. using a tool like https://github.com/djpowell/liverepl, but I haven’t attempted to do so yet — does this sound generally possible? Or, does anyone have any tips / know of another way I can interact with the IntelliJ machine at the REPL?

cfleming21:09:30

You can actually do this with Cursive, although it’s hidden. Go to Help-&gt;Edit custom properties…, and add idea.is.internal=true in the editor that opens. Then restart your IDE and you’ll have a new item in your Tools menu, Start IDE REPL. That’s a REPL on your open IDE instance.

Sam Adams21:09:39

Just what I was after — thanks Colin! I’m curious, is this on track to be an official, documented Cursive feature? And, is the IDE REPL an nREPL/socket-exposed REPL which I could somehow configure as a standard deps-aware Cursive remote REPL?

cfleming23:09:21

I’m not sure about making this a documented feature or not. At the moment it’s hidden, but not very hidden. The IDE REPL isn’t a network REPL, no, it just evaluates its forms directly. However there under Help-&gt;Edit Custom VM Options you can add -Dide.repl.server.port=40000 and you’ll get a socket REPL listening on that port.

Sam Adams01:09:30

Neat, thanks! An enlightening encounter with the streaming-/RPC-REPL divide, for me. Might it be possible/desirable to implement the IDE REPL as an nREPL or pREPL, to enable easier programmatic interaction with IntelliJ via Clojure? If so, would a GitHub issue for the same be welcome?

cfleming02:09:17

No, thanks - it used to use nREPL, but then I switched it to a socket REPL. If you connect to it from the Cursive Remote REPL, that will construct a prepl-like protocol over that connection so it will work in an RPC fashion. If you’re connecting from something else you’ll have to do that bit yourself. It should be fairly easy to set up a prepl over that connection from the client, I think.

cfleming02:09:26

The justification for that is that it’s easier to start a socket REPL from a bare socket, so I can use IntelliJ’s machinery to listen for a socket connection without having to load Clojure itself. Otherwise loading nREPL will necessarily load Clojure at IDE startup (which currently happens anyway, but I’m working to fix that over time).

Sam Adams19:09:43

Gotcha, I see. Thanks for all the info, I really appreciate it.

Sam Adams21:09:37

Does the Cursive remote REPL use Unrepl to establish that pREPL protocol? Or a similar solution you’ve implemented?

cfleming21:09:35

It’s a home-grown thing based on prepl. It’s structured in both directions like nREPL, which allows a few things, principally executing a form in a namespace other than *ns*. This is used when you send a form from a file to the REPL.

👍 2