Metals: Can this be used with Emacs?

Created on 25 Mar 2018  路  12Comments  路  Source: scalameta/metals

Can this be used with Emacs?

https://github.com/emacs-lsp

What should be done to make this happen?

Most helpful comment

I posted late and, in the morning light, wish I'd expressed more appreciation. I'm trying it at such an early stage because it's so badly needed and because I'm optimistic about what it will become. :)

I followed the directions except for building the VSCode extension, which I _think_ is not relevant in emacs. And then of course opening the file in emacs and running lsp-scala-enable instead of code.
Do those settings in package.json do anything outside of VSCode?

The lsp-mode protocol specifies passing a workspace root to the language server. If I can figure out what this means, and how to make metals respect it, then I think I can publish a viable lsp-scala package, and I could document how to use it with metals.

All 12 comments

Hi @NightMachinary! Take a look at #205, there's a similar question. You just need to make an Emacs extension like those lsp-* in the @emacs-lsp org, which will fetch and launch Metals server (using coursier).

Duplicate of #205. Also related to #111. The VS Code client can be used as a reference for how to initialize the server https://github.com/scalameta/metals/blob/b8b681d4372b6a733499ee7248d663c03b52dfd8/vscode-extension/src/extension.ts#L17-L54
It should be possible to connect to Metals with any LSP compliant client.

@NightMachinary in addition to the VSCode extension, check the updated server launch script in bin/start-server.sh, it's very simple and probably you could use it directly from the Emacs extension (although you'll need to add some extra parentheses 馃槣).

I got something working, poorly:

Hacks:

  • I had to hardcode the project root, and cd into it from the launch script to make it the working directory. I hoped setting it as the third argument to lsp-define-stdio-client would be sufficient.
  • The nix-shell is to work around an UnsatisfiedLinkError in leveldbjni. If you're not on NixOS, you shouldn't need this.

Works:

  • Can open a Scala file in my project and run lsp-scala-enable. (Could be a hook.)
  • lsp-rename works within a very narrow scope.
  • lsp-restart-workspace restarts metals
  • lsp-capabilties reports back:
Document sync method: 
The server provides hover support
The server provides completion support
The server provides goto definition support
The server provides references support
The server provides file symbol support
The server provides project symbol support
The server provides code actions
The server provides file formatting

Doesn't work:

  • lsp-info-under-point doesn't seem to do anything. No info on hover, despite eldoc-mode being enabled.
  • lsp-goto-implementation says "Capability not supported by the language server: "implementationProvider"
  • lsp-goto-type-definition says "Capability not supported by the language server: "typeDefinitionProvider"
  • lsp-symbol-highlight doesn't seem to do anything.
  • xref-find-references doesn't find anything
  • xref-find-definitions doesn't find anything
  • company-lsp doesn't complete anything

All of this works, or doesn't work, without errors logged to the Metals console.

I hope this helps on either the emacs end or the metals end of things.

Thanks for the feedback @rossabaker !

Did you follow the instruction in https://github.com/scalameta/metals/blob/master/BETA.md ? There are several steps required from the build side to make definition/completions/references/hover work. Additionally, we recently disabled certain unstable features by default (e.g., completions and sbt server) in preparation for a v0.1 release. It's necessary to use workspace/didChangeConfiguration to enable some features, the settings are documented in the vscode plugin manifest https://github.com/scalameta/metals/blob/871e52b8e02478f403db45e4b172012bb7d2548d/vscode-extension/package.json#L16-L95

goto-implementation and goto-type-definition are recent v3.6 additions to LSP, which we haven't implemented yet but would be simple to support if someone is interested 馃槃

Either way, this project is not ready for public usage so docs/installation steps/features are incomplete. If you want a stable plugin it's best to wait!

I posted late and, in the morning light, wish I'd expressed more appreciation. I'm trying it at such an early stage because it's so badly needed and because I'm optimistic about what it will become. :)

I followed the directions except for building the VSCode extension, which I _think_ is not relevant in emacs. And then of course opening the file in emacs and running lsp-scala-enable instead of code.
Do those settings in package.json do anything outside of VSCode?

The lsp-mode protocol specifies passing a workspace root to the language server. If I can figure out what this means, and how to make metals respect it, then I think I can publish a viable lsp-scala package, and I could document how to use it with metals.

I'm trying it at such an early stage because it's so badly needed and because I'm optimistic about what it will become

I'm glad to hear that! What features in particular are you most interested in?

I personally use IntelliJ so my IDE wishlist is quite big 馃槄 https://geirsson.com/post/2018/03/ide/

Do those settings in package.json do anything outside of VSCode?

The聽features that are disabled in package.json (completions/hover/...) will return empty responses even if the server registers the capability on initilize. The client needs to send appropriate workspace/didChangeConfiguration notifications to register interest in those features. The idea is to cut a first release with only features we consider stable enough to be enabled by default to begin with.

In VS Code, it's possible to edit configuration with Cmd+, and
screen shot 2018-04-01 at 00 38 43

Does the emacs lsp package support configuration?

The lsp-mode protocol specifies passing a workspace root to the language server.

Metals is not compliant with LSP in that it currently discards the workspace uri in the initialize request. I opened https://github.com/scalameta/metals/issues/216 to keep track of respecting the rootUri field in the initialize request, and added some notes on workarounds and why the workspace root is important for definition/references.

I think I can publish a viable lsp-scala package, and I could document how to use it with metals.

That would be cool! I just opened https://github.com/scalameta/metals/issues/217 to track documentation for editor clients.

FYI, our CI already publishes a release to bintray on every merge https://bintray.com/scalameta/maven/metals which should avoid the publishLocal step.

What features in particular are you most interested in?

I'm still learning what LSP is capable of, but I think my priority list would be:

  1. hover information
  2. go to definition
  3. auto completion
  4. auto import from classpath
  5. find references

I would of course be thrilled with any of these in any order. :smile:

Does the emacs lsp package support configuration?

It supports optional init parameters and "extra client capabilities." I don't see anything that quite maps to disabling standard features.

Thanks for the help. I'll keep hacking away on this.

@rossabaker we just added an "overview" document https://github.com/scalameta/metals/blob/master/docs/overview.md which is partly vision for the future + documenting what already exists.

Metals relies on the workspace/didChangeConfiguration feature to enable unstable features like completions. https://microsoft.github.io/language-server-protocol/specification#workspace_didChangeConfiguration I would check how emacs-lsp handles that method.

@rossabaker has called my attention to https://github.com/rossabaker/lsp-scala

There's a PR up adding installation docs for Emacs https://github.com/scalameta/metals/pull/397

Live demo: https://olafurpg.github.io/metals/ (ignore the version numbers, they're dummies)

Was this page helpful?
0 / 5 - 0 ratings