How can I configure a custom REPL prompt for REPL started via clojure cli / deps.edn, in a non-hacky way?
• I want it to print (project-name) user=>, instead of just user=>, ,
◦ while keeping the standard user.clj load behaviour
◦ and, I don't want to switch to a custom ns matching the project name
• I use CIDER and nrepl middleware
◦ I can't figure out how to configure the prompt via project-local .nrepl.el
◦ Is there a :repl-options config for clojure CLI? https://github.com/clojure-emacs/cider-nrepl/blob/v0.52.0/doc/modules/ROOT/pages/usage.adoc
◦ Any undocumented way to send prompt function to nrepl.cmdline? This logic seems to be the key to my requirement: https://github.com/nrepl/nrepl/blob/0d78e7144b260d9c7ff905d890bc668f847a741a/src/clojure/nrepl/cmdline.clj#L382
• I don't want to start a sub-repl.
◦ Custom prompt is possible to do via user.clj (clojure.main/repl :prompt my-custom-prompt-fn)
▪︎ BUT it starts a sub-REPL, and that in turn seems to mess up CIDER's REPL startup.
▪︎ I think so, because it prevents me from using unix domain file sockets.
• I definitely don't want to write a custom REPL client (non-standard tooling defeats the purpose of my current project).
My hack is:
Pass in a custom --repl-fn via my :cider alias in deps.edn.
:cider {;; clj -M:dev:cider
:extra-deps {cider/cider-nrepl {:mvn/version "0.50.2"}
refactor-nrepl/refactor-nrepl {:mvn/version "3.9.1"}}
:main-opts ["-m" "nrepl.cmdline"
"--middleware"
"[cider.nrepl/cider-middleware,refactor-nrepl.middleware/wrap-refactor]"
"--repl-fn" "user/run-repl"
"--interactive"]}
Where my user/run-repl does this....
(defn multiproject-repl-prompt
[_]
(let [project-alias (or (System/getenv "CLJ_MULTIPROJECT_ALIAS")
"none specified")]
(printf "(project alias: %s) \n %s=> "
project-alias
(ns-name *ns*))))
(defn run-repl
([{:keys [server options] :as repl-ctx}]
;; The hack: :prompt injection (hehe :)) into nrepl.cmdline's private `run-repl`.
(#'nrepl.cmdline/run-repl (assoc-in repl-ctx
[:options :prompt]
multiproject-repl-prompt)))
([host port]
(run-repl host port nil))
([host port options]
(run-repl {:server (cond-> {}
host (assoc :host host)
port (assoc :port port))
:options options})))Have you tried setting it via the config file? https://github.com/nrepl/nrepl/blob/c72bb4b13d473ca582200abd2239a8c2bc5a12b4/doc/modules/ROOT/pages/usage/server.adoc#server-configuration
Yes... That is how I found out that a vanilla :prompt option does not work. I have to pass (my custom) :repl-fn .
cat ./.nrepl.edn
{:prompt user/multiproject-repl-prompt ; doesn't work
:repl-fn user/run-repl ; works
}
For now, I'm happy about this hack... it is working how I expect! :)
Greetings, CIDER connoisseurs! There's an exciting new feature waiting for you in the latest MELPA build. After updating, try turning on the new variable cider-download-java-sources (`M-x customize-variable cider-download-java-sources` and then toggle to enable it). Now, CIDER will download Java sources of third-party libraries for Java classes when you request documentation for a class or a method (`C-c C-d C-d` ) or jump to its definition (`M-.`). This feature works without enrich-classpath.
The downloading should work for both tools.deps and Leiningen-based projects. In all cases, it starts a subprocess of either clojure or lein binary (this is the same approach that Clojure's 1.12 add-lib utilizes). This should work well for most cases. You might have problems downloading the sources of dependencies that are not public (i.e. they live in a private repo), and the credentials are non-global but under some specific alias/profile that you start REPL with. If this happens to you, please report it; but I suspect such cases would be rare.
The download usually takes up to a few seconds, and then the downloaded artifact will be reused by all projects. If download failed (most often, because the library didn't publish the -sources.jar artifact to Maven), CIDER will not attempt to download it again until REPL restarts.
Try it out in any project by e.g. jumping to clojure.lang.RT/toArray or bringing up the docs for clojure.lang.PersistentArrayMap.
Fantastic work, Sashko! cider 🚀 🔥
I've just tried it and it works great. This is fantastic - something I've been waiting for for many years!
Better late than never. 😉
Wow, this is the greatest thing ever! I can't tell you how many times I've wished I had this. TIL about enrich-classpath too 😄 Thank you all!
Enrich-classpath was the previous iteration of this functionality. It requires an intrusive setup and is overall more complicated. The latest Java-related features are meant to be a lightweight and flexible replacement for enrich-classpath.