Fork me on GitHub
#calva
<
2021-07-27
>
otwieracz09:07:43

Hey! Is there any support for Typed Clojure in Calva/VSCode?

pez09:07:44

Not in Calva. Probably not in clojure-lsp either, but I am not sure.

otwieracz09:07:24

OK. Thanks for letting me know!

borkdude10:07:32

@pez @viesti made a cool project here: https://github.com/viesti/nrepl-cljs-sci it allows you to connect to a running node process and then evaluate stuff from an nREPL client

borkdude10:07:47

we are trying to come up with a killer use case... ;)

borkdude10:07:18

perhaps if Calva included it (theoretically, just brainstorming), one could connect to the Calva editor plugin through a (remote) nREPL client and ... do stuff!

pez10:08:59

Now back at the computer for some hours. Thinking I should maybe experiment with this idea a bit.

borkdude10:08:46

That's probably the right thing to do for now: experiment, but don't use in production yet, just to get some ideas :)

pez10:08:04

First try: I can start the server, connect to it, and evaluate expressions. However, app/app can’t be resolved…

borkdude10:08:04

what is app/app?

pez10:08:27

It’s the object you initialize the nrepl server with. https://github.com/viesti/nrepl-cljs-sci/blob/main/example/js/index.js

borkdude10:08:48

js/app probably?

borkdude10:08:59

or js/app.app depending on stuff

borkdude10:08:16

depends on how this JS is compiled

viesti10:08:22

should be app/app, exposed it with sci :classes environment

pez10:08:23

That resolves to nil

pez10:08:06

Anything js/… resolves to nil actually.

borkdude10:08:28

what about js/process for example?

viesti10:08:28

js/process should work

pez10:08:09

Another thing, @viesti. The .nrepl-port file can’t be created in the execution context of Calva. It’s a read-only file system.

pez10:08:03

Yes, js/process resolves to something.

viesti10:08:33

I have to check if there's actually a bug in the npm package if app/app isn't resolved

viesti10:08:43

but the idea was that you could expose a JS object to the nrepl server

viesti10:08:00

since exposing stuff in JS doesn't quite work like namespaces in Clojure 🙂

pez10:08:02

Indeed. I am trying with exposing the Calva extension context. And could expose lots of yummy stuff probably. 😃

pez10:08:32

Can I find the app object via process?

borkdude10:08:04

I think you should be able to find app via js if it's exposed on the global object

pez11:08:00

Yeah, maybe it is being mangled by the compiler somehow…

viesti11:08:26

so start-server takes a opts map/object and if it contains a "app" property (or a Clojure keyword), it's exposed under a namespace "app" under the var "app"

borkdude11:08:27

@viesti it might be better if you added #js {:app app} to goog/global

borkdude11:08:34

and then you can access it via js/app.app

viesti11:08:46

should make a note of that 🙂

pez11:08:33

Is there a way we can have just js/app for this?

viesti11:08:09

but funny that app/app worked at some point for me 😄

pez11:08:18

I mean without the extra .app

borkdude11:08:21

then just add like (set! (.-app goog/global) app)

viesti11:08:42

true, that would be neater

viesti11:08:12

so could run that in server-start

viesti11:08:20

bang it to the global

viesti11:08:42

have to work now on some other stuff, can look at this later 🙂

borkdude11:08:57

it doesn't even have to happen in server start, since the object remains the same object

pez11:08:03

Let me know when I can continue my experiments. 😃 I’m thinking that in the longer run maybe Calva should have both this server and a client session to it. Then both the app being developed and Calva would be in the control of the developer. No idea why that would be good but seems cool.

🆒 3
viesti14:08:01

pushed 0.0.12, hopefully with js/app

viesti14:08:06

So a

var nrepl_server = nrepl.start_server(
  {
    // Pass reference to application with the 'app' key
    app: {
      express_app: app,
      root: root
    }
  });
