This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-07-27
Channels
- # announcements (3)
- # babashka (16)
- # beginners (177)
- # calva (102)
- # cider (2)
- # clj-kondo (12)
- # clojars (10)
- # clojure (91)
- # clojure-argentina (3)
- # clojure-australia (5)
- # clojure-europe (16)
- # clojure-nl (1)
- # clojure-uk (10)
- # clojurescript (73)
- # community-development (8)
- # cursive (9)
- # depstar (7)
- # fulcro (5)
- # helix (1)
- # introduce-yourself (1)
- # jobs-discuss (18)
- # lsp (32)
- # luminus (1)
- # malli (2)
- # music (4)
- # off-topic (20)
- # pathom (19)
- # polylith (15)
- # re-frame (4)
- # reagent (6)
- # ring (13)
- # sci (36)
- # shadow-cljs (7)
- # spacemacs (4)
- # sql (3)
- # tools-deps (112)
- # vim (21)
@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
perhaps if Calva included it (theoretically, just brainstorming), one could connect to the Calva editor plugin through a (remote) nREPL client and ... do stuff!
Now back at the computer for some hours. Thinking I should maybe experiment with this idea a bit.
That's probably the right thing to do for now: experiment, but don't use in production yet, just to get some ideas :)
First try: I can start the server, connect to it, and evaluate expressions. However, app/app
can’t be resolved…
It’s the object you initialize the nrepl server with. https://github.com/viesti/nrepl-cljs-sci/blob/main/example/js/index.js
Another thing, @viesti. The .nrepl-port
file can’t be created in the execution context of Calva. It’s a read-only file system.
I have to check if there's actually a bug in the npm package if app/app isn't resolved
Indeed. I am trying with exposing the Calva extension context. And could expose lots of yummy stuff probably. 😃
borkdude might be scared by the path I took 😄 https://github.com/viesti/nrepl-cljs-sci/blob/main/src/nrepl_cljs_sci/core.cljs#L188
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"
yes, that way, made a note: https://github.com/viesti/nrepl-cljs-sci/issues/4
it doesn't even have to happen in server start, since the object remains the same object
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.
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!")
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
Also noticed that I can’t connect with lein repl :connect
, but Calva can connect, as well as clojure
.
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
maybe the error is about trying to print the object that was passed to nrepl.start_server()
?
I really don’t understand why this error happens. It’s beyond weird. I’ll test your idea now…
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"}}
I think I saw a js-keys
snipplet somewhere, https://stackoverflow.com/questions/32467299/clojurescript-convert-arbitrary-javascript-object-to-clojure-script-map/32583549#32583549, via https://clojurians.slack.com/archives/C029PTWD3HR/p1627732660026800?thread_ts=1627729706.016900&cid=C029PTWD3HR
maybe a (js/Object.keys (.-<key with the thing that makes printing hard> js/app))
could provide a more safe peek 😄
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. 😃
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 :)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.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.
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!"
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 :)
but yeah, you should be able to do all sort of interop with object tucked to js/app.app 🙂
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
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 ;)
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!
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.
If Calva is not connected to a repl, then are all the functionalities are provided (indirected) by lsp?
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.
I am using =asdf= to mange npm and other stuff. So the executables are not in some standard /usr/local/bin directories.
I played with integrated and automation shell with no success. Dunno if /bin/sh is something enforced by Calva.
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
Can we skip the prompt for localhost:xxx? It already populates the correct address. No need to press another enter key.
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?
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/