Skip to content

coc.nvim extension for Metals, the Scala language server

Notifications You must be signed in to change notification settings

tani/coc-metals

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

coc-metals

coc-metals npm code style: prettier Dependabot Status

coc-metals is the recommended coc.nvim extension for Metals, the Scala language server. coc-metals offers automated Metals installation, easy configuration, Metals-specific commands, an embedded doctor, implementation of the decoration protocol, and many other small features.

NOTE: The readme is up-to-date with the master branch, so not all features will be available if you're using the latest stable release. The vim page on the Metals site is synced with the latest stable release

Table of Contents

Requirements

coc-metals works with both Vim and Neovim, but we recommend neovim for a smoother experience and extra features such as the decoration protocol.

  • coc.nvim - There are detailed instructions in their repo on how to get set up and running quickly.
  • Java 8 or 11 provided by OpenJDK or Oracle. Eclipse OpenJ9 is not supported, please make sure the JAVA_HOME environment variable points to a valid Java 8 or 11 installation.
  • coc.nvim doesn't come with a default mapping for LSP commands, so you need to configure this in order for any of the commands to work. You can find an example configuration and instructions here

Installing coc-metals

Once you have coc.nvim installed, you can then install Metals a few different ways, but the easiest is by running.

:CocInstall coc-metals

If you'd like to use the latest changes on master, you can also just build from source by using :CocInstall with the repository url.

:CocInstall https://github.com/scalameta/coc-metals

If you'd like to use the latest changes on master, but manage it using a plugin manager to download the extension, then if you are using vim-plug for example, enter the following into where you manage your plugins:

Plug 'scalameta/coc-metals', {'do': 'yarn install --frozen-lockfile'}

Then, issue a :PlugInstall to install the extension, and regularly a :PlugUpdate to update it and pull in the latest changes.

*** Keep in mind that if you are installing directly from the repo via :CocInstall with the repository url or through a plugin manager, remove coc-metals with :CocUninstall coc-metals before you add it in with one of the other methods to not conflict with one another.

Importing a build

The first time you open Metals in a new workspace it prompts you to import the build. Click "Import build" to start the installation step.

Build Import

  • "Not now" disables this prompt for 2 minutes.
  • "Don't show again" disables this prompt forever, use rm -rf .metals/ to re-enable the prompt.
  • Use tail -f .metals/metals.log to watch the build import progress.
  • Behind the scenes, Metals uses Bloop to import sbt builds, but you don't need Bloop installed on your machine to run this step.

Once the import step completes, compilation starts for your open *.scala files.

Once the sources have compiled successfully, you can navigate the codebase with goto definition.

Custom sbt launcher

By default, Metals runs an embedded sbt-launch.jar launcher that respects .sbtopts and .jvmopts. However, the environment variables SBT_OPTS and JAVA_OPTS are not respected.

Update the metals.sbtScript setting to use a custom sbt script instead of the default Metals launcher if you need further customizations like reading environment variables.

sbt-launcher

Speeding up import

The "Import build" step can take a long time, especially the first time you run it in a new build. The exact time depends on the complexity of the build and if library dependencies need to be downloaded. For example, this step can take everything from 10 seconds in small cached builds up to 10-15 minutes in large uncached builds.

Consult the Bloop documentation to learn how to speed up build import.

Importing changes

When you change build.sbt or sources under project/, you will be prompted to re-import the build.

Build Re-Import

Configure Java version

The coc-metals extension uses by default the JAVA_HOME environment variable (via find-java-home) to locate the java executable.

No Java Home

If no JAVA_HOME is detected you can then Open Settings by following the instructions or do it at a later time by using :CocConfig or :CocConfigLocal which will open up your configuration where you can manually enter your JAVA_HOME location.

java-home

coc.nvim uses jsonc as a configuration file format. It's basically json with comment support.

In order to get comment highlighting, please add:

autocmd FileType json syntax match Comment +\/\/.\+$+

Using latest Metals SNAPSHOT

Update the "Server Version" setting to try out the latest pending Metals features.

After updating the version, you'll be triggered to reload the window. This will be necessary before the new version will be downloaded and used.

Update Metals Version

List all workspace compile errors

To list all compilation errors and warnings in the workspace, run the following command.

:CocList diagnostics

Or use the default recommended mapping <space> a.

This is helpful to see compilation errors in different files from your current open buffer.

Diagnostics

Run doctor

