Skip to content

Support hyperlinks to local/project files with scheme like vscode:// / code-oss:// #6785

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
belonesox opened this issue May 3, 2024 · 11 comments
Labels
enhancement Some improvement that isn't a feature

Comments

@belonesox
Copy link

belonesox commented May 3, 2024

What is your suggestion?

Is it possible to enable support for all of this, or are there policy or architectural solutions that will prevent this?

Why do you want this feature?

I wish to support "hyperlink browsing" for my project files (hyperlinks in comments, "includes" in documentation files, etc). Lot of extensions support tunable hyperlinking, like regex robin, but without support for schemes vscode:// / code-oss://, they are unusable in code-server.

Are there any workarounds to get this functionality today?

Unfortunately, no. :(

Are you interested in submitting a PR for this?

I've tried debugging, I see that the RelayURLService that provides all this in vscode is not loaded by dependencies in code-server, looks it is too complicated for a one-line patch.
If there is no policy prohibiting it, and I get a hint on how to do it properly, I may try to implement and test.

@belonesox belonesox added the enhancement Some improvement that isn't a feature label May 3, 2024
@code-asher
Copy link
Member

This is probably an issue with Codespaces/vscode.dev as well right? If so, might be worth sending a feature request upstream.

But also #1571 seems related. In theory you could register a web+code-oss://handler, but I do not believe browsers will let you do code-oss://.

@belonesox
Copy link
Author

belonesox commented May 5, 2024

This is probably an issue with Codespaces/vscode.dev as well right? If so, might be worth sending a feature request upstream.

What github project is upstream to code-server? I thought that this project is upstream to theme "VS Code in the browser".

But also #1571 seems related. In theory you could register a web+code-oss://handler, but I do not believe browsers will let you do code-oss://.

Scheme name not for browsers, but for LinkHandler in code-server, so I do not care, how the scheme would be named (vscode:// is better for compatibility with VSCode), if code-server will support clicking on links in text, and open files like in this demo (look how blue "!include" links open project files):

demo-screencast.mp4

@code-asher
Copy link
Member

What github project is upstream to code-server? I thought that this project is upstream to theme "VS Code in the browser".

code-server consumes VS Code, so that makes VS Code upstream. At least, that is how I understand it.

code-server basically just wraps VS Code's own web server (the thing used in Codespaces), with a few patches and extra endpoints. All the core functionality is in https://github.com/microsoft/vscode.

support clicking on links in text, and open files like in this demo

Ah, I misunderstood what you were asking. The markdown preview runs in an iframe and all network requests are intercepted by a service worker, so it should be technically feasible to make vscode:// links work without needing to register any link handlers with the browser. But, I am not sure what exactly needs to be done.

This looks related: microsoft/vscode#199009

@Vigilans
Copy link

Vigilans commented May 8, 2024

Using this code snippet from microsoft/vscode-python-debugger#136 (comment), and replace vscode:// with code-oss://:

import os
import socket
import json

def _get_vscode_debug_launcher_url(port: int):
    launch_config = {
        "name": "Python: Remote Attach",
        "type": "python",
        "request": "attach",
        "connect": {"host": "localhost", "port": port},
        "pathMappings": [
            {"localRoot": "${workspaceFolder}", "remoteRoot": os.getcwd()}
        ],
        "justMyCode": False,
    }
    launch_config = json.dumps(launch_config)
    return f"code-oss://fabiospampinato.vscode-debug-launcher/launch?args={launch_config}"



def _handle_vscode_remote(vscode_ipc: str, port: int):
    # the VSCode Remote extension does not support `code --open-url {url}` with a `vscode://` extension
    # This may change in the future, but for now we need to bypass this limitation by using the VSCode IPC
    # secket to send the `vscode://` url to the VSCode instance server directly
    import requests

    from urllib3.connection import HTTPConnection
    from urllib3.connectionpool import HTTPConnectionPool
    from requests.adapters import HTTPAdapter

    class VSCodeIPCConnection(HTTPConnection):
        def __init__(self):
            super().__init__("localhost")

        def connect(self):
            self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            self.sock.connect(vscode_ipc)

    class VSCodeIPCConnectionPool(HTTPConnectionPool):
        def __init__(self):
            super().__init__("localhost")

        def _new_conn(self):
            return VSCodeIPCConnection()

    class VSCodeIPCAdapter(HTTPAdapter):
        def get_connection(self, url, proxies=None):
            return VSCodeIPCConnectionPool()

    session = requests.Session()
    session.mount("code-oss://", VSCodeIPCAdapter())
    session.post(
        "code-oss://",
        headers={"content-type": "application/json", "accept": "application/json"},
        json={
            "type": "openExternal",
            "uris": [_get_vscode_debug_launcher_url(port)],
        },
    )

if __name__ == "__main__":
    import debugpy

    # Find an open port to listen on
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(("localhost", 0))
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    port = s.getsockname()[1]
    s.close()

    debugpy.listen(port)

    # If we're in a local vscode terminal session, we need to tell VSCode to connect to the debug adapter
    # using fabiospampinato.vscode-debug-launcher extension
    if os.environ.get("TERM_PROGRAM") == "vscode":
        vscode_ipc = os.environ.get("VSCODE_IPC_HOOK_CLI")
        if vscode_ipc:
            # If VSCode is running in a remote SSH or container session, this gets pretty complex
            _handle_vscode_remote(vscode_ipc, port)
        else:
            # If VSCode is running locally (ie not using the Remote SSH or Remote Containers extensions),
            # this is pretty straightforward
            import subprocess

            subprocess.run(
                ["code", "--open-url", _get_vscode_debug_launcher_url(port)]
            )

    # If we're not in a VSCode terminal window, we will need to prompt the user to connect to the debug adapter
    # with their preferred editor's debugger
    print(f"Waiting for debugger to attach on port {port}...")
    debugpy.wait_for_client()

the code-server page seems handled this url and responds, but do not do anything meaningful:
image

Any chance to look into it to make it work?

@code-asher
Copy link
Member

Very interesting. Sending a code-oss:// link to the socket to launch an extension. I believe this will not help in the case of the readme preview, but it does seem like it has some interesting use cases.

But, I am not sure why it does not work the same as remote. Does it work in Codespaces?

@belonesox
Copy link
Author

belonesox commented May 9, 2024

code-server consumes VS Code, so that makes VS Code upstream. At least, that is how I understand it.

On VS Code it works , code-oss:// or vscode:// depending on product.json depending on urlProtocol parameter in product.json file.

To see how it works, we can install for example https://github.com/dlevs/vscode-regex-robin and add to settings something like

"regexrobin.rules": [
    {
        "regex": "(include|include-entry) +([^\\n]+)",
        "tree": {
            "group": "include links"
        },
        "editor": [
            {
                "link": "vscode://file${fileDirname}/$2",
                "color": "#3639EF",
                "hoverMessage": "Open $2"
            }
        ]
    }
],

and all links like include in text editor of vscode will be hyperlinked and processed as vscode:// (like on screencast).
For code-server here should work "link": "code-oss://file${fileDirname}/$2",, but it does not.

So there is no problem in upstream.

Ah, I misunderstood what you were asking. The markdown preview runs in an iframe and all network requests are intercepted by a service worker, so it should be technically feasible to make vscode:// links work without needing to register any link handlers with the browser.

I seem to have confused you with this screencast (part with markdown preview is irrelevant).

On initialization of VSCode it calls

image

image

image

So if we setup regex-robin like described above, it makes "include" strings in editor to code-oss links

image

and processed it right way

image

image

and finally open as file:

image

I've tried debugging, I see that the RelayURLService that provides all this processing in vscode is not loaded by dependencies in code-server.

Should I make reproduceable example project for code-server? May it help?

@code-asher
Copy link
Member

On VS Code it works
So there is no problem in upstream

Upstream has essentially two separate editors that share most of their code: a native version that runs in Electron, and a web version that runs in the browser with a Node backend. code-server bundles that web version. Microsoft uses that web version in Codespaces, which is why we ask folks to test there to see if it is an upstream issue.

Well, technically they have three versions; they have another web version without any backend (this is what vscode.dev is).

This RelayUrlService appears to be only available in the Electron version. Maybe because it relies on protocol handlers that cannot be registered from the browser. So it will have to be rewritten upstream to work in the browser.

https://github.com/microsoft/vscode/wiki/How-to-Contribute#code-server-web

@belonesox
Copy link
Author

belonesox commented May 10, 2024

Upstream has essentially two separate editors that share most of their code: a native version that runs in Electron, and a web

Oww, sorry for bothering you , I was blind (I thought code-server upstream here, and vscode only for desktop).
¯\_(ツ)_/¯

I debug a little and see — my problem solved:

  • for desktop we should use vscode/code-oss scheme
  • for code-server we should use vscode-remote scheme

It is little inconvenient for settings consistency, but okay.

So here bug can be closed.
Sorry again and thank you!

@code-asher
Copy link
Member

All good, no worries!

Ahhhh vscode-remote works? That is really good to know. Nice find!

@code-asher code-asher closed this as not planned Won't fix, can't repro, duplicate, stale May 10, 2024
@jswhisperer
Copy link

I know it's an old thread and not planned, but hopefully if you do go with a solution in the future it will be a PWA web+code:// schema etc or web+foo:// this is a neat library but a couple issues to test it doesn't resolve windows versus unix-y paths probably broken functionality.

Probably Also broken or needs testing if code-server is installed as a desktop PWA also.

@code-asher
Copy link
Member

Open issue for that is #1571

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Some improvement that isn't a feature
Projects
None yet
Development

No branches or pull requests

4 participants