This context provides a detailed guide on how to configure Neovim's built-in Language Server Protocol (LSP) client using the nvim-lspconfig plugin and a language server installer.
Abstract
The given context is a comprehensive tutorial on configuring the Language Server Protocol (LSP) in Neovim. The tutorial starts with an introduction to the nvim-lspconfig plugin, a collection of common configurations for Neovim's built-in language server client. It then provides step-by-step instructions for installing the plugin, setting up various language servers, and configuring key mappings for LSP features. The tutorial also covers the installation and configuration of nvim-lsp-installer, a plugin that simplifies the process of installing LSP servers. The context concludes with a discussion on how to use LSP for omni completion, and provides screenshots to illustrate the expected outcomes.
Bullet points
The tutorial is about configuring Neovim's built-in Language Server Protocol (LSP) client.
The nvim-lspconfig plugin is used, which provides common configurations for Neovim’s built-in language server client.
The tutorial includes steps for installing and configuring nvim-lspconfig, setting up various language servers, and configuring key mappings for LSP features.
The nvim-lsp-installer plugin is also installed to simplify the installation process of LSP servers.
The tutorial also covers the use of LSP for omni completion.
Screenshots are provided throughout the tutorial to illustrate the expected outcomes.
Neovim for Beginners — LSP (Part 1)
Configure the built-in LSP (Language Server Protocol) client.
Neovim for Beginners — LSP
Neovim supports the Language Server Protocol (LSP), which means it acts as a client to LSP servers and includes a Lua framework vim.lsp (:h vim.lsp) for building enhanced LSP tools. The language servers are provided by third parties.
In this article, we are going to
Configure the nvim-lspconfigplugin that provides common configuration for various language servers.
Configure a language server installer to make it easy to install any language server.
Configure key mappings for the LSP features.
Configure the vim.lsp.omnifunc function (:h vim.lsp.omnifunc) as the omnifunc(:h omnifunc) handler. The omnifuncoption specifies a function to be used for insert mode omni completion with CTRL-X CTRL-O.
Configure the vim.lsp.formatexpr function as the handler for formatexpr(:h formatexpr). The formatexpr option specifies an expression that is evaluated to format a range of lines for the gqoperator or automatic formatting (:h formatoptions).
Configure LSP completion using coq.nvim and nvim-cmp. Previously, we talked about these two completion plugins in this article.
The Neovim configuration files can be found in this repository.
Unlike treesitter or ctags, LSP facilitates features like go-to-definition, find-references, hover, completion, rename, format, refactor, etc., using semantic whole-project analysis. We will get started by installing and configuring nvim-lspconfig.
We install the language servers for Go (gopls), HTML (html), JSON (jsonls), Python (pyright), Rust (rust_analyzer), Lua (sumeko_lua), Javascript/Typescript (tsserver), and Vimscript (vimls).
Check out the list of supported language servers here.
Currently, we do not configure any specific settings for all the language servers so the Lua tables are empty. We will see how to fine-tune a particular language server later.
The on_attach function is called when a language server is attached to a buffer. In this function, we attach the LSP handlers to omnifunc and formatexpr. We also call the function to configure the key mappings.
Check out the documentation (:h vim.lsp.start_client) on the LSP configuration. The debounce_text_changes flag debounces didChange notifications to the server by the given number in milliseconds. No debounce occurs if nil.
We configure key mappings for some of the LSP functions in normal mode. E.g. [d, ]d to navigate the diagnostic messages, K to show the hover documentation.
We also use whichkey to map the prefix <Leader>l and g to several LSP functions. E.g. gd to show the definition, gt to show the type definition.
Tip: For a newer version of Neovim (0.7 and above), try using the new keymap APIs (:h vim.keymap.set()). E.g. we can define the key for hover action like below. Buffer 0 or true means the current buffer.
-- For normal mode
vim.keymap.set("n", "K", vim.lsp.buf.hover, { buffer = 0 })
Run the :PackerInstall command to install the plugins now.
The language servers are installed automatically.
Auto Installation of Language Servers
Omni completion (CTRL-X CTRL-O) should work now.
Omni Completion
The LSP key mappings should also work if the capability is supported. E.g. gd to go to the definition, and gs to show the signature help.
LSP Functions
Type :LspInfo and we can see the language server details for the current buffer.
Lsp Info
Tip: We press K to show the documentation. To go into the hover documentation, press K again. To exit, press q.
Hover Documentation
Tips:
We press gd, gt, gI to navigate to the definition, type definition, or implementation. To go back, we can press Ctrl-t (:h Ctrl-t). Ctrl-t jumps to an older entry in the tag stack.
Type :tags and we can see that the older entries are saved into the tag list. Ctrl-o and Ctrl-i are used for the jump list (:h jumplist).
E.g. in the below screenshot, we press gd to go the definition of the joblib module. We jump to different locations within the file. To go back to the joblib location, instead of pressing Ctrl-o multiple times, we just need to press Ctrl-t.
Navigation using Tags
nvim-cmp
The built-in omni completion is not so helpful. Let’s proceed to configure a completion plugin.
If you are not a Medium member yet and want to become one, click here. You will gain unlimited access to all Medium articles and support my work directly.