joyride

Jason Whitlark 2023-03-21T18:56:34.838549Z

Is it possible to use core.match in joyride? I’ve not found any references either way, and I’ve not gotten the hang of joyride yet.

pez 2023-03-21T19:08:38.319369Z

I don’t think so. At least it’s not included, iirc. Depending on its dependencies you might be able to use it by dropping the library on Joyride’s class path. WDYT, @borkdude ?

Jason Whitlark 2023-03-21T19:51:22.664969Z

BTW, thank you for adding rewrite-clj. Just finished working up my first script for it, and it’s a much nicer way to tweak code in the editor. In Clojure, I use core.match with rewrite-clj to select what rewrite function to call, which is why I was asking.

Jason Whitlark 2023-03-21T19:55:27.956589Z

Another thing I’m trying to figure out is how to tell if the current selection is a form, as rw-clj/of-string will only grab the first form.

pez 2023-03-21T20:04:04.455799Z

I'm super curious about your Joyride scripts!

pez 2023-03-21T20:08:33.068929Z

For checking if the selection is a form, I was about to suggest using the Calva range API to see if (currentForm) will select the same as the selection. But trying the Calva command Calva: Select Current Form with a selection tells me there's a bug there that might affect the API (I don't recall if they use the same implementation, but I think they do). However, if you call currentForm with the just the .-active position from the selection, that should work as well, right? If it selects the same thing as the selection (possibly trimmed) then the current selection is a form.

pez 2023-03-21T20:09:11.015599Z

(Not fully sure, just first thing that came to mind.)

Jason Whitlark 2023-03-21T20:14:23.181149Z

I just finished my first pass, of the first one. A little fn to help convert midje to clojure.test:

(ns port-arrow-form
  (:require ["vscode" :as vscode]
            [joyride.core :as joyride]
            [promesa.core :as p]
            [rewrite-clj.zip :as z]
            [util.editor :as e]))

(def oc (joyride.core/output-channel))
(defn log [x]
  (.appendLine oc (str x)))

(defn get-arrow-clause [zl]
  (let [lhs (z/sexpr zl)
        arrow (-> zl z/right z/string)
        rhs (-> zl z/right z/right z/sexpr)]
    [lhs arrow rhs]))

