How to use (and contribute) to neovim's built-in language server client and nvim-lspconfig

Introduction

I see a lot of posts and comments asking about the built-in language server client, how to use it, and how it compares to coc.nvim (an amazing plugin and ecosystem in itself!). I’ve been trying to answer issues on nvim-lspconfig and neovim, but I thought making a discourse post might be a useful discovery tool for some. I want to cover what nvim-lspconfig is/isn’t, updates to the documentation, and address some differences with CoC.

What is nvim-lspconfig? Is it a language server client?

Neovim contains a language server client, which communicates with language servers via language server protocol. The (current) function of nvim-lspconfig is to manage launching and tracking active language servers, which includes providing good defaults for initializationOptions , which are sent to the server via initialize , and settings which are sent to the server via workspace/didChangeConfiguration . nvim-lspconfig is not the language server client itself, that code is in core.

You do not have to use nvim-lspconfig to use neovim’s built-in language server client, it just makes it much easier! See :help lsp for the documentation. I made a gist showing you how to manually launch a language server without nvim-lspconfig .

Sometimes, we add workaround for servers that don’t fully comply with the LSP spec. If a feature that you may want to add to a server is not enabled by default, there is a section on how to override settings per server in the readme.

How to get started

I see the complaints, and have significantly overhauled the readme as of today. Just to be clear, you do not need to copy anything from CONFIG.md to use nvim-lspconfig! I have updated the docs with a new quickstart section. It’s very easy to extend/modify settings, and you only have to do it once in your config! I haven’t modified the majority of my language server bindings in months!

I made a minimal init.lua that you all can use to try out a “batteries included” language server setup. It uses packer, a cool new(ish) package manager written in lua, and installs everything to temp, so it shouldn’t affect anything permanently on your system. The only thing it doesn’t include, which you all may want, is autocompletion for which I highly recommend comp-e. You can also peruse my personal init.lua which varies in levels of organization/readability.

Does nvim-lspconfig install my language server for me?

:LspInstall and :LspInstallInfo were recently removed from nvim-lspconfig . These never worked all that robustly (except for npm, which is easy enough to use manually), and had no mechanisms for updates which led to bugs arising from old server versions. There are such a wide variety of sources that one can install language servers from (source, npm, cargo, your linux package manager, brew, I personally use nix!) that the support surface would have been incredibly large.

It seems that there has been mention from users of interest on starting a plugin that handles installing and updating language servers. We realize this is a feature a lot of you care about, but it belongs in it’s own plugin that more generally supports system package management. Think system-package from emacs. I’m happy to provide some guidance, but it’s not something I would personally use.

Edit: /u/alex-popov-tech pointed out vim-lsp-settings which you can use to do this. Great resource!

Not all of my language server’s features are supported

There are plugins which use the neovim core language client to provide a richer experience than nvim-lspconfig , such as nvim-jdtls, nvim-metals, and flutter-tools.nvim. I think these are analogous to coc-plugins, whereas nvim-lspconfig takes a more minimalist approach. Many “features” of language servers are not spec adherent, jdtls is one such example, and those workarounds likely belong in their own plugins.

I found a missing feature, where do I report it?

Almost the entirety of the language client functionality is implemented in neovim core, so if there is a bug that is not related to server initialization options, server settings, or server management, it’s probably best to file it in core rather than the nvim-lspconfig repo. Most of the time, these are errors in handlers which respond to messages from the language server. If you get a missing handler error, file it in core.

If you get an error saying that a server does not support a given function (such as formatting), that just means the server hasn’t implemented the functionality yet, and you can file a feature request with the upstream project.

I’ve added detailed instructions in the issue template walking through how to enable logging, and view the log file.

If you want a new language server, believe we are setting the wrong settings/initialization options, or believe the root directory detection is wrong, file it in the nvim-lspconfig repo.

How can I get additional help that may not be an issue, just some general Q&A?

You’re in the right place :slight_smile:

Contributing

I’m not really a polyglot (c/c++, python, haskell, rust, lua, and a little bit of elisp), so it’s really helpful when people that use language servers proactively respond on the issue tracker, especially because many questions are more usage/setup related for languages that I don’t use. It’s especially helpful to file documentation PRs when things are unclear, but remember CONFIG.md is auto-generated from the lua files, so make sure to only edit the documentation in the lua files!

Comparison to CoC.nvim

Some people ask for comparisons to coc.nvim. I would say, that nvim-lspconfig does not provide the same level of functionality (ex: mapping custom handlers and custom vim commands that trigger things besides our generic code action support) per server as a CoC plugin , and it probably won’t. It’s a monorepo that aims to provide minimal defaults, not a plugin ecosystem.

I do think more and more plugins will come out that build upon the language server client in core, like nvim-jdtls and nvim-metals , which will have that level of functionality. The nice part is, nvim-lspconfig is highly extensible, and you can customize many aspects of it by overriding handlers all in the same init.lua that you can now use for your neovim config.

Closing

Thank you for reading. If you have questions, I’ll try to answer. The best way you can help is to use nvim-lspconfig , file PRs when server settings/initializations need to be changed (for everyone), let us know when servers break, provide feedback on how to improve documentation, and help answer issues that arise. Issues should be filed at the respective github trackers. How-to questions can be posted here, and I’ll try to respond.

22 Likes

Thank you for the explanation. And thanks to the core team for starting the discourse.

5 Likes

And you can build any function you need based on the builtin lsp api. It is highly customizable.

1 Like

There is a Neovim lsp plugin that handles update/install of lsp servers GitHub - alexaandru/nvim-lspupdate: Updates installed LSP servers, automatically

1 Like

I thought nvim-compe is the new shiny kid on the block. Does any body have a comparison between the two, especially about performance, which I heard compe is better?
I haven’t got the time to try both yet but I have some problem with compe.nvim not displaying any other sources other than LSP.

1 Like

Sure, I copied and pasted my original post from reddit which predates comp-e. I’ve updated the original post.

The comp-e author is more active and it seems to have a reputation as being “snappier”. I’d recommend you try it out.

3 Likes

You still have kind of the same problems, if you type too fast (blocks you from typing/does not drop data, if too delayed). One need sub-ms time or counter measurement for never delaying typing on autocomplete (rofl.nvim probably gets there at some point).