Metals

Metals

  • Docs
  • Blog
  • GitHub

›Text Editors

Text Editors

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

Build Tools

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

Contributing

  • Integrating a new build tool
  • Integrating a new editor
  • Tree View Protocol
  • Project Goals
  • Contributing to Metals
  • Contributing to the website
  • Making a release
Edit

Vim

Metals works with most LSP clients for Vim:

  • vim-lsc: simple installation and low resource usage but limited functionality (no auto-import, cancellation, formatting, folding).
  • coc.nvim: installation requires neovim or Vim v8.1 along with npm. Feature rich, supports all of LSP.
  • LanguageClient-neovim: client written in Rust.
  • vim-lsp: simple installation but limited functionality (no auto-import, cancellation and no prompt for build import).

In this page, we use coc.nvim (Conquer Of Completion) since it offers a richer user experience but the same steps can be adapted to use Metals with other LSP clients.

Vim demo

Requirements

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.

macOS, Linux or Windows. Metals is developed on macOS and every PR is tested on Ubuntu+Windows.

Scala 2.13, 2.12 and 2.11. Metals supports these Scala versions 2.13.0, 2.13.1, 2.12.8, 2.12.9, 2.12.10, 2.12.7 and 2.11.12. Note that 2.11.x support is deprecated and it will be removed in future releases. It's recommended to upgrade to Scala 2.12 or Scala 2.13

Installing Vim

The coc.nvim plugin requires either Vim >= 8.1 or Neovim >= 0.3.1. Make sure you have the correct version installed.

# If using Vim
vim --version | head
VIM - Vi IMproved 8.1

# If using Neovim
nvim --version | head
NVIM v0.3.7

Installing yarn

coc.nvim requires Node.js in order to work. It also uses Yarn to manage extensions but you could opt-out of it and use vim-plug instead for example.

For convenience we recommend installing both:

curl -sL install-node.now.sh/lts | sh
curl --compressed -o- -L https://yarnpkg.com/install.sh | bash

Installing coc.nvim

Once the requirements are satisfied, we can now proceed to install the following plugins:

  • neoclide/coc.nvim: Language Server Protocol client to communicate with the Metals language server.
  • derekwyatt/vim-scala: for syntax highlighting Scala and sbt source files.

Assuming vim-plug is used (another plugin manager like vundle works too), update ~/.vimrc to include the following settings.

" ~/.vimrc

