calva

James Pratt 2025-04-07T10:23:19.569479Z

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]"]}}}

James Pratt 2025-04-08T10:39:50.426999Z

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꞉> 

mikejcusack 2026-05-05T22:41:45.494469Z

@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!

1
mikejcusack 2026-05-05T22:45:22.851099Z

@pez Thanks for making that a simple config to add extra middleware instead of needing to override the entire command

🙏 1
James Pratt 2025-04-07T10:24:10.213599Z

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.

James Pratt 2025-04-07T10:25:31.456399Z

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

James Pratt 2025-04-07T10:32:48.884419Z

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꞉> 

James Pratt 2025-04-07T10:34:05.165269Z

I presume the command line switches defualt for calva jack in are overridden by what's in my alias??

pez 2025-04-07T10:52:20.732139Z

Calva runs the command you see there. So not overriding main args, if I understand correctly.

James Pratt 2025-04-07T10:58:18.337179Z

I see this when jacking in so I assumed that calva would respect the overrides in my aliases.

pez 2025-04-07T11:20:01.971599Z

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.

pez 2025-04-07T11:22:54.091289Z

The Calva aliases menu includes two aliases that I don’t see in the deps.edn. Have you provided them via myAliases config?

James Pratt 2025-04-07T11:24:04.905249Z

I didn't post all my aliases in deps.edn above. I am only selecting the portal-wrap-nrepl one.

James Pratt 2025-04-07T11:33:57.940699Z

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

James Pratt 2025-04-07T11:35:07.807799Z

I pinged @djblue perhaps he can easily see what is the problem.

pez 2025-04-07T13:33:20.472389Z

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. 😃

❤️ 1
James Pratt 2025-04-07T15:15:04.361639Z

Thanks so much for your help @pez. Much appreciated!!

djblue 2025-04-07T17:05:31.384599Z

https://github.com/djblue/portal/blob/master/.vscode/settings.json#L53-L75 is how I setup a portal repl using the nrepl middleware

🙏 2
James Pratt 2025-04-07T18:15:45.742359Z

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)

djblue 2025-04-07T19:22:46.590649Z

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 .

👍 1
❤️ 1
pez 2025-04-07T20:17:10.377329Z

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 @seancorfieldDocs: https://deploy-preview-2769--calva-docs.netlify.app/custom-commands/#interpolationsubstitution-modifiersGrab latest VSIX here: https://app.circleci.com/pipelines/github/BetterThanTomorrow/calva?branch=custom-snippet-variable-interpolation

3
🙏🏻 1
pez 2025-04-08T16:27:50.881439Z

Latest 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?

2025-04-08T19:42:28.925409Z

I tried it out, works great.

🙏 1
pez 2025-04-08T20:00:44.543589Z

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!

seancorfield 2025-04-09T02:57:25.741879Z

That likely won't happen until I'm back with my "big" computer instead of my laptop, maybe the 12th or later.

seancorfield 2025-04-09T02:57:45.964529Z

(and I'm not interested in testing snitch, at this point anyway)

pez 2025-04-09T06:03:09.009469Z

I just want to make more sure we’re not breaking any existing use.

pez 2025-04-10T15:33:31.136989Z

I just released these changes, @seancorfield. So no stress to get to your big computer because of this. 😃

👍🏻 1
djblue 2025-04-07T20:36:57.603069Z

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

🙏 1
pez 2025-04-07T20:42:22.543219Z

I don’t understand what this means > my source info always gets mapped to .calva/output-window/output.calva-repl

pez 2025-04-07T20:46:10.418659Z

We could consider adding modifiers for the general evaluation commands too, via key bindings. Issue welcome.

djblue 2025-04-07T20:51:31.560349Z

"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 describing

djblue 2025-04-07T20:52:50.554269Z

So then when I start evaluating project code all my stack traces and logs are mapped to .calva/output-window/output.calva-repl

pez 2025-04-07T21:04:50.221719Z

Ah, so that’s looks like a bug. I’ll have a look.

djblue 2025-04-07T21:05:36.768829Z

I'm assuming setting the file/line/column in the nrepl message would fix it, but not sure

pez 2025-04-07T21:06:30.742209Z

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.

👍 1
seancorfield 2025-04-09T12:49:23.767579Z

Yup, but won't be doing my usual workflow for a while, due to the move.

👍 1