Fork me on GitHub
#cider
<
2018-03-22
>
ajs11:03:18

do i understand that output from threads other than the main thread can go to the nrepl buffer? if I read from a socket on another thread (which is handled by the Jetty websocket library), then any logging that socket read does would go to the nrepl buffer?

thheller12:03:58

@bozhidar you talked about removing gradle. how would I go about adding shadow-cljs? it supports injection via shadow-cljs -d cider/cider-nrepl:0.16.0 server?

thheller12:03:47

it writes its nrepl port to .shadow-cljs/nrepl.port (same as .nrepl-port from lein)

bozhidar12:03:47

> do i understand that output from threads other than the main thread can go to the nrepl buffer? if I read from a socket on another thread (which is handled by the Jetty websocket library), then any logging that socket read does would go to the nrepl buffer? At least when dealing with Clojure - what ends up in the nrepl buffer is output that got bound to the server’s stdout/stderr. We’ve got some logic to redirect this to the REPL buffers, so people won’t miss it, but I’m not sure what exactly’s going on in your case.

bozhidar12:03:31

@thheller So, you don’t need lein, boot or something like this? You can just spin the nREPL server with all the deps using the shadow-cljs binary?

bozhidar12:03:18

And I assume the resulting connection is a cljs connection, which is directly ready to be used?

thheller12:03:28

well it also works via lein or boot but has a standalone launcher as well

thheller12:03:39

no the nrepl connection always starts out as CLJ

thheller12:03:11

just like lein

bozhidar12:03:24

We’ll need some way to know we’re in a shadow-cljs project. Is there some file marker we can rely on?

thheller12:03:40

shadow-cljs.edn the config file.

thheller12:03:10

always at the root of the project (like project.clj)

bozhidar12:03:19

OK, so all of this is going to be very easy. I can hack it together myself if you’re afraid of Elisp. 🙂

bozhidar12:03:03

The only open question is how to convert the resulting repl to cljs - I was told there’s not fixed code snippet you can execute, as you had to pass some project-specific build id.

bozhidar12:03:37

It’d be nice to have some easy way to spawn a cljs repl without having the user to type anything themselves.

thheller12:03:48

yes shadow-cljs supports multiple builds and you can "select" which REPL you want to talk to

thheller12:03:54

do you support parsing edn in elisp?

thheller12:03:29

then you could just look at shadow-cljs.edn :builds and let the user select one

bozhidar12:03:32

We don’t currently use it, but a parser was implemented recently so we can leverage it.

thheller12:03:43

its a map of {:build-id build-config}

thheller12:03:19

this just defines one build named :app

thheller12:03:03

to switch the nrepl connection to this build you'd first call (shadow.cljs.devtools.api/watch :app) to start the "worker" which will recompile and all that jazz

thheller12:03:39

then call (shadow.cljs.devtools.api/nrepl-select :app) to switch the current nrepl to this build and turn it into CLJS

thheller12:03:02

similar to what (cemerick.piggieback/cljs-repl repl-env) does

thheller12:03:01

I could add additional helper fns/middleware that lets you query which builds exists and so on

thheller12:03:21

the is also support for starting a browser-repl or node-repl without a build

thheller12:03:18

so the problem appears to be that none of these currently take any arguments

thheller12:03:32

so the quickfix would be to add a no-args version that just picks a "default" build. which is easy it there is only one.

bozhidar12:03:45

Yeah, that’d be nice.

bozhidar12:03:55

How do you switch between different builds?

thheller13:03:08

@bozhidar you can run multiple (shadow.cljs.devtools.api/watch :build1) (shadow.cljs.devtools.api/watch :build2) in parallel. they run in the background. (shadow.cljs.devtools.api/nrepl-select :build1) switches to CLJS of build1. :cljs/quit switches back to CLJ, then call nrepl-select again to switch to either

thheller13:03:34

the REPL actually keeps running as long as the watch is running

thheller13:03:49

just can just connect/disconnect from it any time

thheller13:03:09

