Skip to content

Latest commit

 

History

History
125 lines (93 loc) · 4.81 KB

sorbet-uris.md

File metadata and controls

125 lines (93 loc) · 4.81 KB
Error in user YAML: (<unknown>): mapping values are not allowed in this context at line 3 column 22
---
id: sorbet-uris
title: Working with Synthetic or Missing Files
sidebar_label: sorbet: URIs
---

Note: The Sorbet VS Code extension supports this out-of-the-box. This doc serves as a reference for users of alternative LSP clients to recreate the VS Code extension behavior in their preferred language client.

When typechecking a project, certain files in the project are synthetic. For example: every RBI file which defines the Ruby standard library is not a file on disk, but actually a blob of memory baked into the Sorbet binary executable. Also, some files may be visible to the language server, but missing from the language client.

Sorbet supports a handful of extensions to the language server protocol to enable Go to Definition to work with these files:


The video above shows that Go to Definition on the File.read method (defined in an RBI file contained inside Sorbet itself) opens like a normal, non-modifiable file inside VS Code.

The extensions powering this are:

  • The supportsSorbetURIs property of the initialize request.
  • A custom sorbet/readFile LSP request.
  • In the Sorbet VS Code extension: a TextDocumentContentProvider to present a Virtual Document.
  • The --lsp-directories-missing-from-client command line flag, specifying which extra files the language server knows about, but are not known to the client, which need to be served as virtual sorbet: URI files. (Uncommon, but available)

As seen above, Sorbet's VS Code extension supports this out of the box.

To configure other language clients to support Go to Definition for these files, follow these steps:

1. Pass supportsSorbetURIs at initialization

By default, Sorbet produces https:// URIs for synthetic files in its payload, and normal file:// URIs for all other files (even those which are missing from the client).

The first step is to request that Sorbet send sorbet: URIs for these files instead.

In the initialize request that starts the Sorbet language server, be sure to pass the supportsSorbetURIs property:

"initializationOptions": {
  // ...
  "supportsSorbetURIs": true,
  // ...
}

Different language clients will have different ways to specify initializationOptions when starting a language server. Consult the documentation of your editor or language client for how to pass this option on startup in the initialize request.

Setting supportsSorbetURIs to true informs Sorbet that it can use sorbet: URIs. Whenever a Go to Definition request would attempt to jump into a synthetic or missing file, instead of sending an https:// URI or a file:// URI, it will send a sorbet: URI.

2. Use the sorbet/readFile request to read the virtual file

By default, the language client will not know how to open files with a sorbet: URI, so the next step is to teach it.

Sorbet implements a custom LSP request method called sorbet/readFile which language clients can use to get the text content of a synthetic or missing file:

Request:

Response:

Different language clients have their own way to customize the way files with a certain URI are opened. For example:

The best reference for how to use the sorbet/readFile command is the official Sorbet VS Code extension's TextDocumentContentProvider implementation:

vscode_extension/src/sorbetContentProvider.ts

If you have implemented something which uses the sorbet/readFile request, please contribute an edit to this doc which shares a link to your code, so others can reference it!