To troubleshoot problems with your build workspace, open your coc commands by either using :CocCommand or the recommend mapping <space> c. This will open your command window allowing you to search for metals.doctor-run command.

Run Doctor Command

This command opens an embedded doctor in your preview window. If you're not familiar with having multiple windows, you can use <C-w> + w to jump into it.

Embedded Doctor

Worksheets

Metals allows users to create a *.worksheet.sc file and see evaluations right in their file. In Vim, this is done using comments that are inserted which will allow you to hover on them to expand. In Neovim, this is done using Neovim's virtual text to implement Metal's Decoration Protocol. If using Neovim, make sure to have the following line included in your .vimrc along with your coc.nvim mappings. Also keep in mind that the worksheet needs to be created inside of your project to have access to your dependencies etc. If you create them in the root of your project for example, your worksheet will only have access to the standard lib.

nmap <Leader>ws <Plug>(coc-metals-expand-decoration)

Then, when on the line that you'd like to expand the decoration to get the hover information, execute a <leader>ws in order to see the expanded text for that line.

Decorations with worksheets

Tree View Protocol

Tree View Protocol coc-metals has a built-in implementation of the Tree View Protocol. If you have the recommended mappings copied, you'll notice that in the bottom you'll have some TVP related settings. You can start by opening the TVP panel by using the default <space> t. Once open, you'll see there are two parts to the panel. The first being the MetalsCompile where you can see the status of ongoing compilations for your modules and also options to compile.

MetalsCompile

You are able to trigger the compiles while being on top of the option you are attempting to trigger and pressing r. You can change this default in the settings. You can find all the relevant TVP settings below in the Available Configuration Options.

The second part of the TVP panel is a view of your project and external dependencies. You can navigate through them by jumping to the next or previous nodes, the last or first nodes, or jumping to parent or first child nodes. There are shortcuts to all of these found below. You will see the traits, classes, objects, members, and methods are all color coded.

All Available Commands

  • metals.restartServer
  • metals.build-import
  • metals.build-connect
  • metals.build-restart
  • metals.sources-scan
  • metals.compile-cascade
  • metals.compile-cancel
  • metals.doctor-run
  • metals.logs-toggle
  • metals.tvp
  • metals.tvp.view
  • metals.revealInTreeView
  • metals.new-scala-file

Show document symbols

Run :CocList outline to show a symbol outline for the current file or use the default mapping <space> o.

Document Symbols

Available Configuration Options

The following configuration options are currently available. The easiest way to set these configurations is to enter :CocConfig or :CocLocalConfig to set your global or local configuration settings respectively.

If you'd like to get autocompletion help for the configuration values you can install coc-json.

