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.
This doc covers certain VS Code-specific points, like how to install and configure the VS Code extension. Most of Sorbet’s editor features are not VS Code-specific, and are documented in their own pages (see the “Editor Features” section of the page listing).
Installing and enabling the extension
Install the Sorbet extension from the VS Code extension marketplace.
As long as the current project has a sorbet/config
file,
Sorbet should start automatically whenever a Ruby file is open. To check that
Sorbet has started working, look for "Sorbet: …" in the VS Code status
bar.
As long as it does not say “Sorbet: Disabled,” then Sorbet is working. See Server Status for more information on what the statuses like “Idle” mean.
Troubleshooting startup
I’m not seeing “Sorbet: …” in the status bar
The extension is not active. Here are some steps to try:
Is a Ruby file open? The Sorbet extension does not activate until at least one Ruby file is open.
Make sure the VS Code window is wide enough to display the entire contents of the status bar.
Do not use VS Code’s multi-root workspaces. The Sorbet extension does not support this feature.
I see “Sorbet: Disabled” in the status bar
Sorbet is installed and active, but has chosen not to start the Sorbet process automatically. To manually enable Sorbet, either:
Use the
>Sorbet: Enable
command. The server will start with the default server command.Use the
>Sorbet: Configure
command. A prompt will appear to choose which server configuration to start the Sorbet process with. See the configuration docs to change the configurations.Edit the
.vscode/settings.json
for the current workspace to include this:{ "sorbet.enabled": true }
This may require restarting VS Code.
Sorbet keeps restarting
The Sorbet extension restarts the server process when it stops. If the process crashes on startup, this can cause Sorbet to restart in a loop. Fixing requires fixing the underlying reason for the crash.
Click on “Sorbet: …” in the status bar and then choose “View Output” (or use
the >Sorbet: Show Output
command) to see the Sorbet extension logs.
There is usually an error message which gives a hint why Sorbet crashed. For example:
[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
See below for help with specific error messages.
Note that the “Server will not be restarted” message is logged by a library that the Sorbet VS Code extension uses—the actual restart logic lives at a higher level, so this error message is misleading. Sorbet will be restarted whenever the server process crashes.
“Could not locate Gemfile or .bundle/ directory”
The Sorbet extension uses this command to start the server process by default:
bundle exec srb typecheck --lsp
This assumes the project uses Bundler to manage Ruby dependencies. If that’s not the case, configure how to launch the Sorbet process.
“bundler: command not found: srb”
Either:
The
Gemfile
does not include thesorbet
gemEdit the
Gemfile
as per the instructions here, and then runbundle install
.The
sorbet
gem is included in the Gemfile, but not yet installed.Run
bundle install
, then try again.
“Sorbet’s language server requires at least one input directory”
Sorbet in LSP mode requires a single input directory.
See Sorbet Language Server > Prerequisites > A single input directory for more.
“Sorbet’s language server requires a single input directory”
Sorbet in LSP mode requires a single input directory.
See Sorbet Language Server > Prerequisites > A single input directory for more.
“Watchman is required for Sorbet to detect changes to files”
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.
See Sorbet Language Server > Prerequisites > Watchman for more.
Something else
If you had to troubleshoot an error message you think is common when installing Sorbet, please help by editing this page!
Disabling the extension
There are multiple ways to disable the Sorbet extension, which will stop the Sorbet server process:
Use the
>Sorbet: Disable
command.Click on “Sorbet: …” in the status bar and then choose “Disable Sorbet.”
Edit the
.vscode/settings.json
for the current workspace to include this:{ "sorbet.enabled": false }
This is particularly useful to disable Sorbet for all contributors to a given project, if there’s some reason why Sorbet should not be used in that project.
Command Reference
To run these commands, use VS Code’s Command Palette. To bring up the command palette, use ⇧⌘P on macOS or Ctrl + Shift + P on Linux.
The >
character in the command names below does not need to be typed, unless
it’s been deleted from the text box, or if the palette was opened with the
“Quick Open” menu (⌘P on macOS, Ctrl + P on Linux.)
>Sorbet: Enable
Enables Sorbet, causing the Sorbet server process to start. It will use the most recently selected server launch configuration, or else the default.
>Sorbet: Disable
Disables Sorbet, causing the Sorbet server process to stop.
>Sorbet: Restart
Disables Sorbet, causing the Sorbet server process to stop, then re-enables Sorbet, causing it to launch again, using the current server configuration.
>Sorbet: Configure
Chooses which configuration to run Sorbet with, or choose to disable Sorbet. After choosing a configuration, any running Sorbet process will stop, and a new one will be launched with the chosen configuration.
By default, there are three configurations, which allow opting into experimental features. A given workspace may choose to define its own configurations.
>Sorbet: Show Output
Opens the Sorbet extension’s logs in the output pane. Mostly useful for
Troubleshooting startup. For debugging the Sorbet
extension itself, consider also using >Sorbet: Set Log Level...
to make the
logs more verbose.
Note that the Sorbet output only includes logs from the Sorbet extension. It
does not include debug output from the Sorbet server process. To control log
output from the Sorbet server process, see the
--debug-log-file
command line option. This
flag is not passed by default. To pass it, change the
server configurations.
>Sorbet: Set Log Level...
The Sorbet extension includes various logs designed to help developers troubleshoot problems in the Sorbet extension itself. Use this command to control how verbose Sorbet’s log should be. It may also be helpful to enable logging at VS Code’s language client level.
>Sorbet: Copy Symbol to Clipboard
Copies the fully-qualified name of the symbol under the cursor to the clipboard.
This feature is powered by a custom extension to the LSP specification:
sorbet/showSymbol
request.
The same feature is also available as a right-click context menu item:
>Sorbet: Configure untyped code highligting
>Sorbet: Toggle highlighting untyped code
>Sorbet: Toggle the autocomplete nudge in `typed: false` files
By default, Sorbet shows a completion item in # typed: false
files when there
are no completion results due to the file being # typed: false
, like this:
The goal of the nudge is to encourage upgrading the current file
from # typed: false
to # typed: true
. Use this command to
disable the nudge.
As a reminder, most features, including autocompletion,
have degraded support in # typed: false
files.
Configuration Reference
This section documents configuration options which live in the User or Workspace Settings of VS Code.
For a complete reference of the Sorbet extension’s configuration options, their
types, and their defaults, see the "configuration"
section of the
package.json
file.
Sticky configuration
Sorbet extension settings are sticky: even if the settings.json
file for the
workspace or the user has a given setting, Sorbet will remember when the user
previously changed that the setting from the UI. These choices persist across
reboots of VS Code.
For example, consider the sorbet.enabled
setting and the
>Sorbet: Enable
command in this scenario:
Initially, the
.vscode/settings.json
file for a given workspace has{ "sorbet.enabled": false }
When VS Code starts up, it sees that Sorbet is disabled and does not launch Sorbet.
The user then runs
>Sorbet: Enable
to start Sorbet, does some work, and quits VS Code.The next time VS Code is opened in this workspace, Sorbet will still be enabled and start automatically.
It’s not that the >Sorbet: Enable
command edited the contents of the
.vscode/settings.json
file to flip it to true
, but rather that the Sorbet
extension remembers whether a setting has been changed via a command after
starting up.
The only settings that are not sticky like this are the settings which do not have a command to change the corresponding configuration setting.
sorbet.enabled
Whether Sorbet should be enabled or disabled in this workspace.
sorbet.lspConfigs
This setting controls the command used to launch the Sorbet server process.
The Sorbet extension supports switching between multiple configurations to make
it easy to try out experimental features or register custom command line
options. By default, it ships with three configurations: Sorbet
,
Sorbet (Beta)
, and Sorbet (Experimental)
.
Users can switch between these configurations using the >Sorbet: Configure
command, or by clicking on “Sorbet: …” in the status bar and selecting
"Configure Sorbet".
As mentioned elsewhere:
- Changing the config will cause Sorbet to restart in the chosen configuration.
- Using the UI to change this setting is sticky: Sorbet will use the most recently chosen configuration when next launched.
An example configuration would look like this. Consisder a project that uses Sorbet but that does not use Bundler:
{
"sorbet.lspConfigs": [
{
"id": "without-bundler",
"name": "srb",
"description": "Launch Sorbet using `srb` from the PATH",
"cwd": "${workspaceFolder}",
"command": ["srb", "tc", "--lsp"]
}
]
}
This project would not use bundle exec [...]
to launch the Sorbet server
process.
Some other ideas for how to use this configuration feature:
Pass custom, LSP-specific options that don’t belong in the
sorbet/config
.Wrap the call to
srb tc
in a custom script for the current project, which might do things like make sure the environment is set up correctly before starting Sorbet.Start the server process using a custom, local build of the Sorbet binary.
When setting this setting, it’s recommended to refer to the more complete documentation in the Sorbet extension’s package.json file.
sorbet.userLspConfigs
This setting is largely the same as sorbet.lspConfigs
, but has higher
precedence. It’s designed to allow users to keep their own Sorbet configurations
in VS Code’s User settings.
Normally, Workspace Settings take precedence over User Settings. Having this option gives users the chance to invert that.
Because of this, it’s usually not recommended to commit this setting to
.vscode/settings.json
in a workspace, because it prevents users from launching
Sorbet according to their own preferences.
sorbet.selectedLspConfigId
Which LSP configuration to pick first (see
sorbet.lspConfigs
).
If unset, picks the first one, giving precedence to sorbet.userLspConfigs
.
Remember that settings are sticky, so if the user has
used >Sorbet: Configure
to change the configuration, that most recently
selected configuration will take precedence over this setting.
sorbet.highlightUntyped
Whether to highlight untyped, and where. Defaults to "nowhere"
.
sorbet.typedFalseCompletionNudges
Whether to enable # typed: false
completion nudges. Defaults to true
.
See >Sorbet: Toggle the autocomplete nudge in `typed: false` files
.
sorbet.configFilePatterns
A list of workspace file patterns that contribute to Sorbet’s configuration. Changes to any of those files should trigger a restart of any actively running Sorbet language server.
For example, changes to the sorbet/config
file or the Gemfile.lock
could
mean that the Sorbet process needs to restart (to pick up new options, or a new
version, respectively). The default sorbet.configFilePattern
tracks these two
files are tracked
Projects that have custom scripts that launch Sorbet likely want to set this setting.
Careful: setting this setting completely overwrites the default.
sorbet.revealOutputOnError
Shows the extension output window on errors. Defaults to false
.
Troubleshooting and FAQ
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.
- Another thing to check is whether the Problems tab in VS Code has the same errors as what Sorbet would report when run from the command line (assuming all files have been saved). If the list of errors is different, this usually represents a bug in Sorbet (so long as Sorbet is “Idle” in the IDE).
If you arrive at a set of edits that mess up the diagnostics, please file a bug on the issue tracker.
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.