should show up as
user> js/app
#js {:app #js {:express_app #object[app], :root #js {:response "Hello World!"}}}
and you can bang on the stuff exposed
(set! (.. js/app -app -root -response) "Hello SCI!")

pez16:08:24

Now I get this weird error when evaluating js/app: > [betterthantomorrow.calva]: Proposed API is only available when running out of dev or with the following command line switch: --enable-proposed-api betterthantomorrow.calva

3
pez16:08:30

Also noticed that I can’t connect with lein repl :connect, but Calva can connect, as well as clojure .

viesti17:08:36

hmm, google gives https://github.com/microsoft/vscode/issues/102170, but not sure if it's related. lein repl connect tries to read nrepl port file, if port / host isn't specified

viesti17:08:20

maybe I should try connecting with calva too :)

viesti17:08:46

maybe the error is about trying to print the object that was passed to nrepl.start_server() ?

pez17:08:47

I really don’t understand why this error happens. It’s beyond weird. I’ll test your idea now…

pez17:08:58

Indeed! If I initialize like so:

function startNReplServer(context: vscode.ExtensionContext) {
    const nrepl = require('nrepl-cljs-sci');
    return nrepl.start_server(
        {
            // Pass reference to application with the 'app' key
            app: {
                foo: "bar"
            }
        });
}
js/app evaluates to :
#js {:app #js {:foo "bar"}}

viesti17:08:05

so maybe something in the JS object printing trips things

viesti17:08:42

I have no good idea what actually 🙂

viesti17:08:13

but got also something similar with js/process.env to print out environment variables

viesti17:08:34

maybe a (js/Object.keys (.-<key with the thing that makes printing hard> js/app)) could provide a more safe peek 😄

pez17:08:38

I can print js/process.env using

(-> js/process.env
    js/JSON.stringify
    js/JSON.parse)

pez17:08:06

However, if I try that with the extension context I get Converting circular structure to JSON, which might or might not be the real issue. 😃

pez17:08:22

I’ll play more with this later. Now need to feed the family. 😃

viesti18:08:38

ran into https://www.npmjs.com/package/flatted from https://www.educative.io/edpresso/what-is-typeerror-converting-circular-structure-to-json, it can be used like this:

user> (require '["flatted" :as flatted])
nil
user> (-> js/app
          flatted/stringify
          flatted/parse)
#js {:app #js {:root #js {:response "Hello World!"}}}

;; alternatively call js/require and interop with the result
user> (def flatted (js/require "flatted"))
#'user/flatted
user> (->> js/app
           (.stringify flatted)
           (.parse flatted))
#js {:app #js {:root #js {:response "Hello World!"}}}
that seems to leave out the problematic object totally (at least in the express example), but maybe could be used to narrow to what causes the issue, maybe by looking into each top-level key in the object passed into the nrepl server separately. I guess other option is to traverse the object passed to nrepl server, peek out things from there that you know should exist, until you find something that isn't a circular object graph :)

pez18:08:12

I’m still expected to access the object using js/app.app right?

pez20:08:01

I can print all things from the interface implemented by the extension context…

pez20:08:57

Also, I can do

(js/console.log js/app.app)
Which logs the context object and doesn’t show any members of it that are not part of the interface.

pez20:08:20

Printing the context object isn’t important, really. It just needs to be exposed in order for us to do interesting stuff with Calva and its environment.

viesti05:08:23

yeah, js/app.app should work, I guess I'm not that familiar with JS interop forms since even this works 😄

js/app.app.root.response
"Hello World!"

viesti05:08:42

maybe "app" might not have been the best name to pick, for the global and for the key/property in the object that start_server accepts :)

viesti05:08:04

but yeah, you should be able to do all sort of interop with object tucked to js/app.app 🙂

pez08:08:31

The second .app seems unnecessary. 😃

viesti15:08:51

Right, seems that wrapping with #js isn't actually needed (js macro would need a literal map/vector to wrap the thing), so just doing (set! (.-app js/goog.global) app) now, so things are more simple:

