Fork me on GitHub

I do think it would be nice if certain parts of Calva could be made available as separate projects/libraries. However, this is a ton of work and not a priority at all, with everything else that is a priority. If we expose things, even if we say the API is subject to change, when we do change it and break others' workflows/projects, then we likely will hear about it. It's just not something we want to spend time worrying about or managing at this point in time. If you feel that you'd like to pull some things out of Calva for your own use, then please feel free to do so. Or, if you want to just keep a forked version of Calva with some customizations for yourself, you could do that too and keep it up to date with Calva's published branch. And for some things you desire that make you want these features exposed, there may be other solutions within Calva rather than exposing those features.


is it possible to customize the command line invocation that Calva uses to jack-in?


I'd like to test if replacing powershell.exe with pwsh.exe would help with this issue, but it seems the only way to do so is to create a custom Calva build... is that right?


Not currently, @plexus. I have planned to make the windows executable configurable, because of the two versions of powershell. However, it is very easy to build Calva and experiment with this.


ok, thanks


I’m looking at how to make it configurable by the user. It doesn’t really fit in the custom repl connect sequences, where I first thought it would go. We could add a setting that is just calva.powerShellExecutable, but it is still a bit hard to discover. The whole #clj-on-windows story is complicated as hell… I’ve spent 100+ hours getting the quoting right, and it still fails on some machines. Maybe it is better to advice people to use WSL2 instead? I think that is what @seancorfield does when he helps people in #beginners.


I've completely given up on Clojure on Windows "native" at this point, yes. The Remote-WSL2 extension for VS Code makes it so easy to use VS Code (native on Windows) with all the files and REPL etc all running on WSL2. Like @borkdude I always start a standalone REPL at the terminal and then connect my editor to it. I often have multiple REPLs running, and then I can connect to each one as needed to work on a specific project. I tend to restart VS Code (for a variety of reasons) far more often than I restart my REPLs.

👍 12

@plexus if you have bb installed on Windows, you can also invoke bb.exe --clojure which doesn't need powershell (same as deps.exe basically)


Hmm. Maybe we should bundle bb.exe....


@U0ETXRFEW or just the deps.clj uberjar, since you already use Java. I'm just not certain if people will appreciate Calva using a custom tools.deps runner ;)


I guess you could also re-implement deps.clj to CLJS and invoke it using node :P


PR to make it .cljc welcome ;)


That might actually not be a bad idea, because any JS based editor can then use this to invoke clojure


I think it may fall in that we do not get command line argument parsing that clojure gives us.


I mean as a means to jack in.


The command line argument parsing is implemented in deps.clj itself.


What deps.clj does is basically replace the bash/powershell with JVM Clojure, but porting it to Node CLJS would be a logical next step


but of course, feel free to bundle bb / deps.exe


just make people aware they are using a different non-official tool


non-official as in: not the official cognitect one


Cool. We can make it a project type. So at the gate you would make the choice (as a user). Also, I have plans for babashka in Calva, regardless. 😍


So, I can now launch it on windows using a bundled bb.exe. Makes quoting easier as well. Question is if it will be allowed on all machines… It is a bit hard to make it an option because the quoting is different and some other process settings as well…


@U0ETXRFEW to make it easier, you don't have to invoke bb --clojure from the command line. you can do this from a script as well: script.clj:

(some-> (babashka.deps/clojure ["-Sdescribe"]) (babashka.process/check))
$ bb script.clj
Most quoting issues should disappear now, the invocation will be the same on all OSes


if used from a script that is


so you could emit some temporary file that contains the invocation to not have to go through the command line


Thanks. The thought has crossed my mind. There’s a bit of a point with having it on the command line though. It makes it transparent what command is being issued and people can copy that and use it for starting their project in a Calva friendly way.


I usually just cider-connect instead of cider-jack-in

👍 3

