Skip to content

Metals returns snippets even when a client doesn't support them #1055

@bstaletic

Description

@bstaletic

Describe the bug

The protocol doesn't require clients to support snippet completion. For those clients, the servers are supposed to only provide plain text completion.

One such client is ycmd, whose capabilities you can see here
As you can see, the capabilities don't contain { 'completionItem': { 'snippetSupport': True } } and, according to the protocol, the lack of 'snippetSupport' is supposed to be treated as 'snippetSupport': False.

Unfortunately, completion request returns:

2019-11-09 00:13:32,982 - DEBUG - RX: Received message: b'{"jsonrpc":"2.0","id":20,"result":{"isIncomplete":false,"items":[{"label":"getRemoteEndpoint(): RemoteEndpoint","kind":8,"detail":"(): RemoteEndpoint","preselect":true,"sortText":"00000","filterText":"getRemoteEndpoint","insertTextFormat":2,"textEdit":{"range":{"start":{"line":43,"character":15},"end":{"line":43,"character":15}},"newText":"getRemoteEndpoint"},"data":{"symbol":"org/eclipse/lsp4j/jsonrpc/Launcher#getRemoteEndpoint().","target":"file:/home/bstaletic/aur/metals/src/metals-0.7.6/metals/?id\\u003dmetals"}},{"label":"getRemoteProxy(): MetalsLanguageClient","kind":8,"detail":"(): MetalsLanguageClient","sortText":"00001","filterText":"getRemoteProxy","insertTextFormat":2,"textEdit":{"range":{"start":{"line":43,"character":15},"end":{"line":43,"character":15}},"newText":"getRemoteProxy"},"data":{"symbol":"org/eclipse/lsp4j/jsonrpc/Launcher#getRemoteProxy().","target":"file:/home/bstaletic/aur/metals/src/metals-0.7.6/metals/?id\\u003dmetals"}},{"label":"startListening(): Future[Void]","kind":8,"detail":"(): Future[Void]","sortText":"00002","filterText":"startListening","insertTextFormat":2,"textEdit":{"range":{"start":{"line":43,"character":15},"end":{"line":43,"character":29}},"newText":"startListening"},"data":{"symbol":"org/eclipse/lsp4j/jsonrpc/Launcher#startListening().","target":"file:/home/bstaletic/aur/metals/src/metals-0.7.6/metals/?id\\u003dmetals"}},{"label":"+(other: String): String","kind":2,"detail":"(other: String): String","sortText":"00003","filterText":"+","insertTextFormat":2,"textEdit":{"range":{"start":{"line":43,"character":15},"end":{"line":43,"character":15}},"newText":"+"},"data":{"symbol":"scala/Predef.any2stringadd#`+`().","target":"file:/home/bstaletic/aur/metals/src/metals-0.7.6/metals/?id\\u003dmetals"}},{"label":"formatted(fmtstr: String): String","kind":2,"detail":"(fmtstr: String): String","sortText":"00004","filterText":"formatted","insertTextFormat":2,"textEdit":{"range":{"start":{"line":43,"character":15},"end":{"line":43,"character":15}},"newText":"formatted"},"data":{"symbol":"scala/Predef.StringFormat#formatted().","target":"file:/home/bstaletic/aur/metals/src/metals-0.7.6/metals/?id\\u003dmetals"}},{"label":"parse[U](implicit convert: Convert[Launcher[MetalsLanguageClient],Input], parse: Parse[U], dialect: Dialect): Parsed[U]","kind":2,"detail":"[U](implicit convert: Convert[Launcher[MetalsLanguageClient],Input], parse: Parse[U], dialect: Dialect): Parsed[U]","sortText":"00005","filterText":"parse","insertTextFormat":2,"textEdit":{"range":{"start":{"line":43,"character":15},"end":{"line":43,"character":15}},"newText":"parse"},"data":{"symbol":"scala/meta/parsers/Api#XtensionParseInputLike#parse().","target":"file:/home/bstaletic/aur/metals/src/metals-0.7.6/metals/?id\\u003dmetals"}},{"label":"show[Style[X] \\u003c: scala.meta.prettyprinters.Show[X]](implicit style: Style[Launcher[MetalsLanguageClient]]): String","kind":2,"detail":"[Style[X] \\u003c: scala.meta.prettyprinters.Show[X]](implicit style: Style[Launcher[MetalsLanguageClient]]): String","sortText":"00006","filterText":"show","insertTextFormat":2,"textEdit":{"range":{"start":{"line":43,"character":15},"end":{"line":43,"character":15}},"newText":"show"},"data":{"symbol":"scala/meta/prettyprinters/Api#XtensionShow#show().","target":"file:/home/bstaletic/aur/metals/src/metals-0.7.6/metals/?id\\u003dmetals"}},{"label":"tokenize(implicit convert: Convert[Launcher[MetalsLanguageClient],Input], tokenize: Tokenize, dialect: Dialect): Tokenized","kind":2,"detail":"(implicit convert: Convert[Launcher[MetalsLanguageClient],Input], tokenize: Tokenize, dialect: Dialect): Tokenized","sortText":"00007","filterText":"tokenize","insertTextFormat":2,"textEdit":{"range":{"start":{"line":43,"character":15},"end":{"line":43,"character":15}},"newText":"tokenize"},"data":{"symbol":"scala/meta/tokenizers/Api#XtensionTokenizeInputLike#tokenize().","target":"file:/home/bstaletic/aur/metals/src/metals-0.7.6/metals/?id\\u003dmetals"}},{"label":"asInstanceOf[T0]: T0","kind":2,"detail":"[T0]: T0","sortText":"00008","filterText":"asInstanceOf","insertTextFormat":2,"textEdit":{"range":{"start":{"line":43,"character":15},"end":{"line":43,"character":15}},"newText":"asInstanceOf"},"data":{"symbol":"scala/Any#asInstanceOf().","target":"file:/home/bstaletic/aur/metals/src/metals-0.7.6/metals/?id\\u003dmetals"}},{"label":"equals(x$1: Any): Boolean","kind":8,"detail":"(x$1: Any): Boolean","sortText":"00009","filterText":"equals","insertTextFormat":2,"textEdit":{"range":{"start":{"line":43,"character":15},"end":{"line":43,"character":15}},"newText":"equals"},"data":{"symbol":"java/lang/Object#equals().","target":"file:/home/bstaletic/aur/metals/src/metals-0.7.6/metals/?id\\u003dmetals"}},{"label":"getClass(): Class[_]","kind":8,"detail":"(): Class[_]","sortText":"00010","filterText":"getClass","insertTextFormat":2,"textEdit":{"range":{"start":{"line":43,"character":15},"end":{"line":43,"character":15}},"newText":"getClass"},"data":{"symbol":"java/lang/Object#getClass().","target":"file:/home/bstaletic/aur/metals/src/metals-0.7.6/metals/?id\\u003dmetals"}},{"label":"hashCode(): Int","kind":8,"detail":"(): Int","sortText":"00011","filterText":"hashCode","insertTextFormat":2,"textEdit":{"range":{"start":{"line":43,"character":15},"end":{"line":43,"character":15}},"newText":"hashCode"},"data":{"symbol":"java/lang/Object#hashCode().","target":"file:/home/bstaletic/aur/metals/src/metals-0.7.6/metals/?id\\u003dmetals"}},{"label":"isInstanceOf[T0]: Boolean","kind":2,"detail":"[T0]: Boolean","sortText":"00012","filterText":"isInstanceOf","insertTextFormat":2,"textEdit":{"range":{"start":{"line":43,"character":15},"end":{"line":43,"character":15}},"newText":"isInstanceOf"},"data":{"symbol":"scala/Any#isInstanceOf().","target":"file:/home/bstaletic/aur/metals/src/metals-0.7.6/metals/?id\\u003dmetals"}},{"label":"synchronized[T0](x$1: T0): T0","kind":2,"detail":"[T0](x$1: T0): T0","sortText":"00013","filterText":"synchronized","insertTextFormat":2,"textEdit":{"range":{"start":{"line":43,"character":15},"end":{"line":43,"character":15}},"newText":"synchronized"},"data":{"symbol":"java/lang/Object#synchronized().","target":"file:/home/bstaletic/aur/metals/src/metals-0.7.6/metals/?id\\u003dmetals"}},{"label":"toString(): String","kind":8,"detail":"(): String","sortText":"00014","filterText":"toString","insertTextFormat":2,"textEdit":{"range":{"start":{"line":43,"character":15},"end":{"line":43,"character":15}},"newText":"toString"},"data":{"symbol":"java/lang/Object#toString().","target":"file:/home/bstaletic/aur/metals/src/metals-0.7.6/metals/?id\\u003dmetals"}}]}}'

The completion items contain "inserTextFormat":2, which indicates snippets and triggers an assert in ycmd.

To Reproduce
Steps to reproduce the behavior:

  1. Install YouCompleteMe for vim
  2. Unfortunately, ycmd still doesn't support showMessageRequest, so one will need to apply this patch.
  3. Put let g:ycm_language_server = [ { 'name': 'metals-showMessageRequest', 'filetypes': [ 'scala', 'sbt' ], 'cmdline': [ 'metals-vim' ], 'project_root_files': [ 'build.sbt' ] } ] in your vimrc.
  4. Open a scala file and wait for metals to finish building
  5. Try to complete
  6. The stack trace of the assert can be found in one of the logs visible in :YcmDebugInfo.

Expected behavior

Screenshots

Installation:

  • Operating system: Linux
  • Editor: Vim with YouCompleteMe
  • Metals version: v0.7.6

Additional context

Search terms

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething that is making a piece of functionality unusable

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions