Fork me on GitHub
#calva
<
2023-05-19
>
furkan3ayraktar12:05:30

Hi! The newer versions of Calva are reporting the following when I Jack-in:

Error while connecting cljs REPL: class clojure.lang.Compiler$CompilerException
As a result, I cannot use the cljs REPL. I rolled back my Calva version one by one and discovered that the REPL works as expected on version 2.0.355. Here are the related parts of the settings.json:
{...

  "calva.autoOpenJackInTerminal": true,
  "calva.autoConnectRepl": true,
  "calva.replConnectSequences": [
    {
      "projectType": "shadow-cljs",
      "name": "Start ShadowCLJS REPL",
      "autoSelectForJackIn": true,
      "projectRootPath": [
        "."
      ],
      "cljsType": "shadow-cljs",
      "menuSelections": {
        "cljsLaunchBuilds": [
          "frontend",
          "devcards",
          "test"
        ],
        "cljsDefaultBuild": "frontend"
      }
    },
    {
      "projectType": "deps.edn",
      "name": "Connect ShadowCLJS REPL",
      "autoSelectForConnect": true,
      "projectRootPath": [
        "."
      ],
      "cljsType": "shadow-cljs",
      "menuSelections": {
        "cljsDefaultBuild": "frontend"
      }
    }
  ],

...}

pez12:05:53

Note to self: That’s a very unhelpful error message…

2
pez12:05:36

In 356 we added a check for that we have a cljs runtime before Calva connects the build. (Previously the Calva UI had things look like the cljs REPL was connected even though there might not even be a cljs app running.) Obviously we need some error handling there… What shadow-cljs version are you using?

pez12:05:48

Please file an issue about this, @U2BDZ9JG3.

furkan3ayraktar12:05:19

Here is the shadow-cljs version from package.json:

"shadow-cljs": "2.20.12",

pez12:05:55

And what’s the shadow-cljs version in your deps.edn? (Assuming you are using deps: true or similar.)

furkan3ayraktar12:05:05

Hmm, no, we don’t use deps: true (yet). We define dependencies inside the shadow-cljs.edn. So, it should be using Shadow CLJS from the package.json. There is no other place in this project that we define a Shadow CLJS version.

pez13:05:34

Thanks. I’ll try to reproduce and get back to you.

🙌 2
Bruno Porto14:05:39

Hi! I am using calva in vs code, and was woundering if there is a command reload the current file together with its dependencies and nested dependencies. I can use "Load/evaluate current file" but if I make a change on a deep file, I need to go through reloading each ns in order to successfully run it on target ns. Cheers!

pez14:05:08

Hi! Calva has commands for refreshing namespaces. You should find them in the command palette. Do any of those work?

Bruno Porto14:05:26