(defn main []
  (log "port-arrow-form started")
  (-> (p/let [editor ^js vscode/window.activeTextEditor
              selection (e/current-selection)
              source (str "[ " (e/current-selection-text) " ]")
              zloc (z/of-string source)
              [lhs arrow rhs] (get-arrow-clause (z/down zloc))]
        (e/delete-range! editor selection)
        (e/insert-text!+ (str `(~'is (~'= ~rhs ~lhs)))))))

(when (= (joyride/invoked-script) joyride/*file*)
  (main))

pez 2023-03-21T20:15:30.745379Z

Please feel invited to add that to the examples in the Joyride repo!

👍 1
Jason Whitlark 2023-03-21T20:16:39.285129Z

Will do! How do you feel about a page in doc/ on manipulating clj code?

👍 1
pez 2023-03-21T20:20:09.203679Z

I'd love that!

Jason Whitlark 2023-03-21T20:26:49.569189Z

Here’s a PR for the example. https://github.com/BetterThanTomorrow/joyride/pull/158

Jason Whitlark 2023-03-21T20:28:02.511829Z

If you see any blunders in the example, please let me know. I’ll start sketching out some docs.

Jason Whitlark 2023-03-21T20:29:28.766319Z

One thing I think would be handy for util.editor is a replace-selection! function. I’m never sure if I’m doing it right.

pez 2023-03-21T20:36:35.206729Z

Please add it. 😃 It probably looks very similar to insert-text!+.

Jason Whitlark 2023-03-21T20:54:15.916899Z

👍 I’ll update my PR.

Jason Whitlark 2023-03-21T21:03:44.306209Z

Hmm. I would have expected the following to work, but it seems the delete-range! isn’t being called?

(defn replace-range!
  "Defaults to the current selection."
  ([^js text]
   (replace-range! text vscode/window.activeTextEditor (.-active (current-selection))))
  ([^js text ^js editor ^js position]
   (-> (p/do (delete-range! editor position)
             (insert-text!+ text editor position))
       (p/catch (fn [e]
                  (js/console.error e))))))

pez 2023-03-21T21:06:26.101779Z

It takes a range, not a position. However, I think it is better to implement it with .replace of the text builder.

Jason Whitlark 2023-03-21T21:21:46.240919Z

👍

borkdude 2023-03-21T21:23:36.308039Z

I noticed I'm mentioned in this thread, but don't have much time to read up. Can you summarize what is important for me?

pez 2023-03-21T21:28:27.090969Z

It started with a question about using core.match with Joyride. I guess that's what we want your input on.

borkdude 2023-03-21T21:31:43.385649Z

core.match doesn't run from source in SCI, but it can be added via a config, e.g. here it is in bb: https://github.com/babashka/babashka/blob/master/feature-core-match/babashka/impl/match.clj However! The library is fairly macro rich and cause side effects when they run (if I remember correctly), so those macros also have to be copied and made CLJS-runtime compatible. If I remember correctly the core.match library doesn't run in self-hosted:

$ plk -Sdeps '{:deps {org.clojure/core.match {:mvn/version "RELEASE"}}}'
ClojureScript 1.11.60
cljs.user=> (require '[clojure.core.match :as m])
Unexpected error (ExceptionInfo) compiling at (cljs/core/match.clj:9:1).
Only [lib.ns :only (names)] and optionally `:rename {from to}` specs supported in :use / :use-macros; offending spec: [clojure.core.match :exclude [match matchv match-let matchm]] at line 9 cljs/core/match.clj

borkdude 2023-03-21T21:33:42.271589Z

I think with some effort it is doable, but not trivial. Hope that answers your question

Jason Whitlark 2023-03-21T21:40:38.957349Z

Ok. It was a nice-to-have, but not essential. My cljs is a little too weak to be up to that.

pez 2023-03-21T21:44:46.162099Z

Do we want an issue about it, @borkdude?

Jason Whitlark 2023-03-21T22:00:49.814009Z

I wouldn’t mind putting in some work on it, but I’d need a lot of guidance. I used cljs heavily for a couple of years when it first came out, and have barely touched it since.

pez 2023-03-21T22:03:33.104759Z

It will depend on that @borkdude has the bandwidth. I would be a blind leading a blind. 😃

borkdude 2023-03-21T22:05:08.462599Z

I think the starting point should be an issue on Github and to collect who else would be interested in core.match in joyride. I have added it to bb at the time (by popular request) but I haven't seen much usage of it, to be honest

👍 1
pez 2023-03-21T22:06:39.920919Z

Issue, please, @jason.whitlark. 🙏

Jason Whitlark 2023-03-21T22:22:23.934629Z

I’ve used it on occasion in bb. The stuff I’m porting to joyride was used in clj and bb, depending on the situation. Sure. Create an issue in joyride or SCI?

borkdude 2023-03-21T22:23:42.152419Z

joyride. thanks for the feedback, maybe core.match is used more than I realize

borkdude 2023-03-21T22:24:33.139339Z

as with rewrite-clj we waited a bit until we heard the request often enough to include it in joyride. it does take a bit of extra JS bundle size. eventually I want to make those things lazily loaded, but this requires some internal refactoring

borkdude 2023-03-21T22:25:31.559029Z

but feel free to also start an experimental PR and then we can see how much bundle size it actually adds.

Jason Whitlark 2023-03-21T22:37:25.430669Z

I use it quite a bit with rewrite-clj, since you just get nils when you move too far on a zipper, and it makes it clean for stuff like the following snippet (incomplete, but you get the idea):

(defn get-next-test [zl]
  (let [lhs (z/node zl)
        arrow (-> zl z/right z/string)
        rhs (-> zl z/right z/right z/node)]
    [lhs arrow rhs]))

(defn fix-fact-clause [l a r]
  (match [l a r]
    ;; Handle exceptions
    [actual '=> (['throws e (patt :guard regex?)] :seq)]  `(~'is (~'thrown-with-msg? ~e ~patt ~actual))
    [actual '=> (['throws (patt :guard regex?)] :seq)] `(~'is (~'thrown-with-msg? ~'Exception ~patt ~actual))
    [actual '=> (['throws e] :seq)] `(~'is (~'thrown? ~e  ~actual))
    ;; Handle regexes
    [actual '=> (patt :guard regex?)] `(~'is (~'re-find ~patt ~actual))
    ;; Handle predicate-fns
    [actual '=> (predicate :guard #(and (symbol? %) (= \? (-> % name last))))] `(~'is (~predicate ~actual))
    [actual '=not=> (predicate :guard #(and (symbol? %) (= \? (-> % name last))))] `(~'is (~'not (~predicate ~actual)))
    ;; Handle simple
    [actual '=> true] `(~'is ~actual)
    [actual '=> (['contains x] :seq)] (do (log :added-subcoll?) `(~'is (~'subcoll? ~x ~actual)))
    [actual '=> 'truthy] `(~'is ~actual)
    [actual '=> 'anything] `(~'is (~'anything ~actual))
    [actual '=> false] `(~'is (~'not ~actual))
    [actual '=> 'falsey] `(~'is (~'not ~actual))
    [actual '=> 0] `(~'is (~'zero? ~actual))
    [actual '=> nil] `(~'is (~'nil? ~actual))
    [actual '=> 'nil?] `(~'is (~'nil? ~actual))
    [actual '=> expected] `(~'is (~'= ~expected ~actual))
    [actual '=not=> expected] `(~'is (~'not (~'= ~expected ~actual)))
    :else  :failed-to-translate))

borkdude 2023-03-21T22:39:09.212009Z

neat!

Jason Whitlark 2023-03-21T22:41:32.723969Z

It’s really come in handy. I think of match as my DWIM function. 🙂

borkdude 2023-03-21T22:42:57.849829Z

@jason.whitlark I think adding it to sci.configs is a better idea actually, then we can re-use it anywhere we like, e.g. also in nbb https://github.com/babashka/sci.configs

borkdude 2023-03-21T22:43:30.831549Z

You can check out the other configs for examples. E.g. the js-interop one also has a couple of macros that had to be lifted from the JVM runtime to the JS runtime

borkdude 2023-03-21T22:55:03.421969Z

@jason.whitlark I moved the issue to https://github.com/babashka/sci.configs/issues/19

borkdude 2023-03-21T22:55:09.637979Z

sci.configs is a different repo

Jason Whitlark 2023-03-21T22:59:17.094309Z

Oh, ok.

Jason Whitlark 2023-03-21T23:00:15.459439Z

I sponsored you through joyride. Not sure how that all works, but I’ll put my money where my mouth is. 😉

❤️ 2
borkdude 2023-03-21T23:00:33.528299Z

thanks a lot!

Jason Whitlark 2023-03-21T23:06:54.646469Z

Happy to help. I’ve been making money off Clojure since 2010. Sponsored Rich, way back in the day. I’m glad the various funding models are evolving.

Jason Whitlark 2023-03-21T23:25:38.777539Z

Hmm. I looked at https://github.com/babashka/sci.configs/blob/main/src/sci/configs/applied_science/js_interop.cljs Not sure where to start. I’ll have to take a look at the sci docs when I get a chance. I’ve used it, but not looked under the hood since the beginning.

Jason Whitlark 2023-03-21T23:29:35.479349Z

@pez, the readme link points to src, but it’s now in scripts. Want another PR, or do you want to just tweak it?

pez 2023-03-21T23:39:16.955099Z

I’ll fix it tomorrow. Thanks for heads-up!

Jason Whitlark 2023-03-21T23:42:56.311999Z

👍

pez 2023-03-21T22:01:47.736899Z

The Joyride CI pipeline doesn't run... Circle CI says:

Could not find a usable config.yml, you may have revoked the CircleCI OAuth app.
Please sign out of CircleCI and log back in with your VCS before triggering a new pipeline.
I've tried sign out and sign in again with my Github account. But it remains like this. Anyone have experience with something like that on Circle CI?

borkdude 2023-03-21T22:09:38.459639Z

Maybe a hiccup? https://status.circleci.com/

borkdude 2023-03-21T22:10:31.693429Z

you can add the circleci app to github for this repo or org, maybe that helps. I've also done this with bb etc

pez 2023-03-21T23:18:38.861119Z

Now the pipeline started to work again. Added the Circle CI Checks things to Github, but I don't think that was what you meant?

👍 1