The jack-in story has two sides to it: 1. As a beginner with Clojure it gets a bit too much to also need to understand the concept of editor dependencies. 2. Cooperation in a project gets easier if Calva doesn't demand changes to the project dependencies. It seems to mostly work. 70% or so of the repl sessions are started using Calva jack-in. Windows keep giving us grief. I think that might be why Windows exists.


I've always used cider-connect, as I do not want my dev process to die when my editor restarts


Me too. We are adding a way to copy out the jack-in command line to the clipboard for this purpose.


That said Vscode restarting is very rare. I have uptimes of several months sometimes.


Huh, that's not my experience. Often when an extension is updated or disabled it wants a restart


And things can crash. I just don't find this reliable.


Things can crash. It is just not common.


Haha, optimist


📣 calva-extras.backspacePositional added to calva

👍 3

Not ideal because it does not account for string context ( as Calva).


But does the job for me at the moment.


I've completely given up on Clojure on Windows "native" at this point, yes. The Remote-WSL2 extension for VS Code makes it so easy to use VS Code (native on Windows) with all the files and REPL etc all running on WSL2. Like @borkdude I always start a standalone REPL at the terminal and then connect my editor to it. I often have multiple REPLs running, and then I can connect to each one as needed to work on a specific project. I tend to restart VS Code (for a variety of reasons) far more often than I restart my REPLs.

👍 12

I've switched to using connect from all the Clojure editors I use (calva, cider, conjure) Using connect is much easier and far more flexible, especially with Clojure CLI tools. You don't need editor specific configuration to do anything interesting. Using a separate repl is really easy with some nice aliases in the user-level configuration for Clojure CLI tools. Using connect also make it easier to collaborate via a shared REPL on a remote server. And as others mentioned it's not tied to an editor, so I can use what ever tool is right for the task at hand. In some cases I have used a mixture of terminal UI and a couple of different editors to get things done effectively.

👍 6

I think we are a lot of people who generally use connect instead of jack-in. It’s easy when you get an understanding for how things work, not so easy for beginners. The vast majority of Calva users use jack-in, and that is good and as it should be. We need to make that work as well as we possibly can.


I think jack-in harms beginners -- because they don't start out by understanding the REPL: they just see it as something their editor "does". I think we adopt "easy" approaches far too readily instead of sticking with "simple" and teaching beginners how things actually work.

👍 3

I see where you're coming from here, but I think this is hard to prove and a bit hard to analyze. What about users that take a few looks at Clojure with an editor that didn't allow jack-in, and they see a lot of unfamiliar tasks to complete before getting to a good dev flow, and maybe they throw Clojure aside as a result, at least until hopefully trying again later. It can be hard to remember exactly what it was like to be a beginner. Do we know that using jack-in harms a person's ability to later learn how to start the repl themselves and connect to it? Maybe your point though is that they may not learn more of the auxiliary concepts associated with the Clojure repl as soon since they aren't managing it so much themselves, which again, I think is hard to really know, and it doesn't mean they won't learn them later when they need them, or that it will harm their ability to do so.


@brandon.ringe Pretty much every tutorial starts with a plain REPL started from the command-line and has beginners typing directly into the console REPL -- so most users have the "start a REPL" experience under their belt before they try moving to a connected editor. But "typing directly into the console REPL" is also problematic in its own ways. I think both jack-in and type-in-console are bad for beginners. Overall, we do a terrible job of getting beginners up to speed with a "good" REPL-based workflow.


The problem with jack-in -- based on my observations over the years watching beginners here and elsewhere -- is that it "magics over" how the editor/REPL integration actually works -- and gives an (incorrect) impression that editor integration and command-line REPL are somehow two completely separate things. And when they run into problems with jack-in, especially around figuring out how to persuade the editor to start the REPL exactly like they do from the command-line, it becomes a very editor-specific and somewhat archaic process to debug and fix.


And the weird thing (from my p.o.v.) is that historically we used lein repl to get started at the command-line and it already starts a network REPL that most editors could connect to so we've missed the opportunity to simplify the overall process -- and decomplect the editor/REPL integration.


