Metals LSP 1.0.0

Stable and productive development environment

 

 

Tomasz Godzik VirtusLab

Who am I

Tomasz Godzik

Senior Scala Developer

previously

contributor for Scala Center

Who am I

Tomasz Godzik

Senior Scala Developer

now

team lead for ScalaCLI and Metals teams at VirtusLab

Open source

  • metals - LSP server for Scala

  • mdoc - compiles Scala snippets in mardown files

  • scalameta - version agnostic parser and semantic database

  • dotty - scala 3 compiler

  • bloop - build server for Scala and Java

Open source tooling

What is VirtusLab?

What is VirtusLab?

Metals

Did anyone ever hear of Metals?

Or language server protocol?

Your favourite language in you favourite Editor

How does it work

Client Editor

LSP Server

How does it work

Client Editor

LSP Server

object Main{
  def adding(a : Int, b : Int) = a + b
  val additional = ""
  val one = 1
  val two = 2
  addi_
}

How does it work

Client Editor

LSP Server

object Main{
  def adding(a : Int, b : Int) = a + b
  val additional = ""
  val one = 1
  val two = 2
  addi_
}

Completions

How does it work

Client Editor

LSP Server

object Main{
  def adding(a : Int, b : Int) = a + b
  val additional = ""
  val one = 1
  val two = 2
  addi_
}

Completions

How does it work

Client Editor

LSP Server

object Main{
  def adding(a : Int, b : Int) = a + b
  val additional = ""
  val one = 1
  val two = 2
  addi_
}

How does it work

Client Editor

LSP Server

object Main{
  def adding(a : Int, b : Int) = a + b
  val additional = ""
  val one = 1
  val two = 2
  addi_
}

How does it work

Client Editor

LSP Server

object Main{
  def adding(a : Int, b : Int) = a + b
  val additional = ""
  val one = 1
  val two = 2
  addi_
}

- adding()

- additional

How does it work

Client Editor

LSP Server

object Main{
  def adding(a : Int, b : Int) = a + b
  val additional = ""
  val one = 1
  val two = 2
  addi_
}

- adding()

- additional

How does it work

Client Editor

LSP Server

object Main{
  def adding(a : Int, b : Int) = a + b
  val additional = ""
  val one = 1
  val two = 2
  addi_
}

How does it work

Client Editor

LSP Server

object Main{
  def adding(a : Int, b : Int) = a + b
  val additional = ""
  val one = 1
  val two = 2
  adding(_)
}

Stable and Productive

Stable => Productive

Stable

  • no bugs

  • easy setup

  • works in every environment

Productive

  • no bugs

  • easy setup

  • works in every environment

  • sufficient features

  • quick

  • versatile

When those conditions are not met people will not have a great time.

 

They will complain about their tooling and...

 

Rightly so!

Complications

Metals has a lot of pieces

So we are still not 100 % there

Metals 1.0.0 series is our road to stability and productivity

Metals LSP server

Metals LSP server

Editor

Metals LSP server

Editor

Plugin

Metals LSP server

Editor

Plugin

Build tool

Metals LSP server

Editor

Plugin

Build tool

Build Server Protocol

Metals LSP server

Editor

Plugin

Build tool

Build Server Protocol

Bloop

Metals LSP server

Editor

Plugin

Build tool

Build Server Protocol

Bloop

Indexes

Metals LSP server

Editor

Plugin

Build tool

Build Server Protocol

Bloop

Indexes

Semanticdb

Metals LSP server

Editor

Plugin

Build tool

Build Server Protocol

Bloop

Indexes

Semanticdb

(Presentation) Compiler

Metals LSP server

Editor

Plugin

Build tool

Build Server Protocol

Bloop

Indexes

Semanticdb

(Presentation) Compiler

Worksheets

Metals LSP server

Editor

Plugin

Build tool

Build Server Protocol

Bloop

Indexes

Semanticdb

(Presentation) Compiler

Worksheets

Mdoc

Metals LSP server

Editor

Plugin

Build tool

Build Server Protocol

Bloop

Indexes

Semanticdb

(Presentation) Compiler

Worksheets

Mdoc

Organize imports

Metals LSP server

Editor

Plugin

Build tool

Build Server Protocol

Bloop

Indexes

Semanticdb

(Presentation) Compiler

Worksheets

Mdoc

Organize imports

Scalafix

Metals LSP server

Editor

Plugin

Build tool

Build Server Protocol

Bloop

Indexes

Semanticdb

(Presentation) Compiler

Worksheets

Mdoc

Organize imports

Scalafix

Parser

Metals LSP server

Editor

Plugin

Build tool

Build Server Protocol

Bloop

Indexes

Semanticdb

(Presentation) Compiler

Worksheets

Mdoc

Organize imports

Scalafix

Parser

Scalameta

Metals LSP server

Editor

Plugin

Build tool

Build Server Protocol

Bloop

Indexes

Semanticdb

(Presentation) Compiler

Worksheets

Mdoc