The commands do work fine. Although I could not find a command that would reload the current file along with nested dependencies. e.g: Supose I have 3 namespaces: app.ns1; app.ns2; app.ns3 app.ns1 requires app.ns2 and app.ns2 requires app.ns3. if I make a change in app.ns3 to test something in app.ns1, I need to reload all three files in order to get the behaviour to update accordingly and test it. I was woundering if there is any command that simulates the behaviour of (require 'ns :reload-all)

pez15:05:29

You can give yourself that command pretty easily with custom repl command snippets. I’m on the run, but search http://calva.io and you should find.

Bruno Porto15:05:02

Great! Thanks!

skylize21:05:03

Actully pretty tricky to get a https://calva.io/custom-commands/ snippet to scrape the relevant data for adding :reload-all automatically to all your requires. I think I've mostly got it solved for you. But I've hit a brick wall that I think is probably a bug. Hopefully @U0ETXRFEW will have a chance to help figure out a solution. You can try out the code below if you point the symbol file-text to a string 1+ Clojure forms, with the first form being ns with the same namespace as the current file. The code evaluates that ns form after adding :reload-all to each require. Then for simplicity, it simply evaluates the whole file-text string, instead of trying to strip out the un-patched version of the ns form.

(let [update-seq-when (fn [xs pred y]
                        (map #(if (pred %) y %) xs))
      ns-form ((requiring-resolve 'clojure.edn/read-string) file-text)
      require? #(when (coll? %) (#{:require} (first %)) %)
      require-form (some require? (rest ns-form))
      deps (rest require-form)
      add-reload #(conj (vec %) :reload-all true) 
      reload-ns-form (when (pos? (count deps))
                       (->> deps
                            (map add-reload)
                            (cons :require)
                            (update-seq-when ns-form require?)))]
  (eval reload-ns-form)
  (load-string file-text))
To translate that into a snippet, I expected to be able to strip out the raw newlines, replace file-text with Calva's $file-text to get the current editor's file contents, and use that as the value for`snippet` for an entry in calva.customREPLCommandSnippets. -- settings.json --
{...

    "calva.customREPLCommandSnippets": [
        {
            "name": "Reload required deps and evaluate current namespace",
            "key": "eval-ns-reload",
            "snippet": "(let [update-seq-when (fn [xs pred y] (map #(if (pred %) y %) xs)) ns-form ((requiring-resolve 'clojure.edn/read-string) $file-text) require? #(when (coll? %) (#{:require} (first %)) %) require-form (some require? (rest ns-form)) deps (rest require-form) add-reload #(conj (vec %) :reload-all true) reload-ns-form (if-not (pos? (count deps)) ns-form (->> deps (map add-reload) (cons :require) (update-seq-when ns-form require?)))] (eval reload-ns-form)) (load-string $file-text)",
        },
    ],

...}
Unfortunately it seems that Calva does not actually inject the file contents as text for $file-text. Instead it immediately evaluates the whole file and injects whatever is returned at the end of the evaluation. Since the docs clearly state "The text of the current file edited," and not "The result of evaluating the current file," this screams "bug" to me. --- Once we get the snippet working, you can do the following for shortcuts. ( Using default shortcuts: ) • Edit the key to something shorter like rn to find it quickly in the Run Custom REPL Command menu. <`ctrl+alt+space r n enter`> • Edit the key to a single unused char like u for Calva to turn it into a key chord for you. <`ctrl+alt+space u`> • Keep the longer key value and set up you own shortcut, using that key as an arg to calva.runCustomREPLCommand. -- keybindings.json --
{...

    {
        "key": "ctrl+alt+shift+r",
        "command": "calva.runCustomREPLCommand",
        "args": "eval-ns-reload"
    }

...}

pez07:05:08

I might be misunderstanding something. I was thinking something like

{
            "key": "r",
            "name": "Require-reload current namespace",
            "snippet": "(require '$ns :reload-all)"
        }
Which I have been using myself a bit, even though I don’t often need it. If I change something in app.ns3 I evaluate that something and I can then test it from app.ns1, without any require reload.

skylize12:05:33

Using your example, If I evaluate app.ns1, then open, make changes to, save, and close app.ns3, those changes will not be reflected in app.ns1 until I explicitly eval or reload app.ns3 or restart the repl. If I understand the request correctly, this is the type of scenario of concern; and the desire is to eval app.ns1 from app.ns1 in such a way that app.ns3 is automatically reloaded because it is a transitive dependency.

pez18:05:46

Again, I might have misunderstood. But the snippet I use, and pasted above, allows for: 1. Have app.ns1 require app.ns2, which require app.ns3 2. Load app.ns1 3. Evaluate something in app.ns1 which uses something in app.ns2 which in turn uses something in app.ns3 4. Update the something in app.ns3, save the file. 5. Open the editor with app.ns1, run the snippet ctrl+alt+space r 6. Evaluate something in app.ns1 which uses something in app.ns2 which in turn uses something in app.ns3 -> updated result

skylize19:05:37

Cool. Way simpler than what I did. It never even occurred to me that requiring the current namespace into itself might work correctly.

metal 2
Bruno Porto12:05:34

Thanks a lot guys!! The combination of your answers worked perfectly! Thanks a lot!

🙏 2
popeye15:05:55

I had to switch my system from ubuntu to Windows for obvious reason 😞, How can I configure calva key setting to follow same as unix command ?

pez16:05:31

I think most keys are the same. Anything in particular you miss?

popeye16:05:16

ctrl+alt+ c and enter is not working

pez16:05:48

Does it work from the command palette? How are you starting the repl?

popeye16:05:56

ctrl +al +c and cltr +alt + j

pez17:05:26

The REPL starts and connects fine? What kind of project is it? Also 😄: > Does it work from the command palette?

popeye17:05:16

i just noticed that repl is not started properly, I am taking a look

👍 2
Bobbi Towers18:05:18

I'm curious what are the origins of the style of inline evaluation that Calva uses. I think the first time I saw it was Light Table, but was it done in Lisp editors before that? I imagine the roots go back to Smalltalk or something, but I'd like to research it a bit because I will be discussing it on a podcast 🤓

pez18:05:20

I stole it from CIDER. Could date back to some Symbolic Lisp Machine, or even earlier.

Bobbi Towers18:05:03

oh yeah, I was thinking that CIDER probably did that before Light Table

seancorfield19:05:13

Since this has come up, I often find that the inline display -- at the end of the line -- is not visible, since I do not have word wrap on and keep my editor window tightly-cropped (I hate wrapped lines, so this forces me to break code into multiple lines to keep lines reasonably short). I would love an option for Calva to show the inline display below the current line, essentially indented to match the start of the form evaluated.

seancorfield19:05:55

(It's not a really high priority most of the time since I have evaluations go through Portal middleware and into one of my two Portal windows -- I have Calva's REPL output hidden -- but there are times, when don't have the Portal middleware running, e.g., in a remote server, and so I have to try to remember to use ctrl+alt+t t or ctrl+alt+t space instead of the more muscle memory ctrl+enter or alt+enter 🙂 )

Bobbi Towers19:05:25

fwiw the evaluation result runs off screen even with word wrap