I agree with you on some of this. Though, I think the issue you speak of around jack-in isn't necessarily a problem with jack-in but with either how it's implemented or the supporting docs. We can provide a tool for making getting started easier while also educating them on what's happening, and how to perform the process themselves. Hopefully @alexmiller and others publish improved getting started material on as he mentioned. I'm looking forward to that.


we have come to see "Pretty much every tutorial starts with a plain REPL started from the command-line" as bad and we should stop doing that


because there's nowhere to go from there. you're backing to starting over to get into an editor / files / projects /repl connected editor / structural editing


we should just be getting them to repl-connected editor and start in a file - everything from there is additive. (and just never type directly into a repl)


I find Clover with it's absence of even having a repl that takes stdin to be actually good in this regard - you have to eval from your editor if you want to do anything


@alexmiller Agreed. I keep repeating Stu's comment about "I'm always baffled when I see people typing into their REPL" (or whatever his exact wording was).


Yes, I also like Chlorine/Clover for that: no more typing into a REPL!


and that startup process you see with Clover/Calva could be even easier if you could easily launch a non-project REPL and jack-in to it


But the elephant in the room at this point is nREPL: nearly all editors need it to talk to a REPL and while lein repl and boot repl start nREPL servers, the Clojure CLI doesn't.

☝️ 3

(and jack-in kind of papers over that by adding nREPL as a dependency behind the scenes)


