Metals

Metals

  • Docs
  • Blog
  • GitHub

›Integrating with Metals

Text Editors

  • Overview
  • Visual Studio Code
  • Vim
  • Sublime Text
  • Emacs
  • Eclipse

Build Tools

  • Overview
  • Bloop
  • Gradle
  • Maven
  • Mill
  • sbt

Contributing

  • Project Goals
  • Contributing to Metals
  • Contributing to the website
  • Making a release
  • Tests overview

Integrating with Metals

  • Remote Language Servers
  • Integrating a new build tool
  • Integrating a new editor
  • Tree View Protocol
  • Decoration Protocol
  • Debug Adapter Protocol

Troubleshooting

  • Proxy and mirrors
  • Frequently asked questions
Edit

Debug Adapter Protocol

Metals implements the Debug Adapter Protocol, which can be used by the editor to communicate with JVM to run and debug code.

How to add support for debugging in my editor?

There are two main ways to add support for debugging depending on the capabilities exposed by the client.

Via code lenses

The editor needs to handle two commands in its language client extension: metals-run-session-start and metals-debug-session-start. Those commands should get executed automatically by the lsp client once the user activates a code lens. The difference between them is that the former ignores all breakpoints being set while the latter respects them. The procedure of starting the run/debug session is as follows:

Then we can request the debug adapter uri from the metals server using the debug-adapter-start command.

Via simple commands

Apart from using code lenses, users can start a debug session by executing the debug-adapter-start command with the following params:

  • for main class
{
  "mainClass": "com.foo.App",
  "buildTarget": "foo",
  "args": ["bar"],
  "jvmOptions": ["-Dpropert=123"],
  "env": { "RETRY": "TRUE" },
  "envFile": ".env"
}
  • for test class
{
  "testClass": "com.foo.FooSuite",
  "buildTarget": "foo"
}

buildTarget is an optional parameter, which might be useful if there are identically named classes in different modules. A uri will be returned that can be used by the DAP client.

envFile is an optional parameter, which allows you to specify a path to a .env file with additional environment variables. The path can be either absolute or relative to your project workspace. The parser supports single line as well as multi-line quoted values (without value substitution). Any variables defined in the env object take precedence over those from the .env file. Here's an example of a supported .env file:

# 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

Wiring it all together

No matter which method you use, you still need to connect the debug adapter extension specific to you editor using the aforementioned uri and let it drive the run/debug session. For reference, take a look at the vscode implementation and how it is wired up together

Debugging the connection

Create the following trace files to spy on incoming/outgoing JSON communication between the debug server and editor.

# macOS
touch ~/Library/Caches/org.scalameta.metals/dap-server.trace.json
touch ~/Library/Caches/org.scalameta.metals/dap-client.trace.json
# Linux
touch ~/.cache/metals/dap-server.trace.json
touch ~/.cache/metals/dap-client.trace.json
← Decoration ProtocolProxy and mirrors →
  • How to add support for debugging in my editor?
    • Via code lenses
    • Via simple commands
    • Wiring it all together
  • Debugging the connection
Metals
Overview
Text EditorsBuild ToolsProject GoalsContributing
Editors
Visual Studio CodeVimSublime TextEmacsEclipse
Social
Copyright © 2021 Metals