Integrating a new editor
Metals is a language server implemented in Scala that communicates with a single client over JSON-RPC.
Requirements
Java 11, 17 provided by OpenJDK or Oracle. Eclipse OpenJ9 is not
supported, please make sure the JAVA_HOME
environment variable
points to a valid Java 11 or 17 installation.
macOS, Linux or Windows. Metals is developed on many operating systems and every PR is tested on Ubuntu, Windows and MacOS.
Scala 2.13, 2.12, 2.11 and Scala 3. Metals supports these Scala versions:
-
Scala 2.11: 2.11.12
-
Scala 2.12: 2.12.17, 2.12.18, 2.12.19, 2.12.20
-
Scala 2.13: 2.13.12, 2.13.13, 2.13.14, 2.13.15
-
Scala 3: 3.3.1, 3.3.3
Scala 3 versions from 3.3.4 are automatically supported by Metals.
Any older Scala versions will no longer get bugfixes, but should still work properly with newest Metals.
Note that 2.11.x support is deprecated and it will be removed in future releases. It's recommended to upgrade to Scala 2.12 or Scala 2.13
Starting the server
Use Coursier to obtain the JVM classpath of Metals:
coursier bootstrap org.scalameta:metals_2.13:1.4.1 -o metals -f
(optional) It's recommended to enable JVM string de-duplication and provide a generous stack size and memory options.
coursier bootstrap \
--java-opt -XX:+UseG1GC \
--java-opt -XX:+UseStringDeduplication \
--java-opt -Xss4m \
--java-opt -Xms100m \
org.scalameta:metals_2.13:1.4.1 -o metals -f
See Metals server properties for additional system properties that are supported by the server.
JSON-RPC communication takes place over standard input/output so the Metals server doesn't print anything to the console when it starts. Instead, before establishing a connection with the client, Metals logs notifications to a global directory:
# macOS
~/Library/Caches/org.scalameta.metals/global.log
# Linux
$XDG_CACHE_HOME/org.scalameta.metals/global.log
# Linux (alternative)
$HOME/.cache/org.scalameta.metals/global.log
# Windows
{FOLDERID_LocalApplicationData}\.cache\org.scalameta.metals\global.log
After establishing a connection with the client, Metals redirects logs to the
.metals/metals.log
file in the LSP workspace root directory.
Metals supports two kinds of JSON-RPC endpoints:
- Language Server Protocol: for the main functionality of the server, including editor text synchronization and semantic features such as goto definition.
- Metals extensions: for additional functionality that is missing in LSP but improves the user experience.
Configuring the server
Over time the recommended way to configure Metals has shifted from heavily
relying on the Metals server properties to being
fully able to be configured via InitializationOptions
which are exchanged
during the
initialize
process. While Metals will still work being fully configured by server
properties, we strongly recommend that instead you rely on the
InitializationOptions
which are thoroughly covered below in the
initialize
section.
Language Server Protocol
Consult the LSP specification to learn more about how LSP works. Metals uses the following endpoints from the specification.
initialize
- the
rootUri
field is used to configure Metals for that workspace directory. The working directory for where server is started has no significant meaning. - at this point, Metals uses only full text synchronization. In the future, it will be able to use incremental text synchronization.
didChangeWatchedFiles
client capability is used to determine whether to register file watchers.
InitializationOptions
During initialize
we also have the ability to pass in InitializationOptions
.
This is the primary way to configure Metals. In Metals we have a few different
"providers". Some are LSP extensions, such as metals/inputBox
which you read
about below, and others used to be server properties that have been migrated to
InitializationOptions
. M
The currently available settings for InitializationOptions
are listed below.
interface InitializationOptions: {
compilerOptions: {
completionCommand?: string;
isCompletionItemDetailEnabled?: boolean;
isCompletionItemDocumentationEnabled?: boolean;
isCompletionItemResolve?: boolean;
isHoverDocumentationEnabled?: boolean;
isSignatureHelpDocumentationEnabled?: boolean;
overrideDefFormat?: "ascii" | "unicode";
parameterHintsCommand?: string;
snippetAutoIndent?: boolean;
}
debuggingProvider?: boolean;
decorationProvider?: boolean;
inlineDecorationProvider?: boolean;
didFocusProvider?: boolean;
doctorProvider?: "json" | "html";
executeClientCommandProvider?: boolean;
globSyntax?: "vscode" | "uri";
icons?: "vscode" | "octicons" | "atom" | "unicode";
inputBoxProvider?: boolean;
isVirtualDocumentSupported?: boolean;
isExitOnShutdown?: boolean;
isHttpEnabled?: boolean;
openFilesOnRenameProvider?: boolean;
quickPickProvider?: boolean;
renameFileThreshold?: number;
statusBarProvider?: "on" | "off" | "log-message" | "show-message";
treeViewProvider?: boolean;
testExplorerProvider?: boolean;
openNewWindowProvider?: boolean;
copyWorksheetOutputProvider?: boolean;
commandInHtmlFormat?: "vscode" | "sublime";
doctorVisibilityProvider?: boolean;
}
You can also always check these in the
InitializationOptions.scala
file where you'll find all of the options and descriptions. Alternatively you can check out the typescript equivalent - MetalsInitializationOptions.ts
compilerOptions.completionCommand
An optional string value for a command identifier to trigger completion
(textDocument/signatureHelp
) in the editor.
Possible values:
"editor.action.triggerSuggest"
: currently used by Visual Studio Code and coc.nvim.- empty: for all other editors.
compilerOptions.isCompletionItemDetailEnabled
Boolean value signifying whether or not the CompletionItem.detail
field should
be populated.
Default value: true
compilerOptions.isCompletionItemDocumentationEnabled
Boolean value signifying whether or not the CompletionItem.documentation
field
should be populated.
Default value: true
compilerOptions.isCompletionItemResolve
Boolean value signifying whether the client wants Metals to handle the
completionItem/resolve
request.
https://microsoft.github.io/language-server-protocol/specification#completionItem_resolve
Default value: true
compilerOptions.isHoverDocumentationEnabled
Boolean value signifying whether to include docstrings in a textDocument/hover
request.
Default value: true
compilerOptions.isSignatureHelpDocumentationEnabled
Boolean value signifying whether or not the SignatureHelp.documentation
field
should be populated.
Default value: true
compilerOptions.overrideDefFormat
Whether or not the presentation compiler overrides should show unicode icon or just be in ascii format.
Possible Values:
"ascii"
(default)unicode
show the "🔼" icon in overrides.
compilerOptions.parameterHintsCommand
An optional string value for a command identifier to trigger parameter hints
(textDocument/signatureHelp
) in the editor. Metals uses this setting to
populate CompletionItem.command
for completion items that move the cursor
inside an argument list. For example, when completing "".stripSu@@
into
"".stripSuffix(@@)
, Metals will automatically trigger parameter hints if this
setting is provided by the editor.
Possible values:
"editor.action.triggerParameterHints"
: Used by Visual Studio Code and coc.nvim.- empty: for all other editors.
compilerOptions.snippetAutoIndent
Certain editors will automatically insert indentation equal to that of the reference line that the operation started on. This is relevant in the case of multiline textEdits such as the "implement all methods" completion.
Possible values:
on
: (default): the client automatically adds in the indentation. This is the case for VS Code, Sublime, and coc.nvim.off
: the client does not add any indentation when receiving a multi-line textEdit
copyWorksheetOutputProvider
Boolean value signifying whether or not the client supports running CopyWorksheetOutput server command and copying its results into the local buffer.
Default value: false
debuggingProvider
Boolean value to signify that the client supports the Debug Adapter Protocol.
Default value: false
decorationProvider
Boolean value to signify that the client supports the Decoration Protocol.
Default value: false
didFocusProvider
Boolean value to signify that the client supports the
metals/didFocusTextDocument
extension.
Default value: false
disableColorOutput
Useful for certain DAP clients that are unable to handle color codes for output. This will remove the color codes coming from whatever DAP server is currently being used.
Default value: false
doctorProvider
Format that you'd like Doctor to return information in.
Possible values:
html
: (default): Metals will return html that can be rendered directly in the browser or web viewjson
: json representation of the information returned by Doctor. See the json format here.
executeClientCommandProvider
Possible values:
off
(default): themetals/executeClientCommand
notification is not supported. Client commands can still be handled by enabling-Dmetals.http=on
.on
: themetals/executeClientCommand
notification is supported and all Metals client commands are handled.
globSyntax
Controls the glob syntax for registering file watchers on absolute directories.
Registration happens via client/registerCapability
for the
workspace/didChangeWatchedFiles
method, if
the editor client supports it.
Possible values:
uri
(default): URI-encoded file paths, with forward slash/
for file separators regardless of the operating system. Includesfile://
prefix.vscode
: use regular Path.toString for the absolute directory parts (/
on macOS+Linux and\
on Windows) and forward slashes/
for relative parts. For example,C:\Users\IEUser\workspace\project/*.{scala,sbt,properties}
. This mode is used by the VS Code client.
inlineDecorationProvider
If the client implements the Metals Decoration Protocol and supports decorations to be shown inline and not only at the end of a line.
Default: false
icons
Possible values:
none
(default): don't display icons in messages.vscode
: use Octicons such as$(rocket)
for status bar messages, as supported by th VS Code status bar.unicode
: use unicode emojis like 🚀 for status bar messages.
inputBoxProvider
Possible values:
off
(default): themetals/inputBox
request is not supported. In this case, Metals tries to fall back towindow/showMessageRequest
when possible.on
: themetals/inputBox
request is fully supported.
isExitOnShutdown
Possible values:
off
(default): runSystem.exit
only on theexit
notification, as required by the LSP specification.on
: runSystem.exit
after theshutdown
request, going against the LSP specification. This option is enabled by default for Sublime Text to prevent the Metals process from staying alive after Sublime Text has quit withCmd+Q
. It's not possible for Sublime Text packages to register a callback when the editor has quit. See LSP#410 for more details.
isHttpEnabled
Possible values:
off
(default): don't start a server with the Metals HTTP client.on
: start a server with the [Metals HTTP client] to interact with the server through a basic web UI. This option is needed for editor clients that don't support necessary requests such aswindow/showMessageRequest
.
openFilesOnRenameProvider
Boolean value to signify whether or not the client opens files when doing a rename.
Default: false
openNewWindowProvider
Boolean value signifying whether or not the client supports opening up a new window with the newly created project. Used in conjunction with the New Project Provider.
Default value: false
quickPickProvider
Boolean value to signify whether or not the client implements the
metals/quickPick
extensions.
Default value: false
renameFileThreshold
The max amount of files that you would like the client to open if the client is
a openFilesOnRenameProvider
.
Default value: 300
statusBarProvider
Possible values:
off
(default): themetals/status
notification is not supported.on
: themetals/status
notification is supported.log-message
: translatemetals/status
notifications towindow/logMessage
notifications.show-message
: translatemetals/status
notifications towindow/showMessage
show notifications however the client displays messages to the user.
treeViewProvider
Boolean value signifying whether or not the client supports the Tree View Protocol.
Default value: false
testExplorerProvider
Boolean value to signify whether or not the client implements the Test Explorer.
doctorVisibilityProvider
Boolean value to signify whether or not the client implements the "metals/doctorVisibilityDidChange"
.
This JSON notification is used to keep track of doctor state. If client implements this provider then Metals server
will send updates to the doctor view.
Experimental Capabilities
All of the features that used to be set with experimental
can now all be set
via InitializationOptions
. This is the preferred way to configure Metals.
initialized
Triggers build server initialization and workspace indexing. The initialized
notification is critical for any Metals functionality to work.
shutdown
It is very important that the client sends a shutdown request in order for Metals to clean up open resources.
- persists incremental compilation analysis files. Without a
shutdown
hook, Metals will need to re-compile the entire workspace on next startup. - stops ongoing processes such as
sbt bloopInstall
- closes database connections
exit
Kills the process using System.exit
.
client/registerCapability
If the client declares the workspace.didChangeWatchedFiles
capability during
the initialize
request, then Metals follows up with a
client/registerCapability
request to register file watchers for certain glob
patterns.
textDocument/didOpen
Triggers compilation in the build server for the build target containing the
opened document. Related, see metals/didFocusTextDocument
.
textDocument/didChange
Required to know the text contents of the current unsaved buffer.
textDocument/didClose
Cleans up resources.
textDocument/didSave
Triggers compilation in the build server and analyses if the build needs to be re-imported.
textDocument/publishDiagnostics
Metals forwards diagnostics from the build server to the editor client.
Additionally, Metals publishes Information
diagnostics for unexpected
compilation errors when navigating external library sources.
textDocument/definition
Metals supports goto definition for workspace sources in addition to external library sources.
- Library sources live under the directory
.metals/readonly
and they are marked as read-only to prevent the user from editing them. - The destination location can either be a Scala or Java source file. It is recommended to have a Java language server installed to navigate Java sources.
textDocument/references
Metals finds symbol references for workspace sources but not external library dependencies.
LSP does not support streaming references so when project sources have not been
compiled at the point of a request, Metals returns immediately with potentially
incomplete results and triggers a background cascade compilation to find new
symbol references. If new symbol references are discovered after the background
compilation completes, Metals sends a notification via metals/status
and
window/logMessage
asking the user to run "find references" again.
textDocument/documentSymbol
Returns DocumentSymbol[]
if the client declares support for hierarchical
document symbol or SymbolInformation[]
otherwise.
textDocument/formatting
Formats the sources with the Scalafmt version
that is declared in .scalafmt.conf
.
- when
.scalafmt.conf
is missing, Metals sends awindow/showMessageRequest
to create the file. - when
.scalafmt.conf
exists but doesn't declare aversion
setting, Metals sends ametals/inputBox
when supported (with fallback towindow/showMessageRequest
when unsupported) to prependversion=$VERSION
to the.scalafmt.conf
file. - the first format request is usually slow because Metals needs to download
Scalafmt artifacts from Maven Central. While the download happens, Metals adds
a message in the status bar via
metals/status
and detailed download progress information is logged to.metals/metals.log
.
textDocument/hover
Returns Hover
for specified text document and position - lsp spec.
Metals also support an extended version of this method that supports hover for selection range. The extended stucture of request params is the following:
interface HoverExtParams {
textDocument: TextDocumentIdentifier;
/** Either `position` or `range` should be specified */
position?: Position;
range?: Range;
}
workspace/didChangeWatchedFiles
Optional. Metals uses a built-in file watcher for critical functionality such as
Goto Definition so it is OK if an editor does not send
workspace/didChangeWatchedFiles
notifications.
Metals listens to workspace/didChangeWatchedFiles
notifications from the
editor for nice-to-have but non-critical file watching events. Metals
automatically registers for the following glob patterns if the editor supports
dynamic registration for file watching.
{
"watchers": [
{
"globPattern": {
"left": "file:///to/workspace/*.sbt"
}
},
{
"globPattern": {
"left": "file:///to/workspace/pom.xml"
}
},
{
"globPattern": {
"left": "file:///to/workspace/*.sc"
}
},
{
"globPattern": {
"left": "file:///to/workspace/*?.gradle"
}
},
{
"globPattern": {
"left": "file:///to/workspace/*.gradle.kts"
}
},
{
"globPattern": {
"left": "file:///to/workspace/project/*.{scala,sbt}"
}
},
{
"globPattern": {
"left": "file:///to/workspace/project/project/*.{scala,sbt}"
}
},
{
"globPattern": {
"left": "file:///to/workspace/project/build.properties"
}
},
{
"globPattern": {
"left": "file:///to/workspace/.metals/.reports/bloop/*/*"
}
},
{
"globPattern": {
"left": "file:///to/workspace/**/.bsp/*.json"
}
},
{
"globPattern": {
"left": "file:///to/workspace/**/BUILD"
}
},
{
"globPattern": {
"left": "file:///to/workspace/**/BUILD.bazel"
}
},
{
"globPattern": {
"left": "file:///to/workspace/WORKSPACE"
}
},
{
"globPattern": {
"left": "file:///to/workspace/WORKSPACE.bazel"
}
},
{
"globPattern": {
"left": "file:///to/workspace/**/*.bzl"
}
},
{
"globPattern": {
"left": "file:///to/workspace/*.bazelproject"
}
}
]
}
The editor is responsible for manually watching these file patterns if the
editor does not support dynamic file watching registration but can still send
workspace/didChangeWatchedFiles
notifications.
workspace/executeCommands
Used to trigger a Metals server command.
workspace/didChangeConfiguration
Used to update Metals user configuration.
window/logMessage
Used to log non-critical and non-actionable information. The user is only expected to use the logs for troubleshooting or finding metrics for how long certain events take.
window/showMessage
Used to send critical but non-actionable notifications to the user. For
non-critical notifications, see metals/status
.
window/showMessageRequest
Used to send critical and actionable notifications to the user. To notify the user about long running tasks that can be cancelled.
Metals server properties
There are various Metals server properties that can be configured through JVM system properties. A system property is passed to the server like this:
# with `java` binary
java -Dmetals.statistics=all ...
# with `coursier bootstrap`
coursier bootstrap --java-opt -Dmetals.statistics=all ...
Below are the available server properties:
-Dmetals.verbose
Possible values:
off
(default): don't log unnecessary details.on
: emit very detailed logs, should only be used when debugging problems.
-Dmetals.statistics
By default, Metals logs only the most relevant metrics like time it takes to run sbt and import a workspace. To enable further metrics, update this property with a comma separated list of the following supported values:
memory
: print memory usage of the navigation index after build import.definition
: print total time to respond totextDocument/definition
requests.
Set the value to -Dmetals.statistics=all
to enable all statistics.
-Dmetals.h2.auto-server
Possible values:
on
(default): use H2AUTO_SERVER=TRUE
mode to support multiple concurrent Metals servers in the same workspace. If this option is enabled, the Metals H2 database communicate to other concurrently running Metals servers via TCP through a free port. In case of failure to establish aAUTO_SERVER=TRUE
connection, Metals falls back toAUTO_SERVER=FALSE
.off
: do not useAUTO_SERVER=TRUE
. By disabling this option, it's not possible to run concurrent Metals servers in the same workspace directory. For example, it's not possible to have both VS Code and Vim installed with Metals running in the same directory. In case there are multiple Metals servers running in the same workspace directory, Metals falls back to using an in-memory database resulting in a degraded user experience.
-Dmetals.pc.debug
Possible values:
off
(default): do not log verbose debugging information for the presentation compiler.on
: log verbose debugging information for the presentation compiler.
-Dbloop.sbt.version
Version number of the sbt-bloop plugin to use for the "Install build" command.
Default value is -Dbloop.sbt.version=2.0.5
.
The below properties are also available as user configuration options. It's preferable to set these there:
-Dmetals.bloop-port
Port number of the Bloop server to connect to. Should only be used if Bloop
server was set up in a custom way. Default value is 8212
.
Possible values are any allowed port number that the Bloop server is able to run on.
Metals user configuration
Users can customize the Metals server through the LSP
workspace/didChangeConfiguration
notification. Unlike server properties, it is
normal for regular Metals users to configure these options.
User configuration options can optionally be provided via server properties
using the -Dmetals.
prefix. System properties may be helpful for editor
clients that don't support workspace/didChangeConfiguration
. In case user
configuration is defined both via system properties and
workspace/didChangeConfiguration
, then workspace/didChangeConfiguration
takes precedence.
Java Home directory
The Java Home directory used for indexing JDK sources and locating the java
binary.
Default: JAVA_HOME
environment variable with fallback to user.home
system property.
Example:
{
"metals": {
"javaHome": "/Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home"
}
}
sbt script
Optional absolute path to an sbt
executable to use for running sbt bloopInstall
.
By default, Metals uses java -jar sbt-launch.jar
with an embedded launcher while respecting
.jvmopts
and .sbtopts
. Update this setting if your sbt
script requires more customizations
like using environment variables.
Default: empty string ""
.
Example:
{
"metals": {
"sbtScript": "/usr/local/bin/sbt"
}
}
Gradle script
Optional absolute path to a gradle
executable to use for running gradle bloopInstall
.
By default, Metals uses gradlew with 7.5.0 gradle version. Update this setting if your gradle
script requires more customizations
like using environment variables.
Default: empty string ""
.
Example:
{
"metals": {
"gradleScript": "/usr/local/bin/gradle"
}
}
Maven script
Optional absolute path to a maven
executable to use for generating bloop config.
By default, Metals uses mvnw maven wrapper with 3.6.1 maven version. Update this setting if your maven
script requires more customizations
Default: empty string ""
.
Example:
{
"metals": {
"mavenScript": "/usr/local/bin/mvn"
}
}
Mill script
Optional absolute path to a mill
executable to use for running mill mill.contrib.bloop.Bloop/install
.
By default, Metals uses mill wrapper script with 0.5.0 mill version. Update this setting if your mill
script requires more customizations
like using environment variables.
Default: empty string ""
.
Example:
{
"metals": {
"millScript": "/usr/local/bin/mill"
}
}
Scalafmt config path
Optional custom path to the .scalafmt.conf file.
It should be a path (relative or absolute - though an absolute path is recommended) and use
forward slashes /
for file separators (even on Windows).
Default: empty string ""
.
Example:
{
"metals": {
"scalafmtConfigPath": "project/.scalafmt.conf"
}
}
Scalafix config path
Optional custom path to the .scalafix.conf file.
It should be a path (relative or absolute - though an absolute path is recommended) and use
forward slashes /
for file separators (even on Windows).
Default: empty string ""
.
Example:
{
"metals": {
"scalafixConfigPath": "project/.scalafix.conf"
}
}
Ammonite JVM Properties
Optional list of JVM properties to pass along to the Ammonite server.
Each property needs to be a separate item.\n\nExample: -Xmx1G
or -Xms100M
"
Default: []
.
Example:
{
"metals": {
"ammoniteJvmProperties": ["-Xmx1G"]
}
}
Excluded Packages
Packages that will be excluded from completions, imports, and symbol searches.
Note that this is in addition to some default packages that are already excluded. The default excluded packages are listed below:
META-INF
images
toolbarButtonGraphics
jdk
sun
oracle
java.awt.desktop
org.jcp
org.omg
org.graalvm
com.oracle
com.sun
com.apple
apple
com.sourcegraph.shaded
If there is a need to remove one of the defaults, you are able to do so by including the
package in your list and prepending --
to it.
Example:
["--sun"]
Default: []
.
Example:
{
"metals": {
"excludedPackages": ["akka.actor.typed.javadsl"]
}
}
Don't generate Bloop plugin file for sbt
If true, Metals will not generate metals.sbt
files under the assumption that sbt-bloop is already manually installed in the sbt build. Build import will fail with a 'not valid command bloopInstall' error in case Bloop is not manually installed in the build when using this option.
Default: false
Example:
{
"metals": {
"bloopSbtAlreadyInstalled": false
}
}
Version of Bloop
This version will be used for the Bloop build tool plugin, for any supported build tool, while importing in Metals as well as for running the embedded server
Default: 2.0.5
Example:
{
"metals": {
"bloopVersion": "1.4.0-RC1"
}
}
Bloop JVM Properties
Optional list of JVM properties to pass along to the Bloop server. Please follow this guide for the format https://scalacenter.github.io/bloop/docs/server-reference#global-settings-for-the-server"
Default: ["-Xmx1G"].
Example:
{
"metals": {
"bloopJvmProperties": ["-Xmx1G"]
}
}
Should display lenses with links to super methods
Super method lenses are visible above methods definition that override another methods. Clicking on a lens jumps to super method definition. Disabled lenses are not calculated for opened documents which might speed up document processing.
Default: false
Example:
{
"metals": {
"superMethodLensesEnabled": false
}
}
Should display type annotations for inferred types
When this option is enabled, each method that can have inferred types has them displayed either as additional decorations if they are supported by the editor or shown in the hover.
Default: false
Example:
{
"metals": {
"inlayHints.inferredTypes.enable": false
}
}
Should display implicit parameter at usage sites
When this option is enabled, each method that has implicit arguments has them displayed either as additional decorations if they are supported by the editor or shown in the hover.
Default: false
Example:
{
"metals": {
"inlayHints.implicitArguments.enable": false
}
}
Should display implicit conversion at usage sites
When this option is enabled, each place where an implicit method or class is used has it displayed either as additional decorations if they are supported by the editor or shown in the hover.
Default: false
Example:
{
"metals": {
"inlayHints.implicitConversions.enable": false
}
}
Should display type annotations for type parameters
When this option is enabled, each place when a type parameter is applied has it displayed either as additional decorations if they are supported by the editor or shown in the hover.
Default: false
Example:
{
"metals": {
"inlayHints.typeParameters.enable": false
}
}
Should display type annotations in pattern matches
When this option is enabled, each place when a type is inferred in a pattern match has it displayed either as additional decorations if they are supported by the editor or shown in the hover.
Default: false
Example:
{
"metals": {
"inlayHints.hintsInPatternMatch.enable": false
}
}
Use semantic tokens highlight
When this option is enabled, Metals will provide semantic tokens for clients that support it. The feature should work within all supported files extensions aside from Java.
Default: true
Example:
{
"metals": {
"enableSemanticHighlighting": false
}
}
Indent snippets when pasted.
When this option is enabled, when a snippet is pasted into a Scala file, Metals will try to adjust the indentation to that of the current cursor.
Default: false
Example:
{
"metals": {
"enableIndentOnPaste": false
}
}
Default fallback Scala version
The Scala compiler version that is used as the default or fallback in case a file doesn't belong to any build target or the specified Scala version isn't supported by Metals. This applies to standalone Scala files, worksheets, and Ammonite scripts.
Default: 3.3.4
Example:
{
"metals": {
"fallbackScalaVersion": 3.3.4
}
}
Test UI used for tests and test suites
Default way of handling tests and test suites. The only valid values are "code lenses" and "test explorer". See https://scalameta.org/metals/docs/integrations/test-explorer for information on how to work with the test explorer.
Default: Code Lenses
Example:
{
"metals": {
"testUserInterface": test explorer
}
}
Eclipse Java formatter config path
Optional custom path to the eclipse-formatter.xml file.
It should be a path (relative or absolute - though an absolute path is recommended) and use
forward slashes /
for file separators (even on Windows).
Default: empty string ""
.
Example:
{
"metals": {
"javaFormat.eclipseConfigPath": "formatters/eclipse-formatter.xml"
}
}
Eclipse Java formatting profile
If the Eclipse formatter file contains more than one profile, this option can be used to control which is used.
Default: empty string ""
.
Example:
{
"metals": {
"javaFormat.eclipseProfile": "GoogleStyle"
}
}
Scala CLI launcher
Optional absolute path to a scala-cli
executable to use for running a Scala CLI BSP server.
By default, Metals uses the scala-cli from the PATH, or it's not found, downloads and runs Scala
CLI on the JVM (slower than native Scala CLI). Update this if you want to use a custom Scala CLI
launcher, not available in PATH.
Default: empty string ""
.
Example:
{
"metals": {
"scalaCliLauncher": "/usr/local/bin/scala-cli"
}
}
Custom project root
Optional relative path to your project's root. If you want your project root to be the workspace/workspace root set it to "." .
Default: empty string ""
.
Example:
{
"metals": {
"customProjectRoot": "backend/scalaProject/"
}
}
Show all compilation debugging information
If a build server supports it (for example Bloop or Scala CLI), setting it to true will make the logs contain all the possible debugging information including about incremental compilation in Zinc.
Default: false
Example:
{
"metals": {
"verboseCompilation": true
}
}
Import build when changes detected without prompting
Automatically import builds rather than prompting the user to choose. "initial" will only automatically import a build when a project is first opened, "all" will automate build imports after subsequent changes as well.
Default: off
Example:
{
"metals": {
"autoImportBuild": all
}
}
Default to using build tool as your build server.
If your build tool can also serve as a build server, default to using it instead of Bloop.
Default: false
Example:
{
"metals": {
"defaultBspToBuildTool": true
}
}
Metals server commands
The client can trigger one of the following commands through the
workspace/executeCommand
request.
Analyze stacktrace
Command: "analyze-stacktrace"
Arguments: [string], where the string is a stacktrace.
Converts provided stacktrace in the parameter to a format that contains links to locations of places where the exception was raised.
If the configuration parameter of the client commandInHtmlFormat
is set
then client is requested to display html with links
already pointing to proper locations in user codebase.
Otherwise client will display simple scala file
but with code lenses that direct user to proper location in codebase.
Switch build server
Command: "bsp-switch"
Arguments: null
Prompt the user to select a new build server to connect to.
This command does nothing in case there are less than two installed build servers on the computer. In case the user has multiple BSP servers installed then Metals will prompt the user to select which server to use.
Connect to build server
Command: "build-connect"
Arguments: null
Establish a new connection to the build server and reindex the workspace.
This command can be helpful in scenarios when Metals feels unresponsive, for example when reopening Metals after the computer it has been sleeping.
Cancel compilation
Command: "compile-cancel"
Arguments: null
Cancel the currently ongoing compilation, if any.
Cascade compile
Command: "compile-cascade"
Arguments: null
Compile the current open files along with all build targets in this workspace that depend on those files.
By default, Metals compiles only the current build target and its dependencies when saving a file. Run the cascade compile task to additionally compile the inverse dependencies of the current build target. For example, if you change the API in main sources and run cascade compile then it will also compile the test sources that depend on main.
Clean compile
Command: "compile-clean"
Arguments: null
Recompile all build targets in this workspace.
By default, Metals compiles the files incrementally. In case of any compile artifacts corruption this command might be run to make sure everything is recompiled correctly.
Convert positional arguments to named ones
Command: "convert-to-named-arguments"
Arguments: Object with TextDocumentPositionParams of the target Apply and numUnnamedArgs
(int)
Whenever a user chooses code action to convert to named arguments, this command is later run to determine the parameter names of all unnamed arguments and insert names at the correct locations.
Copy Worksheet Output
Command: "copy-worksheet-output"
Arguments: [uri], the uri of the worksheet that you'd like to copy the contents of.
Copy the contents of a worksheet to your local buffer.
Note: This command returns the contents of the worksheet, and the LSP client is in charge of taking that content and putting it into your local buffer.
Discover main classes to run and return the object
Command: "discover-jvm-run-command"
Arguments: DebugUnresolvedTestClassParams object Example:
{
"path": "path/to/file.scala",
"runType": "run"
}
Response:
{
"targets": ["id1"],
"dataKind": "scala-main-class",
"data": {
"class": "Foo",
"arguments": [],
"jvmOptions": [],
"environmentVariables": [],
"shellCommand": "java ..."
}
}
Gets the DebugSession object that also contains a command to run in shell based on JVM environment including classpath, jvmOptions and environment parameters.
Discover tests
Command: "discover-tests"
Arguments: An object with uri, when request is meant to discover test cases for uri
{
uri: file:///home/dev/foo/Bar.scala
}
or empty object if request is meant to discover all test suites
{}
Discovers all tests in project or a file. See ClientCommands.UpdateTestExplorer to see how response looks like.
Extract member definition
Command: "extract-member-definition"
Arguments: This command should be sent in with the LSP TextDocumentPositionParams
Whenever a user chooses a code action to extract a definition of a Class/Trait/Object/Enum this command is later ran to extract the code and create a new file with it
Generate BSP Config
Command: "generate-bsp-config"
Arguments: [string], name of the build server.
Checks to see if your build tool can serve as a BSP server. If so, generate the necessary BSP config to connect to the server. If there is more than one build tool for a workspace, you can then choose the desired one and that one will be used to generate the config.
After the config is generated, Metals will attempt to auto-connect to it.
The build servers that Metals knows how to detect and start:
- sbt
- mill-bsp
Note: while Metals does know how to start Bloop, Bloop will be started when you trigger a build
import or when you use bsp-switch
to switch to Bloop.
Goto location for position
Command: "goto-position"
Arguments: [location], where the location is a lsp location object.
Move the cursor to the location provided in arguments. It simply forwards request to client.
Go to super method/field definition
Command: "goto-super-method"
Arguments: This command should be sent in with the LSP TextDocumentPositionParams
Jumps to super method/field definition of a symbol under cursor according to inheritance rules.
When A {override def x()} <:< B <:< C {def x()}
and on method 'A.x' it will jump directly to 'C.x'
as method x() is not overridden in B.
If symbol is a reference of a method it will jump to a definition.
If symbol under cursor is invalid or does not override anything then command is ignored.
Goto location for symbol
Command: "goto"
Arguments: [string], where the string is a SemanticDB symbol.
Move the cursor to the definition of the argument symbol.
Import build
Command: "build-import"
Arguments: null
Import the latest changes from the build to for example pick up new library dependencies.
By default, Metals automatically prompts you to import the build when sources of the build change. Use this command to manually trigger an import build instead of relying on the automatic prompt.
Insert inferred type of a value
Command: "insert-inferred-type"
Arguments: This command should be sent in with the LSP TextDocumentPositionParams
Whenever a user chooses code action to insert the inferred type this command is later ran to calculate the type and insert it in the correct location.
Inline value
Command: "inline-value"
Arguments: This command should be sent in with the LSP TextDocumentPositionParams
Whenever a user chooses code action to inline a value this command is later ran to find all the references to choose the correct inline version (if possible to perform)
Create new scala file
Command: "new-scala-file"
Arguments: [string[]], where the first is a directory location for the new file. The second and third positions correspond to the file name and file type to allow for quick creation of a file if all are present.
Create and open new Scala file.
The currently allowed Scala file types that can be passed in are:
- scala-file (Empty file)
- scala-class (Class)
- scala-case-class (Case Class)
- scala-enum (Enum)
- scala-object (Object)
- scala-trait (Trait)
- scala-package-object (Package Object)
- scala-worksheet (Worksheet)
- scala-script (Scala Script(Ammonite or Scala CLI))
Note: requires 'metals/inputBox' capability from language client.
Create new java file
Command: "new-java-file"
Arguments: [string[]], where the first is a directory location for the new file. The second and third positions correspond to the file name and file type to allow for quick creation of a file if all are present.
Create and open a new Java file.
The currently allowed Java file types that ca be passed in are:
- java-class (Class)
- java-interface (Interface)
- java-enum (Enum)
- java-record (Record)
Note: requires 'metals/inputBox' capability from language client.
New Scala Project
Command: "new-scala-project"
Arguments: null
Create a new Scala project using one of the available g8 templates.
This includes simple projects as well as samples for most of the popular Scala frameworks.
The command reuses the Metals quick pick extension to work and can function with window/showMessageRequest
,
however the experience will not be optimal in that case. Some editors might also offer to open the newly created
project via openNewWindowProvider
, but it is not necessary for the main functionality to work.
Restart presentation compiler
Command: "presentation-compiler-restart"
Arguments: null
Restart running presentation compiler instances.
Metals automatically restarts the presentation compiler after every successful compilation in the build tool so this command should not be needed for normal usage. Please report an issue if you need to use this command.
Reset Choice Popup
Command: "reset-choice"
Arguments: [string?], where string is a choice value.
ResetChoicePopup command allows you to reset a decision you made about different settings. E.g. If you choose to import workspace with sbt you can decide to reset and change it again.
Provided string is optional but if present it must be one of defined in PopupChoiceReset.scala
If a choice is not provided it will execute interactive mode where user is prompt to select
which choice to reset.
Reset notifications
Command: "reset-notifications"
Arguments: null
ResetNotifications command allows you to reset all the dismissed notifications. E.g. If you choose to dismiss build import forever, this command will make the notification show up again.
Extract method from range
Command: "extract-method"
Arguments: LSP [TextDocumentIdentifier
], (https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocumentIdentifier),
LSP [Range
], range of the code you'd like to extract as method,
LSP [Position
], position where the definition of extracted method will be created.
Whenever a user chooses code action to extract method, this command is later ran to calculate parameters for the newly created method and create its definition.
Restart build server
Command: "build-restart"
Arguments: null
Unconditionally stop the current running Bloop server and start a new one using Bloop launcher
Run doctor
Command: "doctor-run"
Arguments: null
Open the Metals doctor to troubleshoot potential problems with the build.
This command can be helpful in scenarios where features are not working as expected such as compile errors are not appearing or completions are not correct.
Run all Scalafix Rules
Command: "scalafix-run"
Arguments: This command should be sent in with the LSP TextDocumentPositionParams
Run all the supported scalafix rules in your codebase.
If the rules are missing please add them to user configuration metals.scalafixRulesDependencies
.
Their format is the coursier one https://get-coursier.io/
Run a set of Scalafix Rules
Command: "scalafix-run-only"
Arguments: RunScalafixRulesParams object Example:
{
"textDocumentPositionParams": {
"textDocument": {
"uri": "path/to/file.scala"
},
"position": {
"line": 70,
"character": 33
}
},
"rules": ["ExplicitResultTypes"]
}
Run a set of Scalafix rules in your codebase.
If no rules are specified, this command will prompt the user to select one from a list of their project's enabled rules.
If you want to run all rules, use the scalafix-run
command instead.
Decode file
Command: "file-decode"
Arguments: [uri], uri of the file with any parameters required for decoding. Examples:
- javap:
metalsDecode:file:///somePath/someFile.java.javap
metalsDecode:file:///somePath/someFile.scala.javap
metalsDecode:file:///somePath/someFile.class.javap
metalsDecode:file:///somePath/someFile.java.javap-verbose
metalsDecode:file:///somePath/someFile.scala.javap-verbose
metalsDecode:file:///somePath/someFile.class.javap-verbose - semanticdb:
metalsDecode:file:///somePath/someFile.java.semanticdb-compact
metalsDecode:file:///somePath/someFile.java.semanticdb-detailed
metalsDecode:file:///somePath/someFile.scala.semanticdb-compact
metalsDecode:file:///somePath/someFile.scala.semanticdb-detailed
metalsDecode:file:///somePath/someFile.java.semanticdb.semanticdb-compact
metalsDecode:file:///somePath/someFile.java.semanticdb.semanticdb-detailed
metalsDecode:file:///somePath/someFile.scala.semanticdb.semanticdb-compact
metalsDecode:file:///somePath/someFile.scala.semanticdb.semanticdb-detailed - tasty:
metalsDecode:file:///somePath/someFile.scala.tasty-decoded
metalsDecode:file:///somePath/someFile.tasty.tasty-decoded - jar:
metalsDecode:jar:file:///somePath/someFile-sources.jar!/somePackage/someFile.java
- build target:
metalsDecode:file:///workspacePath/buildTargetName.metals-buildtarget
Response:
interface DecoderResponse {
requestedUri: string;
value?: string;
error?: string
}
Decode a file into a human readable format.
Compilation involves various binary files that can't be read directly
in a text editor so they need to be decoded into a human readable format.
Examples include .class
and .semanticdb
.
Disconnect from old build server
Command: "build-disconnect"
Arguments: null
Unconditionally cancel existing build server connection without reconnecting
List build targets
Command: "list-build-targets"
Arguments: null
Retrieve a list of build targets for the workspace.
Scan sources
Command: "sources-scan"
Arguments: null
Walk all files in the workspace and index where symbols are defined.
Is automatically run once after initialized
notification and incrementally
updated on file watching events. A language client that doesn't support
file watching can run this manually instead. It should not be much slower
than walking the entire file tree and reading *.scala
files to string,
indexing itself is cheap.
Start Ammonite build server
Command: "ammonite-start"
Arguments: null
Start Ammonite build server
Start debug adapter
Command: "debug-adapter-start"
Arguments: DebugSessionParameters object Example:
{
"targets": ["mybuild://workspace/foo/?id=foo"],
dataKind: "scala-main-class",
data: {
className: "com.foo.App"
}
}
Start a new debugger session with fully specified DebugSessionParams
Start main class
Command: "debug-adapter-start"
Arguments: DebugUnresolvedMainClassParams object Example:
{
"mainClass": "path/to/file.scala",
"buildTarget": "metals"
}
Start a new debugger session by resolving a main class by name and target
Start test suite
Command: "debug-adapter-start"
Arguments: ScalaTestSuitesDebugRequest object Example:
{
"target": "metals"
"requestData" : {
"suites": ["com.foo.FooSuite"],
"jvmOptions": []],
"environmentVariables": [],
}
}
Start a new debugger session for a test suite, can be used to run a single test case
Start test suite
Command: "debug-adapter-start"
Arguments: DebugUnresolvedTestClassParams object Example:
{
"testClass": "com.foo.FooSuite"
}
Start a new debugger session by resolving a test suite by name and possibly target.
Attach to a running jvm process
Command: "debug-adapter-start"
Arguments: DebugUnresolvedAttachRemoteParams object Example:
{
"hostName": "localhost",
"port": 1234,
"buildTarget": "metals",
}
Start a new debugger session by attaching to existing jvm process.
Try to discover a test or main to run.
Command: "debug-adapter-start"
Arguments: DebugDiscoveryParams object Example:
{
"path": "path/to/file.scala",
"runType": "run",
}
Start a new debugger session by running the discovered test or main class.
Stop Ammonite build server
Command: "ammonite-stop"
Arguments: null
Stop Ammonite build server
Go to super method/field definition in hierarchy
Command: "super-method-hierarchy"
Arguments: This command should be sent in with the LSP TextDocumentPositionParams
When user executes this command it will calculate inheritance hierarchy of a class that contains given method. Then it will filter out classes not overriding given method and a list using 'metalsQuickPick' will be displayed to which super method user would like to go to. Command has no effect on other symbols than method definition. QuickPick will show up only if more than one result is found.
Start Scala CLI server
Command: "scala-cli-start"
Arguments: null
Start Scala CLI server
Stop Scala CLI server
Command: "scala-cli-stop"
Arguments: null
Stop Scala CLI server
Open an issue on GitHub
Command: "open-new-github-issue"
Arguments: null
Open the Metals repository on GitHub to ask a question or report a bug.
Open a feature request
Command: "browser-open-url:https://github.com/scalameta/metals-feature-requests/issues/new?template=feature-request.yml"
Arguments: null
Open the Metals repository on GitHub to open a feature request.
Create a zip with error reports
Command: "zip-reports"
Arguments: null
Creates a zip from incognito and bloop reports with additional information about build targets.
Clean and restart build server
Command: "reset-workspace"
Arguments: null
Clean metals cache and restart build server.
When using Bloop, clears all directories in .bloop. This will ensure that Bloop will have a fully reset state.
Metals client commands
The Metals server can send one of the following client commands if the client
supports the metals/executeClientCommand
notification,
Open a specified folder either in the same or new window
Command: "metals-open-folder"
Arguments: An object with uri
and newWindow
fields.
Example:
{
"uri": "file://path/to/directory",
"newWindow": true
}
Open a new window with the specified directory.
Run doctor
Command: "metals-doctor-run"
Arguments: string
, the HTML to display in the focused window.
Focus on a window displaying troubleshooting help from the Metals doctor.
If doctorProvider
is set to "json"
then the schema is as follows:
export interface DoctorOutput {
/** Metals Doctor title */
title: string;
/** Version of the doctor json format, 0 if empty
* The latest version is: 6
*/
version: String;
/**
* Contains metals version and jdk info and a brief information about understanding
* the Doctor placed in here as well. (since version 3 (replaces headerText))
*/
header: DoctorHeader;
/**
* Troubleshooting help for each workspace folder.
*/
folders: DoctorFolderResult[];
}
export interface DoctorFolderResult {
/**
* Contains decisions that were made about what build tool or build server
* the user has chosen.
*/
header: DoctorFolderHeader
/**
* If build targets are detected in your workspace, they will be listed here with
* the status of related functionality of Metals for each build target.
*/
targets?: DoctorBuildTarget[];
/** Messages given if build targets cannot be found */
messages?: DoctorRecommendation[];
/** Explanations for the various statuses present in the doctor */
explanations?: DoctorExplanation[];
/** Error reports reported from Metals */
errorReports: ErrorReportInfo[];
}
export interface DoctorHeader {
/** java version and location information */
jdkInfo?: string;
/** the version of the server that is being used */
serverInfo: string;
/** small description on what a build target is */
buildTargetDescription: string;
}
export interface DoctorFolderHeader {
/** information about java used for project */
projectsJavaInfo?: string;
/** if Metals detected multiple build tools, this specifies the one the user has chosen */
buildTool?: string;
/** the build server that is being used */
buildServer: string;
/** if the user has turned the import prompt off, this will include a message on
* how to get it back.
*/
importBuildStatus?: string;
}
export interface DoctorBuildTarget {
/** Name of the build target */
buildTarget: string;
/** Status of compilation for build this build target (since version 2) */
compilationStatus: string;
/** Can contain Scala version, sbt version or Java */
targetType: string;
/** Status of diagnostics */
diagnostics: string;
/** Status of completions, hovers and other interactive features*/
interactive: string;
/** Status of semanticdb indexes */
semanticdb: string;
/** Status of debugging */
debugging: string;
/** Status of java support */
java: string;
/** Any recommendations in how to fix any issues that are found above */
recommendation: string;
}
export interface DoctorRecommendation {
/** Title of the recommendation */
title: string;
/** Recommendations related to the found issue. */
recommendations: string[]
}
export interface DoctorExplanation {
/** Title of the explanation */
title: string;
/** Explanations of statuses that can be found in the doctor */
recommendations: string[]
}
export interface ErrorReportInfo {
/** Display name of the error */
name: string;
/** Timestamp of the report creation date */
timestamp: number;
/** Error report file uri */
uri: string;
/** Build target that the error is associated with */
buildTarget?: string;
/** Short error summary */
shortSummary: string;
/** The type of error -- This can be metals, metals-full, or bloop currently */
errorReportType: string;
}
Reload doctor
Command: "metals-doctor-reload"
Arguments: string
, the HTML to display in the focused window.
Reload the HTML contents of an open Doctor window, if any. Should be ignored if there is no open doctor window.
If doctorProvider
is set to "json"
, then the schema is the same as found above in "metals-run-doctor"
Toggle logs
Command: "metals-logs-toggle"
Arguments: null
Focus or remove focus on the output logs reported by the server via window/logMessage
.
In VS Code, this opens the "output" channel for the Metals extension.
Open problems
Command: "metals-diagnostics-focus"
Arguments: null
Focus on the window that lists all published diagnostics.
In VS Code, this opens the "problems" window.
Goto location
Command: "metals-goto-location"
Arguments: First required parameter is LSP Location
object with uri
and range
fields.
Second parameter is optional and has signature otherWindow: Boolean
.
It gives a hint to client that if possible it would be good to open location in
another buffer/window.
Example:
[{
"uri": "file://path/to/Definition.scala",
"range": {
"start": {"line": 194, "character": 0},
"end": {"line": 194, "character": 1}
},
"otherWindow" : true
},
]
Move the cursor focus to the provided location
Echo command
Command: "metals-echo-command"
Arguments: string
, the command ID to execute on the client.
A client command that should be forwarded back to the Metals server.
Metals may register commands in client UIs like tree view nodes that should be forwarded back to the Metals server if the client clicks on the UI elements.
Refresh model
Command: "metals-model-refresh"
Arguments: null
Note: This request is deprecated and Metals will favor Code Lens Refresh Request if supported by the client.
Notifies the client that the model has been updated and it should be refreshed (e.g. by resending code lens request)
Show the stacktrace in the client.
Command: "metals-show-stacktrace"
Arguments: [string], the markdown representation of the stacktrace
Show the stacktrace modified with links to specific files.
Copy Worksheet Output
Command: "metals.copy-worksheet-output"
Arguments: [uri], the uri of the worksheet that you'd like to copy the contents of.
Copy the contents of a worksheet to your local buffer.
Note: This command should execute the copy-worksheet-output server command to get the output to copy into the buffer.
Server will attempt to create code lens with this command if copyWorksheetOutputProvider
option is set.
Start run session
Command: "metals-run-session-start"
Arguments: DebugSessionParameters object. It should be forwarded to the debug-adapter-start command as is.
Example:
{
"targets": ["mybuild://workspace/foo/?id=foo"],
dataKind: "scala-main-class",
data: {
className: "com.foo.App"
}
}
Starts a run session. The address of a new Debug Adapter can be obtained by using the debug-adapter-start metals server command with the same arguments as provided to this command.
Start debug session
Command: "metals-debug-session-start"
Arguments: DebugSessionParameters object. It should be forwarded to the debug-adapter-start command as is.
Example:
{
"targets": ["mybuild://workspace/foo/?id=foo"],
dataKind: "scala-main-class",
data: {
className: "com.foo.App"
}
}
Starts a debug session. The address of a new Debug Adapter can be obtained by using the debug-adapter-start metals server command with the same arguments as provided to this command.
Connect to build server.
Command: "metals-build-connect"
Arguments: null
Establish a new connection to the build server and reindex the workspace.
This command can be helpful in scenarios when Metals feels unresponsive, for example when reopening Metals after the computer it has been sleeping.
Metals HTTP client
Metals has an optional web interface that can be used to trigger server commands and respond to server requests. This interface is not intended for regular users, it exists only to help editor plugin authors integrate with Metals.
The server is enabled by passing the -Dmetals.http=on
system property. The
server runs by default at http://localhost:5031
.
When the port 5031 is taken the next free increment is chosen instead (5032,
5033, ...).
Metals LSP extensions
Editor clients can opt into receiving Metals-specific JSON-RPC requests and notifications. Metals extensions are not defined in LSP and are not strictly required for the Metals server to function but it is recommended to implement them to improve the user experience.
To enable Metals extensions, start the main process with the system property
-Dmetals.extensions=true
.
Debug Adapter Protocol
Metals implements and additional protocol for running and debugging inside the editor, see the Debug Adapter Protocol.
Tree View Protocol
Metals implements several custom JSON-RPC endpoints related to rendering tree views in the editor client, the Tree View Protocol.
Decoration Protocol
Metals implements an LSP extension to display non-editable text in the editor, see the Decoration Protocol.
metals/status
The Metals status notification is sent from the server to the client to notify
about non-critical and non-actionable events that are happening in the server.
Metals status notifications are a complement to window/showMessage
and
window/logMessage
. Unlike window/logMessage
, status notifications should
always be visible in the user interface. Unlike window/showMessage
, status
notifications are not critical meaning that they should not demand too much
attention from the user.
In general, Metals uses status notifications to update the user about ongoing events in the server such as batch compilation in the build server or when a successful connection was established with the build server.
The "🚀 Imported build" and "🔄 Compiling explorer" messages at the bottom of
the window are metals/status
notifications.
Notification:
- method:
metals/status
- params:
MetalsStatusParams
defined as follows:
interface MetalsStatusParams {
/** The text to display in the status bar. */
text: string;
/** If true, show the status bar. */
show?: boolean;
/** If true, hide the status bar. */
hide?: boolean;
/** If set, display this message when user hovers over the status bar. */
tooltip?: string;
/** If set, execute this command when the user clicks on the status bar item. */
command?: string;
}
metals/didFocusTextDocument
The Metals did focus notification is sent from the client to the server when the
editor changes focus to a new text document. Unlike textDocument/didOpen
, the
did focus notification is sent even when the text document is already open.
Observe that the compilation error appears as soon as UserTest.scala
is
focused even if the text document was already open before. The LSP
textDocument/didOpen
notification is only sent the first time a document so it
is not possible for the language server to re-trigger compilation when moves
focus back to UserTest.scala
that depends on APIs defined in User.scala
.
Notification:
- method:
metals/didFocusTextDocument
- params:
string
, the URI of the document where the focused was moved to.
metals/executeClientCommand
The Metals execute client command is sent from the server to the client to
trigger an action inside the editor. This notification is a copy of the
workspace/executeCommand
except
- execute client command is a notification, not a request
- execute client command is initiated from the server, not the client
See Metals client commands for the list of supported client commands.
Notification:
- method:
metals/executeClientCommand
- params:
ExecuteCommandParams
, as defined in LSP.
metals/inputBox
The Metals input box request is sent from the server to the client to let the
user provide a string value for a given prompt. Unlike
window/showMessageRequest
, the metals/inputBox
request allows the user to
provide a custom response instead of picking a pre-selected value.
Request:
- method:
metals/inputBox
- params:
MetalsInputBoxParams
defined as follows. Note, matchesInputBoxOptions
in the Visual Studio Code API:
export interface MetalsInputBoxParams {
/**
* The value to prefill in the input box.
*/
value?: string;
/**
* The text to display underneath the input box.
*/
prompt?: string;
/**
* An optional string to show as place holder in the input box to guide the user what to type.
*/
placeHolder?: string;
/**
* Set to `true` to show a password prompt that will not show the typed value.
*/
password?: boolean;
/**
* Set to `true` to keep the input box open when focus moves to another part of the editor or to another window.
*/
ignoreFocusOut?: boolean;
}
- result:
MetalsInputBoxResult
defined as follows:
export interface MetalsInputBoxResult {
value?: string;
cancelled?: boolean;
}
metals/quickPick
The Metals quick pick request is sent from the server to the client to let the
user provide a string value by picking one out of a number of given options. It
is similar to window/showMessageRequest
, but the metals/quickPick
request
has richer parameters, that can be used to filter items to pick, like
description
and detail
.
Request:
- method:
metals/quickPick
- params:
MetalsQuickInputParams
defined as follows. It partially matchesQuickPickOptions
in the Visual Studio Code API, but it also containsitems
ofMetalsQuickPickItem
, which, in it's turn, partially matchesQuickPickItem
, but these interfaces do not contain options for picking many items:
export interface MetalsQuickPickParams {
/**
* An array of items that can be selected from.
*/
items: MetalsQuickPickItem[];
/**
* An optional flag to include the description when filtering the picks.
*/
matchOnDescription?: boolean;
/**
* An optional flag to include the detail when filtering the picks.
*/
matchOnDetail?: boolean;
/**
* An optional string to show as place holder in the input box to guide the user what to pick on.
*/
placeHolder?: string;
/**
* Set to `true` to keep the picker open when focus moves to another part of the editor or to another window.
*/
ignoreFocusOut?: boolean;
}
export interface MetalsQuickPickItem {
/**
* An id for this items that should be return as a result of the picking.
*/
id: string;
/**
* A human readable string which is rendered prominent.
*/
label: string;
/**
* A human readable string which is rendered less prominent.
*/
description?: string;
/**
* A human readable string which is rendered less prominent.
*/
detail?: string;
/**
* Always show this item.
*/
alwaysShow?: boolean;
}
- result:
MetalsQuickPickResult
defined as follows:
export interface MetalsQuickPickResult {
itemId?: string;
cancelled?: boolean;
}
metals/windowStateDidChange
The metals/windowStateDidChange
notification is sent from the client to the
server to indicate whether the editor application window is focused or not. When
the editor window is not focused, Metals tries to avoid triggering expensive
computation in the background such as compilation.
Notification:
- method:
metals/windowStateDidChange
- params:
WindowStateDidChangeParams
defined as follows:
interface WindowStateDidChangeParams( {
/** If true, the editor application window is focused. False, otherwise. */
focused: boolean;
}
metals/openWindow
The metals/openWindow
params are used with the New Scala Project
functionality. After the new project has been created, if the editor has the
ability to open the project in a new window then these params are used with the
metals-open-folder
command.
interface MetalsOpenWindowParams {
/** Location of the newly created project. */
uri: string;
/** Whether or not to open the project in a new window. */
openNewWindow: boolean;
}
metals/findTextInDependencyJars
The FindTextInDependencyJars
request is sent from the client to the server to perform a search though files in the classpath
including binary and sources jars. In response it returns a standard list of Location
from the LSP spec.
In case if this endpoint was called with empty query.pattern
or empty options.include
server sends metals/inputBox
request to the client to obtain these values.
Request:
- method:
metals/findTextInDependecyJars
- params:
FindTextInDependencyJarsRequest
defined as follows.
/**
* Currenly, only `pattern` field is used for search.
* See: https://github.com/scalameta/metals/issues/3234
*/
interface TextSearchQuery {
/**
* The text pattern to search for.
*/
pattern?: string;
/**
* Whether or not `pattern` should be interpreted as a regular expression.
*/
isRegExp?: boolean;
/**
* Whether or not the search should be case-sensitive.
*/
isCaseSensitive?: boolean;
/**
* Whether or not to search for whole word matches only.
*/
isWordMatch?: boolean;
}
interface FindTextInFilesOptions {
/** Include file filter. Example: `*.conf` */
include?: string;
/** Exclude file filter. Example: `*.conf` */
exclude?: string;
}
interface FindTextInDependencyJarsRequest(
options?: FindTextInFilesOptions;
query: TextSearchQuery
)
Response:
- result:
Location[]
metals/doctorVisibilityDidChange
When the client opens the doctor view, it will send in visible: true
to the
server and then visible: false
when the doctor view is closed. This will
ensure that the doctor checks aren't calculated on the server side when they
aren't needed to since they won't be seen by the client anyways.
Notification:
- method:
metals/doctorVisibilityDidChange
- params:
DoctorVisibilityDidChangeParams
interface DoctorVisibilityDidChangeParams {
visible: boolean;
}