2

I am building a VS Code extension that prints some output to the Output panel of VS Code and one of the things I am printing is a file name and a line number. I want to be able to click (or ctrl click) on the file name and go to the file and location in question (if it belongs to the current workspace).

I have tried both printing it like so:

fileName.txt:12
fileName.txt(12)
./fileName.txt(12)

but none of these have worked so far.

Is there a correct way of doing this? I would like to avoid printing the absolute path if possible (I would prefer to print relative paths).

starball
  • 20,030
  • 7
  • 43
  • 238

1 Answers1

2

According to the GitHub issue discussion at Support relative paths as links in output #167211, you should be able to do this using the DocumentLinkProvider API, which you can find documentation for at code.visualstudio.com/api/references/vscode-api#DocumentLinkProvider<T>.

According to the documentation for DocumentLinkProvider<T>#provideDocumentLinks(...),

Note that the editor ships with a default provider that detects http(s) and file links.

And according to other issue tickets on GitHub (such as #149153), it also has basic automatic support for absolute paths to files that are inside the workspace that aren't full URLs with protocol specifiers like http(s):// and file://, however, it doesn't support paths with spaces in them. (see related feature requests such as #163778 and #586)

So if you only print absolute paths to files that are in the workspace that don't have spaces in them, you don't need to do anything. VS Code will do it for you.

Otherwise, you need to explicitly write a DocumentLinkProvider and register it with registerDocumentLinkProvider. Implement DocumentLinkProvider#provideDocuentLinks to return an array of DocumentLinks. Create your output channel with a dedicated language ID, and use that language ID in the DocumentSelector argument you pass to createOutputChannel.

It will probably looks something like this:

const outputChannel = createOutputChannel(
  "my-output-channel-name",
  "my-output-channel-language-id"
);
const documentLinkProviderDisposable = vscode.languages.registerDocumentLinkProvider(
  { language: "my-output-channel-language-id" },
  {
    provideDocumentLinks: (doc) => {
      // TODO: implement your actual logic
      return [new DocumentLink(
        new Range(...),
        new Uri(...) // or Uri.file(...)
      )];
    }
  }
);

In the package.json:

  "contributes": {
    ...
    "languages": [
      {
        "id": "my-output-channel-language-id",
        ...
      }
    ],
    ...
  },

Relevant VS Code API Reference docs:

Note: I think your users might need to make sure they do not have "editor.links": false in their settings.json files.

starball
  • 20,030
  • 7
  • 43
  • 238