id | title | sidebar_label |
---|---|---|
vscode |
Extension for Visual Studio Code |
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.
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:
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:
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.
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.
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",
"."
]
}]
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.
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.
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 VSCode 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.
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".
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.
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.
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.
Go to Definition/Go to Type Definition/Find all References is not working / Find all References is missing some expected results.
First, make sure that Sorbet is running. You should see "Sorbet: Idle" in VS Code's status bar.
It's possible that the feature is working as intended. Go to Definition and Find all References are not available in all circumstances. A ‘Yes’ entry in the following table indicates two distinct things:
- A language construct where these features work. For example, you can right click a class reference and go to its definition or find its references in typed and untyped files.
- An item that will be included in the results of these features. For example, the result of Find all References on a method includes method calls in typed files, but not method calls in untyped files.
# typed: true or above |
# typed: false |
|
---|---|---|
Class/module/constant definition or reference | Yes | Yes |
ivar (@foo) | Yes, if defined* | Yes, if defined* |
cvar (@@foo) | Yes, if defined* | Yes, if defined* |
Method definition | Yes | Results only** |
Method call | Yes | No |
Local variable | Yes | No |
* Indicates that the variable
must be defined with T.let
.
Otherwise, Sorbet doesn’t see that variable as having ever been defined.
** You cannot use either feature from this language construct, but this item will be included in Go to Definition/Find all References results from typed files.
We have these restrictions in place to avoid weird/nonsensical behavior caused by untyped files, which may have partial and potentially incorrect type information. We heartily encourage you to type files to gain access to these features.
Note that some items marked "Yes" in the table may not work with these features
if Sorbet does not have the necessary type information. In particular, method
calls on an object foo
where foo
is untyped will not be included in Find all
References and will not work with Go to Definition because Sorbet is unable to
resolve which method is being called at that location. Using # typed: strict
should suss out most of these untyped locations on a per-file basis.
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.
Ensure that you see "Sorbet: Idle" and not "Sorbet: Disabled" at the bottom of VS Code. If Sorbet is enabled and it is returning a weird/unexpected definition site, please try to reproduce the issue on https://sorbet.run/ and file a bug on the issue tracker.
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.
- Are you in a
typed: false
file? No completion results are expected. - Is the place where you're trying to see results unreachable? For example, after a return statement, or in an else condition that can't happen? Sorbet can't provide completion results here.
- Can you see completion results for other things? Sorbet only supports completing local variables, methods, keywords, suggested sigs, classes, modules, and constants right now. Notably, it doesn't support completing the names of instance variables.
You'll have to type at least one character after the dot (like x.f) or after the colon (like A::B) before completion results show up.
We tried to get this working before the initial ship, but it ended up being a more complicated change than we expected. We have a couple ideas how to support this, so expect this to be supported in the future.
Completion results can come from many different extensions, not just Sorbet. You can try to figure out what extension returned the results by looking at the icon that VS Code shows in the completion list:
Results from Sorbet will only ever have 1 of 6 icons (currently): method
,
variable
, field
, class
, interface
, module
, enum
, keyword
, and
snippet
.
Notably, the abc icon (word
) means the results came either from VS Code’s
editor.wordBasedSuggestions
setting or some other generic autocomplete
extension.
Also, snippet
results can come from other extensions. Snippet results that
come from Sorbet will always say (sorbet)
somewhere in the snippet
description. Sorbet does not have control over any snippet results that don't
say (sorbet)
in them; if they look wrong, the only suggestion is to turn them
off.
Sorbet inserts a suggested snippet into the document when accepting a completion result.
- Snippet results will have highlighted sections inside them.
- These represent "holes" (tabstops) that you'll need to fill in—the aim is that every tabstop is for a required argument (i.e., optional / default arguments won't be present).
- As the default text for each of these holes, Sorbet uses the type of the corresponding argument.
- Press
TAB
to cycle through the holes (tabstops), or pressESC
to deselect all the tabstops.
It is not possible to opt-out of these completion snippets. If you find that this is annoying, please let us know.