Extension for Visual Studio Code
The Sorbet extension for Visual Studio Code integrates with the Sorbet language server to provide IDE-like features for typed Ruby files.
Installing and enabling the Sorbet extension
Install the
Sorbet extension from the VS Code extension marketplace.
Then, add the following configuration to your workspace’s settings.json
:
"sorbet.enabled": true
The next time you open a Ruby file in the workspace, Sorbet will automatically try to run via the following command:
bundle exec srb typecheck --lsp
If needed, you can customize how the extension launches Sorbet via the
sorbet.lspConfigs
setting:
"sorbet.lspConfigs": [{
"id": "stable",
"name": "Sorbet",
"description": "Stable Sorbet Ruby IDE features",
"cwd": "${workspaceFolder}",
"command": [
"bundle",
"exec",
"srb",
"typecheck",
"--lsp"
]
}]
Once Sorbet is activated, it will display its status in VS Code’s status line. For example, this is what you will see when Sorbet is busy typechecking your latest edits:
For the best experience, Sorbet requires Watchman, which listens for changes to the files on disk in addition to edits that happen to files open in the editor. For example, without Watchman installed, Sorbet will not detect when files have changed on disk due to things like changing the currently checked out branch.
Sorbet simply requires that the watchman
binary be somewhere visible on the
PATH
environment variable. There are installation instructions for various
platforms in the
Watchman docs.
If you cannot install watchman
to somewhere on the PATH
, you can use the
--watchman-path=...
command line flag to srb tc
to specify a path to the
watchman
binary.
If you cannot install watchman
at all, pass the --disable-watchman
flag to
srb tc
. This will mean that Sorbet only reads the files from disk at startup,
and afterwards only ever sees contents of files that have been opened or changed
in the editor.
You can use the sorbet.lspConfigs
setting described above to have the VS Code
extension always pass these command line flags when starting Sorbet.
Also, watchman requires that watched projects either be version controlled (e.g.
have a .git
folder in the project root) or have a .watchmanconfig
file at
the root of the project. Without one of these, watchman will not be able to
start successfully. See LSP: A note on watchman for
more.
Features
Live error squiggles for Sorbet typechecking errors (demo):
Type information and documentation on hover (demo):
Go to definition / type definition (demo):
Find all references (demo):
Autocomplete, including sig suggestion (demo):
Rename constants and methods (demo):
Quick fixes (autocorrects) on errors (demo):
Workspace symbol search:
Custom extension: Copy Symbol to Clipboard
(If you are not using the Sorbet VS Code, you can reimplement this feature in
your preferred LSP client using the sorbet/showSymbol
LSP request.)
Switching between configurations
The Sorbet extension supports switching between multiple configurations to make
it easy to try out experimental features. By default, it ships with three
configurations: stable, beta, and experimental. Workspaces can specify
alternative configurations via the sorbet.lspConfigs
setting.
Users can select between these configurations on-the-fly by clicking on “Sorbet” in VS Code’s status line and selecting "Configure Sorbet". Sorbet will then restart in the chosen configuration. Sorbet will also remember this configuration choice for the user’s future sessions in the workspace.
Disabling the Sorbet extension
There are multiple ways to disable the Sorbet extension depending on your goals.
- You can click on Sorbet in VS Code’s status line and click on Disable Sorbet, which will immediately stop Sorbet in that workspace. You will need to click on Enable Sorbet to reenable Sorbet in that workspace. This is a handy way to temporarily disable Sorbet if it is causing problems.
- Workspaces can set the
sorbet.enabled
setting tofalse
, which prevents Sorbet from running in the workspace.
Troubleshooting and FAQ
Startup
Error: “Sorbet’s language server requires a single input directory. However, 0 are configured”
This error can happen if you have not initialized Sorbet in your project. Please follow the instructions to initialize Sorbet.
If initializing Sorbet in your project is not desirable or possible, an
alternative fix is to override the default extension configuration in the
project’s .vscode/settings.json
file and provide the project directory as
"."
:
"sorbet.lspConfigs": [{
"id": "stable",
"name": "Sorbet",
"description": "Stable Sorbet Ruby IDE features",
"cwd": "${workspaceFolder}",
"command": [
"bundle",
"exec",
"srb",
"typecheck",
"--lsp",
"."
]
}]
I’m not seeing “Sorbet: Disabled” or “Sorbet: Idle” in the status bar of my VSCode window
That means the extension isn’t active. Here are some steps to try:
- Did you open a Ruby file? The Sorbet extension isn’t activated until you open at least one Ruby file in your editor.
- Make sure your VS Code window is wide enough to display the entire contents of the status bar.
- Ensure that you are not using VS Code’s Multi-root Workspaces feature, which this extension does not support.
Sorbet keeps restarting.
Click on Sorbet in the status bar, and then click on View Output. A log should pop up, and will typically contain some error messages that are causing the restart.
If you see an error that looks like this:
[Error - 9:36:32 AM] Connection to server got closed. Server will not be restarted.
Running Sorbet LSP with:
bundle exec srb typecheck --lsp
Could not locate Gemfile or .bundle/ directory
…then you probably need to run bundle install
to install Sorbet.
Diagnostics / error squiggles
Sorbet is reporting diagnostics (error squiggles) that don’t make sense.
If the errors are persistent, and you can reproduce your problem in the sandbox at https://sorbet.run/, then you’ve found an issue with Sorbet in general, not necessarily the VS Code Sorbet extension. Please file a bug tagged with “IDE” on the issue tracker.
If the errors are not persistent:
- First, is Sorbet still typechecking? If it is, wait for the status bar to display “Sorbet: Idle.” before judging the diagnostics.
- If the diagnostics remain nonsensical when Sorbet is Idle, try restarting Sorbet (click on Sorbet in the status bar, and click on Restart Sorbet).
- If the diagnostics become fixed, then you might have discovered a bug in Sorbet.
If you arrive at a set of edits that mess up the diagnostics, please file a bug on the issue tracker.
Hover
When I hover on something, VS Code shows “Loading…”
Is Sorbet still typechecking or initializing? If so, this is expected behavior; Sorbet cannot show you type information until it finishes catching up with your edits. “Loading…” should get replaced with hover information once the status bar displays “Sorbet: Typechecking in background” or "Sorbet: Idle".
Hover doesn’t work / hover isn’t showing information for my file
Is the file untyped (# typed: false
or ignore
)? Hover only works in typed
files. You will need to make your file # typed: true
.
Does the file have a syntax error? If so, you need to resolve it before hover will work again.
If the file is typed, Sorbet is "Idle", and hover isn’t working, try to reproduce the problem on https://sorbet.run and file a bug on the issue tracker.
Hover is showing incorrect type information for something.
Does your file have a syntax error? If so, resolve it before proceeding.
If the problem persists with your syntax errors fixed, you may have found a bug in Sorbet! Check to see if it’s in the GitHub issue tracker. If you don’t see anything relevant there, try to golf the problem down to something small on https://sorbet.run and file a bug on the issue tracker.
Hover is not showing documentation that I’ve written / is showing incorrect documentation.
Internally, Hover uses the “Go to Definition” logic to locate documentation. If “Go to Definition” takes you to the wrong location, then Sorbet doesn’t have the type information it needs to locate your documentation.
Did you include an empty line between your documentation and the thing you are defining? We expect documentation to immediately precede the definition (or its sig).
# valid documentation location
def foo; end
# valid documentation location
sig {void}
def foo; end
sig {void}
# valid documentation location
def foo; end
# invalid documentation location
def foo; end
Is this an instance or class variable? The variable
must be defined with T.let
,
and the documentation must precede the T.let
. Otherwise, Sorbet doesn’t see
that variable as having ever been defined.
Otherwise, try to reproduce the issue on https://sorbet.run/ and file a bug on the issue tracker.
Find all References
Find all References is not working / Find all References is missing some expected results.
Make sure that Sorbet is running. You should see “Sorbet: Idle” in VS Code’s status bar. Otherwise, see Feature support by strictness level.
If the information in that document doesn’t apply (e.g., the current file is
# typed: true
or higher), check whether the expression is T.untyped
. See
Troubleshooting for more information.
Find all References is slow.
The speed of Find all References depends on how many files contain an identifier
with the same name, as we use that information as a first-pass filter over the
source files before refining to actual references. For example, searching for
references to a class’s initialize
will involve a scan over most files in a
project even if the specific initialize
you are looking for is only used in
one file.
Find all References also waits for “Typechecking in background…” to complete so that it does not contend with typechecking for CPU time.
Find all References brought me to a file that I cannot edit.
These features may return results in type definitions for core Ruby libraries, which are baked directly into the Sorbet executable and are not present on the file system.
In order to display these files in your editor and to support navigating through them, we’ve configured the Sorbet extension to display them in this read-only view. Note that certain extension features, like hover and Go to Definition, will not function in some of these special files.
Reporting metrics
Sorbet does not require metrics gathering for full functionality. If you are seeing a log line like “Sorbet metrics gathering disabled,” Sorbet is working as intended.
It is possible to ask the Sorbet VS Code extension to collect and report usage metrics. This is predominantly useful if you maintain a large Ruby codebase that uses Sorbet, and want to gather metrics on things like daily users and editor responsiveness.
To start gathering metrics, implement a
custom VS Code command
using the name sorbet.metrics.getExportedApi
.
The implementation of this command should simply return an object like this:
{
metricsEmitter: ...
}
The metricsEmitter
value should conform to the MetricsEmitter
interface
declared in the Sorbet VS Code extension source code. Most likely, you will want
to implement this interface by importing a StatsD client, connecting to an
internal metrics reporting host, and forwarding requests from the
MetricEmitter
interface function calls to the StatsD client of your choice.