Configuration Option Description
metals.serverVersion The version of the Metals server artifact. Requires reloading the window.
metals.serverProperties Optional list of properties to pass along to the Metals server. By default, the environment variable JAVA_OPTS and .jvmopts file are respected.
metals.javaHome Optional path to the Java home directory. Requires reloading the window. Defaults to the most recent Java 8 version computed by the locate-java-home npm package.
metals.sbtScript Optional absolute path to an sbt executable to use for running sbt bloopInstall. By default, Metals uses java -jar sbt-launch.jar with an embedded launcher while respecting .jvmopts and .sbtopts. Update this setting if your sbt script requires more customizations like using environment variables.
metals.millScript Optional absolute path to a mill executable to use for running mill mill.contrib.Bloop/install. By default, Metals uses an embedded millw script while respecting .mill-version file. Update this setting if your mill script requires more customizations.
metals.mavenScript Optional absolute path to a mvn executable to use for running mvn ch.epfl.scala:maven-bloop_2.10:<bloop_version>:bloopInstall. By default, Metals uses an embedded mvnw script. Update this setting if your mvn script requires more customizations.
metals.gradleScript Optional absolute path to a gradle executable to use for running gradle bloopInstall. By default, Metals uses an embedded gradlew script. Update this setting if your gradle script requires more customizations.
metals.pantsTargets The pants targets to export. Space separated list of Pants targets to export, for example src/main/scala:: src/main/java::. Syntax such as src/{main,test}:: is not supported."
metals.scalafmtConfigPath Optional custom path to the .scalafmt.conf file. Should be relative to the workspace root directory and use forward slashes / for file separators (even on Windows).
metals.customRepositories Optional list of custom resolvers passed to Coursier when fetching metals dependencies. For documentation on accepted values see the Coursier documentation. The extension will pass these to Coursier using the COURSIER_REPOSITORIES environment variable after joining the custom repositories with a pipe character (
metals.bloopVersion This version will be used for the Bloop build tool plugin, for any supported build tool,while importing in Metals as well as for running the embedded server
metals.bloopSbtAlreadyInstalled If true, Metals will not generate a project/metals.sbt file under the assumption that sbt-bloop is already manually installed in the sbt build. Build import will fail with a 'not valid command bloopInstall' error in case Bloop is not manually installed in the build when using this option.
metals.statusBarEnabled Turn on usage of the statusBar integration. Note: You need to ensure you are adding something like %{coc#status()} in order to display it, or use a plugin that includes a status integration.
metals.treeviews.toggleNode Expand / Collapse tree node (default <CR>)
metals.treeviews.initialWidth Initial Tree Views panels (default 40)
metals.treeviews.initialViews Initial views that the Tree View Panel Dispalys. Done mess with this unless you know what you're doing.
metals.treeviews.gotoLastChild Go to the last child Node (defalt J)
metals.treeviews.gotoParentNode Go to parent Node (default p)
metals.treeviews.gotoFirstChild Go to first child Node (default K)
metals.treeviews.executeCommand Execute command for node (default r)
metals.treeviews.gotoPrevSibling Go to prev sibling (default <C-k>)
metals.treeviews.gotoNextSibling Go to next sibling (default <C-j>)
metals.treeviews.forceChildrenReload Force the reloading of the children of this node. May be useful when the wrong result is cached and tree contains invalid data. (default f)
metals.treeviews.executeCommandAndOpenTab Execute command and open node under cursor in tab (if node is class, trait and so on) (default t)
metals.treeviews.executeCommandAndOpenSplit Execute command and open node under cursor in horizontal split (if node is class, trait and so on) (default s)
metals.treeviews.executeCommandAndOpenVSplit Execute command and open node under cursor in horizontal split (if node is class, trait and so on) (default v)

Enable on type formatting for multiline string formatting

on-type

To properly support adding | in multiline strings we are using the onTypeFormatting method. To enable the functionality you need to enable coc.preferences.formatOnType setting.

coc-preferences-formatOnType

Shut down the language server

The Metals server is shutdown when you exit vim as you normally would.

:wq

This step clean ups resources that are used by the server.

Statusline integration

It's recommended to use a statusline integration with coc-metals in order to allow messages to be displayed in your status line rather than as a message. This will allow for a better experience as you can continue to get status information while entering a command or responding to a prompt. However, we realize that not everyone by default will have this setup, and since the user needs to see messages about the status of their build, the following is defaulted to false.

"metals.statusBarEnabled": true

Again, it's recommended to make this active, and use a statusline plugin, or manually add the coc status information into your statusline. coc.nvim has multiple ways to integrate with various statusline plugins. You can find instructions for each of them located here. If you're unsure of what to use, vim-airline is a great minimal choice that will work out of the box.

With vim-airline, you'll notice two noteworthy things. The first will be that you'll have diagnostic information on the far right of your screen.

Diagnostic statusline

You'll also have metals status information in your status bar.

Status bar info

Without a statusline integration, you'll get messages like you see below.

No status line

If you don't use a statusline plugin, but would still like to see this information, the easiest way is to make sure you have the following in your .vimrc.

set statusline^=%{coc#status()}%{get(b:,'coc_current_function','')}

Formatting on save

If you'd like to have :w format using Metals + Scalafmt, then make sure you have the following in your :CocConfig.

"coc.preferences.formatOnSaveFiletypes": ["scala"]

Gitignore

The Metals server places logs and other files in the .metals/ directory. The Bloop compile server places logs and compilation artifacts in the .bloop directory. A Bloop plugin that generates Bloop configuration is added in the project/metals.sbt file. It's recommended to ignore these directories and file from version control systems like git.

# ~/.gitignore
.metals/
.bloop/
project/metals.sbt

Troubleshooting

If you have any questions or issues with coc-metals, please submit an issue in this repo if it pertains to the extension. If the issues is general to Metals, please submit it in the Metals issue repo. If you have any feature requests, we also have a feature request issue repo.

Contributing

If you're interested in contributing, please visit the CONTRIBUTING guide for help on getting started.

Theme

The screen shots are in Neovim. The theme is onedark with syntax highlighting added by vim-scala. The status bar is vim-airline, and all being ran in iTerm2.

About

coc.nvim extension for Metals, the Scala language server

Resources

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published

Languages

  • TypeScript 94.0%
  • Vim Script 6.0%