well I have my own preferences there, but I think that is not important to a beginner (it's important to implementors of course :)


ideally I want any editor to support both, even if the experience is not the same


I think it's highly unlikely that we're going to recommend any getting started path on that doesn't work with clojure cli


Yup, definitely. Clover/Chlorine support a wide variety of REPLs now -- including nREPL -- but also as simple as lumo etc.


I've been using Clover some this week too and I do like the structure of that


but I realize all that stuff is hard from editor impl pov (I'm glad I'm not working on it and can just make unreasonable requests of others :)

😄 3

props to my oss maintainer brethren


It seems that the main things people want from editor integration that Socket REPL/pREPL don't provide out of the box are: 1) a way to interrupt long-running evaluation and 2) a way to manage evaluations that produce infinite (or very large) results. That's my perception, mostly based on talking to a few of the integration folks, so I don't know if that's the entire story.


I have to admit I also like that about Clover, the lack of ability to type into the "repl" window. I think part of the reason @U0ETXRFEW has kept this is related back to the getting started tutorials. If we didn't allow that then beginners might be confused, ask questions, request we add it, etc., because they got started this way and may think that's the "repl-driven" experience people discuss (another issue with tutorials). I think in time it could be done away with though, and this would make maintenance of the repl window a bit easier too.


when I work (in Cursive primarily) I almost entirely "work" from my editor, but I do use the repl window to do a few things (mostly (pst *e) because I leave the repl window sitting in user with clojure.repl referred).

Cris B22:01:36

There are different kinds of beginners - really there's very little in common between (say) a beginner-to-programming and a java-programmer-beginner-to-lisps. As an experienced developer starting with clojure I haven't found jack-in confusing. I naturally ignored the 'type into the REPL' instructions and started with a blank slate project in a connected editor. Over time as I've figured out the tooling (somewhat) I've backpedaled to using a manually-started REPL and then connecting. But jack-in was very handy to get a frictionless start with.


beginner-to-programming is a special case and not one that we as a Clojure core team is trying to satisfy. I think there is a great deal of commonality between new-to-a-lisp though


The Calva REPL window is really just an editor (vs code speak for what Emacs calls a buffer), just like any other editor. It would be a bit strange if it didn’t allow evaluations just like the other files. When I first created it, I tried not giving it a prompt. But VS Code wouldn’t really let me. I needed a way to display the current namespace… Anyway, we try to encourage people to stay in their files. We’re Stu’ed like that. 😃

👍 3
Cris B22:01:02

I can quite see a total beginner not being a major case in point @alexmiller. I was assuming @seancorfield’s comments about the 'magic' of jack-in inhibiting gaining understanding of the real tooling story was about complete beginners. It's hard to imagine a reasonably experienced programmer falling into that?


It's not hard for me to imagine based on what I've seen here (and in other forums) over the years 🙂


Just a couple of more cents: half a year ago I started developing Clojure in my day-time job. I have been meddling around with it for some two years now I think. I’m a very experienced programmer, even a bit FP, but completely new to Lisp/Clojure/REPL/etc. I think in this situation there’s quite a big learning curve. So many things you have to learn and understand. So many options. Quite overwhelming frankly. So to me the easy jack-in of Calva was absolutely great, because it allowed me to just start using things without also having to figure out all the details of that part of the story. And today I still use jackin all the time, I don’t have a reason to start a REPL outside and connect to it. Maybe when I have a few more years of experience I will, maybe I won’t , but to me the jack-in is awesome 😍

calva 6

I have yet to see a beginner harmed by this.


Does jack-in require a project context?


That is, can I just open a new file and jack-in to start a repl? Not at a computer right now to try it


I kinda agree with @seancorfield here


I know you do. And I think you are both wrong. 😃


What a terrible world it would be if we all agreed on everything... 🙂


Indeed. 😃


For the record, even if I am working hard with getting jack-in right, the connect story is also important and never forgotten.


My experience is that I used to spend 90% of Calva support with helping people to get the editor dependencies right, constantly worried about all those who gave up without asking for support. Since releasing jack-in I instead spend the support time with helping people using their connected REPL. It is so much better.

👍 3

I was pretty confused for a while "$%?!? this jack-in thing ?!". The name is good for cider dev, less so for user. Better name "repl-in".


Agree. I felt almost the same when I first knew about Jack-In. I get used to run a repl starting in a separate terminal. But now I often use Jack-In.


@alexmiller currently it does require a project context. But there is no particular reason it does. We should fix it. Please chime in on this issue:



❤️ 3

I know you guys probably already know this, but since nREPL now supports sideloading middleware, you could have Calva sideload the middleware it needs after connecting to the nREPL server. I've been doing that in my plugin for a while now and I really like how it works.


It's going to be a bit of work, though, of course. 🙂


(It'l also affect the size of the deliverable, because you'd need to vendor in all the middleware you want to load.)


I've looked into it just a bit. Totally cool feature. But, yeah, quite some work. What's your use case?


Well, I wanted an editor plugin that can connect to a "plain" nREPL server. (Ideally, it'd be a socket REPL or prepl server, but that's not viable for a bunch of reasons.) Basically, it works like this: - User starts an nREPL server from the command line (by running the equivalent of clojure -Sdeps '{:deps {nrepl/nrepl {:mvn/version "RELEASE"}}}' -M -m nrepl.cmdline) - User connects to the server from the editor. The editor plugin doesn't know anything about how to start an nREPL server. - The editor plugin sideloads the middleware it needs (e.g. for clojure.test integration) - Off we go. For any subsequent connections, the middleware is already there, so no need to load it again or anything.


I see where you're coming from here, but I think this is hard to prove and a bit hard to analyze. What about users that take a few looks at Clojure with an editor that didn't allow jack-in, and they see a lot of unfamiliar tasks to complete before getting to a good dev flow, and maybe they throw Clojure aside as a result, at least until hopefully trying again later. It can be hard to remember exactly what it was like to be a beginner. Do we know that using jack-in harms a person's ability to later learn how to start the repl themselves and connect to it? Maybe your point though is that they may not learn more of the auxiliary concepts associated with the Clojure repl as soon since they aren't managing it so much themselves, which again, I think is hard to really know, and it doesn't mean they won't learn them later when they need them, or that it will harm their ability to do so.


I don’t think jack-in vs connect is inherently problematic. A beginner needs to understand they are “connecting to Clojure” but whether that’s in process or out of process is not really much different. Imo not needing to understand project context is more important (at first). We (Rich and others) have been working through better getting started directions for the Clojure site and I think a focus of that has been getting people to “editor with connected repl” first (not repl only - where nothing is persistent, that’s a dead end), and not project context (not needed, can be additive to what you’re doing later)

👍 6

Jackin is nice in being able to keep you “in the tool” and defer needing to understand the details. I like that Calva is explicit about seeing the command and what’s happening there even if you’re launching in process


That at least sets the stage for learning more about how that works


I agree. It's awesome too that there's an effort by you and Rich and the others to improve the getting started directions for the Clojure site.


Now we are talking!


To make an analogy (hopefully not a terrible one), learning to drive with an automatic transmission doesn't necessarily make it harder for you to learn to drive with a manual transmission.


@brandon.ringe In England, if you pass your test on an automatic transmission, you are not licensed to drive a manual transmission -- or at least that used to be the case. You have to take your test on a manual transmission in order to drive a manual (and you are also licensed to drive an automatic at that point).


(and I can't resist seeing automatic transmission = easy vs manual transmission = simple 🙂 )


I agree with you with the easy vs simple argument, but we don't have to see easy as always bad. That makes sense to me, the separate driving tests, but I don't think it detracts from my previous statement.


(just to be clear: if you learn on manual and take a test on manual, you're licensed for both manual and automatic; if you learn/test on automatic, you can't drive manual until you've also taken a test on manual -- not sure if that was how you read it, given your "separate driving tests" comment?)


And, yes, our goal should be to make the simple path also be easy. Or easy enough.


I see, but I think it's good to give the user (driver) a choice like that.


I think the concept of jack-in is what makes the simple path easy, but like I mentioned before, how that's done is what's important.


Editor integrations requiring nREPL is part of why jack-in appeared and why it is "easy" -- especially when you switch from lein to the Clojure CLI. Another reason I think our reliance on nREPL is unfortunate by this point. Side-loading of nREPL into a plain Socket REPL will help, when that happens.


I see - so this more so can be boiled down to an issue with reliance on nREPL, at least in your mind. I know others might echo that sentiment, and I can't say I have a strong stance on that one way or the other. I'm much newer to Clojure than yourself though. 😄


If we'd had the Socket REPL built into Clojure from day one, I think we might never have seen nREPL, and all editors would happily connect to a plain Socket REPL and perhaps side-load some affordances (such as unrepl/unravel). But... at this point we'll never know 🙂


I've been implementing a Clojure editor plugin from scratch for the past nine months or so. I would love to support plain socket REPL or prepl, but I ended up going with nREPL for these reasons: - nREPL has structured input and structured output. Socket REPL has neither, prepl only has structured output. - Crucially, nREPL is easily extensible. Things like symbol lookup and auto-completion support are much easier to implement. Also, since it supports sideloading, there's no need for a jack-in type of thing any more since editors no longer need to presume that the server is running a certain set of middleware. I just run clojure -M:nrepl, connect to the server from my editor, and off we go. - nREPL uses Bencode by default. Implementing a streaming Bencode encoder/decoder from scratch is trivial. Supporting EDN would take a lot more work (a subset of EDN might suffice, though). - nREPL has interruptible evaluations. I agree that the capability to "upgrade" a socket REPL or a prepl connection into an nREPL connection would be really cool, though.


My point is that even though the Socket REPL and prepl exist, there are still good reasons to go with nREPL.


nREPL is wonderful. Super smart design enabling a tool smith to super quick get down to deliver user value.


It's great, except for ClojureScript. 😛


Piggieback takes care of a lot of that for me. And shadow-cljs comes with its own middleware for it. It's super smooth to work with ClojureScript in Calva.


Well, we already discussed this a bit earlier elsewhere, but to me, even with Piggieback or shadow-cljs, the ClojureScript experience is a far cry from the Clojure experience. But this is somewhat of an expansive topic. 🙂 Ideally, I'd want ClojureScript evaluation to "just work", like Clojure does. If I have a ClojureScript view open in my editor, the editor should send my evaluations to ClojureScript automatically, instead of having to switch between ClojureScript and Clojure REPLs manually. clojure.test integration should work. The auto-completion and symbol lookup features built into nREPL should also work with ClojureScript. And so on.


> The load-file nREPL operation will only load the state of files from disk. This is in contrast to "regular" Clojure nREPL operation, where the current state of a file's buffer is loaded without regard to its saved state on disk. Also, that is a big problem with Piggieback, in my view.


So for me ClojureScript evaluation just works. With cljs files in the CLJS REPL, with cljc files I have need to toggle if the cljc repl isn’t the cljs one, but that is quite rare, because reasons. auto-complete works, symol lookup too, even JavaScript symbols. Also code navigation and signature help and about everything. The only whole thing lacking is the test runner. But I get by with just evaluating things like (cljs,test/run-test) . Haven’t even noticed that load-file difference, but it is probably my workflow. I seldom save files, so evaluate them form by form after having loaded them. (From disk apparently).


"Our mileages may vary" is probably a good summary here. 🙂


Haha. Have you tried it in Calva?


Not yet. I've no doubt things work better in Calva, but I don't (want to) rely on the CIDER middleware stack. Ideally, I'd like ClojureScript support be better out of the box. I'll give it a try, though -- I'm quite curious about how switching between ClojureScript and Clojure evaluation works.


Calva keeps two REPL sessions open. From cljs files the cljs repl is used. That’s the full story. 😃


I'm not sure it's quite that simple. 😛 I think it might be that Calva requires that your project is set up in a certain way. I just tried it and nothing happens if I try evaluating from a ClojureScript buffer. Calva also knows about Figwheel, shadow-cljs etc., whereas I don't want my editor plugin to have to know anything about the build tool du jour. Anyway, this topic is quite involved, and I don't want to take up more of your time with my blathering. 🙂


I love spending time on talking about these things. 😃 Huge topic. For the record. though. Calvas repl session handling, including cljc toggle, was there long before Calva new anything about the build tool du jour. Pretty sure it is that simple. Haha.


I believe you. In all likelihood, I'm just doing something wrong, not Calva. Wasn't trying to say that Calva is doing something wrong here. :) I'm not quite sure we're talking about exactly the same thing, though, and I don't know how to use Calva, so... Anyway, I guess my point is that with Clojure, I can just start an nREPL server in the Terminal. In my editor plugin, there is only one option: connect. Once the user does that, they're off. What I'd like to do is that if the user then opens a ClojureScript view, everything would work exactly as well as with Clojure — or as close as possible. Obviously, there are differences we can't really do away with. For example, the user must have a ClojureScript dependency, and they must select the JavaScript runtime environment (Node.js, browser, etc.) at some point. Calva might might work like that already, but there's just something I'm missing. I'll need to look into it at some point, when I'm a bit less busy with work.


I don't have a clear picture in my head about the whole thing anyway, since the ClojureScript world is significantly messier than the JVM world (it seems to me, anyway), so it all's going to take some thinking.


Yes, it is messier. What Calva does is something like so: 1. Create the Clojure REPL session 2. Clone it 3. Promote the clone to a ClojureScript REPL Promoting it is different between tools and also people create their own CLJS repls. What Calva “knows” about these tools is actually just convenience configuration. The users can create their own. We call it Connect Sequences. See where you fid some example configurations at the bottom.


Thank you! I'll definitely take a look. :thumbsup::skin-tone-2:


It can be made a bit simpler than that, I think. Calva takes a bit of a “holding hand” approach- 😃


So, I created a feature request about helping people with those first Clojure steps. Please chime in, Calva friends.