A Scala extension for Zed (powered by Metals)
- Coursier
- Install Metals:
cs install metals
Note: You need to have the path to metals
exported at shell init (e.g. by an entry in ~/.bashrc
), as zed
does not currently seem to pick up exported environment variables when started from a terminal. So it's not enough to export PATH="$PATH:~/.local/share/coursier/bin"
in a shell and run zed
from there. It will fail to start Metals in that case (and will not say so in the LSP log; but nothing but syntax highlighting will work then).
You can set Metals user configuration settings
in your zed settings.json in lsp.metals.settings
. For example, to enable displaying type annotations for inferred types
as inlay hints:
{
"lsp": {
"metals": {
"settings": {
"inlayHints": {
"inferredTypes": {
"enable": true
}
}
}
}
}
}
You can also set Metals initialization options and
Metals server properties in your zed settings.json
in lsp.metals.binary.arguments
and lsp.metals.initialization_options
, respectively.
For example, to enable HTTP server (running on http://localhost:5031 by default) for executing client commands, which currently are not supported by zed directly, you can use:
{
"lsp": {
"metals": {
"binary": {
"arguments": [
"-Dmetals.http=on"
]
},
"initialization_options": {
"isHttpEnabled": true
}
}
}
}
To turn on inlay hints you can use the configuration below:
{
"inlay_hints": {
"enabled": true,
"show_type_hints": true,
"show_parameter_hints": true,
"show_other_hints": true,
"show_background": false,
"edit_debounce_ms": 700,
"scroll_debounce_ms": 50
},
"lsp": {
"metals": {
"settings": {
"inlayHints": {
"inferredTypes": {
"enable": true
},
"implicitArguments": {
"enable": true
},
"implicitConversions": {
"enable": true
},
"typeParameters": {
"enable": true
},
"hintsInPatternMatch": {
"enable": true
}
}
}
}
}
}
Both sections need to be set, since Zed doesn't turn on inlay hints by default and Metals also needs to know which hints users wants to see.
The extension supports detecting tests by checking if the test class inherits from specific traits
For ScalaTest:
- AnyWordSpec / WordSpec
- AnyFunSpec / FunSpec
- AnyFunSuite / FunSuite
- AnyFlatSpec / FlatSpec
- AnyFeatureSpec / FeatureSpec
- AnyPropSpec / PropSpec
- AnyFreeSpec / FreeSpec
For Specs2:
- Specification
For Munit:
- FunSuite
For Munit Extensions:
- ScalaCheckSuite
- CatsEffectSuite
- ZSuite
- Http4sSuite
- SnapshotSuite
- RequestResponsePactForger
- HedgehogSuite
- TapirGoldenOpenAPISuite
- TapirGoldenOpenAPIValidatorSuite
For Hedgehog:
- Properties
For Weaver Test:
- SimpleIOSuite / IOSuite
For ZIO Test:
- ZIOSpecDefault
If your favorite test framework is not included, or more traits are have been added, please update the runnables.scm
file found in the languages/scala
directory
In order to get the run icon in the gutter, you need to provide zed with a task that run the test class.
The task must have the tag scala-test
in order to be detected by the editor.
Following is an example task that you can add to your editor, to know more about tasks refer to Zed Documentation.
[
{
"label": "run tests with bloop",
"name": "run-bloop-test",
"command": "./run-bloop-tests.sh ${ZED_WORKTREE_ROOT} ${ZED_SYMBOL}",
"working_directory": "${workspace_root}",
"environment": {
"PATH": "${env.PATH}"
},
"keystroke": "ctrl-shift-r",
"tags": ["scala-test"]
}
]
The corresponding minimal run-bloop-test.sh
which must be placed in your project root.
If you want to place it anywhere else you'll have to adjust the task accordingly.
#!/bin/bash
project_name=$(basename $1) # Extract the project name from the $ZED_WORKTREE_ROOT
filename=$2
bloop test $project_name -o "*$filename*"
In order to get the run icon in the gutter, you need to provide zed with a task that run the main class.
The task must have the tag scala-main
in order to be detected by the editor.
Following is an example task that you can add to your editor, to know more about tasks refer to Zed Documentation.
[
{
"label": "run main with bloop",
"name": "run-main",
"command": "./run-bloop-main.sh ${ZED_WORKTREE_ROOT} ${ZED_FILE} ${ZED_SYMBOL}",
"working_directory": "${workspace_root}",
"environment": {
"PATH": "${env.PATH}"
},
"tags": ["scala-main"]
}
]
The corresponding minimal run-bloop-main.sh
which must be placed in your project root.
If you want to place it anywhere else you'll have to adjust the task accordingly.
#!/bin/bash
project_name=$(basename $1) # Extract the project name from the $ZED_WORKTREE_ROOT
filepath=$2
mainname=$3
package_name=$(cat $filepath | grep -E '^package ' | sed 's/package //') # Extract the package name from the main file
bloop run $project_name -m "$package_name.$mainname"
To release the extension, you need to bump the version in Cargo.toml
and extension.toml
in the root of the repository and create a tag for the version (example bump: e8b826cb3fc0f5f054aa0012e17824f8904a73f5.
After that, you need to open up a PR on zed-industries/extensions (example: zed-industries/extensions#29, the PR must :
- Update the submodule on extensions/scala to the appropriate commit
- Update the file
extensions.toml
to set the appropriate version for the extension in the[scala]
section