Skip to content

Commit

Permalink
docs: update readme (neovim#1677)
Browse files Browse the repository at this point in the history
  • Loading branch information
mjlbach authored Jan 23, 2022
1 parent 9c30d56 commit b1c5ed0
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 126 deletions.
131 changes: 51 additions & 80 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,20 @@ Neovim supports the Language Server Protocol (LSP), which means it acts as a cli

Neovim provides an interface for all of these features, and the language server client is designed to be highly extensible to allow plugins to integrate language server features which are not yet present in Neovim core such as [**auto**-completion](https://github.com/neovim/nvim-lspconfig/wiki/Autocompletion) (as opposed to manual completion with omnifunc) and [snippet integration](https://github.com/neovim/nvim-lspconfig/wiki/Snippets).

These features are not implemented in this repo, but in Neovim core. See `:help lsp` for more details.
**These features are not implemented in this repo**, but in Neovim core. See `:help lsp` for more details.

## Install

* Requires [Neovim v0.6.0](https://github.com/neovim/neovim/releases/tag/v0.6.0) or [Nightly](https://github.com/neovim/neovim/releases/tag/nightly). Update Neovim and 'lspconfig' before reporting an issue.
* Requires [Neovim v0.6.1](https://github.com/neovim/neovim/releases/tag/v0.6.1) or [Nightly](https://github.com/neovim/neovim/releases/tag/nightly). Update Neovim and 'lspconfig' before reporting an issue.

* Install 'lspconfig' like any other Vim plugin, e.g. with [vim-plug](https://github.com/junegunn/vim-plug):
* Install 'lspconfig' like any other Vim plugin, e.g. with [packer.nvim](https://github.com/wbthomason/packer.nvim):

```vim
Plug 'neovim/nvim-lspconfig'
```lua
local use = require('packer').use
require('packer').startup(function()
use 'wbthomason/packer.nvim' -- Package manager
use 'neovim/nvim-lspconfig' -- Collection of configurations for the built-in LSP client
end)
```

## Quickstart
Expand All @@ -41,129 +45,100 @@ These features are not implemented in this repo, but in Neovim core. See `:help
npm i -g pyright
```

2. Add the language server setup to your init.vim. The server name must match those found in the table of contents in [server_configurations.md](doc/server_configurations.md). This list is also accessible via `:help lspconfig-server-configurations`.
2. Add the language server setup to your init.lua.

```lua
lua << EOF
require'lspconfig'.pyright.setup{}
EOF
```
3. Create a project, this project must contain a file matching the root directory trigger. See [Automatically launching language servers](#Automatically-launching-language-servers) for additional info.
```bash
mkdir test_python_project
cd test_python_project
git init
touch main.py
```

4. Launch neovim, the language server will now be attached and providing diagnostics (see `:LspInfo`)
3. Launch neovim, the language server will now be attached and providing diagnostics (see `:LspInfo`)

```
nvim main.py
```

5. See [Keybindings and completion](#Keybindings-and-completion) for mapping useful functions and enabling omnifunc completion
## Automatically launching language servers
In order to automatically launch a language server, 'lspconfig' searches up the directory tree from your current buffer to find a file matching the `root_dir` pattern defined in each server's configuration. For [pyright](doc/server_configurations.md#pyright), this is any directory containing ".git", "setup.py", "setup.cfg", "pyproject.toml", or "requirements.txt").
Language servers require each project to have a `root` in order to provide completion and search across symbols that may not be defined in your current file, and to avoid having to index your entire filesystem on each startup.
## Enabling additional language servers
Enabling most language servers is as easy as installing the language server, ensuring it is on your PATH, and adding the following to your config:
```vim
lua << EOF
require'lspconfig'.rust_analyzer.setup{}
EOF
```
4. See [Keybindings and completion](#Keybindings-and-completion) for mapping useful functions and enabling omnifunc completion

For a full list of servers, see [server_configurations.md](doc/server_configurations.md) or `:help lspconfig-server-configurations`. This document contains installation instructions and additional, optional, customization suggestions for each language server. For some servers that are not on your system path (e.g., `jdtls`, `elixirls`), you will be required to manually add `cmd` as an entry in the table passed to `setup`. Most language servers can be installed in less than a minute.

## Keybindings and completion
## Suggested configuration

'lspconfig' does not map keybindings or enable completion by default. The following example configuration provides suggested keymaps for the most commonly used language server functions, and manually triggered completion with omnifunc (\<c-x\>\<c-o\>).

'lspconfig' does not map keybindings or enable completion by default. Manual, triggered completion can be provided by neovim's built-in omnifunc. For autocompletion, a general purpose [autocompletion plugin](https://github.com/neovim/nvim-lspconfig/wiki/Autocompletion) is required. The following example configuration provides suggested keymaps for the most commonly used language server functions, and manually triggered completion with omnifunc (\<c-x\>\<c-o\>).
Note: **you must pass the defined `on_attach` as an argument to every `setup {}` call** and **the keybindings in `on_attach` only take effect after the language server has started (attached to the current buffer)**.
Note: **you must pass the defined `on_attach` as an argument to every `setup {}` call** and **the keybindings in `on_attach` only take effect on buffers with an active language server**.

```lua
lua << EOF
local nvim_lsp = require('lspconfig')
-- Mappings.
-- See `:help vim.diagnostic.*` for documentation on any of the below functions
local opts = { noremap=true, silent=true }
vim.api.nvim_set_keymap('n', '<space>e', '<cmd>lua vim.diagnostic.open_float()<CR>', opts)
vim.api.nvim_set_keymap('n', '[d', '<cmd>lua vim.diagnostic.goto_prev()<CR>', opts)
vim.api.nvim_set_keymap('n', ']d', '<cmd>lua vim.diagnostic.goto_next()<CR>', opts)
vim.api.nvim_set_keymap('n', '<space>q', '<cmd>lua vim.diagnostic.setloclist()<CR>', opts)
vim.api.nvim_set_keymap('n', '<space>f', '<cmd>lua vim.lsp.buf.formatting()<CR>', opts)

-- Use an on_attach function to only map the following keys
-- after the language server attaches to the current buffer
local on_attach = function(client, bufnr)
local function buf_set_keymap(...) vim.api.nvim_buf_set_keymap(bufnr, ...) end
local function buf_set_option(...) vim.api.nvim_buf_set_option(bufnr, ...) end

-- Enable completion triggered by <c-x><c-o>
buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc')
vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc')

-- Mappings.
local opts = { noremap=true, silent=true }

-- See `:help vim.lsp.*` for documentation on any of the below functions
buf_set_keymap('n', 'gD', '<cmd>lua vim.lsp.buf.declaration()<CR>', opts)
buf_set_keymap('n', 'gd', '<cmd>lua vim.lsp.buf.definition()<CR>', opts)
buf_set_keymap('n', 'K', '<cmd>lua vim.lsp.buf.hover()<CR>', opts)
buf_set_keymap('n', 'gi', '<cmd>lua vim.lsp.buf.implementation()<CR>', opts)
buf_set_keymap('n', '<C-k>', '<cmd>lua vim.lsp.buf.signature_help()<CR>', opts)
buf_set_keymap('n', '<space>wa', '<cmd>lua vim.lsp.buf.add_workspace_folder()<CR>', opts)
buf_set_keymap('n', '<space>wr', '<cmd>lua vim.lsp.buf.remove_workspace_folder()<CR>', opts)
buf_set_keymap('n', '<space>wl', '<cmd>lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))<CR>', opts)
buf_set_keymap('n', '<space>D', '<cmd>lua vim.lsp.buf.type_definition()<CR>', opts)
buf_set_keymap('n', '<space>rn', '<cmd>lua vim.lsp.buf.rename()<CR>', opts)
buf_set_keymap('n', '<space>ca', '<cmd>lua vim.lsp.buf.code_action()<CR>', opts)
buf_set_keymap('n', 'gr', '<cmd>lua vim.lsp.buf.references()<CR>', opts)
buf_set_keymap('n', '<space>e', '<cmd>lua vim.diagnostic.open_float()<CR>', opts)
buf_set_keymap('n', '[d', '<cmd>lua vim.diagnostic.goto_prev()<CR>', opts)
buf_set_keymap('n', ']d', '<cmd>lua vim.diagnostic.goto_next()<CR>', opts)
buf_set_keymap('n', '<space>q', '<cmd>lua vim.diagnostic.setloclist()<CR>', opts)
buf_set_keymap('n', '<space>f', '<cmd>lua vim.lsp.buf.formatting()<CR>', opts)

vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gD', '<cmd>lua vim.lsp.buf.declaration()<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gd', '<cmd>lua vim.lsp.buf.definition()<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'K', '<cmd>lua vim.lsp.buf.hover()<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gi', '<cmd>lua vim.lsp.buf.implementation()<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<C-k>', '<cmd>lua vim.lsp.buf.signature_help()<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<space>wa', '<cmd>lua vim.lsp.buf.add_workspace_folder()<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<space>wr', '<cmd>lua vim.lsp.buf.remove_workspace_folder()<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<space>wl', '<cmd>lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<space>D', '<cmd>lua vim.lsp.buf.type_definition()<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<space>rn', '<cmd>lua vim.lsp.buf.rename()<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<space>ca', '<cmd>lua vim.lsp.buf.code_action()<CR>', opts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gr', '<cmd>lua vim.lsp.buf.references()<CR>', opts)
end

-- Use a loop to conveniently call 'setup' on multiple servers and
-- map buffer local keybindings when the language server attaches
local servers = { 'pyright', 'rust_analyzer', 'tsserver' }
for _, lsp in ipairs(servers) do
nvim_lsp[lsp].setup {
for _, lsp in pairs(servers) do
require('lspconfig')[lsp].setup {
on_attach = on_attach,
flags = {
-- This will be the default in neovim 0.7+
debounce_text_changes = 150,
}
}
end
EOF
```

The `on_attach` hook is used to only activate the bindings after the language server attaches to the current buffer.
Manual, triggered completion is provided by neovim's built-in omnifunc. For **auto**completion, a general purpose [autocompletion plugin](https://github.com/neovim/nvim-lspconfig/wiki/Autocompletion) is required.

## Debugging

If you have an issue with 'lspconfig', the first step is to reproduce with a [minimal configuration](https://github.com/neovim/nvim-lspconfig/blob/master/test/minimal_init.lua).

The most common reasons a language server does not start or attach are:

1. The language server is not installed. 'lspconfig' does not install language servers for you. You should be able to run the `cmd` defined in each server's lua module from the command line and see that the language server starts. If the `cmd` is an executable name, ensure it is on your path.
1. The language server is not installed. 'lspconfig' does not install language servers for you. You should be able to run the `cmd` defined in each server's lua module from the command line and see that the language server starts. If the `cmd` is an executable name instead of an absolute path to the executable, ensure it is on your path.

2. Missing filetype plugins. Certain languages are not detecting by vim/neovim because they have not yet been added to the filetype detection system. Ensure `:set ft?` shows the filetype and not an empty value.

2. Not triggering root detection. The language server will only start if it is opened in a directory, or child directory, containing a file which signals the *root* of the project. Most of the time, this is a `.git` folder, but each server defines the root config in the lua file. See [server_configurations.md](doc/server_configurations.md) or the source for the list of root directories.
3. Not triggering root detection. **Some** language servers will only start if it is opened in a directory, or child directory, containing a file which signals the *root* of the project. Most of the time, this is a `.git` folder, but each server defines the root config in the lua file. See [server_configurations.md](doc/server_configurations.md) or the source for the list of root directories.

3. Misconfiguration. You must pass `on_attach` and `capabilities` for **each** `setup {}` if you want these to take effect. You must also **not call `setup {}` twice for the same server**. The second call to `setup {}` will overwrite the first.
4.You must pass `on_attach` and `capabilities` for **each** `setup {}` if you want these to take effect.

:LspInfo provides a handy overview of your active and configured language servers. Note, that it will not report any configuration changes applied in `on_new_config`.
5. **Do not call `setup {}` twice for the same server**. The second call to `setup {}` will overwrite the first.

Before reporting a bug, check your logs and the output of `:LspInfo`. Add the following to your init.vim to enable logging:

```lua
lua << EOF
vim.lsp.set_log_level("debug")
EOF
```

Attempt to run the language server, and open the log with:

```
:lua vim.cmd('e'..vim.lsp.get_log_path())
```
Expand All @@ -183,7 +158,6 @@ The following support tab-completion for all arguments:

Please see the [wiki](https://github.com/neovim/nvim-lspconfig/wiki) for additional topics, including:

* [Installing language servers automatically](https://github.com/neovim/nvim-lspconfig/wiki/Installing-language-servers-automatically)
* [Snippets support](https://github.com/neovim/nvim-lspconfig/wiki/Snippets)
* [Project local settings](https://github.com/neovim/nvim-lspconfig/wiki/Project-local-settings)
* [Recommended plugins for enhanced language server features](https://github.com/neovim/nvim-lspconfig/wiki/Language-specific-plugins)
Expand All @@ -195,15 +169,12 @@ a new configuration for it would be appreciated. You can follow these steps:

1. Read [CONTRIBUTING.md](CONTRIBUTING.md).

2. Choose a language from [the coc.nvim wiki](https://github.com/neoclide/coc.nvim/wiki/Language-servers) or
[emacs-lsp](https://github.com/emacs-lsp/lsp-mode#supported-languages).

3. Create a new file at `lua/lspconfig/SERVER_NAME.lua`.
2. Create a new file at `lua/lspconfig/server_configurations/SERVER_NAME.lua`.

- Copy an [existing config](https://github.com/neovim/nvim-lspconfig/blob/master/lua/lspconfig/server_configurations/)
to get started. Most configs are simple. For an extensive example see
[texlab.lua](https://github.com/neovim/nvim-lspconfig/blob/master/lua/lspconfig/server_configurations/texlab.lua).

4. Ask questions on our [Discourse](https://neovim.discourse.group/c/7-category/7) or in the [Neovim Gitter](https://gitter.im/neovim/neovim).
3. Ask questions on our [Discourse](https://neovim.discourse.group/c/7-category/7) or in the [Neovim Gitter](https://gitter.im/neovim/neovim).

You can also help out by testing [PRs with the `needs-testing`](https://github.com/neovim/nvim-lspconfig/issues?q=is%3Apr+is%3Aopen+label%3Aneeds-testing) label) that affect language servers you use regularly.
Loading

0 comments on commit b1c5ed0

Please sign in to comment.