This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-06-01
Channels
- # announcements (7)
- # babashka (72)
- # beginners (62)
- # biff (1)
- # calva (9)
- # cider (8)
- # clj-kondo (35)
- # clj-otel (8)
- # cljsrn (11)
- # clojure (98)
- # clojure-europe (25)
- # clojure-germany (1)
- # clojure-norway (9)
- # clojure-uk (2)
- # clojured (3)
- # clojurescript (12)
- # conjure (3)
- # core-logic (4)
- # cursive (18)
- # datalevin (9)
- # datomic (5)
- # defnpodcast (2)
- # exercism (1)
- # graalvm (5)
- # gratitude (6)
- # hyperfiddle (3)
- # interop (12)
- # jobs (1)
- # joyride (34)
- # lsp (22)
- # meander (14)
- # missionary (16)
- # nbb (88)
- # off-topic (4)
- # pathom (20)
- # podcasts-discuss (1)
- # polylith (13)
- # portal (10)
- # re-frame (6)
- # releases (2)
- # remote-jobs (2)
- # rewrite-clj (3)
- # shadow-cljs (3)
- # spacemacs (6)
- # vim (24)
My first attempt to lazy load Calva in user space failed: https://clojurians.slack.com/archives/C03S1KBA2/p1654070707175239
This is what I tried with:
(defn- my-main []
(println "Hello World, from my-main in user activate.cljs script")
(clear-disposables!)
(-> (vscode/extensions.getExtension "betterthantomorrow.calva")
(.activate)
(p/then (fn [_api]
(.appendLine (joyride/output-channel) "Calva activated. Requiring dependent namespaces.")
(require '[my-lib]) ; See this script for why we require it
(require '[z-joylib.clojure-symbols :as clojure-symbols])
(push-disposable (clojure-symbols/register-provider!))))
(p/catch (fn [error]
(vscode/window.showErrorMessage (str "Requiring Calva failed: " error))))))
So, I got my answers to this here: https://clojurians.slack.com/archives/C03S1KBA2/p1654070707175239 and the code now looks like so:
(defn- my-main []
(println "Hello World, from my-main in user_activate.cljs script")
(clear-disposables!) ;; Any disposables add with `push-disposable!`
;; will be cleared now. You can push them anew.
;;; MARK require VS Code extensions
;; In an activation.cljs script it can't be guaranteed that a
;; particular extension is active, so we can't safely `(:require ..)`
;; in the `ns` form. Here's what you can do instead, using Calva
;; as the example. To try it for real, copy the example scripts from:
;;
;; Then un-ignore the forms in the promise handler and run
;; *Joyride; Run User Script* -> activate.cljs
;; (Or reload the VS Code window.)
(-> (vscode/extensions.getExtension "betterthantomorrow.calva")
;; Force the Calva extension to activate
(.activate)
;; The promise will resolve with the extension's API as the result
(p/then (fn [_api]
(.appendLine (joyride/output-channel) "Calva activated. Requiring dependent namespaces.")
;; In `my-lib` and `z-joylib.calva-api` the Calva extension
;; is required, which will work fine since now Calva is active.
(require '[my-lib])
#_(require '[z-joylib.calva-api])
;; Code in your keybindings can now use the `my-lib` and/or
;; `z-joylib.calva-api` namespace(s)
;; Registering a symbols provider
(require '[z-joylib.clojure-symbols :as clojure-symbols])
;; Entering the Gilardi scenario.
(push-disposable! ((resolve 'clojure-symbols/register-provider!)))))
(p/catch (fn [error]
(vscode/window.showErrorMessage (str "Requiring Calva failed: " error))))))
Where the relevant part is (push-disposable! ((resolve 'clojure-symbols/register-provider!)))
.
@borkdude, you said this will stop working once we have ❤️ sci-async ❤️ in place. Is there a way I can prepare this script for that future, or is it something I need to wait with doing?When a user has a script with the same name in both workspace and user areas. They will write to the same namespace, won't they? This will currently always happen with the activate.cljs
scripts, right?
I guess what I want to do is write something in the docs about it. But first I need to understand the implications a bit better. For instance, right now I have a (defonce !db (atom {:disposables []}))
in both my activate.cljs
files. I'm struggling a bit with figuring out if this is a problem.
Yes, we discussed that before, it's a classpath: user:workspace But if you load both files explicitly (as happens with activation.cljs), then those namespaces will be "merged", as in, side effects will happen in the same namespace
So if user/activation.cljs
has (ns foo)
and project/activation.cljs
also has (ns foo)
, and you have vars with the same name, this will conflict
In this !db
case it will become a problem.
1. User activate.cljs
loads and pushes some disposables and swaps them into the db.
2. Workspace activate.cljs
does the same. Swapping into the same db.
3. The user reloads one of these. All disposables are cleared. Only one set of disposables are re-created.
So the user needs to use different names for these, right?
Yes, it's safest to require
unique namespace names from our activation.cljs scripts, I think
Yes. That doesn't matter, but your !db
var has to live in a unique namespace to not conflict
Oh, wow. Using clojure-lsp refactor-rename on the !db
symbol in my workspace activate script to !workspace-db
renamed it in my user activate script as well.
For now the naming scheme you suggest would solve this. But as soon as we fix the problem with allowing joyride to work for all projects in the VS Code window...
Dear Joyriders. Please note that the change in v0.0.15 means you'll need to copy any custom things you might have in your current activate.cljs
scripts over to user_activate.cljs
and/or workspace_activate.cljs
. Please also note that the user_activate.cljs
file will again be auto-created for you. The silver lining here is that it is a more useful activation script skeleton, with facilities for registering VS Code disposables in a REPL reloadable manner. It also has a recipe for safely requiring VS Code extensions, and you should start using that instead of any non-lazy requiring you might be doing today
Dear Joyriders. Please note that the change in v0.0.15 means you'll need to copy any custom things you might have in your current activate.cljs
scripts over to user_activate.cljs
and/or workspace_activate.cljs
. Please also note that the user_activate.cljs
file will again be auto-created for you. The silver lining here is that it is a more useful activation script skeleton, with facilities for registering VS Code disposables in a REPL reloadable manner. It also has a recipe for safely requiring VS Code extensions, and you should start using that instead of any non-lazy requiring you might be doing today
Joyride friends: in Clover, I expose multiple APIs that expect or return EDN. I'm currently translating them to JS, but it can be tricky: for example, one API is (eval-and-present <text> <range>)
. The range, in this case, is #js [ #js [1 2] #js [1 3]]
, for example - it's quite hard to write and we have to remember to use #js
before, or use clj->js
.
Maybe this is also an SCI version, but maybe there's a way to make this conversion either semi-automatic, or at least somehow on ClojureScript side I can detect that it was a "SCI Vector" and convert back to JS... WDYT? I know all of the problems that SCI needs to face (advanced compilation renaming the methods, etc) but I don't know, maybe there's some way to at least preserve some method name that I can call on Clover side... :thinking_face:
@mauricio.szabo Do you mean, you would call an extension function on joyride to convert to JS?
Or expose this to the objects that come from Joyride side
Sure - this is what happens right now: https://gitlab.com/clj-editors/clover/-/blob/master/src/clover/joyride.cljs#L20-25
All code that expects parameters from Joyride call norm-range
, that basically checks if the object is what we expect (a Javascript array of arrays) and if it's not, it will simply ignore the parameter and prepare a default value.
So if users want to call your extension function, then they would have to convert to JS, is that what you mean?
I wanted to check if I detect that the object is not a Javascript array of arrays, if I could convert it to JS - that way, people could call my extension with (do-something "a-text" [[1 1] [1 2]])
, without needing to convert the second parameter
That probably doesn't work since your extension is compiled in a different project than joyride
On my extension side I could use something like (if-let [as-js-obj (.-as_js_object param)) ...
I think it's not unreasonable to expect that users should call extension functions using JS types
So, I got my answers to this here: https://clojurians.slack.com/archives/C03S1KBA2/p1654070707175239 and the code now looks like so:
(defn- my-main []
(println "Hello World, from my-main in user_activate.cljs script")
(clear-disposables!) ;; Any disposables add with `push-disposable!`
;; will be cleared now. You can push them anew.
;;; MARK require VS Code extensions
;; In an activation.cljs script it can't be guaranteed that a
;; particular extension is active, so we can't safely `(:require ..)`
;; in the `ns` form. Here's what you can do instead, using Calva
;; as the example. To try it for real, copy the example scripts from:
;;
;; Then un-ignore the forms in the promise handler and run
;; *Joyride; Run User Script* -> activate.cljs
;; (Or reload the VS Code window.)
(-> (vscode/extensions.getExtension "betterthantomorrow.calva")
;; Force the Calva extension to activate
(.activate)
;; The promise will resolve with the extension's API as the result
(p/then (fn [_api]
(.appendLine (joyride/output-channel) "Calva activated. Requiring dependent namespaces.")
;; In `my-lib` and `z-joylib.calva-api` the Calva extension
;; is required, which will work fine since now Calva is active.
(require '[my-lib])
#_(require '[z-joylib.calva-api])
;; Code in your keybindings can now use the `my-lib` and/or
;; `z-joylib.calva-api` namespace(s)
;; Registering a symbols provider
(require '[z-joylib.clojure-symbols :as clojure-symbols])
;; Entering the Gilardi scenario.
(push-disposable! ((resolve 'clojure-symbols/register-provider!)))))
(p/catch (fn [error]
(vscode/window.showErrorMessage (str "Requiring Calva failed: " error))))))
Where the relevant part is (push-disposable! ((resolve 'clojure-symbols/register-provider!)))
.
@borkdude, you said this will stop working once we have ❤️ sci-async ❤️ in place. Is there a way I can prepare this script for that future, or is it something I need to wait with doing?