Skip to main content

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 view
  • json: json representation of the information returned by Doctor. See the json format here.
executeClientCommandProvider

Possible values:

  • off (default): the metals/executeClientCommand notification is not supported. Client commands can still be handled by enabling -Dmetals.http=on.
  • on: the metals/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. Includes file:// 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): the metals/inputBox request is not supported. In this case, Metals tries to fall back to window/showMessageRequest when possible.
  • on: the metals/inputBox request is fully supported.
isExitOnShutdown

Possible values:

  • off (default): run System.exit only on the exit notification, as required by the LSP specification.
  • on: run System.exit after the shutdown 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 with Cmd+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 as window/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): the metals/status notification is not supported.
  • on: the metals/status notification is supported.
  • log-message: translate metals/status notifications to window/logMessage notifications.
  • show-message: translate metals/status notifications to window/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 a window/showMessageRequest to create the file.
  • when .scalafmt.conf exists but doesn't declare a version setting, Metals sends a metals/inputBox when supported (with fallback to window/showMessageRequest when unsupported) to prepend version=$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 to textDocument/definition requests.

Set the value to -Dmetals.statistics=all to enable all statistics.

-Dmetals.h2.auto-server

Possible values:

  • on (default): use H2 AUTO_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 a AUTO_SERVER=TRUE connection, Metals falls back to AUTO_SERVER=FALSE.
  • off: do not use AUTO_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"]
}
}

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.

Metals http client

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.

Metals status bar

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.

Metals did focus

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, matches InputBoxOptions 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 matches QuickPickOptions in the Visual Studio Code API, but it also contains items of MetalsQuickPickItem, which, in it's turn, partially matches QuickPickItem, 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;
}