Metals: Document new functionality

Created on 30 Mar 2019  ·  15Comments  ·  Source: scalameta/metals

A lot has happened since the last stable release. Before releasing v0.5, we should update the website to document new functionality such as

  • completions
  • hover
  • signature help

In particular, we should validate all the features work reliably in the supported editors (vim, emacs, sublime, atom).

Most helpful comment

This is the only remaining issue blocking a v0.5 release! I have published
v0.5.0-M1 so people can try out a non-SNAPSHOT.

I have personally used VS Code + Metals for two weeks now and I'm pretty happy
with the new functionality. It would be great to confirm before the stable
release that the features also work outside of VS Code.

  • [x] VS Code: @olafurpg / @gabro /@jvican
  • [ ] Atom: @laughedelic
  • [ ] Vim: @ceedubs / anyone else?. I recommend trying out coc.nvim instead of
    vim-lsc because coc.nvim implements several advanced completion features
    that Metals supports.
  • [ ] Emacs: @JesusMtnez / @coreyoconnor / @rossabaker
  • [ ] Sublime Text: @ayoub-benali

Below is a checklist of features that may need minor tweaking to improve the UX
outside of VS Code. The cursor position is indicated by @@.

Completions

In LSP, it's called textDocument/completion but in the editor it may be called
something else.

  • scope completion, try completing a variable like println@@
  • member completion, try completing a member of a type such Predef.println@@.
  • auto-import completion, try completing a symbol that is not in scope, like
    Future@@ and if you select the option Future - scala.concurrent it adds a
    local import scala.concurrent.Future
  • override def completion, inside a class/object/trait, complete def @@ and it
    shows methods that can be overridden by the superclass
class Main {
    // should show "override def toString(): String` along with hashCode, equals, ...
    def @@
}
  • named argument completion, assert(true, mess@@) should complete message =
  • snippet completion, completing a method like assert@@ should move the cursor
    inside parentheses like assert(@@)
  • completion item resolution, Java method parameters should not have names like
    x$1, for example "".substrin@@ should display
    substring(beginIndex: Int, endIndex: Int): String instead of
    substring(x$1: Int, x$2: Int): String. I suspect this won't work in Vim or
    Sublime, you may need to trigger a command in Emacs.
  • string literal into interpolator completion, try completing a variable name
    inside a plain literal
locally {
    val susan = "Susan"
    "Hello $susa@@" // should complete into s"Hello $susan"
}
  • string literal member into curly brace completion, try completing a type
    member name of a spliced identifier inside a string interpolator
locally {
  val numbers = List(1)
  s"Hello $numbers.head@@" // should complete into s"Hello ${numbers.head}"
}
  • completion sorting, validate the sorting is not alphabetical
Option(1) match {
  case S@@ // Should suggest `Some` at the top, not `Seq`
}
  • trigger characters, typing Predef.@@ should trigger completion.
  • exhaustive match completion, completing on a sealed type should propose a
    "match (exhaustive)` completion
// before
Option(1) match@@
// after
Option(1) match {
  case None => @@
  case Some(value) =>
}
  • case completion, completing on the case keyword should suggest valid types
