Skip to main content

Metals v0.9.5 - Lithium

· 11 min read

We're happy to announce the release of Metals v0.9.5, which brings about some of the long awaited features such as implicit decorations and the organize imports code action. We also greatly simplified connecting to the sbt BSP server and added support for Scala 3's first milestone 3.0.0-M1.

Commits since last release185
Merged PRs70
Contributors9
Closed issues33
New features5

For full details: https://github.com/scalameta/metals/milestone/28?closed=1

Metals is a language server for Scala that works with VS Code, Vim, Emacs, Sublime Text, Atom and Eclipse. Metals is developed at the Scala Center and VirtusLab with the help from Lunatech along with contributors from the community.

TL;DR

Check out https://scalameta.org/metals/, and give Metals a try!

  • Organize imports code action.
  • Show implicit parameters and inferred type decorations.
  • Improved sbt BSP support.
  • Support for Scala 3.0.0-M1.
  • Remote debugging.
  • Environment variables in run/debug.

Organize imports code action

One of the most requested features in the Metals repository, current list can be found here, was the ability to automatically organize imports. We are happy to announce, that thanks to mlachkar's amazing contributions to both Scalafix and Metals, this new feature is now available via an Organize imports code action.

imports

Depending on the editor this code action can be invoked differently, please consult your specific editor's documentation. For example in Visual Studio Code 'organize imports' can be invoked from command console, shortcut, or from the dropdown menu when right clicking inside a file.

The organize imports code action is enabled using Scalafix and specifically the awesome organize imports rule created by liancheng.

The rule can be used to automatically sort imports in a file by the Ascii order, which is the default setting, or use the user specific configuration defined using scalafix configuration file. This file can be either .scalafix.conf in the current workspace or an absolute file specified in the metals.scalafixConfigPath user setting. It's important to note that the new code action is consistent with how sbt's scalafix plugin will behave.

An example scalafix configuration for the organize imports rule can look like this:

OrganizeImports {
groups = ["re:javax?\\.", "scala.", "*"]
removeUnused = true
}

This will sort imports into 3 groups defined with regexes and remove any unused ones. Specifically, it will turn:

import scala.collection.mutable.{Buffer, ArrayBuffer}
import java.time.Clock
import java.lang.{Long => JLong, Double => JDouble}

object RemoveUnused {
val buffer: ArrayBuffer[Int] = ArrayBuffer.empty[Int]
val long: JLong = JLong.parseLong("0")
}

into

import java.lang.{Long => JLong}

import scala.collection.mutable.ArrayBuffer

object RemoveUnused {
val buffer: ArrayBuffer[Int] = ArrayBuffer.empty[Int]
val long: JLong = JLong.parseLong("0")
}

Please do NOT use the Scalafix built-in RemoveUnused.imports together with OrganizeImports to remove unused imports, since it might result in a broken code.

More information can be found in the liancheng/scalafix-organize-imports repository.

Show implicits and type decorations

Another highly anticipated feature was the ability to show additional information about the code, which is not provided explicitly. In this new release, users can use two new options when looking through their code:

  • metals.showImplicitArguments will enable users to see implicit parameters within their code:

params

  • metals.showInferredType will enable users to see inferred type for any generic methods they are using:

types

Both new options are disabled by default, since they add a great number of information, which might not be necessary for all users. Full name with package for each of the additional types or values will be available on hover.

These options can be set in Metals options in VS Code or in Emacs (lsp-metals) using lsp-metals-show-implicit-arguments and lsp-metals-show-inferred-type variables set to t.

Unfortunately, due to current limitations, additional decorations are only possible in Visual Studio Code and Emacs. In other editors the additional information is available via hover and new With synthetics added section, which shows how the whole current line would look with the additional decorations.

Example of how this alternative approach looks in Vim:

vim-sample

Improved sbt BSP support