alternatively you could just call (shadow.cljs.devtools.api/browser-repl) which starts the browser repl, opens a browser, and switches the REPL to CLJS

thheller13:03:37

or (shadow.cljs.devtools.api/node-repl)

thheller13:03:56

these aren't tied to any build so they require no config

bozhidar13:03:05

Interesting.

bozhidar13:03:43

So you can have 3 different types of shadow-cljs repls?

thheller14:03:59

well technically its just one type, the browser-repl and node-repl are just utility fns to just quickly spin up a REPL without having to configure a build first

dpsutton14:03:28

it sounds like shadow-cljs works the way we want piggieback to eventually work: with suspendable cljs repls in a single repl

dpsutton14:03:58

maybe make a new workflow for shadow cljs and then migrate piggieback to work like that. without a sibling repl

jmckitrick14:03:06

It looks like everyone is talking about cider integration with shadow, correct?

dpsutton14:03:15

its all the latest buzz

jmckitrick14:03:26

I’m interested it trying it, and I’ll document it in shadow if someone doesn’t beat me to it.

jmckitrick14:03:58

Let me finish reading the guide, and then I’ll be ready to try it. What’s the quick start so far to connect cider to nREPL with shadow?

thheller14:03:59

@jmckitrick easiest currently should be to run shadow-cljs server externally in a terminal and use cider-connect to connect to it

jmckitrick14:03:36

It looks like I’m connected, but jump-to-var requires op "info" via cider-nrepl. So I probably needed to start something else first….

jmckitrick14:03:46

I know cider auto-injects stuff for figwheel

thheller14:03:12

right you need to add [cider/cider-nrepl <version>] to your deps manually

thheller14:03:25

or run shadow-cljs -d cider/cider-nrepl:version server in the terminal

thheller14:03:51

we were talking about adding support in cider to launch shadow-cljs directly

jmckitrick14:03:32

Ah, that’s the next logical step.

dpsutton14:03:51

@thheller your project is so thoughtful to its end users

jmckitrick14:03:58

So I assume I need to pick through my lein dependencies and copy the cljs ones into the shadow.edn to start @thheller

thheller14:03:45

you can also specify :lein true and just run shadow-cljs via lein. https://shadow-cljs.github.io/docs/UsersGuide.html#Leiningen

jmckitrick14:03:32

Hmm. I’m trying to decide if I want to start out with lein integration or not…

jmckitrick14:03:41

Maybe I’ll do that to make it easier for now.

thheller14:03:11

@dpsutton I hope so 🙂

jmckitrick14:03:22

@dpsutton We’ve been hearing a lot about new user experience, so this is good to hear.

jmckitrick15:03:22

I’ve run cider-connect and I have a REPL running. How do I tell cider to begin using this connection for jump-to-var etc?

jmckitrick15:03:01

Actually, this might not be a cljs REPL.

jmckitrick15:03:55

Sweet! I’m connected.

jmckitrick15:03:01

I just ran….

jmckitrick15:03:12

(shadow.cljs.devtools.api/nrepl-select :app)

jmckitrick15:03:32

Time to write some docs….

bozhidar17:03:02

> it sounds like shadow-cljs works the way we want piggieback to eventually work: with suspendable cljs repls in a single repl

tanzoniteblack17:03:44

I was looking at a coworker of mine who uses intellij's screen yesterday, and saw that apparently his setup puts unused variables (as in, introduced in a let, but then never actually referenced) in a different color; is there a way to do something similar in cider?

bozhidar17:03:36

I don’t think you can suspend and resume a cljs session with shadow-cljs, but I might be mistaken. At any rate - @bhauman’s latest idea about piggieback would make this irrelevant (most likely), as it would enable using one REPL for both clj/cljs without the need for a second connection at all. I think everyone would agree that’d be quite handy. 🙂

bozhidar17:03:44

@tanzoniteblack CIDER itself doesn’t support this, but it’s doable. clj-refactor might have some functionality for this, not sure about that.

thheller17:03:20

@bozhidar it can suspend and resume