" Configuration for vim-plug
Plug 'derekwyatt/vim-scala'
Plug 'neoclide/coc.nvim', {'do': { -> coc#util#install()}}

" Configuration for vim-scala
au BufRead,BufNewFile *.sbt set filetype=scala

Run :PlugInstall to install the plugin. If you already have coc.nvim installed, be sure to update to the latest version with :PlugUpdate.

Configuration

We need to tell coc.nvim that our LSP server is going to be metals. In order to do so, we need to run :CocConfig and input our configuration. Here's the recommended default:

// vim:    ~/.vim/coc-settings.json
// neovim: ~/.config/nvim/coc-settings.json
{
  "languageserver": {
    "metals": {
      "command": "metals-vim",
      "rootPatterns": ["build.sbt"],
      "filetypes": ["scala", "sbt"]
    }
  }
}

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

In order to get comments highlighting, please add:

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

Generating metals binary

If you now start Vim in a Scala project then it will fail since the metals-vim binary does not exist yet.

Next, build a metals-vim binary for the latest Metals release using the Coursier command-line interface.

Version Published Resolver
0.7.7-SNAPSHOT 10 Oct 2019 22:08 -r sonatype:releases
0.7.7-SNAPSHOT 10 Oct 2019 22:08 -r sonatype:snapshots
# Make sure to use coursier v1.1.0-M9 or newer.
curl -L -o coursier https://git.io/coursier
chmod +x coursier
./coursier bootstrap \
  --java-opt -Xss4m \
  --java-opt -Xms100m \
  --java-opt -Dmetals.client=coc.nvim \
  org.scalameta:metals_2.12:0.7.7-SNAPSHOT \
  -r bintray:scalacenter/releases \
  -r sonatype:snapshots \
  -o /usr/local/bin/metals-vim -f

Make sure the generated metals-vim binary is available on your $PATH.

Configure the system properties -Dhttps.proxyHost=… -Dhttps.proxyPort=… if you are behind an HTTP proxy.

The -Dmetals.client=coc.nvim flag is important since it configures Metals for usage with the coc.nvim client.

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.

Import build

  • "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 server property -Dmetals.sbt-script=/path/to/sbt to use a custom sbt script instead of the default Metals launcher if you need further customizations like reading environment variables.

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.

Import sbt changes

LSP commands key mapping

coc.nvim doesn't come with a default key mapping for LSP commands, you need to configure it yourself.

Here's a recommended configuration:

" ~/.vimrc
" Configuration for coc.nvim

" Smaller updatetime for CursorHold & CursorHoldI
set updatetime=300

" don't give |ins-completion-menu| messages.
set shortmess+=c

" always show signcolumns
set signcolumn=yes

" Some server have issues with backup files, see #649
set nobackup
set nowritebackup

" Better display for messages
set cmdheight=2

" Use <c-space> for trigger completion.
inoremap <silent><expr> <c-space> coc#refresh()

" Use <cr> for confirm completion, `<C-g>u` means break undo chain at current position.
" Coc only does snippet and additional edit on confirm.
inoremap <expr> <cr> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"

" Use `[c` and `]c` for navigate diagnostics
nmap <silent> [c <Plug>(coc-diagnostic-prev)
nmap <silent> ]c <Plug>(coc-diagnostic-next)

" Remap keys for gotos
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)

" Remap for do codeAction of current line
nmap <leader>ac <Plug>(coc-codeaction)

" Remap for do action format
nnoremap <silent> F :call CocAction('format')<CR>

" Use K for show documentation in preview window
nnoremap <silent> K :call <SID>show_documentation()<CR>

function! s:show_documentation()
  if &filetype == 'vim'
    execute 'h '.expand('<cword>')
  else
    call CocAction('doHover')
  endif
endfunction

" Highlight symbol under cursor on CursorHold
autocmd CursorHold * silent call CocActionAsync('highlight')

" Remap for rename current word
nmap <leader>rn <Plug>(coc-rename)

" Show all diagnostics
nnoremap <silent> <space>a  :<C-u>CocList diagnostics<cr>
" Find symbol of current document
nnoremap <silent> <space>o  :<C-u>CocList outline<cr>
" Search workspace symbols
nnoremap <silent> <space>s  :<C-u>CocList -I symbols<cr>
" Do default action for next item.
nnoremap <silent> <space>j  :<C-u>CocNext<CR>
" Do default action for previous item.
nnoremap <silent> <space>k  :<C-u>CocPrev<CR>
" Resume latest coc list
nnoremap <silent> <space>p  :<C-u>CocListResume<CR>

Learn more about coc.nvim

For comprehensive documentation about coc.nvim, run the following command.

:help coc-contents

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.

Close buffer without exiting

To close a buffer and return to the previous buffer, run the following command.

:bd

This command is helpful when navigating in library dependency sources in the .metals/readonly directory.

Shut down the language server

The Metals server is shutdown when you exit vim as usual.

:wq

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

Run doctor

To troubleshoot problems with your build workspace execute the following command.

:call CocRequestAsync('metals', 'workspace/executeCommand', { 'command': 'doctor-run' })

This command opens your browser with a table like this.

Run Doctor

Note: the binary metals-vim needs to be built using -Dmetals.http=true for this command to work.

Manually start build import

To manually start the sbt bloopInstall step, call the following command below. This command works only for sbt builds at the moment.

:call CocRequestAsync('metals', 'workspace/executeCommand', { 'command': 'build-import' })

Manually connect with build server

To manually tell Metals to establish a connection with the build server, call the command below. This command works only at the moment if there is a .bloop/ directory containing JSON files.

:call CocRequestAsync('metals', 'workspace/executeCommand', { 'command': 'build-connect' })

Show document symbols

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

Document Symbols

Gitignore .metals/ and .bloop/

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. It's recommended to ignore these directories from version control systems like git.

# ~/.gitignore
.metals/
.bloop/
← AtomSublime Text →
  • Requirements
  • Installing Vim
  • Installing yarn
  • Installing coc.nvim
    • Configuration
    • Generating metals binary
  • Importing a build
    • Custom sbt launcher
    • Speeding up import
    • Importing changes
    • LSP commands key mapping
  • Learn more about coc.nvim
  • List all workspace compile errors
  • Close buffer without exiting
  • Shut down the language server
  • Run doctor
  • Manually start build import
  • Manually connect with build server
  • Show document symbols
  • Gitignore .metals/ and .bloop/
Metals
Overview
Text EditorsBuild ToolsProject GoalsContributing
Editors
Visual Studio CodeAtomVimSublime TextEmacsEclipse
Social
Copyright © 2019 Metals