Metals was started by Gabriele Petronella and Ólafur Páll Geirsson in November 2017 as an experiment to get Scalafix support
in VS Code. The name "Metals" origins from Meta Language Server. As of January 2017, the project has 4 maintainers,
but nobody is currently employed to work directly on the project.
All of the images in this document demonstrate existing functionality of Metals. However, note that most features of Metals
are at proof-of-concept stage and require more work to reach an acceptable level of quality for day-to-day coding.
Main ideas
- Bring Scalameta-based tools to the editor
- Beyond completions: fast navigation even for massive codebases, linting, refactoring, code browsing, formatting, build,
test
- Index semantic information to enable multiple analyses to run fast and in parallel.
- Minimize surface interaction with compiler APIs
- Use SemanticDB as an interchange format
textDocument/publishDiagnostics
- Use scalafix to display linting errors in the editor.
- Users can configure the custom rules through
.scalafix.conf
.
textDocument/codeAction
- Server responds with auto-fixes through
textDocument/codeAction
.
- When an auto-fix is selected, the server uses scalafix to
workspace/applyEdit
.
- Scalafix patch data structures are converted to LSP
TextEdit
, which describe how to edit individual tokens.
textDocument/formatting
- Uses scalafmt to implement
textDocument/formatting
.
- The user can configure the editor to run format on file save.
- In case of another conflicting Scala formatter plugin, for example Scalariform, the user can configure the server to
disable formatting.
textDocument/definition
- Use SemanticDB to index positions for definitions in project and dependency sources
- Works for both Scala and Java dependencies.
- Uses only parser to index dependency sources. This approach is lightweight and fast, but may result in jumping to the
wrong method overload.
textDocument/hover
- Uses SemanticDB to display signature information on hover.
- Includes modifiers to help distinguish packages, objects, implicits, finals, overrides.
textDocument/references
- Use SemanticDB to generate an online code browser with IDE navigation features.
- Can generate site that can be served with any static file server, including GitHub Pages.
- Static site for a corpus of ~2 million lines of code takes ~250mb compressed and generates in ~15s on a Macbook Pro laptop
(of which 10s are used for I/O).
- SemanticDB is cross-built against Scala.js, enabling cross-platform tooling development.
textDocument/completion
Uses Scala Presentation Compiler to
- auto-complete scope and type members.
- lookup overloaded method signatures.
- completion results are sorted in "smart" order
textDocument/documentSymbol
- Use Scalameta parser to display symbol outline and go to symbol in open buffer.
sbt/exec
- Integrate with sbt server to run compile on file save
- The command that is run on file save is configurable via editor settings
- Diagnostics are published directly from sbt
Roadmap
- Compile errors with the Scala Presentation Compiler (
textDocument/publishDiagnostics
):
- [x] On build compile via sbt server
- [x] As you type
- Linting with Scalafix (
textDocument/publishDiagnostics
):
- [x] On build compile
- [x] As you type
- Refactoring with Scalafix:
- [ ] Move class (
workspace/applyEdit
)
- [ ] Organize imports (
workspace/applyEdit
)
- [x] Remove unused imports (
textDocument/codeAction
)
- [x] Rename local symbol (
textDocument/rename
)
- [ ] Rename global symbol (
textDocument/rename
)
- [ ] Rename filename on class/trait/object rename (
textDocument/rename
)
- [ ] Rename matching test suites on class/trait/object rename (
textDocument/rename
)
- Formatting with Scalafmt:
- [x] Whole file (
textDocument/formatting
)
- [ ] Selected range (
textDocument/rangeFormatting
)
- [ ] As you type (
textDocument/onTypeFormatting
)
- Code assistance:
- [x] Auto-complete symbols in scope as you type (
textDocument/completions
)
- [ ] Auto-complete global symbol and insert missing imports (
textDocument/completions
)
- [x] Show parameter list as you type (
textDocument/signatureHelp
)
- [x] Show type at position (
textDocument/hover
)
- Go to definition with SemanticDB (
textDocument/definition
):
- [x] Inside the project
- [x] From project files to Scala dependency source files
- [x] From project files to Java dependency source files
- [ ] From project dependency to project dependency
- Find references with SemanticDB (
textDocument/references
):
- [x] In file (
textDocument/documentHighlight
)
- [x] In project
- [ ] In dependencies
- Lookup symbol definition by name:
- [x] In file (
textDocument/documentSymbol
)
- [x] In workspace (
workspace/symbol
)
- [ ] In workspace with fuzzy match (
workspace/symbol
)
- [ ] In clean workspace without compilation (
workspace/symbol
)
- Symbol outline:
- [x] In file as you type (
textDocument/documentSymbol
)
- Build Server Protocol:
- [ ] Import project
- [ ] Run compile on file save
- [ ] Run test suite