Fork me on GitHub
#portal
<
2022-05-06
>
R.A. Porter18:05:26

I have no idea when/how/why it changed, but since I rebooted this morning I'm having a lot of trouble starting portal with the :intellij launcher. Reporting that the intellij.edn file can't be found, and my quick-so-far scan is coming up empty as to what should be writing that file out.

1
djblue18:05:16

Any errors showing up in intellij?

R.A. Porter18:05:22

Didn't see any. I may have a janky version of the plugin from my efforts last week to help with the linux problem. I'm going to reinstall it.

🙏 1
R.A. Porter18:05:29

I see the problem. The change you made recently to delete the config file on exit - same behavior on vscode too, I believe - means that if I try to run portal on repl start before opening the tool window (after a project restart), it'll fail. Need to open the window first. It's a little less ergonomic, but not terrible.

djblue19:05:16

Feels like previously your repl init code may have been using stale connection info, so I wonder how it was working :thinking_face:

R.A. Porter19:05:44

Excellent question. :rolling_on_the_floor_laughing:

seancorfield19:05:30

@djblue I'm playing around with driving Portal via custom REPL commands in Calva and I can't figure out how to get the Portal UI to select the most recently tap>'d item...?

seancorfield19:05:46

Once an item is selected, I can expand/collapse it -- although it doesn't seem to show that item is selected unless I switch to the Portal UI window itself.

djblue20:05:23

Interesting, what do these REPL commands look like?

seancorfield20:05:51

"calva.customREPLCommandSnippets": [
      {
        "name": "Tap Last Exception",
        "key": "e",
        "snippet": "(tap> (Throwable->map *e))"
      },
      {
        "name": "Portal Clear",
        "key": "k",
        "snippet": "(portal.api/clear)"
      },
      {
        "name": "Portal First",
        "key": "1",
        "snippet": "(portal.api/eval-str \"(doto portal.ui.state/state portal.ui.commands/history-first portal.ui.commands/select-none portal.ui.commands/select-child portal.ui.commands/select-child)\")"
      },
      {
        "name": "Portal Expand",
        "key": "right",
        "snippet": "(portal.api/eval-str \"(portal.ui.commands/toggle-expand portal.ui.state/state)\")"
      },
    ]

djblue20:05:36

Do you have the result of running the eval-str?

seancorfield20:05:40

I'm trying to tap a datafied exception and then expand it 🙂

djblue20:05:30

Ohhh, I wonder if I should add a metadata flag to always expand a viewer :thinking_face:

seancorfield20:05:39

So I basically want to call toggle-expand on the most recently tap> item.

👍 1
seancorfield20:05:17

Well, being able to navigate around Portal via the ui.commands seems reasonable but I can't get it to work reliably.

djblue20:05:51

Can you open the js console within vs-code and see if the portal ui is throwing any exceptions?

djblue20:05:51

I think the vs command is Toggle Developer Tools

seancorfield20:05:41

No exceptions. I can navigate one step at a time (and focus switches to the Portal panel in VS Code). I just don't seem to be able to chain multiple ui.commands.

djblue20:05:26

Ohh, I think I know what's happening 😬 They commands are executed async

seancorfield20:05:00

Well, there's also perhaps the issue that Portal seems to lose its selection until I tab in the UI...

seancorfield20:05:20

Maybe there's a command missing to "reset" something...?

seancorfield20:05:53

Ah, I can select-none to reset things... But, yeah, I think the main issue is not being able to chain those async commands?

seancorfield20:05:59

Clover introduce a macro for its customizations to make this easier, but if there's a way to eval-str something that will either run the command sync or wait for the async command to complete...?

djblue20:05:40

Something like:

(let [state portal.ui.state/state]
  (-> (portal.ui.commands/history-first state)
      (.then #(portal.ui.commands/select-none state))
      (.then #(portal.ui.commands/select-child state))
      (.then #(portal.ui.commands/select-child state))))
Might work for now

djblue20:05:06

I'll see about adding some async macros 👌

seancorfield20:05:55

Much like Clover's p/let I suspect. OK, at least I know what to do now. Thank you!

👍 1
seancorfield20:05:09

Awesome: I have a hot key to expand/collapse the most recently tap'd value now!

djblue20:05:16

BTW I think you can require a cljs ns from your class path, something like (eval-str "(require 'my.commands)") and then eval your own fns

djblue20:05:39

Might make it easier to manager the more complex fns

seancorfield20:05:28

That would assume I have cljs on my classpath -- I don't do any cljs dev 🙂

👍 1
djblue20:05:32

Another option would be to slurp the file from a well known location :thinking_face:

seancorfield20:05:32

Yeah, but I want this self-contained so VS Code syncs the commands across multiple machines and have it work in any project.

💯 1
seancorfield20:05:49

Context: I'm looking at switching away from Clover if I can convert all of my Clover customizations into custom REPL commands for Calva and many of them rely on Portal-related stuff 🙂

👍 1
djblue22:05:21

Does calva support socket repl or have you moved to nrepl?

seancorfield23:05:44

I have, very grudgingly, moved to nREPL 😞

djblue23:05:06

Do you mind sharing why? I have moved in the other direction, from nrepl to socket.

seancorfield23:05:48

I'm getting a bit frustrated with the slow progress of Clover compared to the very fast progress of Calva, mostly.

djblue23:05:45

Yeah, the community around nrepl is much larger / active 💯

seancorfield23:05:53

Also, since we switched something up in our deployed applications which start a Socket REPL server, Clover can no longer connect to them (well, specifically, I think unrepl no longer works with them, which breaks Clover). That means that we can't retain the "same" workflow between local and remote REPLs (and I am not adding nREPL servers to those processes!) so there's less inertia for me to stay with Clover / Socket REPL server locally.

seancorfield23:05:48

I've really not spent a great deal of time learning Calva in the past because I've been using Clover for the live eval/REPL part but the lack of inline results and a number of features that Clover supports but Calva supports much better have made me yearn for the Calva UX 🙂 and that, unfortunately, means relying on nREPL and Calva's live integration. It's very frustrating for me, to be honest. I really don't want to have to use nREPL.

seancorfield23:05:22

So today, because it's been a week at work, I decided I wanted to do something "light & fluffy" as a break, so I've spent nearly all day reading the Calva docs and learning what it's really capable of (and it's impressive!) and so I've been experimenting with Calva (and nREPL) all afternoon, and switching my VS Code customizations over from Clover's config.cljs file to customREPLCommandSnippets in Calva -- hence my lower-level Portal questions 🙂

💯 1
djblue23:05:00

That makes a lot of sense. For me, I've found it easier to develop a custom REPL workflow (custom eval/test assertions output/unsupported runtimes) when using a socket repl vs nrepl middleware.

seancorfield23:05:41

Yes, I particularly dislike the middleware approach of nREPL. I prefer a simple "Here's some Clojure code, evaluate it please!" API 🙂

☝️ 1
djblue23:05:37

I think nrepl is great for a standard clj experience but everything else is a second class citizen. For my socket repl setup, I can send a piece of code from my editor directly to portal.api/eval-str, which is usually all want.

seancorfield00:05:12

You're doing cljs tho' right?

djblue00:05:43

Yeah, I connect to one socket repl which hosts eval fns for clj/cljs/portal/bb 🙌

djblue00:05:04

Also, the dispatch is custom, so I can look at filenames or any other piece of data and decide where to send it 😆

djblue00:05:41

This is probably way more than most people need, but I never have to worry about state any more since everything is written down in code

seancorfield00:05:37

For the VS Code version of Portal, would you consider adding a command to open VS Code's simple browser with a URL string? Specifically, if I (tap> (clojure.java.javadoc/javadoc-url <some-class-name>)), I'd like to be able to easily tell Portal to open that URL via the built-in browser instead of the external browser.

djblue00:05:06

What happens currently? It is opened in the default system browser?

seancorfield00:05:19

Yeah, I hear you on state... and it frustrates me that nREPL inherently assumes you want a string back (which then has to be parsed again into a data structure).

seancorfield00:05:54

If VS Code sees a string that is a URL, you can cmd-click on it (on macOS) and it opens your default web browser to that URL.

djblue00:05:22

So, instead, when you cmd click, you would rather it open in the same vscode tab?

seancorfield00:05:38

(I do a bit of clean up on the URL in the code above that)

djblue00:05:40

Does that open the URL in the same tab of the Portal UI or in another new vscode tab?

djblue00:05:16

I think preferring vs-code when opening links is reasonable, I'm just curious what you'd expect, same tab or new tab?

seancorfield00:05:08

I don't mind where it opens. I can't actually remember where it opens with Clover when I do that. I think it opens in the group where I am editing and running the eval command... but I can't confirm that now since I no longer have Clover installed 😆

👍 1
seancorfield00:05:05

I'm a bit surprised VS Code doesn't just have a setting for it... and if you invoke simple browser via the command palette, it prompts for the URL. You can open it programmatically with a specific URL.

djblue00:05:12

So I think there are two options, add a new portal viewer for urls/url-strings which open the url in an iframe, or add custom vs-code logic for opening links. I think the security sandboxing of the first is better because allowing arbitrary js to run in the context of vs-code tab could be dangerous :thinking_face:

seancorfield00:05:15

VS Code has Simple Browser built-in. That's what I want to use.

seancorfield00:05:50

If Portal had a command to hook into VS Code's executeCommand function, I'd be all set 🙂

seancorfield00:05:41

Otherwise, I might be able to do it somehow by leveraging Joyride -- but capturing the result of the Clojure execution is kind of a pain for that.

seancorfield00:05:42

(pretty sure Joyride doesn't support that javadoc-url call 🙂 )

djblue00:05:30

I'm trying to open a github url in Simple Browser, but it seems to be blocked because it's being loaded in an iframe

djblue00:05:05

So, is the new vs-code tab an important aspect for you? If not, adding an iframe url viewer would be easy and work in other environments 👌

djblue00:05:21

Sorry for all the questions, just trying to narrow down exactly what aspects are important

seancorfield00:05:48

I know Simple Browser isn't great for the general case and I don't need Portal to add URL viewing. You can do that if you want.

seancorfield00:05:37

What I want is the ability to execute commands in VS Code from Portal programmatically -- like Clover does.

1
seancorfield00:05:53

I can already spawn an external browser direct from Clojure. Don't want that 🙂

seancorfield00:05:01

I like that Simple Browser is just another VS Code tab that I can move from group to group and open/close programmatically when I want. I used it for viewing ClojureDocs too.

👍 1
seancorfield00:05:16

I like that it doesn't require any functionality in Portal -- other than the bridge to invoke executeCommand. To do this via Calva or Joyride is much more complex.

seancorfield00:05:17

And it opens up other possibilities for users of Portal since they can also use it to script VS Code in different ways.

seancorfield00:05:50

(the fact that Portal is already programmatically scriptable is the gateway drug to all of this)

djblue00:05:47

Thanks for elaborating on your expectations ❤️ Let me see what I can do 👌

djblue00:05:16

What I'm hearing is that you want a vscode command that can yank selected values from the Portal UI and apply them to other existing vs-code commands :thinking_face:

seancorfield01:05:25

Portal already has enough of an API to be able to navigate programmatically and yank those values into cljs (via eval-str style execution), yes? Or am I misunderstanding things?

seancorfield01:05:47

(sorry, stepped away to make pizza -- Friday night tradition: from scratch pizza at home)

🤤 1
djblue01:05:40

Web Cljs yes or the connected host runtime, but the extension (vscode host runtime) is the missing player

1
djblue22:05:25

I've been thinking about this a little and I'm wondering if adding a vscode command to get the currently selected value (`portal.getSelected` probably as an edn string) within the context of vscode would solve your problem? I assume you would then be able to add a joyride scripts that coordinates passing the url from portal into anything 👌

djblue22:05:31

Let me know what you think

seancorfield22:05:27

I haven't started playing with Joyride yet. It can't script Calva yet -- because Calva has no API. I haven't looked at how Joyride could get hold of and manipulate the Portal API -- but, yes, being able to pull the current selection into Joyride would work.

seancorfield22:05:34

However, it seems that if you are just tapping values into Portal, the latest value doesn't automatically become the selected one?

djblue22:05:17

I'm thinking if I can provide it as normal vscode command you should be able to execute it like any command

djblue22:05:43

No, portal doesn't auto select value by default

seancorfield22:05:50

That was part of the problem I had with the toggle expand stuff: I had to re-navigate into Portal each time to get part of the tree to be selected.

seancorfield22:05:19

So portal.getSelected doesn't help, but portal.getLatestValue or similar would work 🙂

1
djblue22:05:20

That's a good point, it shouldn't be so hard to get a hold of unselected data within portal

seancorfield22:05:21

In general, I would want selection to auto-follow the latest tap>'d value by default.

2
seancorfield01:05:21

As an update to this (very long) thread, today Calva sprouted an Extension API that makes it possible to evaluate code via its connected REPL, which means that Joyride can now take selected code from the current editor, wrap it up with some extra code, submit it to the connected REPL for evaluation, get the result back (as a string), decode it as EDN to get a Clojure/Script value or data structure, and then use that to interact with VS Code -- so I now have the ability to open Simple Browser in VS Code via Joyride, using the result of evaluating arbitrary Clojure code via Calva! Being able to pull the selected and/or latest values out of Portal via the API becomes even more usable at this point since they could be retrieved via Joyride and reprocessed in arbitrary ways via Calva's connected REPL, to be tap>'d back into Portal in new ways 🙂

💯 3
seancorfield01:05:21

As an update to this (very long) thread, today Calva sprouted an Extension API that makes it possible to evaluate code via its connected REPL, which means that Joyride can now take selected code from the current editor, wrap it up with some extra code, submit it to the connected REPL for evaluation, get the result back (as a string), decode it as EDN to get a Clojure/Script value or data structure, and then use that to interact with VS Code -- so I now have the ability to open Simple Browser in VS Code via Joyride, using the result of evaluating arbitrary Clojure code via Calva! Being able to pull the selected and/or latest values out of Portal via the API becomes even more usable at this point since they could be retrieved via Joyride and reprocessed in arbitrary ways via Calva's connected REPL, to be tap>'d back into Portal in new ways 🙂

💯 3