Organize imports

Scalafix

Parser

Scalameta

Debugging

Metals LSP server

Editor

Plugin

Build tool

Build Server Protocol

Bloop

Indexes

Semanticdb

(Presentation) Compiler 2/3

Worksheets

Mdoc

Organize imports

Scalafix

Parser

Scalameta

Debugging

Scala debug adapter

  • A lot of pieces

  • Independently developed

  • But it complicates things

Fixing things in another library or tool fixes things in metals

 

A lot more people contribute (via proxy)

Stability improvements

Presentation compiler implementation in the Scala 3 compiler itself

public abstract class PresentationCompiler {
	public CompletableFuture<List<Node>> 
		semanticTokens(VirtualFileParams params)

	public abstract CompletableFuture<CompletionList> 
		complete(OffsetParams params);

	public abstract CompletableFuture<CompletionItem> 
		completionItemResolve(CompletionItem item, String symbol);

	public abstract CompletableFuture<SignatureHelp> 
		signatureHelp(OffsetParams params);

	public abstract CompletableFuture<Optional<HoverSignature>> 
		hover(OffsetParams params);
    
    ...
 }
  • tested with each PR

  • separate module to depend on

  • interface to be used by different clients

All thanks to tight cooperation with the compiler team

Metals will no longer totally drop support for any Scala version

Reporting

 

We cannot always easily see what is going wrong.

 

Adding self diagnostics and reporting mechanisms

 

Bsp server status

 

Errors from build server show up

 

  • compiler issues

  • server issues

  • integration (js/native) issues

 

Error reports in the doctor

 

 

Automatically search for project root

 

Smaller improvements

 

  • moving features to use presentation compiler

  • fallback to symbol search as a last possibility

Plenty of bugfixes

A lot of the ideas come from the users

 

Do let us know if you feel something would improve your live.

Productivity improvements

Scala CLI integration

 

  • scripts recognized as Scala CLI / Ammonite

  • fallback BSP server  if no build tool

  • dependency completions

  • semantic highlighting

  • (soon) single file support

Scala CLI integration

Quick demo

Multiple workspace folders

 

  • previously, Metals would only work in single workspaces
  • LSP can work with multiple folders at the same time
  • it would be confusing for the users
  • you can have single metals server for multiple projects

Multiple workspace folders

 

Basic Java support

  • we already had some features implemented
  • newest ones completions and hover using the java compiler directly
  • much simpler than Java LSP
  • missing still things like signature help, semantic highlight (anything behind our interface)
  • outside contribution

Actionable diagnostics

Compiler or build tools know how to fix their stuff (most of the time)

 

 We can propagate automatic fixes suggestions form the compiler to the IDEs

 

This gives us errors with ready fixes for the user to try

 

Works with Scala 2 and 3 compilers

Actionable diagnostics

Actionable diagnostics

Bonus: How to deal with your issues?

Report it?

1. Is it reproducible?

2. Does this happen on a specific project?

3. Does this happen on a platform?

4. Are there any reports shown in the doctor?

5. Is the build server connected?

6. Dump as much information into an issue

I just want it to work!

1. Connect to build server command.

 

metals.build-connect

2. Restart build server.

 

metals.build-restart

3. Clean compile.

 

metals.compile-clean

4. Reset all the caches.

 

metals.reset-workspace

5. Write on discord.

 

I do try to help out as soon as possible

Advanced debuging

  • set debug flag

  • look through the doctor

  • jstack/jmap

  • verbose compilation (coming soon)

 

Bonus 2: Future plans?

Bazel integration

Soon

  • based on github.com/JetBrains/bazel-bsp
  • also github.com/bazelbuild/rules_scala
  • semanticdb support added to rules scala
  • PR is ready! Final reviews ongoing.

Type decorations from the presentation compiler

Soon

  • additional virtual text in your code
  • things like implicit parameters, inferred type etc.
  • previously only semanticdb
  • new approach unblocks more features
  • more up to date, doesn't require compilation

Type decorations from the presentation compiler

Soon

Inlay hints

This year

  • LSP equivalent of current decorations
  • much better editor support
  • hover, go to definition, insert decoration

Remove unused imports (Scala 3)

 

This year

  • requires warnings generated in semanticdb
  • PR almost merged
  • most likely from Scala 3.3.2 (LTS) and 3.4.0

Best effort compilation

when done

Presentation compiler approach on a whole module level.

object O{
  def foo(): Int = {
    "" // error expected Int
  }
}

Things we know of:

 

  • Scalafix inferred types rule

  • Scala 3 mocks

  • scalameta parser compiled with Scala 3

What do you need more from Scala 3 tooling?

 

We can help!

 

Presentation

Questions?

Social media:

Twitter @TomekGodzik,

Mastodon https://fosstodon.org/@tgodzik  

 

Contact as at VirtusLab: tgodzik@virtuslab.com

Copy of Metals 1.0.0

By Tomek Godzik

Copy of Metals 1.0.0

  • 27