List(Option(1)).map {
  case@@ // should suggest "case None =>` and `case Some(value) =>`

Server configuration

  • -Dmetals.signature-help.command: a command ID to automatically trigger
    signature help (parameter hints) when a completion snippet moves the cursor
    into parentheses assert(@@). In VS Code, this value is
    "editor.action.triggerParameterHints".
  • -Dmetals.completion.command: a command ID to trigger a follow-up completion
    in the editor after selecting certain completions. In VS Code, this value is
    "editor.action.triggerSuggest".
  • -Dmetals.override-def-format: valid values are ascii (default) or
    unicode. If set to unicode, then Metals uses the symbols ⏫ and 🔼 instead
    of "override def" and "def" to save horizontal space in the UI.

Hover (aka. show type at point)

In LSP, it's called textDocument/hover but in the editor it may be called
something else.

  • markdown rendering, Option(1).ma@@p(_ + 1) should appear like this
  • range highlighting, observe in the screenshot above how .map(_.toString) is
    not highlighted

Server configuration

  • -Dmetals.hover.documentation: a boolean true (default) or false. If set
    to false, then the docstring is left empty, which can be desirable if you only
    care about seeing the expression type and symbol signature.

Signature help (aka. parameter hints)

In LSP, it's called textDocument/signatureHelp but in the editor it may be
called something else.

  • when inside a parameter list, you should see the signature of the method
  • active parameter, the currently active argument should be highlighted.
    Example, y: Int in the image above.
  • overloaded methods, all overloads should be displayed. Example, math.max has
    four overloads that can be cycled through by clicking the up/down arrows in
    the image above.
  • trigger character, typing ( should automatically trigger signature help.
  • docstrings for active parameter and method symbol should be displayed.

Server configuration

  • -Dmetals.signature-help.documentation: a boolean true (default) or
    false. If set to false, then the docstring is left empty, which can be
    desirable if you only care about seeing the symbol signature.

Folding ranges

In LSP, it's called textDocument/foldingRange but in the editor it may be
called something else.

  • code folding, for example you can fold large multiline strings
  • import folding, for example you can fold large groups of imports
  • comment folding, for example you can fold large groups of single-line comments

Document highlight

In LSP, it's called textDocument/documentHighlight but in the editor it may be
called something else.

  • triggering document highlight on a variable should highlight all occurrences
    of that symbol in the current file

All 15 comments

This is the only remaining issue blocking a v0.5 release! I have published
v0.5.0-M1 so people can try out a non-SNAPSHOT.

I have personally used VS Code + Metals for two weeks now and I'm pretty happy
with the new functionality. It would be great to confirm before the stable
release that the features also work outside of VS Code.

  • [x] VS Code: @olafurpg / @gabro /@jvican
  • [ ] Atom: @laughedelic
  • [ ] Vim: @ceedubs / anyone else?. I recommend trying out coc.nvim instead of
    vim-lsc because coc.nvim implements several advanced completion features
    that Metals supports.
  • [ ] Emacs: @JesusMtnez / @coreyoconnor / @rossabaker
  • [ ] Sublime Text: @ayoub-benali

Below is a checklist of features that may need minor tweaking to improve the UX
outside of VS Code. The cursor position is indicated by @@.

Completions

In LSP, it's called textDocument/completion but in the editor it may be called
something else.

  • scope completion, try completing a variable like println@@
  • member completion, try completing a member of a type such Predef.println@@.
  • auto-import completion, try completing a symbol that is not in scope, like
    Future@@ and if you select the option Future - scala.concurrent it adds a
    local import scala.concurrent.Future
  • override def completion, inside a class/object/trait, complete def @@ and it
    shows methods that can be overridden by the superclass
class Main {
    // should show "override def toString(): String` along with hashCode, equals, ...
    def @@
}
  • named argument completion, assert(true, mess@@) should complete message =
  • snippet completion, completing a method like assert@@ should move the cursor
    inside parentheses like assert(@@)
  • completion item resolution, Java method parameters should not have names like
    x$1, for example "".substrin@@ should display
    substring(beginIndex: Int, endIndex: Int): String instead of
    substring(x$1: Int, x$2: Int): String. I suspect this won't work in Vim or
    Sublime, you may need to trigger a command in Emacs.
  • string literal into interpolator completion, try completing a variable name
    inside a plain literal
locally {
    val susan = "Susan"
    "Hello $susa@@" // should complete into s"Hello $susan"
}
  • string literal member into curly brace completion, try completing a type
    member name of a spliced identifier inside a string interpolator
locally {
  val numbers = List(1)
  s"Hello $numbers.head@@" // should complete into s"Hello ${numbers.head}"
}
  • completion sorting, validate the sorting is not alphabetical
Option(1) match {
  case S@@ // Should suggest `Some` at the top, not `Seq`
}
  • trigger characters, typing Predef.@@ should trigger completion.
  • exhaustive match completion, completing on a sealed type should propose a
    "match (exhaustive)` completion
// before
Option(1) match@@
// after
Option(1) match {
  case None => @@
  case Some(value) =>
}
  • case completion, completing on the case keyword should suggest valid types
List(Option(1)).map {
  case@@ // should suggest "case None =>` and `case Some(value) =>`

Server configuration

  • -Dmetals.signature-help.command: a command ID to automatically trigger
    signature help (parameter hints) when a completion snippet moves the cursor
    into parentheses assert(@@). In VS Code, this value is
    "editor.action.triggerParameterHints".
  • -Dmetals.completion.command: a command ID to trigger a follow-up completion
    in the editor after selecting certain completions. In VS Code, this value is
    "editor.action.triggerSuggest".
  • -Dmetals.override-def-format: valid values are ascii (default) or
    unicode. If set to unicode, then Metals uses the symbols ⏫ and 🔼 instead
    of "override def" and "def" to save horizontal space in the UI.

Hover (aka. show type at point)

In LSP, it's called textDocument/hover but in the editor it may be called
something else.

  • markdown rendering, Option(1).ma@@p(_ + 1) should appear like this
  • range highlighting, observe in the screenshot above how .map(_.toString) is
    not highlighted

Server configuration

  • -Dmetals.hover.documentation: a boolean true (default) or false. If set
    to false, then the docstring is left empty, which can be desirable if you only
    care about seeing the expression type and symbol signature.

Signature help (aka. parameter hints)

In LSP, it's called textDocument/signatureHelp but in the editor it may be
called something else.

  • when inside a parameter list, you should see the signature of the method
  • active parameter, the currently active argument should be highlighted.
    Example, y: Int in the image above.
  • overloaded methods, all overloads should be displayed. Example, math.max has
    four overloads that can be cycled through by clicking the up/down arrows in
    the image above.
  • trigger character, typing ( should automatically trigger signature help.
  • docstrings for active parameter and method symbol should be displayed.

Server configuration

  • -Dmetals.signature-help.documentation: a boolean true (default) or
    false. If set to false, then the docstring is left empty, which can be
    desirable if you only care about seeing the symbol signature.

Folding ranges

In LSP, it's called textDocument/foldingRange but in the editor it may be
called something else.

  • code folding, for example you can fold large multiline strings
  • import folding, for example you can fold large groups of imports
  • comment folding, for example you can fold large groups of single-line comments

Document highlight

In LSP, it's called textDocument/documentHighlight but in the editor it may be
called something else.

  • triggering document highlight on a variable should highlight all occurrences
    of that symbol in the current file

I've been using metals with Emacs for the past two weeks (SNAPSHOTS versions). So far everything I tried worked pretty well.
I'll try to test everything in this issue this weekend or next week to confirm Emacs integration :smile:

Thank you for this amazing work! :clap: :tada:

BTW, to try out v0.5.0-M1

  • VS Code: update the "server version" setting
  • Atom: update the "Metals version" setting
  • Other: regular installation instructions on the website except use 0.5.0-M1 instead of 0.4.4

https://scalameta.org/metals/docs/editors/vscode.html#using-latest-metals-snapshot

I found some error messages in vscode's console

bad option: -P:semanticdb:synthetics:on
bad option: -P:semanticdb:failures:warning

I have to manually add the following settings in my build.sbt in case of those errors

addCompilerPlugin("org.scalameta" % "semanticdb-scalac" % "4.1.5" cross CrossVersion.full)

@Atry Thank for trying it out! Please report a separate issue, that looks unrelated to the new release.

I just reported the issue at https://github.com/scalameta/metals/issues/647

Now I am busy uninstalling IntelliJ

Is it expected that the hover docs cannot define the exact collection in a overriden method, like in the image?

image

I see ${coll} but I can't tell if it's a generic placeholder, or if some substitution should happen, based on the current variable type

@ivanopagano that is a bug with the Scaladoc to Markdown conversion, which is not following the coll variable, defined with a @define declaration.

See

image

and

image

/cc @mudsam who worked on this

From https://github.com/scala/scala/blob/v2.12.1/src/library/scala/collection/IterableLike.scala#L1

Tracking this in #648, thanks for reporting!

Fantastic work @olafurpg :tada: !

I'm a long time user of NeoVim and I've been using one of the latest snapshots for a while and I'm pretty impressed with how fast it is!

Just to give you some feedback I got completions working using vim-lsc but I had to tweak it a bit to got it working properly (i.e. disabling showing empty preview window on autocompletion).

I gave coc.vim a go but it was hard to get it working smoothly. I don't know about others, I felt it buggy like it was last time I tried it but I might have tried it with the wrong config or so.

Keep up the amazing work!

Great, work @olafurpg and others involved!

I've been using Metals snapshots with Neovim and vim-lsc pretty steadily at work for a couple of months now. Overall, I've been very pleased. I haven't figured out how to get a working Nix derivation for coc.nvim yet, so I only have data for vim-lsc.

Certain things that I do seem to get it into a state where completion no longer works until I restart Neovim. I don't see anything unusual in the logs when this happens, and I haven't reported it yet, because I don't have a minimal example to reproduce it. I'll keep an eye on it but thought that this might be a good time to put it on someone's radar.

I've regularly used most of the features described here. Below are my results walking through them just now. Most things just work. I've listed below things that don't work quite as desired (I haven't mentioned the things that _do_ work perfectly).

  • auto-import completion: completing an import line like import Future@@ works, but local import isn't added for something like Future@@ (with vim-lsc).
  • snippet completion: I end up with something like assert($0) and the cursor is not inside the parentheses. I think that this is a known limitation of using Metals with vim-lsc?
  • completion item resolution: confirmed that I still see parameter names like x$1 on vim-lsc.
  • string literal into interpolator completion: this works, but you need an s at the beginning of your string, which is missing in the example
  • string literal member into curly brace completion: this works, but I end up with ${numbers.head$0}, which I think is consistent with completion templates generally being wonky when using Metals with vim-lsc.
  • exhaustive match completion: this works, but I end up with Option(1) match { case None => $0 case Some(x) =>} (^@ instead of newlines).
  • signature help - overloaded methods: with vim-lsc I don't see a way to cycle through overloaded variants
  • folding ranges - this doesn't seem to be supported in vim-lsc

@gvolpe @ceedubs Thank you for the feedback! I opened a separate ticket to discuss vim https://github.com/scalameta/metals/issues/650 The and $0 markers are part of the LSP snippet format (https://macromates.com/manual/en/snippets) that metals uses to declare "increase indent" and "place cursor here", respectively

Looking good so far under emacs. I haven't tested everything in the list.

I'm using console mode emacs with evil and company mode. What I've confirmed working:

  1. completions (using lsp-company). No issues encountered.
  2. hover. Markdown rendering does not occur. I suspect this is specific to console mode emacs. markdown-mode is installed.
  3. highlight. No issues encountered.

FWIW I've been using 0.5.0-M1 for a few hours with neovim (0.3.4) and vim-lsc (the latest HEAD, 4fd4668) and it's great so far! I've only encountered two bugs:

  1. When I choose to import the build, it works (I can see metals start doing stuff in the logs) but I get this weird error:

    Screenshot 2019-04-11 at 20 46 14

  2. When I close vim I see an error on the console after vim has disappeared:

    [lsc:Error] Command exited unexpectedly: metals-vim
    

    The only thing logged to metals.log at shutdown is this, which looks pretty normal:

    INFO  shutting down Metals
    10potj.socket' finished.
    INFO  bloop exit: 0
    

Awesome work!

I'm using neovim with LanguageClient-neovim, so far so good, but I still need to use it for few days to give and meaningful feedback. I already saw some of the problems reported by @ceedubs so I suppose it's neovim related, not necessary lsp client.

By the way now LanguageClient-neovim DO implement window/showMessageRequest :tada:

I'll try to keep you updated as soon as I have tested it a bit more.

Congrats again for the work

Was this page helpful?
0 / 5 - 0 ratings