clojure-emacs / cider

The Clojure Interactive Development Environment that Rocks for Emacs
https://cider.mx
GNU General Public License v3.0
3.55k stars 645 forks source link

Support for calling clojure-cli-command inside WSL #3233

Open derinsh0 opened 2 years ago

derinsh0 commented 2 years ago

Is your feature request related to a problem? Please describe.

An alternative for Windows users is to call the clojure compiler and other tools via Windows Subsystem for Linux, for example wsl.exe clj ...

Describe the solution you'd like

Either a customization variable to allow command prefixes, or to programmatically call clj if "cli-command" is wsl.

Describe alternatives you've considered

A workaround is to set cider-clojure-cli-command to wsl and edit the command manually by typing clj after the wsl executable path. This is suboptimal.

Additional context

Most if not all development tools surrounding Clojure are Unix-based. There are advantages for working within WSL.

vemv commented 2 years ago

I'd like to understand, would it not suffice for you to customize cider-clojure-cli-command from "clojure" to "wsl.exe clj" (or "wsl.exe clojure", which IIRC would be best)?

bbatsov commented 2 years ago

I'm using WSL myself and I simply run Emacs within the Linux container. I guess what's proposed applies to running Emacs within Windows, right?

I think that's probably more of a documentation issue than something we need to change in CIDER, as I still know people who just run Clojure/CIDER directly in Windows and we shouldn't assume too much with the default configuration.

derinsh0 commented 2 years ago

@vemv Of course, I should have included that. The issue I got was that the variable was parsed as one string, and it complained “wsl.exe clj” is not in exec-path. Since both powershell and pwsh are interpreted as special cases by cider.el (base64 encoded with clj included), I’m thinking if wsl could be as well.

@bbatsov Yes. I am running w32-gui Emacs in Windows and have noticed I have a use-case for running clojure dev within the Linux container. I can probably hack cider.el but thought I should first bring the request up.

vemv commented 2 years ago

Since both powershell and pwsh are interpreted as special cases by cider.el (base64 encoded with clj included), I’m thinking if wsl could be as well.

That would sound reasonable to me.

And a generic approach would be to detect spaces in commands, and if so split the string, and later splice that list into the rest of the given command.

derinsh0 commented 2 years ago

I am favoring the latter idea personally. I'm not entirely sure how defcustom works but adding the option of using a list sounds functionally right (and future-proof) to me, e.g. '("wsl" "clj"), or unpacking a string as you said.

vemv commented 2 years ago

Making the defcustom accept lists and strings alike SGTM. PR welcome.

The defcustom would have to be updated to declare :type '(or string (list string)), I believe.

bbatsov commented 2 years ago

Yeah, something like this would be good as it's a problem to some extent even today with shadow-cljs REPLs that require commands like npx shadow-cljs. I hacked something together to make this work, but there's definitely room for improvement there. One problem remains quite elusive - how to make sure that the think you're trying to invoke together with npx or wsl.exe actually exists.

derinsh0 commented 2 years ago

I'm glad you agree. I've been looking around cider.el a bit to gain some information but this is obviously beyond my skills. Defcustom wouldn't be the main obstacle I suppose.

I setq'd the variable to '("wsl" "clj") and extended cider--resolve-command with

  (if (listp command)
       (when-let* 
         ((precommand (executable-find (car command)))) (concat (shell-quote-argument precommand) " " (cadr command)))
... old let-form

and ran (cider-jack-in-resolve-command 'clojure-cli) which gives me

"\"c:/WINDOWS/system32/wsl.exe\" clj"

which I think is correct. But cider-jack-in-cljs will complain Wrong type argument: stringp, ("wsl" "clj"). It somehow bypasses resolve-command fn for extra validation.