Fork me on GitHub
#portal
<
2021-10-08
>
seancorfield18:10:38

@djblue How's the VS Code work coming along? Any early .vsix files for eager pre-alpha testers to try out? 🙂

djblue18:10:43

Pretty close to being done. I've been trying to get the syntax colors but I guess those aren't available to extensions 😭

djblue18:10:23

I can share the 0.16.0 jar/vsix here if you would like to try it out 👌

djblue18:10:38

To avoid some confusion: The vscode extension mainly acts as a launcher so you only have to have it installed, there aren't any commands you run from within vscode

djblue18:10:34

(portal.api/open {:launcher :vs-code})

djblue18:10:18

For a fun feature preview, try using the new keyboard shortcut g d on a selected var 😏

seancorfield19:10:59

But it runs as a view inside VS Code?

👍 1
djblue19:10:23

Yup, it should launch inside of vs-code

seancorfield22:10:18

Finally got around to actually trying it -- AWESOME!!!

seancorfield22:10:43

I've added a task to my (Clover) config that launches Portal inside VS Code and bound it to ctrl-; shift-p and I'm off to the races! 🙂

yes 1
seancorfield22:10:19

My own customizations no longer seem to work (that were messing with those internal hash maps of functions) -- I guess that's been changed now and I need to customize it a different way?

seancorfield22:10:31

OK, figured that out and updated my setup.

seancorfield22:10:55

go to definition 🙂 very nice!

seancorfield23:10:07

Seems like the webview panel inside VS Code isn't a full browser, in terms of CSS rendering? When I slurp a Java doc URL and view as HTML, it's pretty much an unstyled HTML page. Still usable, but not as clean as viewing docs in a browser.

djblue23:10:54

I was going to add a portal.api/register! fn

djblue23:10:08

So the barrier to entry is basically just any clj/s var

djblue23:10:14

I'll look into the webview issue 👌

seancorfield00:10:13

Cool. I'm just calling portal.runtime/register! right now but will switch to an API version once it's there. It's working really nicely for me. Once 0.16.0 is on Clojars, I'll publish my updated dot-clojure and vscode-clover-setup.

👍 1
seancorfield00:10:42

Here's what I have in Clover's config.cljs:

(defn portal-start []
  (p/let [here (editor/get-selection)]
    (editor/eval-and-render
     (assoc here :text
            (str "(do"
                 " (in-ns 'dev)"
                 " (def portal"
                 "  ((requiring-resolve 'portal.api/open)"
                 "   {:launcher :vs-code}))"
                 " (install-portal-extras)"
                 " (add-tap (requiring-resolve 'portal.api/submit)))")))))

(defn portal-clear []
  (p/let [here (editor/get-selection)]
    (editor/eval-and-render (assoc here :text "(portal.api/clear)"))))
and here's my key bindings for that
{
        "key": "ctrl+; shift+k",
        "command": "workbench.action.tasks.runTask",
        "args": "Clover: Portal clear"
    },
    {
        "key": "ctrl+; shift+P",
        "command": "workbench.action.tasks.runTask",
        "args": "Clover: Portal start"
    },
