Fork me on GitHub
#emacs
<
2023-11-26
>
Dave Anderson19:11:28

Anyone using the combination of cider, shadow-cljs and envrc? I have a .envrc that pulls in all of clojure, jdk and node tools into $PATH, and it almost all works with cider and envrc, except cider-jack-in-cljs fails with just error in process sentinel: Could not start nREPL server: /usr/bin/env: 'node': No such file or directory. So... Something within cider's nREPL logic ends up not inheriting the buffer's environment and so can't find node and other tooling. Anyone encountered this before and know how to get everything to play nice, before I go read cider source code and try to figure it out myself?

ag20:11:18

That probably has more to do with how Emacs understands your environment, rather than CIDER. Maybe check your process-environment var?https://www.gnu.org/software/emacs/manual/html_node/elisp/System-Environment.html

Dave Anderson20:11:16

ah, that sounds like the right place to dig in, thanks. Indeed, that var doesn't include per-buffer envrc customizations, so if cider ends up using that env to spawn children... Yup, that'll do it. Cheers.

Dave Anderson20:11:25

aha, yes, this is because of how envrc mutates process-environment buffer-locally for each buffer, but since nREPL spawns a separate buffer and then runs child processes from there, it ends up with the emptier global environment instead of the environment that came with the origin buffer. Looks like envrc has some machinery to patch the appropriate inheritance into other packages, now I just need to find the right place in CIDER to make that environment propagation happen. Thanks for the hint!

vemv13:11:36

I see there's a https://github.com/purcell/envrc package (purcell also authored https://github.com/purcell/exec-path-from-shell so you can trust that stuff)

aisamu14:11:23

I suspect that's what Dave was referring to with: > envrc has some machinery to patch the appropriate inheritance into other packages The tricky part is probably: > find the right place in CIDER to make that environment propagation happen I use envrc heavily and can can confirm that jack-in works beautifully for regular clojure REPLs. I've never tested a clojurescript REPL with this setup. Sometimes there are some hiccups but invoking envrc-allow/reload always fixes it!

Dave Anderson17:11:26

yeah the standard jack-in works fine, it seems to be something specific to how the shadow-cljs setup happens that breaks the chain of environment variables.

vemv17:11:45

tbh I don't find env variables the best tool for the job here - instead I would suggest looking into a combination of aliases/profiles and JVM properties (or maybe aliases alone, depending on the intent) envs of course can work, but from the cider pespective it's the difference between 'supported' and 'here be dragons'

vemv17:11:42

another approach, which I recommend for a variety of reasons, is to avoid jacking in to begin with. use shadow-cljs from the CLI instead, it will honor .envrc and survive Emacs crashes if any

aisamu17:11:02

If his setup is anything like mine, the PATH is used to make the JVM and clojure itself available to the existing process (i.e. nothing is installed globally) This is not such an uncommon usecase (nix, virtual envs) - there are dozens of us!

vemv17:11:08

Yeah but one thing is to set the PATH once to the same global value than the terminal, and another, is to have PATH re-computed depending on the default-directory

aisamu17:11:15

(The aliases and JVM properties are still fully managed by deps edn)

aisamu17:11:01

Yup! The envrc machinery does that perfectly with a regular clojure jack-in (I don't claim to understand how 😅), but for the two step cljs repl there seems to be a hiccup somewhere

aisamu17:11:58

Would you have a minimal repro, Dave? I could try it here

Dave Anderson17:11:10

I don't at the minute, but I can put one together this evening. My exact case is unfortunately weird (combination of Nix, envrc, emacs and so forth), but I can see if I can narrow it down.

Dave Anderson17:11:10

Based on the envrc docs, almost certainly the issue is that the shadow-cljs jack-in ends up spawning a subprocess through a path that isn't one of the standard "run a subprocess" functions that envrc-mode patches to add environment propagation; or that cider creates a new buffer for the repl and then starts invoking subprocesses from there, which breaks the chain of env inheritance from the source code buffer. All completely valid things to do, it just doesn't play terribly well with the environment varying per-directory the way I have things set up 🙂

vemv17:11:56

Just for completeness sake, .dir-locals / .dir-locals2 is another approach that could work. But yeah if you get to investigate and improve things, that'd be nice as well!

Dave Anderson17:11:04

And yes, certainly just running the cljs repl from outside emacs should fix that perfectly well

Dave Anderson17:11:25

oh I don't know what that is, I'll take a look, thanks

Dave Anderson17:11:32

Part of my problem is that I'm also completely new to the clj ecosystem generally, and haven't touched the underlying Java ecosystem and conventions for years. So, quite a large learning curve for how things want to work vs. how I have things set up for other languages! But I'm sure I can figure something out, eventually.

aisamu17:11:24

I'm more than happy to help try narrowing this down! My emacs-fu is limited, but our workflows seem to be quite similar (nix + direnv, project-scoped deps).

Dave Anderson17:11:47

yup, that looks like the same setup! So are you not doing ClojureScript stuff then, is that why you're not hitting the same thing?

aisamu17:11:03

Yup, I haven't used cljs for a long while! But I'm a heavy user of clj jack-in

Dave Anderson17:11:28

yeah, the clj part seemed to work fine. I wanted to play with Fulcro, hence trying to get cljs working. That said, I then saw that cider has fairly limited clojurescript support, in particular hot reloading (on the JS side) allegedly doesn't work. So, I may be stuck with intellij to get a workable environment, alas.

aisamu17:11:01

cider has fairly limited clojurescript support, in particular hot reloading (on the JS side) allegedly doesn't workWorth noting that, at least back when I used it, the only thing not working was step debugging. The rest worked fine once I nailed all the repl incantations!

Dave Anderson17:11:19

oh! Well then.

vemv17:11:14

hot code reloading certainly works. it's mostly the responsibility of shadow-cljs and minimal boilerplate in your app (https://github.com/reducecombine/icd.scroll/blob/a9e84249ca931df6338a876d4aa7698f688e7321/src/icd/scroll/app.cljs#L13-L18) after each hot-reload, in your emacs both the cljs and js autocompletions will look at the reloaded environment. stuff that works: repl, navigation, doc doesn't: debugger, running tests (other than using the repl), inspector

Dave Anderson18:11:17

Gotcha. Well, those I can definitely live without in my IDE, for my current purposes.