[email protected]:.../shadow-cljs$ shadow-cljs cljs-repl browser
[5:1]~cljs.user=> (def x 1)
#'cljs.user/x
[5:1]~cljs.user=> :cljs/quit
[email protected]:.../shadow-cljs$ shadow-cljs cljs-repl browser
[6:1]~cljs.user=> (inc x)
2
[6:1]~cljs.user=>

jmckitrick17:03:23

@bozhidar I’m willing to help with the cider/shadow integration. I have it working locally. Or have you already started?

thheller17:03:58

this is from a terminal but it works just fine over nrepl as well

bozhidar17:03:31

I haven’t started, but it’s probably best for me to do this, as I already know exactly what needs to be done. But if you do it by tomorrow morning that’d be fine by me - I’m already super busy as it is. 😄

jmckitrick17:03:13

If it only takes a day, I’ll defer to you. It would take me a bit longer, lol.

bozhidar17:03:53

@thheller piggieback also has :cljs/quit but I think this wipes the cljs session clean, therefore the conversation about adding :cljs/pause and :cljs/resume there.

bozhidar17:03:29

@jmckitrick It’s something like an hour of work, but who has an hour these days. 🙂

bozhidar17:03:49

I do think that this is pretty important, though, so I’ll try to do it as soon as tomorrow.

jmckitrick17:03:06

@bozhidar I know what you mean. I’ll work on documentation, then.

thheller17:03:22

which conversation? are these intended as nrepl ops?

dpsutton18:03:20

if all supported cljs sessions are suspendable, we could more mimic shadow-cljs. That's why i was saying there might be some benefit in making a custom jack-in-shadow-cljs and then making the current piggieback workflow work like that. and then unify them into a cider-jack-in-clojurescript with a single repl

bozhidar18:03:10

What exactly would be special about jack-in-shadow? After all apart from running different commands you’d be doing exactly the same thing as for piggieback - you start a clj repl and evaluate some expression in it to convert it to a cljs repl. The only difference I see is that with shadow we’ll know definitely in advance what type of REPL to start - with piggieback you can never know if the users wants rhino, nashorn, node, etc. If they have a figwheel dep that’s probably what they want, but you can never be certain. Same for weasel.

dpsutton18:03:33

that it currently doesn't spawn a sibling repl but just changes the clj repl.

dpsutton18:03:43

that's what i mean. it's the paradigm of a single repl for clj/cljs

dpsutton18:03:15

so if those mechanics work, if we get piggieback to be suspendable and not require a separate repl, all the other workflows would naturally just then be configuration in the shadow jack in workflow

thheller18:03:45

:cljs/resume seems problematic to me

thheller18:03:52

:cljs/pause is fine

dpsutton18:03:27

if you pause, how do you renter that repl?

thheller18:03:39

what if I start build for :build1 then pause it, start build2, pause that. how do I get back to 1 without going through 2

dpsutton18:03:59

ah i see. resume needs an argument?

bozhidar18:03:13

Yeah, yeah. But those details are not a big deal in the end of the day. To make what you say work we’ll also have to add provisions to all eval commands to toggle the repl type depending on the type of the source buffer (.clj or .cljs). I’m also wondering what are we supposed to do when evaluating code from a .cljc file. Now it’s easy - we send it to both REPLs, but if there’s just one I guess we have to decide if we want to run the clj code, then the cljs code and the quit cljs for each expression.

dpsutton18:03:43

> Now it’s easy - we send it to both REPLs, I don't like this and I want to remove it

bozhidar18:03:53

That’s why I generally prefer the idea of being able to send the code type as a parameter to eval - makes of this “magic” redundant.

dpsutton18:03:55

I like a known dispatch type

thheller18:03:29

I like dedicated ops even more but the code type param works as well

thheller18:03:07

we could have cljs/pause as an nrepl op. returns on message with some kind of identifier. then another nrepl op cljs/resume with :id <that-identifier>

thheller18:03:20

so it doesn't go through eval but goes through nrepl middleware