In recent months, eed3si9n and adpi2 worked, under the auspices of Scala Center, on making sbt capable of acting as a Build Server Protocol server. This enables Metals and other editors such as Intellij IDEA to directly communicate with sbt in order to compile the user's code.

Some more work was required in order to make the new features work smoothly with Metals and currently, thanks to ckipp01, users can easily try out the new sbt BSP support. It's important to note that using Bloop instead of sbt is still the recommended approach as we believe it provides the best user experience and features like running or debugging are still not yet implemented for sbt. More details and explanations can be found in the blogpost.

Remote debugging

Thanks to the great work of pvid, Metals now supports remote debugging, which means that it can attach to a running process with the proper JVM options specified. There is no longer a need to run the application or test from within the editor.

In case of a simple java process those options will take a form of for example:

-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005

Some of the more important options here are:

  • suspend=y will make the process wait for Metals to connect to it if specified to y. n will cause the process to run normally.
  • address=5005 specifies which port to use and it can be any free port.

For a detailed explanation of the different options please refer to the proper documentation here

When using sbt, remote debugging can be achieved by specifying additional settings:

javaOptions in run := List("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"),
fork in run := true

This will cause running sbt run to wait for Metals to connect to it, which might be especially useful when reading user input, which is currently impossible to do for example from within VS Code. Similarly, these options can be specified in any of the supported build tools.

To later connect to the running process, you need to use the additional Attach request type with the buildTarget, hostname and port fields specified. In case of Visual Studio Code this will take a form of:

{
"type": "scala",
"request": "attach",
"name": "Attach",
"buildTarget": "root",
"hostName": "localhost",
"port": 5005
}

Environment variables in run/debug

Metals now supports specifying additional environment options when running or debugging applications. This can be done twofold:

  • By specifying the new env field:
{
"type": "scala",
"name": "Debug Main",
"request": "launch",
"mainClass": "Main",
"args": ["hello", "world"],
"env": { "VARIABLE1": " 123" }
}
  • By using the envFile field:
{
"type": "scala",
"name": "Debug Main",
"request": "launch",
"mainClass": "Main",
"args": ["hello", "world"],
"envFile": "local.env"
}

Where the local.env file can take a form of:

# single line values
key1=value 1
key2='value 2' # ignored inline comment
key3="value 3"

# multi-line values
key4='line 1
line 2'
key5="line 1
line 2"

# export statements
export key6=value 6

# comma delimiter
key7:value 6

# keys cannot contain dots or dashes
a.b.key8=value 8 # will be ignored
a-b-key9=value 9 # will be ignored

The format is adapted from mefellows/sbt-dotenv and bkeepers/dotenv. Example json configurations above are defined for Visual Studio Code, the type and name fields can be omitted when using in other clients.

This new feature has been contributed by mwz. Thanks for the great work!

Miscellaneous

  • Removed javax from default excluded packages - it can be added back in the configuration.
  • Fixed top level completions in empty files.
  • Fixed issues with run/debug when using VPN.
  • Fixed go to java sources in standalone worksheets.
  • Fixed issues with worksheets if the workspace was not first compiled.
  • Fixed sbt completions coming from project/*.scala files.
  • Only use import {java.util => ju} when there are conflicting symbols in the file.
  • Muted InvalidProtocolException in the logs - this exception might happen. normally and does not break anything.
  • Changed scalafix and scalafmt location in user configuration to absolute path.
  • Only report parsing errors after Scala version is confirmed for a file.
  • Added automatic retry in case of build server connection failure.

Contributors

Big thanks to everybody who contributed to this release or reported an issue!

$ git shortlog -sn --no-merges v0.9.4..v0.9.5
Chris Kipp
Scala Steward
Tomasz Godzik
Michael Wizner
Meriam Lachkar
Gabriele Petronella
Krzysiek Bochenek
Pavol Vidlicka
Vadim Chelyshov

Merged PRs

v0.9.5 (2020-11-10)

Full Changelog

Merged pull requests: