I'm having trouble working out how to wrap nrepl with portals middleware so that I can open a portal sub repl in calva. Following https://github.com/djblue/portal/blob/master/doc/guides/nrepl.md#toolsdeps, I experimented with different command line switches but haven't worked out what settings I need in my deps.edn alias. Tried this but it is not working:
{:paths ["src"]
:resource-paths ["resources"]
:deps {org.clojure/clojure {:mvn/version "1.12.0"}
com.hyperfiddle/rcf {:mvn/version "20220926-202227"}}
:aliases {:portal-wrap-nrepl
{:extra-deps
{cider/cider-nrepl {:mvn/version "0.28.5"}
djblue/portal {:mvn/version "0.58.5"}}
:main-opts ["-m" "nrepl.cmdline"
"--middleware"
"[cider.nrepl/cider-middleware,portal.nrepl/wrap-portal]"]}}}doh! Thanks for catching my mistake! Success!
(p/repl portal)
; To quit, type: :cljs/quit
[:repl {:session-id #uuid "b0fa9744-5266-4888-8d0c-7e0aa1f526cd"}]
clj꞉user꞉> @djblue I've been wondering how I can get repl evalutations to automatically send to Portal. Adding the extra middleware, as you mentioned above, did the trick. Thanks!
@pez Thanks for making that a simple config to add extra middleware instead of needing to override the entire command
Getting this error message:
clj꞉user꞉>
(p/repl portal)
; Execution error (ExceptionInfo) at portal.api/repl (api.cljc:209).
; Please start nREPL with `portal.nrepl/wrap-repl` middleware to enable the portal subrepl.I want to experiment with the sub-repl to create custom viewers. https://cljdoc.org/d/djblue/portal/0.58.5/doc/guides/custom-viewer
This is what I see in the repl output when I jack in:
; Starting Jack-in: (cd /Users/jamiep/Documents/clj/aoc; clojure -Sdeps '{:deps {nrepl/nrepl {:mvn/version,"1.0.0"},cider/cider-nrepl {:mvn/version,"0.28.7"}}}' -M:portal-wrap-nrepl)
; Using host:port localhost:56652 ...
; Hooking up nREPL sessions ...
; Connected session: clj
; Evaluating code from settings: 'calva.autoEvaluateCode.onConnect.clj'
(when-let [requires (resolve 'clojure.main/repl-requires)] (clojure.core/apply clojure.core/require @requires))
nil
clj꞉user꞉>
; Jack-in done.
clj꞉user꞉> I presume the command line switches defualt for calva jack in are overridden by what's in my alias??
Calva runs the command you see there. So not overriding main args, if I understand correctly.
I see this when jacking in so I assumed that calva would respect the overrides in my aliases.
I think it looks like it does. According to your output it runs:
clojure -Sdeps '{:deps {nrepl/nrepl {:mvn/version,"1.0.0"},cider/cider-nrepl {:mvn/version,"0.28.7"}}}' -M:portal-wrap-nrepl
So if you run that in the termnal, and instead of Jack-in, you connect Calva to the running repl. I think you’ll get the same error.
One thing I notice is that you have cider-nrepl dependency in your alias. That command line overrides that dependency. But I don’t think this is the problem.The Calva aliases menu includes two aliases that I don’t see in the deps.edn. Have you provided them via myAliases config?
I didn't post all my aliases in deps.edn above. I am only selecting the portal-wrap-nrepl one.
oh, well. Thanks for your quick response @pez as always. For now I'll just experiment with sending code to portal with portal.api/eval-str
I pinged @djblue perhaps he can easily see what is the problem.
There is also extraNReplMiddleware you can provide via a custom connect sequence: https://calva.io/connect-sequences/#settings-for-adding-custom-sequences I think that probably the portal middleware can be added that way instead of via an alias. In theory that should land you in the same spot as you are now, but who knows. 😃
Thanks so much for your help @pez. Much appreciated!!
https://github.com/djblue/portal/blob/master/.vscode/settings.json#L53-L75 is how I setup a portal repl using the nrepl middleware
Odd I have everything from the repl outputting to portal which I think means I have the middleware installed but when I try this, I get an error:
(p/repl portal)
; Execution error (ExceptionInfo) at portal.api/repl (api.cljc:209).
; Please start nREPL with `portal.nrepl/wrap-repl` middleware to enable the portal subrepl.
portal.api/repl (api.cljc:209)
portal.api/repl (api.cljc:198)
user/eval11967 (NO_SOURCE_FILE:23679)
clojure.lang.Compiler/eval (Compiler.java:7700)
clojure.core/eval (core.clj:3232)
clojure.core/eval (core.clj:3228)
nrepl.middleware.interruptible-eval/evaluate (interruptible_eval.clj:87)
clojure.core/apply (core.clj:667)
clojure.core/with-bindings* (core.clj:1990)
nrepl.middleware.interruptible-eval/evaluate (interruptible_eval.clj:87)
clojure.main/repl (main.clj:437)
clojure.main/repl (main.clj:459)
clojure.main/repl (main.clj:368)
nrepl.middleware.interruptible-eval/evaluate (interruptible_eval.clj:84)
nrepl.middleware.interruptible-eval/evaluate (interruptible_eval.clj:56)
nrepl.middleware.interruptible-eval/interruptible-eval (interruptible_eval.clj:152)
nrepl.middleware.session/session-exec (session.clj:218)
nrepl.middleware.session/session-exec (session.clj:217)
java.lang.Thread/run (Thread.java:1583)Ohh, I think I see the issue. Portal has a few https://github.com/djblue/portal/blob/master/src/portal/nrepl.clj#L324-L328and it seems you are using portal.nrepl/wrap-portal which is just for tapping eval results. What you need to include is portal.nrepl/wrap-repl , or you could include them all via portal.nrepl/middleware .
Dear Calva friends. What if we could define custom variables that would allow us to replace defn with, e.g. defn* and evaluate the top level form with that without editing the file, thus allowing us to use @abhinav.omprakash10’s https://github.com/AbhinavOmprakash/snitch at will? With PR 2769's Custom REPL Command Variable Modifiers this will be possible. Check this example out:
{
"name": "qol: Add Snitch dependency",
"repl": "clj",
"snippet": "(require '[clojure.repl.deps :refer [add-libs]])\n\n\n(add-libs '{org.clojars.abhinav/snitch {:mvn/version \"0.1.16\"}})"
},
{
"name": "qol: Evaluate as Snitch defn* ",
"repl": "clj",
"snippet": "(require '[snitch.core :refer [defn* defmethod* *fn *let]])\n${top-level-form|replace|^\\(defn-?|(defn*}"
}
It’s the second one that uses a modifier: ${top-level-form|replace|^\\(defn-?|(defn*} . Now you can use that custom command to evaluate any function, instrumenting it with inline defs of all its local bindings. If you prefer to do it via keybindings:
{
"key": "ctrl+alt+c s",
"when": "calva:connected",
"command": "calva.runCustomREPLCommand",
"args": {
"snippet": "(require '[snitch.core :refer [defn* defmethod* *fn *let]])\n${top-level-form|replace|^\\(defn-?|(defn*}",
"repl": "clj"
}
},
There is also a pr-str modifier. Please check the docs out, and please take the VSIX for a spin so that we can release with more confidence that it doesn’t break stuff. Feedback welcome!
cc: @djblue @seancorfield
• Docs: https://deploy-preview-2769--calva-docs.netlify.app/custom-commands/#interpolationsubstitution-modifiers
• Grab latest VSIX here: https://app.circleci.com/pipelines/github/BetterThanTomorrow/calva?branch=custom-snippet-variable-interpolationLatest VSIX for this PR tries to fix the issue with mapping the source, @djblue. Can you try it and check if you think it is fixed/improved/just as bad as before?
I tried it out, works great.
Sean is on the road. Let’s see when he finds a computer and can check that his workflow still works. Meanwhile I am running with the VSIX and am having a great Snitch time!
That likely won't happen until I'm back with my "big" computer instead of my laptop, maybe the 12th or later.
(and I'm not interested in testing snitch, at this point anyway)
I just want to make more sure we’re not breaking any existing use.
I just released these changes, @seancorfield. So no stress to get to your big computer because of this. 😃
My two pieces of feedback would be:
• I prefer "calva.evaluateEnclosingForm" over "calva.runCustomREPLCommand" for eval'ing my project code because my source info always gets mapped to .calva/output-window/output.calva-repl when using "calva.runCustomREPLCommand" which breaks other parts of my workflow.
• I would prefer data over strings, but that does feel a bit harder to implement
I don’t understand what this means
> my source info always gets mapped to .calva/output-window/output.calva-repl
We could consider adding modifiers for the general evaluation commands too, via key bindings. Issue welcome.
"calva.customREPLCommandSnippets": [
{
"name": "example",
"snippet": "*file*", // always .calva/output-window/output.calva-repl even when in project files
"repl": "clj"
}
],
should demonstrate the behavior I'm describingSo then when I start evaluating project code all my stack traces and logs are mapped to .calva/output-window/output.calva-repl
Ah, so that’s looks like a bug. I’ll have a look.
I'm assuming setting the file/line/column in the nrepl message would fix it, but not sure
Hmmm, thinking one more second, I think it may be a bit inherent from how we evaluate these commands. But we should be able to change that. Please file an issue.
Yup, but won't be doing my usual workflow for a while, due to the move.