user> js/app
#js {:express_app #object[app], :root #js {:response "Hello World!"}}
user> (set! (.-response js/app.root) "Hello SCI!")
nil

viesti15:08:04

pushed that in 0.0.13

viesti11:07:59

yeah, was surprised how well this hacking session on nrepl-cljs-sci went, trying to make more of JS interop work better and I'm welcome for killer app ideas ;)

pez11:07:46

I've seen some activity around this, but haven't made sense of it yet. I'll check it out some when I'm by the computer. Sounds awesome!

introom12:07:41

What’s the difference between connecting to a repl IN and NOT IN a project?

pez13:07:16

That's a good question. We should find better names for those. IN project means that Calva will look for project and nrepl-port files in the current workspace/folder. With the other option you only provide ip and port for the seever.

introom14:07:36

If Calva is not connected to a repl, then are all the functionalities are provided (indirected) by lsp?

pez15:07:10

It is a mix of Calva's and clojure-lsp's static services.

introom14:07:14

I am seeing the command not found error. While starting vscode from terminal might fix the problem. I wonder, if the /bin/sh in the snapshot is hardcoded by Calva or not. Maybe I could change it to my own shell (fish) to bypass the environment variable issue.

introom14:07:43

I am using =asdf= to mange npm and other stuff. So the executables are not in some standard /usr/local/bin directories.

pez15:07:42

I start vscode from the terminal to give it the environment i need.

introom15:07:41

Can we change /bin/sh to another shell?

pez16:07:55

Vscode has settings for that.

introom16:07:53

I played with integrated and automation shell with no success. Dunno if /bin/sh is something enforced by Calva.

pez17:07:18

Have you tried starting vscode from a terminal where npx is in the path?

pez17:07:14

I'm not by a computer and don't remember if we spawn a shell.

introom14:07:58

Starting by terminal works fine for me.

introom16:07:03

I am having difficulty in using replConnectSequences to simplify connecting to an already running shadowcljs repl. Below is my configure:`

{
    "calva.replConnectSequences": [
        { 
            "name": "my app shadow-cljs",
            "projectType": "shadow-cljs",
            "cljsType": {
                "dependsOn": "shadow-cljs",
                "buildsRequired": true,
                "isStarted": true,
                "connectCode": "(shadow.cljs.devtools.api/nrepl-select %BUILD%)",
                // this works
                // "connectCode": "(shadow.cljs.devtools.api/nrepl-select :mobile)",
                "isConnectedRegExp": "To quit, type: :cljs/quit",
            },
            "menuSelections": {
                "cljsDefaultBuild": ":mobile",
            }
        },
    ]
}
I cannot replace the %BUILD% with the :mobile build target. The err output is:
clj꞉shadow.user꞉> 
; Creating cljs repl session...
; Connecting cljs repl: coinguard shadow-cljs...
;   The Calva Connection Log might have more connection progress information.
; Execution error (AssertionError) at shadow.cljs.devtools.api/get-worker (api.clj:54).
Assert failed: (keyword? id)
; Error while connecting cljs REPL: TypeError: Cannot read property 'search' of undefined

introom16:07:43

It would be preferable if I could see exactly what commands Calva is executing.

pez17:07:59

Try with cljstype "shadow-cljs", and w/o the colon before the default build.

introom14:07:11

Can we skip the prompt for localhost:xxx? It already populates the correct address. No need to press another enter key.

pez15:07:19

It’s not supported currently. Issue and PR welcome.

dabrazhe21:07:52

How can I access the calva's "dev console" to see error messages?

bringe03:07:13

In VSCode's menu, you can go to Help -> Toggle Developer Tools -> Console tab.

fubar22:07:30

Is there a way to disable the VS Code vim extension just when you have Clojure files open, so that it doesn’t interfere with Calva?

bringe03:07:03

There may be a way to do this with VS Code settings, but I'm not sure. Also, if you haven't read this already, it may be helpful: https://calva.io/vim/