and the dev/install-portal-extras is
(defn- install-portal-extras
  []
  (try
    (let [r!   (requiring-resolve 'portal.runtime/register!)
          html (fn [url]
                 (with-meta
                   [:div
                    {:style {:background :white}}
                    [:portal.viewer/html (slurp url)]]
                   {:portal.viewer/default :portal.viewer/hiccup}))]
      ;; install extra functions:
      (run! (fn [[k f]] (r! f {:name k}))
            {'dev/->file   (requiring-resolve ')
             'dev/->html   html
             'dev/->map    (partial into {})
             'dev/->set    (partial into #{})
             'dev/->vector (partial into [])}))
    (catch Throwable _)))

seancorfield00:10:54

I originally had :portal.launcher/window-title (System/getProperty "user.dir") in the open invocation which works great for the Chrome browser version but seems to prevent the VS Code panel from opening? Is there a way to set the Portal tab name in VS Code? Or could it just ignore options that don't work?

djblue17:10:05

Interesting, I'm able to use :portal.launcher/window-title (System/getProperty "user.dir") without issue :thinking_face:

seancorfield22:10:21

OK, I'll try that again.

👍 1
seancorfield22:10:03

OK, it was an unrelated issue: if I open a workspace in VS Code rather than just a project, the launcher doesn't open.

seancorfield22:10:33

So something like code . then connect to a REPL then portal.api/open -- that works.

seancorfield22:10:02

But code some.code-workspace then connect to the same REPL then portal.api/open -- nothing happens.

seancorfield22:10:26

I don't have a workspace that has just one folder (project). All my workspaces have multiple projects (folders). So that seems to be confusing the VS Code launcher. If I run the regular launcher, it works, and I get a browser window.

seancorfield22:10:56

Yeah, I can reproduce that reliably. code some.code-workspace can open a regular (Chrome) Portal window but cannot open a VS Code window. The code "runs" but doesn't open a window.

seancorfield22:10:21

portal.api/open returns #portal.runtime.jvm.client.Portal {:session-id #uuid "9807ae4d-5d75-489f-816f-2eeb5e1768d0"} as expected but nothing opens in VS Code.

seancorfield22:10:41

((requiring-resolve 'portal.api/open)) ; works in standalone project and workspace
  ((requiring-resolve 'portal.api/open) {:launcher :vs-code}) ; works in standalone project but NOT in a workspace
Hope that helps @djblue LMK if I can do more testing for you.

👍 1
djblue23:10:47

That makes sense, I think my assumption of a root level folder is broken then.

djblue23:10:29

I'll see if I can fix the launcher for workspaces 👌

djblue23:10:38

Does those separate projects represent separate processes / repl connections? Or just multiple libraries as part of a single process?

djblue23:10:05

(defn- get-workspace-folder []
  (-> vscode/workspace
      .-workspaceFolders
      (aget 0)
      (.. -uri -path)))
This is the bit that's problematic in the vs-code extension

seancorfield23:10:48

If it helps, I figured out that if I copy .portal/vs-code.edn from the workspace root folder (where it is created once Portal is activated) to the folder where the REPL is started, then it works.

👍 1
seancorfield23:10:42

So it seems to get confused by the fact that the REPL is running in a different folder to the workspace root (which will just happen to be the first folder in the workspace).

djblue23:10:46

Yeah, I might invert the relationship and have the repl process drop a file and the extension watch for it in all workspaces folders :thinking_face:

seancorfield23:10:24

That won't work for setups where the REPL is started in a different folder -- that is not a root folder.

seancorfield23:10:47

At work, we have a workspace with two folders: wsmain and worldsingles. But the REPL is always started in wsmain/clojure.

djblue23:10:04

Interesting :thinking_face:

seancorfield23:10:42

In the general case, I may well start a REPL in a folder that is completely outside any VS Code workspace.

djblue23:10:31

The other idea I had was limiting the vs-code http-server port range and doing a broadcast from the repl process

seancorfield23:10:10

So the server process started in Portal (as an extension) is a VS Code HTTP server? Interesting.

djblue23:10:01

Well there are two. One in the extension waiting for a call to open a webview and another in the repl process hosting everything else.

seancorfield23:10:43

Oh, I guess I was confused by the add-tap in the extension code... That's for you to debug the extension?

👍 1
djblue23:10:39

Yeah, I was initially playing with everything inside the vs-code extension process

seancorfield00:10:14

Well, I guess for my use case, it would work if the JVM launcher walked up the file system looking for .portal?

seancorfield00:10:47

That would at least allow a REPL to be started in a subfolder which is common in monorepo situations.

djblue00:10:15

That's interesting :thinking_face:

djblue00:10:12

Is it common the have two process for a single mono repo? I wonder if one repl would clobber another

seancorfield00:10:20

In the more general case, I don't think Portal could possibly know how to bridge a REPL started in an arbitrary different folder tho'...

seancorfield00:10:41

For monorepos, you typically have just one REPL. It just isn't always started in the root.

👍 1
seancorfield00:10:31

But I can imagine people having multiple Clojure projects in a workspace and having multiple REPLs -- one from each Clojure project -- but Calva/Clover is only going to be connected to one of them at any point in time.

seancorfield00:10:47

If I leave the .portal/vs-code.edn file around (and .gitignore it), will Portal always just reuse that server/port?

djblue00:10:28

Not currently, but it could. Although I do thing the parent walking trick should be easy enough to do

seancorfield00:10:09

OK, so one problem you'd have is that if you started two instances of VS Code -- one in a folder and one for a workspace for which that is the root folder -- it would overwrite the vs-code.edn file in that folder.

seancorfield00:10:16

And in fact if you reload VS Code, it reactivates the extensions and would overwrite the workspace root vs-code.edn file anyway with a new port number -- and then the REPL still running would try to talk to the old server which has gone away, right?

seancorfield00:10:03

So I think you need to have the extension code reuse vs-code.edn to avoid that scenario?

seancorfield00:10:32

(I reload/restart VS Code a lot more often than I restart a REPL)

seancorfield00:10:10

Would I have to do portal.api/close on the JVM every time I restarted VS Code in order to clear the old server information and get the JVM Portal to connect to the (new) VS Code server?

djblue00:10:13

The vs-code.edn file is only used for the initial portal.api/open function. So if you restart and a new file is available and you call portal.api/open again it should be wired against the new instance of vs-code.

djblue00:10:50

A jar with the latest code if you are down to try it out again

seancorfield00:10:03

I did a symlink between the two folders to test what happens if I reload VS Code (and that puts a different port into vs-code.edn) but leave the REPL running -- and the answer is: that works just fine, so the REPL does not "lose" the Portal connection.

💯 1
seancorfield00:10:15

I'll remove the symlink and try that updated JAR next.

seancorfield00:10:18

Perfect! Yup, that finds the .portal/vs-code.edn up the file tree and works "as expected". Thank you!

awesome 1
seancorfield00:10:42

I'll have to think about what to do with the multi-project workspace thing. I suspect I can solve that with symlinks (so all the REPL-based projects in the workspace talk to the same VS Code Portal instance...).

djblue00:10:50

Thanks for making sure the extension works!

seancorfield00:10:35

With the multi-project workspace, it seems like I need to open a separate Portal view in VS Code for each backend REPL, if I want to switch between them -- because there's no way to just tell the backend "Oh, yeah, Portal is open and it's on port XYZ". But that's fine. I can definitely live with that (and it is a very unusual setup).

seancorfield00:10:47

(and that was part of why I wanted the Portal window title to include the directory where the open call was made so I could keep track of which Portal was attached to which REPL anyway).

💯 1
seancorfield00:10:18

(and, yes, that's with symlinks in place for all the folders in the workspace, pointing to a "master" .portal folder elsewhere 🙂 )

djblue00:10:21

Yeah, currently the portal client ui can only handle a connection to a single runtime. In the future I might remove this limitation

seancorfield01:10:37

Clover can only connect to one REPL so that's fine.

seancorfield01:10:31

Here's what my OSS project workspace looks like with two REPLs in the background (for honeysql and next.jdbc) and two Portal views:

djblue01:10:09

Ahh, now I get why you use workspaces 💯

👀 1
djblue01:10:15

One more question if you have the time. Would you rather specify :launcher :vs-code or have portal assume you want to use vs-code if it can find the .portal/vs-code.edn file?

seancorfield01:10:34

I would rather it was explicit. I may still want to launch a browser-based Portal window sometimes.

👍 1