1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-01-23 22:30:04 +08:00

chore(lspconfig): update bundle lspconfig

This commit is contained in:
wsdjeg 2022-06-21 14:24:21 +08:00
parent f0f1acc964
commit b7e45f2b1d
62 changed files with 8050 additions and 4792 deletions

2
bundle/README.md vendored
View File

@ -31,7 +31,7 @@ In `bundle/` directory, there are two kinds of plugins: forked plugins without c
- [defx.nvim](https://github.com/Shougo/defx.nvim/tree/df5e6ea6734dc002919ea41786668069fa0b497d) - [defx.nvim](https://github.com/Shougo/defx.nvim/tree/df5e6ea6734dc002919ea41786668069fa0b497d)
- [dein.vim](https://github.com/Shougo/dein.vim/tree/452b4a8b70be924d581c2724e5e218bfd2bcea14) - [dein.vim](https://github.com/Shougo/dein.vim/tree/452b4a8b70be924d581c2724e5e218bfd2bcea14)
- [indent-blankline.nvim](https://github.com/lukas-reineke/indent-blankline.nvim/tree/045d9582094b27f5ae04d8b635c6da8e97e53f1d) - [indent-blankline.nvim](https://github.com/lukas-reineke/indent-blankline.nvim/tree/045d9582094b27f5ae04d8b635c6da8e97e53f1d)
- [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig/tree/507f8a570ac2b8b8dabdd0f62da3b3194bf822f8) - [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig/tree/c55e830aa18bd15f36f7534947ec7471f2b43af7)
- [deoplete-lsp](https://github.com/deoplete-plugins/deoplete-lsp/tree/c466c955e85d995984a8135e16da71463712e5e5) - [deoplete-lsp](https://github.com/deoplete-plugins/deoplete-lsp/tree/c466c955e85d995984a8135e16da71463712e5e5)
- [nvim-cmp](https://github.com/hrsh7th/nvim-cmp/tree/3192a0c57837c1ec5bf298e4f3ec984c7d2d60c0) - [nvim-cmp](https://github.com/hrsh7th/nvim-cmp/tree/3192a0c57837c1ec5bf298e4f3ec984c7d2d60c0)
- [cmp-neosnippet](https://github.com/notomo/cmp-neosnippet/tree/2d14526af3f02dcea738b4cea520e6ce55c09979) - [cmp-neosnippet](https://github.com/notomo/cmp-neosnippet/tree/2d14526af3f02dcea738b4cea520e6ce55c09979)

View File

@ -3,9 +3,3 @@ name: Pull Request
about: Submit a pull request about: Submit a pull request
title: '' title: ''
--- ---
<!--
If you want to make changes to the README.md, do so in scripts/README_template.md.
The CONFIG.md is auto-generated with all the options from the various LSP configuration;
do not edit it manually
-->

View File

@ -1 +0,0 @@
Notice: CONFIG.md was moved to [doc/server_configurations.md](https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md). This notice will be removed after the release of neovim 0.6.

View File

@ -44,35 +44,62 @@ Additionally, the following options are often added:
* `init_options`: a table sent during initialization, corresponding to initializationOptions sent in [initializeParams](https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#initializeParams) as part of the first request sent from client to server during startup. * `init_options`: a table sent during initialization, corresponding to initializationOptions sent in [initializeParams](https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#initializeParams) as part of the first request sent from client to server during startup.
* `settings`: a table sent during [`workspace/didChangeConfiguration`](https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#didChangeConfigurationParams) shortly after server initialization. This is an undocumented convention for most language servers. There is often some duplication with initOptions. * `settings`: a table sent during [`workspace/didChangeConfiguration`](https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#didChangeConfigurationParams) shortly after server initialization. This is an undocumented convention for most language servers. There is often some duplication with initOptions.
A minimal example for adding a new language server is shown below for `pyright`, a python language server included in lspconfig: An example for adding a new language server is shown below for `pyright`, a python language server included in lspconfig:
```lua ```lua
-- Only `configs` must be required, util is optional if you are using the root resolver functions, which is usually the case.
local configs = require 'lspconfig.configs'
local util = require 'lspconfig.util' local util = require 'lspconfig.util'
-- Having server name defined here is the convention, this is often times also the first entry in the `cmd` table. local bin_name = 'pyright-langserver'
local server_name = 'pyright' local cmd = { bin_name, '--stdio' }
configs[server_name] = { if vim.fn.has 'win32' == 1 then
cmd = { 'cmd.exe', '/C', bin_name, '--stdio' }
end
local root_files = {
'pyproject.toml',
'setup.py',
'setup.cfg',
'requirements.txt',
'Pipfile',
'pyrightconfig.json',
}
local function organize_imports()
local params = {
command = 'pyright.organizeimports',
arguments = { vim.uri_from_bufnr(0) },
}
vim.lsp.buf.execute_command(params)
end
return {
default_config = { default_config = {
-- This should be executable on the command line, arguments (such as `--stdio`) are additional entries in the list. cmd = cmd,
cmd = { 'pyright-langserver' },
-- These are the filetypes that the server will either attach or start in response to opening. The user must have a filetype plugin matching the filetype, either via the built-in runtime files or installed via plugin.
filetypes = { 'python' }, filetypes = { 'python' },
-- The root directory that lspconfig uses to determine if it should start a new language server, or attach the current buffer to a previously running language server. root_dir = util.root_pattern(unpack(root_files)),
root_dir = util.find_git_ancestor single_file_support = true,
end, settings = {
python = {
analysis = {
autoSearchPaths = true,
useLibraryCodeForTypes = true,
diagnosticMode = 'workspace',
},
},
},
},
commands = {
PyrightOrganizeImports = {
organize_imports,
description = 'Organize Imports',
},
}, },
docs = { docs = {
-- The description should include at minimum the link to the github project, and ideally the steps to install the language server.
description = [[ description = [[
https://github.com/microsoft/pyright https://github.com/microsoft/pyright
`pyright`, a static type checker and language server for python `pyright`, a static type checker and language server for python
`pyright` can be installed via `npm`
`npm install -g pyright`
]], ]],
}, },
} }
@ -98,7 +125,7 @@ PRs are checked with [luacheck](https://github.com/mpeterv/luacheck), [StyLua](h
## Generating docs ## Generating docs
Github Actions automatically generates `server_configurations.md`. Only modify `scripts/README_template.md` or the `docs` table in the server config (the lua file). Do not modify `server_configurations.md` directly. Github Actions automatically generates `server_configurations.md`. Only modify `scripts/README_template.md` or the `docs` table in the server config Lua file. Do not modify `server_configurations.md` directly.
To preview the generated `server_configurations.md` locally, run `scripts/docgen.lua` from To preview the generated `server_configurations.md` locally, run `scripts/docgen.lua` from
`nvim` (from the project root): `nvim` (from the project root):

View File

@ -1,8 +1,8 @@
Copyright Neovim contributors. All rights reserved. Copyright Neovim contributors. All rights reserved.
nvim-lsp is licensed under the terms of the Apache 2.0 license. nvim-lspconfig is licensed under the terms of the Apache 2.0 license.
nvim-lsp's license follows: nvim-lspconfig's license follows:
==== ====
Apache License Apache License

View File

@ -1,80 +1,58 @@
# lspconfig # nvim-lspconfig
A [collection of common configurations](doc/server_configurations.md) for Neovim's built-in [language server client](https://neovim.io/doc/user/lsp.html). [Configs](doc/server_configurations.md) for the [Nvim LSP client](https://neovim.io/doc/user/lsp.html) (`:help lsp`).
This plugin allows for declaratively configuring, launching, and initializing language servers you have installed on your system. * **Do not file Nvim LSP client issues here.** The Nvim LSP client does not live here. This is only a collection of LSP configs.
**Disclaimer: Language server configurations are provided on a best-effort basis and are community-maintained. See [contributions](#contributions).** * If you found a bug in the Nvim LSP client, [report it at the Nvim core repo](https://github.com/neovim/neovim/issues/new?assignees=&labels=bug%2Clsp&template=lsp_bug_report.yml).
* These configs are **best-effort and unsupported.** See [contributions](#contributions).
`lspconfig` has extensive help documentation, see `:help lspconfig`. See also `:help lspconfig`.
# LSP overview
Neovim supports the Language Server Protocol (LSP), which means it acts as a client to language servers and includes a Lua framework `vim.lsp` for building enhanced LSP tools. LSP facilitates features like:
- go-to-definition
- find-references
- hover
- completion
- rename
- format
- refactor
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.
## Install ## Install
* 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. * Requires [Neovim 0.7](https://github.com/neovim/neovim/releases/tag/v0.6.1) or [Nightly](https://github.com/neovim/neovim/releases/tag/nightly). Update Nvim and nvim-lspconfig before reporting an issue.
* Install nvim-lspconfig like any other Vim plugin, e.g. with [packer.nvim](https://github.com/wbthomason/packer.nvim):
* Install 'lspconfig' like any other Vim plugin, e.g. with [packer.nvim](https://github.com/wbthomason/packer.nvim):
```lua ```lua
local use = require('packer').use local use = require('packer').use
require('packer').startup(function() require('packer').startup(function()
use 'wbthomason/packer.nvim' -- Package manager use 'wbthomason/packer.nvim' -- Package manager
use 'neovim/nvim-lspconfig' -- Collection of configurations for the built-in LSP client use 'neovim/nvim-lspconfig' -- Configurations for Nvim LSP
end) end)
``` ```
## Quickstart ## Quickstart
1. Install a language server, e.g. [pyright](doc/server_configurations.md#pyright) 1. Install a language server, e.g. [pyright](doc/server_configurations.md#pyright)
```bash ```bash
npm i -g pyright npm i -g pyright
``` ```
2. Add the language server setup to your init.lua. 2. Add the language server setup to your init.lua.
```lua ```lua
require'lspconfig'.pyright.setup{} require'lspconfig'.pyright.setup{}
``` ```
3. Launch Nvim, the language server will attach and provide diagnostics.
3. Launch neovim, the language server will now be attached and providing diagnostics (see `:LspInfo`)
``` ```
nvim main.py nvim main.py
``` ```
4. Run `:LspInfo` to see the status or to troubleshoot.
5. See [Keybindings and completion](#Keybindings-and-completion) to setup common mappings and omnifunc completion.
4. See [Keybindings and completion](#Keybindings-and-completion) for mapping useful functions and enabling omnifunc completion See [server_configurations.md](doc/server_configurations.md) (`:help lspconfig-all` from Nvim) for the full list of configs, including installation instructions and additional, optional, customization suggestions for each language server. For servers that are not on your system path (e.g., `jdtls`, `elixirls`), you must manually add `cmd` to the `setup` parameter. Most language servers can be installed in less than a minute.
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.
## Suggested configuration ## 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\>). nvim-lspconfig does not set 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\>).
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**. 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
-- Mappings. -- Mappings.
-- See `:help vim.diagnostic.*` for documentation on any of the below functions -- See `:help vim.diagnostic.*` for documentation on any of the below functions
local opts = { noremap=true, silent=true } local opts = { noremap=true, silent=true }
vim.api.nvim_set_keymap('n', '<space>e', '<cmd>lua vim.diagnostic.open_float()<CR>', opts) vim.keymap.set('n', '<space>e', vim.diagnostic.open_float, opts)
vim.api.nvim_set_keymap('n', '[d', '<cmd>lua vim.diagnostic.goto_prev()<CR>', opts) vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, opts)
vim.api.nvim_set_keymap('n', ']d', '<cmd>lua vim.diagnostic.goto_next()<CR>', opts) vim.keymap.set('n', ']d', vim.diagnostic.goto_next, opts)
vim.api.nvim_set_keymap('n', '<space>q', '<cmd>lua vim.diagnostic.setloclist()<CR>', opts) vim.keymap.set('n', '<space>q', vim.diagnostic.setloclist, opts)
-- Use an on_attach function to only map the following keys -- Use an on_attach function to only map the following keys
-- after the language server attaches to the current buffer -- after the language server attaches to the current buffer
@ -84,51 +62,58 @@ local on_attach = function(client, bufnr)
-- Mappings. -- Mappings.
-- See `:help vim.lsp.*` for documentation on any of the below functions -- See `:help vim.lsp.*` for documentation on any of the below functions
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gD', '<cmd>lua vim.lsp.buf.declaration()<CR>', opts) local bufopts = { noremap=true, silent=true, buffer=bufnr }
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gd', '<cmd>lua vim.lsp.buf.definition()<CR>', opts) vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, bufopts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'K', '<cmd>lua vim.lsp.buf.hover()<CR>', opts) vim.keymap.set('n', 'gd', vim.lsp.buf.definition, bufopts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gi', '<cmd>lua vim.lsp.buf.implementation()<CR>', opts) vim.keymap.set('n', 'K', vim.lsp.buf.hover, bufopts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<C-k>', '<cmd>lua vim.lsp.buf.signature_help()<CR>', opts) vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, bufopts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<space>wa', '<cmd>lua vim.lsp.buf.add_workspace_folder()<CR>', opts) vim.keymap.set('n', '<C-k>', vim.lsp.buf.signature_help, bufopts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<space>wr', '<cmd>lua vim.lsp.buf.remove_workspace_folder()<CR>', opts) vim.keymap.set('n', '<space>wa', vim.lsp.buf.add_workspace_folder, bufopts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<space>wl', '<cmd>lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))<CR>', opts) vim.keymap.set('n', '<space>wr', vim.lsp.buf.remove_workspace_folder, bufopts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<space>D', '<cmd>lua vim.lsp.buf.type_definition()<CR>', opts) vim.keymap.set('n', '<space>wl', function()
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<space>rn', '<cmd>lua vim.lsp.buf.rename()<CR>', opts) print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<space>ca', '<cmd>lua vim.lsp.buf.code_action()<CR>', opts) end, bufopts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gr', '<cmd>lua vim.lsp.buf.references()<CR>', opts) vim.keymap.set('n', '<space>D', vim.lsp.buf.type_definition, bufopts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<space>f', '<cmd>lua vim.lsp.buf.formatting()<CR>', opts) vim.keymap.set('n', '<space>rn', vim.lsp.buf.rename, bufopts)
vim.keymap.set('n', '<space>ca', vim.lsp.buf.code_action, bufopts)
vim.keymap.set('n', 'gr', vim.lsp.buf.references, bufopts)
vim.keymap.set('n', '<space>f', vim.lsp.buf.formatting, bufopts)
end end
-- Use a loop to conveniently call 'setup' on multiple servers and local lsp_flags = {
-- map buffer local keybindings when the language server attaches -- This is the default in Nvim 0.7+
local servers = { 'pyright', 'rust_analyzer', 'tsserver' }
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, debounce_text_changes = 150,
} }
require('lspconfig')['pyright'].setup{
on_attach = on_attach,
flags = lsp_flags,
}
require('lspconfig')['tsserver'].setup{
on_attach = on_attach,
flags = lsp_flags,
}
require('lspconfig')['rust_analyzer'].setup{
on_attach = on_attach,
flags = lsp_flags,
-- Server-specific settings...
settings = {
["rust-analyzer"] = {}
}
} }
end
``` ```
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. Manual, triggered completion is provided by Nvim's builtin omnifunc. For *auto*completion, a general purpose [autocompletion plugin](https://github.com/neovim/nvim-lspconfig/wiki/Autocompletion) is required.
## Debugging ## Troubleshooting
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). If you have an issue, 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: 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 instead of an absolute path to the executable, ensure it is on your path. 1. The language server is not installed. nvim-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. 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.
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. 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.
4. You must pass `on_attach` and `capabilities` for **each** `setup {}` if you want these to take effect. 4. You must pass `on_attach` and `capabilities` for **each** `setup {}` if you want these to take effect.
5. **Do not call `setup {}` twice for the same server**. The second call to `setup {}` will overwrite the first. 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: Before reporting a bug, check your logs and the output of `:LspInfo`. Add the following to your init.vim to enable logging:
@ -140,24 +125,22 @@ vim.lsp.set_log_level("debug")
Attempt to run the language server, and open the log with: Attempt to run the language server, and open the log with:
``` ```
:lua vim.cmd('e'..vim.lsp.get_log_path()) :LspLog
``` ```
Most of the time, the reason for failure is present in the logs. Most of the time, the reason for failure is present in the logs.
## Built-in commands ## Commands
* `:LspInfo` shows the status of active and configured language servers. * `:LspInfo` shows the status of active and configured language servers.
The following support tab-completion for all arguments:
* `:LspStart <config_name>` Start the requested server name. Will only successfully start if the command detects a root directory matching the current config. Pass `autostart = false` to your `.setup{}` call for a language server if you would like to launch clients solely with this command. Defaults to all servers matching current buffer filetype. * `:LspStart <config_name>` Start the requested server name. Will only successfully start if the command detects a root directory matching the current config. Pass `autostart = false` to your `.setup{}` call for a language server if you would like to launch clients solely with this command. Defaults to all servers matching current buffer filetype.
* `:LspStop <client_id>` Defaults to stopping all buffer clients. * `:LspStop <client_id>` Defaults to stopping all buffer clients.
* `:LspRestart <client_id>` Defaults to restarting all buffer clients. * `:LspRestart <client_id>` Defaults to restarting all buffer clients.
## The wiki ## Wiki
Please see the [wiki](https://github.com/neovim/nvim-lspconfig/wiki) for additional topics, including: See the [wiki](https://github.com/neovim/nvim-lspconfig/wiki) for additional topics, including:
* [Automatic server installation](https://github.com/neovim/nvim-lspconfig/wiki/Installing-language-servers#automatically)
* [Snippets support](https://github.com/neovim/nvim-lspconfig/wiki/Snippets) * [Snippets support](https://github.com/neovim/nvim-lspconfig/wiki/Snippets)
* [Project local settings](https://github.com/neovim/nvim-lspconfig/wiki/Project-local-settings) * [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) * [Recommended plugins for enhanced language server features](https://github.com/neovim/nvim-lspconfig/wiki/Language-specific-plugins)
@ -165,16 +148,11 @@ Please see the [wiki](https://github.com/neovim/nvim-lspconfig/wiki) for additio
## Contributions ## Contributions
If you are missing a language server on the list in [server_configurations.md](doc/server_configurations.md), contributing If you are missing a language server on the list in [server_configurations.md](doc/server_configurations.md), contributing
a new configuration for it would be appreciated. You can follow these steps: a new configuration for it helps others, especially if the server requires special setup. Follow these steps:
1. Read [CONTRIBUTING.md](CONTRIBUTING.md). 1. Read [CONTRIBUTING.md](CONTRIBUTING.md).
2. Create a new file at `lua/lspconfig/server_configurations/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/) - 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 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). [texlab.lua](https://github.com/neovim/nvim-lspconfig/blob/master/lua/lspconfig/server_configurations/texlab.lua).
3. Ask questions on our [Discourse](https://neovim.discourse.group/c/7-category/7) or in the [Neovim Matrix room](https://app.element.io/#/room/#neovim:matrix.org).
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.

View File

@ -1,29 +1,14 @@
*lspconfig.txt* For Nvim version 0.6.1+ Last change: 2021 Nov 7 *lspconfig.txt* For Nvim version 0.7+
==============================================================================
TABLE OF CONTENTS *lspconfig-toc*
1. Introduction (|lspconfig|) nvim-lspconfig provides user-contributed configs for the Nvim |lsp| client.
2. LSP overview (|lspconfig-lsp|)
3. Quickstart (|lspconfig-quickstart|) Type |gO| to see the table of contents.
4. Setup {} (|lspconfig-setup|)
5. Global defaults (|lspconfig-global-defaults|)
6. Server configurations (|lspconfig-configurations|)
6a. Adding servers (|lspconfig-adding-servers|)
7. Root directories (|lspconfig-root-detection|)
7a. Advanced detection (|lspconfig-root-advanced|)
7b. Single file support (|lspconfig-single-file-support|)
8. Commands (|lspconfig-commands|)
9. Keybindings (|lspconfig-keybindings|)
10. Completion (|lspconfig-completion|)
11. Debugging (|lspconfig-debugging|)
12. Logging (|lspconfig-logging|)
13. Scope (|lspconfig-scope|)
============================================================================== ==============================================================================
INTRODUCTION *lspconfig* INTRODUCTION *lspconfig*
`lspconfig` is a collection of community contributed configurations for the nvim-lspconfig is a collection of community-contributed configurations for the
built-in language server client in Neovim core. This plugin provides four built-in language server client in Nvim core. This plugin provides four
primary functionalities: primary functionalities:
- default launch commands, initialization options, and settings for each - default launch commands, initialization options, and settings for each
@ -35,33 +20,10 @@ primary functionalities:
- utility commands such as LspInfo, LspStart, LspStop, and LspRestart for - utility commands such as LspInfo, LspStart, LspStop, and LspRestart for
managing language server instances managing language server instances
`lspconfig` is not required to use the built-in client, it is only one front-end nvim-lspconfig is not required to use the builtin Nvim |lsp| client, it is
interface for when a language server specific plugin is not available. just a convenience layer.
See |lspconfig-server-configurations| by typing `K` over it for the complete See |lspconfig-all| for the complete list of language server configurations.
list of language servers configurations.
==============================================================================
LSP OVERVIEW *lspconfig-lsp*
Nvim supports the Language Server Protocol (LSP) via the built-in language
server client. LSP facilitates many features, some of which include:
- go-to-definition
- find-references
- hover
- completion
- rename
- format
- refactor
These features are implemented in Neovim core, not `lspconfig`. See `:help lsp`
for more details.
NOTE: Feature availability depends on the implementation details of the
server. A server may implement only a subset of these features. Always
consult the server documentation before filing a bug report on a missing
feature.
============================================================================== ==============================================================================
QUICKSTART *lspconfig-quickstart* QUICKSTART *lspconfig-quickstart*
@ -73,12 +35,12 @@ QUICKSTART *lspconfig-quickstart*
require'lspconfig'.clangd.setup{} require'lspconfig'.clangd.setup{}
< <
- create a new project, ensure that it contains a root marker which matches the - create a new project, ensure that it contains a root marker which matches the
server requirements specified in |lspconfig-server-configurations|. server requirements specified in |lspconfig-all|.
- open a file within that project, such as `main.c`. - open a file within that project, such as `main.c`.
- If you need more information about a server configuration, read the corresponding - If you need more information about a server configuration, read the corresponding
entry in |lspconfig-server-configurations|. entry in |lspconfig-all|.
============================================================================== ==============================================================================
THE SETUP METAMETHOD *lspconfig-setup* THE SETUP METAMETHOD *lspconfig-setup*
@ -92,9 +54,8 @@ Using the default configuration for a server is simple:
> >
require'lspconfig'.clangd.setup{} require'lspconfig'.clangd.setup{}
< <
The available server names are listed in |lspconfig-server-configurations| and The available server names are listed in |lspconfig-all| and match the server
match the server name in `config.SERVER_NAME` defined in each configuration's name in `config.SERVER_NAME` defined in each configuration's source file.
source file.
The purpose of `setup{}` is to wrap the call to Nvim's built-in The purpose of `setup{}` is to wrap the call to Nvim's built-in
`vim.lsp.start_client()` with an autocommand that automatically launch a `vim.lsp.start_client()` with an autocommand that automatically launch a
@ -269,8 +230,7 @@ The global defaults for all servers can be overridden by extending the
============================================================================== ==============================================================================
SERVER CONFIGURATIONS *lspconfig-configurations* SERVER CONFIGURATIONS *lspconfig-configurations*
See |lspconfig-server-configurations| by typing `K` over it for the complete See |lspconfig-all| for the complete list of language server configurations.
list of language servers configurations.
While the `setup {}` function is the primary interface to `lspconfig`, for While the `setup {}` function is the primary interface to `lspconfig`, for
servers for which there is not a configuration, it is necessary to define a servers for which there is not a configuration, it is necessary to define a
@ -320,22 +280,18 @@ After you set `configs.SERVER_NAME` you can add arbitrary language-specific
functions to it if necessary. functions to it if necessary.
Example: Example:
> >
configs.texlab.buf_build = buf_build configs.texlab.buf_build = buf_build
< <
============================================================================== ==============================================================================
ADDING NEW SERVERS *lspconfig-adding-servers* ADDING NEW SERVERS *lspconfig-new*
The three steps for adding and enabling a new server configuration are: The steps for adding and enabling a new server configuration are:
- load the `lspconfig` module (note that this is a stylistic choice) 1. load the `lspconfig` module (note that this is a stylistic choice) >
>
local lspconfig = require 'lspconfig' local lspconfig = require 'lspconfig'
< <
- define the configuration 2. define the configuration >
>
local configs = require 'lspconfig.configs' local configs = require 'lspconfig.configs'
-- Check if the config is already defined (useful when reloading this file) -- Check if the config is already defined (useful when reloading this file)
@ -352,8 +308,7 @@ The three steps for adding and enabling a new server configuration are:
} }
end end
- call `setup()` to enable the FileType autocmd 3. call `setup()` to enable the FileType autocmd >
>
lspconfig.foo_lsp.setup{} lspconfig.foo_lsp.setup{}
< <
============================================================================== ==============================================================================
@ -489,10 +444,10 @@ attached to a given buffer.
-- Mappings. -- Mappings.
-- See `:help vim.diagnostic.*` for documentation on any of the below functions -- See `:help vim.diagnostic.*` for documentation on any of the below functions
local opts = { noremap=true, silent=true } local opts = { noremap=true, silent=true }
vim.api.nvim_set_keymap('n', '<space>e', '<cmd>lua vim.diagnostic.open_float()<CR>', opts) vim.keymap.set('n', '<space>e', vim.diagnostic.open_float, opts)
vim.api.nvim_set_keymap('n', '[d', '<cmd>lua vim.diagnostic.goto_prev()<CR>', opts) vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, opts)
vim.api.nvim_set_keymap('n', ']d', '<cmd>lua vim.diagnostic.goto_next()<CR>', opts) vim.keymap.set('n', ']d', vim.diagnostic.goto_next, opts)
vim.api.nvim_set_keymap('n', '<space>q', '<cmd>lua vim.diagnostic.setloclist()<CR>', opts) vim.keymap.set('n', '<space>q', vim.diagnostic.setloclist, opts)
-- Use an on_attach function to only map the following keys -- Use an on_attach function to only map the following keys
-- after the language server attaches to the current buffer -- after the language server attaches to the current buffer
@ -502,46 +457,54 @@ attached to a given buffer.
-- Mappings. -- Mappings.
-- See `:help vim.lsp.*` for documentation on any of the below functions -- See `:help vim.lsp.*` for documentation on any of the below functions
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gD', '<cmd>lua vim.lsp.buf.declaration()<CR>', opts) local bufopts = { noremap=true, silent=true, buffer=bufnr }
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gd', '<cmd>lua vim.lsp.buf.definition()<CR>', opts) vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, bufopts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'K', '<cmd>lua vim.lsp.buf.hover()<CR>', opts) vim.keymap.set('n', 'gd', vim.lsp.buf.definition, bufopts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gi', '<cmd>lua vim.lsp.buf.implementation()<CR>', opts) vim.keymap.set('n', 'K', vim.lsp.buf.hover, bufopts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<C-k>', '<cmd>lua vim.lsp.buf.signature_help()<CR>', opts) vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, bufopts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<space>wa', '<cmd>lua vim.lsp.buf.add_workspace_folder()<CR>', opts) vim.keymap.set('n', '<C-k>', vim.lsp.buf.signature_help, bufopts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<space>wr', '<cmd>lua vim.lsp.buf.remove_workspace_folder()<CR>', opts) vim.keymap.set('n', '<space>wa', vim.lsp.buf.add_workspace_folder, bufopts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<space>wl', '<cmd>lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))<CR>', opts) vim.keymap.set('n', '<space>wr', vim.lsp.buf.remove_workspace_folder, bufopts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<space>D', '<cmd>lua vim.lsp.buf.type_definition()<CR>', opts) vim.keymap.set('n', '<space>wl', function()
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<space>rn', '<cmd>lua vim.lsp.buf.rename()<CR>', opts) print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<space>ca', '<cmd>lua vim.lsp.buf.code_action()<CR>', opts) end, bufopts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', 'gr', '<cmd>lua vim.lsp.buf.references()<CR>', opts) vim.keymap.set('n', '<space>D', vim.lsp.buf.type_definition, bufopts)
vim.api.nvim_buf_set_keymap(bufnr, 'n', '<space>f', '<cmd>lua vim.lsp.buf.formatting()<CR>', opts) vim.keymap.set('n', '<space>rn', vim.lsp.buf.rename, bufopts)
vim.keymap.set('n', '<space>ca', vim.lsp.buf.code_action, bufopts)
vim.keymap.set('n', 'gr', vim.lsp.buf.references, bufopts)
vim.keymap.set('n', '<space>f', vim.lsp.buf.formatting, bufopts)
end end
-- Use a loop to conveniently call 'setup' on multiple servers and local lsp_flags = {
-- map buffer local keybindings when the language server attaches -- This is the default in Nvim 0.7+
local servers = { 'pyright', 'rust_analyzer', 'tsserver' }
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, debounce_text_changes = 150,
} }
require('lspconfig')['pyright'].setup{
on_attach = on_attach,
flags = lsp_flags,
}
require('lspconfig')['tsserver'].setup{
on_attach = on_attach,
flags = lsp_flags,
}
require('lspconfig')['rust_analyzer'].setup{
on_attach = on_attach,
flags = lsp_flags,
-- Server-specific settings...
settings = {
["rust-analyzer"] = {}
}
} }
end
<
Note: these keymappings are meant for illustration and override some
infrequently used default mappings.
============================================================================== ==============================================================================
COMPLETION SUPPORT *lspconfig-completion* COMPLETION SUPPORT *lspconfig-completion*
Manually triggered completion can be provided by Nvim's built-in omnifunc. Manually triggered completion can be provided by Nvim's built-in omnifunc.
See `:help omnifunc` for more details. See |lsp-config|.
For autocompletion, Nvim does not offer built-in functionality at this time. For autocompletion, Nvim does not provide built-in functionality. Consult the
Consult the `lspconfig` wiki, which provides configuration examples for using a nvim-lspconfig wiki, which provides configuration examples for using
completion plugin with the built-in client a completion plugin with the built-in client
============================================================================== ==============================================================================
DEBUGGING *lspconfig-debugging* DEBUGGING *lspconfig-debugging*
@ -554,17 +517,17 @@ is typically (in rough order):
- a plugin - a plugin
- overrides in a user configuration - overrides in a user configuration
- the built-in client in Nvim core - the built-in client in Nvim core
- `lspconfig` - nvim-lspconfig
The first step in debugging is to test with a minimal configuration (such as The first step in debugging is to test with a minimal configuration (such as
`../test/minimal_init.lua`). Historically, many users problems are due to `../test/minimal_init.lua`). Historically, many users problems are due to
plugins or misconfiguration. plugins or misconfiguration.
Should that fail, identifying which component is the culprit is challenging. Should that fail, identifying which component is the culprit is challenging.
The following are the only categories of bugs that pertain to `lspconfig`. The following are the only categories of bugs that pertain to nvim-lspconfig.
- The root directory inferred for your project is wrong, or it should be - The root directory inferred for your project is wrong, or it should be
detected but is not due to a bug in the `lspconfig` path utilities. detected but is not due to a bug in the nvim-lspconfig path utilities.
- The server is launching, but you believe that the default settings, - The server is launching, but you believe that the default settings,
initialization options, or command arguments are suboptimal and should be initialization options, or command arguments are suboptimal and should be
replaced based on your understanding of the server documentation. replaced based on your understanding of the server documentation.
@ -574,14 +537,14 @@ tracker. All bugs pertaining to plugins should be reported to the respective
plugin. All missing features in a language server should be reported to the plugin. All missing features in a language server should be reported to the
upstream language server issue tracker. upstream language server issue tracker.
For debugging `lspconfig` issues, the most common hurdles users face are: For debugging nvim-lspconfig issues, the most common hurdles users face are:
- The language server is not installed or is otherwise not executable. - The language server is not installed or is otherwise not executable.
`lspconfig` does not install language servers for you. Ensure the `cmd` nvim-lspconfig does not install language servers for you. Ensure the `cmd`
defined in `server_configurations.md` is executable from the command defined in `server_configurations.md` is executable from the command
line. If the absolute path to the binary is not supplied in `cmd`, ensure line. If the absolute path to the binary is not supplied in `cmd`, ensure
it is on your PATH. it is on your PATH.
- No root detected. `lspconfig` is built around the concept of projects. See - No root detected. nvim-lspconfig is built around the concept of projects. See
|lspconfig-root-detection| for more details. Most of the time, |lspconfig-root-detection| for more details. Most of the time,
initializing a git repo will suffice. initializing a git repo will suffice.
- Misconfiguration. Often users will override `cmd`, `on_init`, or - Misconfiguration. Often users will override `cmd`, `on_init`, or
@ -608,7 +571,7 @@ the built-in client, specifically considering the RPC logs. Example:
Attempt to run the language server, and open the log with: Attempt to run the language server, and open the log with:
> >
:lua vim.cmd('e'..vim.lsp.get_log_path()) :LspLog
< <
Note that `ERROR` messages containing `stderr` only indicate that the log was Note that `ERROR` messages containing `stderr` only indicate that the log was
sent to `stderr`. Many servers counter-intuitively send harmless messages sent to `stderr`. Many servers counter-intuitively send harmless messages

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,13 @@ function M._root._setup()
'-nargs=0', '-nargs=0',
description = '`:LspInfo` Displays attached, active, and configured language servers', description = '`:LspInfo` Displays attached, active, and configured language servers',
}, },
LspLog = {
function()
vim.cmd(string.format('tabnew %s', vim.lsp.get_log_path()))
end,
'-nargs=0',
description = '`:LspLog` Opens the Nvim LSP client log.',
},
LspStart = { LspStart = {
function(server_name) function(server_name)
if server_name then if server_name then

View File

@ -1,6 +1,6 @@
local util = require 'lspconfig.util' local util = require 'lspconfig.util'
local api, validate, lsp = vim.api, vim.validate, vim.lsp local api, validate, lsp = vim.api, vim.validate, vim.lsp
local tbl_extend = vim.tbl_extend local tbl_deep_extend = vim.tbl_deep_extend
local configs = {} local configs = {}
@ -25,7 +25,7 @@ function configs.__newindex(t, config_name, config_def)
local M = {} local M = {}
local default_config = tbl_extend('keep', config_def.default_config, util.default_config) local default_config = tbl_deep_extend('keep', config_def.default_config, util.default_config)
-- Force this part. -- Force this part.
default_config.name = config_name default_config.name = config_name
@ -48,7 +48,7 @@ function configs.__newindex(t, config_name, config_def)
end end
end end
config = tbl_extend('keep', config, default_config) config = tbl_deep_extend('keep', config, default_config)
if util.on_setup then if util.on_setup then
pcall(util.on_setup, config) pcall(util.on_setup, config)
@ -88,6 +88,7 @@ function configs.__newindex(t, config_name, config_def)
end end
if root_dir then if root_dir then
-- Lazy-launching: attach when a buffer in this directory is opened.
api.nvim_command( api.nvim_command(
string.format( string.format(
"autocmd BufReadPost %s/* unsilent lua require'lspconfig'[%q].manager.try_add_wrapper()", "autocmd BufReadPost %s/* unsilent lua require'lspconfig'[%q].manager.try_add_wrapper()",
@ -95,6 +96,7 @@ function configs.__newindex(t, config_name, config_def)
config.name config.name
) )
) )
-- Attach for all existing buffers in this directory.
for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
local bufname = api.nvim_buf_get_name(bufnr) local bufname = api.nvim_buf_get_name(bufnr)
if util.bufname_valid(bufname) then if util.bufname_valid(bufname) then
@ -136,21 +138,19 @@ function configs.__newindex(t, config_name, config_def)
M.manager = nil M.manager = nil
end end
local make_config = function(_root_dir) local make_config = function(root_dir)
local new_config = vim.tbl_deep_extend('keep', vim.empty_dict(), config) local new_config = tbl_deep_extend('keep', vim.empty_dict(), config)
new_config = vim.tbl_deep_extend('keep', new_config, default_config) new_config.capabilities = tbl_deep_extend('keep', new_config.capabilities, {
new_config.capabilities = new_config.capabilities or lsp.protocol.make_client_capabilities()
new_config.capabilities = vim.tbl_deep_extend('keep', new_config.capabilities, {
workspace = { workspace = {
configuration = true, configuration = true,
}, },
}) })
if config_def.on_new_config then if config_def.on_new_config then
pcall(config_def.on_new_config, new_config, _root_dir) pcall(config_def.on_new_config, new_config, root_dir)
end end
if config.on_new_config then if config.on_new_config then
pcall(config.on_new_config, new_config, _root_dir) pcall(config.on_new_config, new_config, root_dir)
end end
new_config.on_init = util.add_hook_after(new_config.on_init, function(client, result) new_config.on_init = util.add_hook_after(new_config.on_init, function(client, result)
@ -159,7 +159,7 @@ function configs.__newindex(t, config_name, config_def)
client.offset_encoding = result.offsetEncoding client.offset_encoding = result.offsetEncoding
end end
-- Send `settings to server via workspace/didChangeConfiguration -- Send `settings` to server via workspace/didChangeConfiguration
function client.workspace_did_change_configuration(settings) function client.workspace_did_change_configuration(settings)
if not settings then if not settings then
return return
@ -182,6 +182,7 @@ function configs.__newindex(t, config_name, config_def)
if bufnr == api.nvim_get_current_buf() then if bufnr == api.nvim_get_current_buf() then
M._setup_buffer(client.id, bufnr) M._setup_buffer(client.id, bufnr)
else else
if vim.api.nvim_buf_is_valid(bufnr) then
api.nvim_command( api.nvim_command(
string.format( string.format(
"autocmd BufEnter <buffer=%d> ++once lua require'lspconfig'[%q]._setup_buffer(%d,%d)", "autocmd BufEnter <buffer=%d> ++once lua require'lspconfig'[%q]._setup_buffer(%d,%d)",
@ -192,22 +193,25 @@ function configs.__newindex(t, config_name, config_def)
) )
) )
end end
end
end) end)
new_config.root_dir = _root_dir new_config.root_dir = root_dir
new_config.workspace_folders = { new_config.workspace_folders = {
{ {
uri = vim.uri_from_fname(_root_dir), uri = vim.uri_from_fname(root_dir),
name = string.format('%s', _root_dir), name = string.format('%s', root_dir),
}, },
} }
return new_config return new_config
end end
local manager = util.server_per_root_dir_manager(function(_root_dir) local manager = util.server_per_root_dir_manager(function(root_dir)
return make_config(_root_dir) return make_config(root_dir)
end) end)
-- Try to attach the buffer `bufnr` to a client using this config, creating
-- a new client if one doesn't already exist for `bufnr`.
function manager.try_add(bufnr) function manager.try_add(bufnr)
bufnr = bufnr or api.nvim_get_current_buf() bufnr = bufnr or api.nvim_get_current_buf()
@ -240,6 +244,8 @@ function configs.__newindex(t, config_name, config_def)
end end
end end
-- Check that the buffer `bufnr` has a valid filetype according to
-- `config.filetypes`, then do `manager.try_add(bufnr)`.
function manager.try_add_wrapper(bufnr) function manager.try_add_wrapper(bufnr)
bufnr = bufnr or api.nvim_get_current_buf() bufnr = bufnr or api.nvim_get_current_buf()
local buf_filetype = vim.api.nvim_buf_get_option(bufnr, 'filetype') local buf_filetype = vim.api.nvim_buf_get_option(bufnr, 'filetype')
@ -250,6 +256,7 @@ function configs.__newindex(t, config_name, config_def)
return return
end end
end end
-- `config.filetypes = nil` means all filetypes are valid.
else else
manager.try_add(bufnr) manager.try_add(bufnr)
end end
@ -257,7 +264,7 @@ function configs.__newindex(t, config_name, config_def)
M.manager = manager M.manager = manager
M.make_config = make_config M.make_config = make_config
if reload and not (config.autostart == false) then if reload and config.autostart ~= false then
for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
manager.try_add_wrapper(bufnr) manager.try_add_wrapper(bufnr)
end end

View File

@ -0,0 +1,46 @@
local util = require 'lspconfig.util'
return {
default_config = {
filetypes = { 'apexcode' },
root_dir = util.root_pattern 'sfdx-project.json',
on_new_config = function(config)
if not config.cmd and config.apex_jar_path then
config.cmd = {
'java',
'-cp',
config.apex_jar_path,
'-Ddebug.internal.errors=true',
'-Ddebug.semantic.errors=' .. tostring(config.apex_enable_semantic_errors or false),
'-Ddebug.completion.statistics=' .. tostring(config.apex_enable_completion_statistics or false),
'-Dlwc.typegeneration.disabled=true',
}
if config.apex_jvm_max_heap then
table.insert(config.cmd, '-Xmx' .. config.apex_jvm_max_heap)
end
table.insert(config.cmd, 'apex.jorje.lsp.ApexLanguageServerLauncher')
end
end,
},
docs = {
description = [[
https://github.com/forcedotcom/salesforcedx-vscode
Language server for Apex.
For manual installation, download the JAR file from the [VSCode
extension](https://github.com/forcedotcom/salesforcedx-vscode/tree/develop/packages/salesforcedx-vscode-apex).
```lua
require'lspconfig'.apex_ls.setup {
apex_jar_path = '/path/to/apex-jorje-lsp.jar',
apex_enable_semantic_errors = false, -- Whether to allow Apex Language Server to surface semantic errors
apex_enable_completion_statistics = false, -- Whether to allow Apex Language Server to collect telemetry on code completion usage
}
```
]],
default_config = {
root_dir = [[root_pattern('sfdx-project.json')]],
},
},
}

View File

@ -2,7 +2,6 @@ local util = require 'lspconfig.util'
return { return {
default_config = { default_config = {
cmd = { 'arduino-language-server' },
filetypes = { 'arduino' }, filetypes = { 'arduino' },
root_dir = util.root_pattern '*.ino', root_dir = util.root_pattern '*.ino',
}, },
@ -13,38 +12,52 @@ https://github.com/arduino/arduino-language-server
Language server for Arduino Language server for Arduino
The `arduino-language-server` can be installed by running: The `arduino-language-server` can be installed by running:
go get -u github.com/arduino/arduino-language-server
The `arduino-cli` tools must also be installed. Follow these instructions for your distro: ```
https://arduino.github.io/arduino-cli/latest/installation/ go install github.com/arduino/arduino-language-server@latest
```
After installing the `arduino-cli` tools, follow these instructions for generating The `arduino-cli` tool must also be installed. Follow [these
a configuration file: installation instructions](https://arduino.github.io/arduino-cli/latest/installation/) for
https://arduino.github.io/arduino-cli/latest/getting-started/#create-a-configuration-file your platform.
and make sure you install any relevant platforms libraries:
https://arduino.github.io/arduino-cli/latest/getting-started/#install-the-core-for-your-board
The language server also requires `clangd` be installed. It will look for `clangd` by default but After installing `arduino-cli`, follow [these
the binary path can be overridden if need be. instructions](https://arduino.github.io/arduino-cli/latest/getting-started/#create-a-configuration-file)
for generating a configuration file if you haven't done so already, and make
sure you [install any relevant platforms
libraries](https://arduino.github.io/arduino-cli/latest/getting-started/#install-the-core-for-your-board).
Make sure to save the full path to the created `arduino-cli.yaml` file for later.
After all dependencies are installed you'll need to override the lspconfig command for the The language server also requires `clangd` to be installed. Follow [these
language server in your setup function with the necessary configurations: installation instructions](https://clangd.llvm.org/installation) for your
platform.
Next, you will need to decide which FQBN to use.
To identify the available FQBNs for boards you currently have connected, you may use the `arduino-cli` command, like so:
```sh
$ arduino-cli board list
Port Protocol Type Board Name FQBN Core
/dev/ttyACM0 serial Serial Port (USB) Arduino Uno arduino:avr:uno arduino:avr
^^^^^^^^^^^^^^^
```
After all dependencies are installed you'll need to set the command for the
language server in your setup:
```lua ```lua
lspconfig.arduino_language_server.setup({ require'lspconfig'.arduino_language_server.setup {
cmd = { cmd = {
-- Required
"arduino-language-server", "arduino-language-server",
"-cli-config", "/path/to/arduino-cli.yaml", "-cli-config", "/path/to/arduino-cli.yaml",
-- Optional "-fqbn", "arduino:avr:uno",
"-cli", "/path/to/arduino-cli", "-cli", "arduino-cli",
"-clangd", "/path/to/clangd" "-clangd", "clangd"
}
} }
})
``` ```
For further instruction about configuration options, run `arduino-language-server --help`. For further instruction about configuration options, run `arduino-language-server --help`.
]], ]],
}, },
} }

View File

@ -0,0 +1,32 @@
local util = require 'lspconfig.util'
local bin_name = 'astro-ls'
local cmd = { bin_name, '--stdio' }
if vim.fn.has 'win32' == 1 then
cmd = { 'cmd.exe', '/C', bin_name, '--stdio' }
end
return {
default_config = {
cmd = cmd,
filetypes = { 'astro' },
root_dir = util.root_pattern('package.json', 'tsconfig.json', 'jsconfig.json', '.git'),
init_options = {
configuration = {},
},
},
docs = {
description = [[
https://github.com/withastro/language-tools/tree/main/packages/language-server
`astro-ls` can be installed via `npm`:
```sh
npm install -g @astrojs/language-server
```
]],
default_config = {
root_dir = [[root_pattern("package.json", "tsconfig.json", "jsconfig.json", ".git")]],
},
},
}

View File

@ -2,15 +2,13 @@ local util = require 'lspconfig.util'
return { return {
default_config = { default_config = {
cmd = { 'beancount-langserver', '--stdio' }, cmd = { 'beancount-language-server', '--stdio' },
filetypes = { 'beancount' }, filetypes = { 'beancount', 'bean' },
root_dir = util.find_git_ancestor, root_dir = util.find_git_ancestor,
single_file_support = true, single_file_support = true,
init_options = { init_options = {
-- this is the path to the beancout journal file -- this is the path to the beancout journal file
journalFile = '', journalFile = '',
-- this is the path to the python binary with beancount installed
pythonPath = 'python3',
}, },
}, },
docs = { docs = {
@ -20,7 +18,7 @@ https://github.com/polarmutex/beancount-language-server#installation
See https://github.com/polarmutex/beancount-language-server#configuration for configuration options See https://github.com/polarmutex/beancount-language-server#configuration for configuration options
]], ]],
default_config = { default_config = {
root_dir = [[root_pattern("elm.json")]], root_dir = [[root_pattern(".git")]],
}, },
}, },
} }

View File

@ -1,10 +1,17 @@
local util = require 'lspconfig.util' local util = require 'lspconfig.util'
local root_files = {
'compile_commands.json',
'.ccls',
}
return { return {
default_config = { default_config = {
cmd = { 'ccls' }, cmd = { 'ccls' },
filetypes = { 'c', 'cpp', 'objc', 'objcpp' }, filetypes = { 'c', 'cpp', 'objc', 'objcpp' },
root_dir = util.root_pattern('compile_commands.json', '.ccls', '.git'), root_dir = function(fname)
return util.root_pattern(unpack(root_files))(fname) or util.find_git_ancestor(fname)
end,
offset_encoding = 'utf-32', offset_encoding = 'utf-32',
-- ccls does not support sending a null root directory -- ccls does not support sending a null root directory
single_file_support = false, single_file_support = false,
@ -37,7 +44,9 @@ lspconfig.ccls.setup {
]], ]],
default_config = { default_config = {
root_dir = [[root_pattern("compile_commands.json", ".ccls", ".git")]], root_dir = function(fname)
return util.root_pattern(unpack(root_files))(fname) or util.find_git_ancestor(fname)
end,
}, },
}, },
} }

View File

@ -21,12 +21,16 @@ local function switch_source_header(bufnr)
end end
end end
local root_pattern = util.root_pattern('compile_commands.json', 'compile_flags.txt', '.git') local root_files = {
'.clangd',
'.clang-tidy',
'.clang-format',
'compile_commands.json',
'compile_flags.txt',
'configure.ac', -- AutoTools
}
local default_capabilities = vim.tbl_deep_extend( local default_capabilities = {
'force',
util.default_config.capabilities or vim.lsp.protocol.make_client_capabilities(),
{
textDocument = { textDocument = {
completion = { completion = {
editsNearCursor = true, editsNearCursor = true,
@ -34,15 +38,13 @@ local default_capabilities = vim.tbl_deep_extend(
}, },
offsetEncoding = { 'utf-8', 'utf-16' }, offsetEncoding = { 'utf-8', 'utf-16' },
} }
)
return { return {
default_config = { default_config = {
cmd = { 'clangd' }, cmd = { 'clangd' },
filetypes = { 'c', 'cpp', 'objc', 'objcpp' }, filetypes = { 'c', 'cpp', 'objc', 'objcpp', 'cuda' },
root_dir = function(fname) root_dir = function(fname)
local filename = util.path.is_absolute(fname) and fname or util.path.join(vim.loop.cwd(), fname) return util.root_pattern(unpack(root_files))(fname) or util.find_git_ancestor(fname)
return root_pattern(filename)
end, end,
single_file_support = true, single_file_support = true,
capabilities = default_capabilities, capabilities = default_capabilities,
@ -59,14 +61,27 @@ return {
description = [[ description = [[
https://clangd.llvm.org/installation.html https://clangd.llvm.org/installation.html
**NOTE:** Clang >= 9 is recommended! See [this issue for more](https://github.com/neovim/nvim-lsp/issues/23). - **NOTE:** Clang >= 11 is recommended! See [#23](https://github.com/neovim/nvim-lsp/issues/23).
- If `compile_commands.json` lives in a build directory, you should
clangd relies on a [JSON compilation database](https://clang.llvm.org/docs/JSONCompilationDatabase.html) specified symlink it to the root of your source tree.
as compile_commands.json or, for simpler projects, a compile_flags.txt. ```
For details on how to automatically generate one using CMake look [here](https://cmake.org/cmake/help/latest/variable/CMAKE_EXPORT_COMPILE_COMMANDS.html). Alternatively, you can use [Bear](https://github.com/rizsotto/Bear). ln -s /path/to/myproject/build/compile_commands.json /path/to/myproject/
```
- clangd relies on a [JSON compilation database](https://clang.llvm.org/docs/JSONCompilationDatabase.html)
specified as compile_commands.json, see https://clangd.llvm.org/installation#compile_commandsjson
]], ]],
default_config = { default_config = {
root_dir = [[root_pattern("compile_commands.json", "compile_flags.txt", ".git") or dirname]], root_dir = [[
root_pattern(
'.clangd',
'.clang-tidy',
'.clang-format',
'compile_commands.json',
'compile_flags.txt',
'configure.ac',
'.git'
)
]],
capabilities = [[default capabilities, with offsetEncoding utf-8]], capabilities = [[default capabilities, with offsetEncoding utf-8]],
}, },
}, },

View File

@ -1,13 +1,8 @@
local util = require 'lspconfig.util' local util = require 'lspconfig.util'
local bin_name = 'clarity-lsp'
if vim.fn.has 'win32' == 1 then
bin_name = bin_name .. '.cmd'
end
return { return {
default_config = { default_config = {
cmd = { bin_name }, cmd = { 'clarity-lsp' },
filetypes = { 'clar', 'clarity' }, filetypes = { 'clar', 'clarity' },
root_dir = util.root_pattern '.git', root_dir = util.root_pattern '.git',
}, },

View File

@ -1,10 +1,13 @@
local util = require 'lspconfig.util' local util = require 'lspconfig.util'
local root_files = { 'CMakeLists.txt', 'cmake' }
return { return {
default_config = { default_config = {
cmd = { 'cmake-language-server' }, cmd = { 'cmake-language-server' },
filetypes = { 'cmake' }, filetypes = { 'cmake' },
root_dir = util.root_pattern('.git', 'compile_commands.json', 'build'), root_dir = function(fname)
return util.root_pattern(unpack(root_files))(fname) or util.find_git_ancestor(fname)
end,
single_file_support = true, single_file_support = true,
init_options = { init_options = {
buildDirectory = 'build', buildDirectory = 'build',
@ -17,7 +20,7 @@ https://github.com/regen100/cmake-language-server
CMake LSP Implementation CMake LSP Implementation
]], ]],
default_config = { default_config = {
root_dir = [[root_pattern(".git", "compile_commands.json", "build") or dirname]], root_dir = [[root_pattern(".git", "compile_commands.json", "build")]],
}, },
}, },
} }

View File

@ -14,7 +14,7 @@ https://github.com/elbywan/crystalline
Crystal language server. Crystal language server.
]], ]],
default_config = { default_config = {
root_dir = [[root_pattern('shard.yml', '.git') or dirname]], root_dir = [[root_pattern('shard.yml', '.git')]],
}, },
}, },
} }

View File

@ -1,36 +1,8 @@
local util = require 'lspconfig.util' local util = require 'lspconfig.util'
local bin_name = 'dart'
local find_dart_sdk_root_path = function()
if os.getenv 'FLUTTER_SDK' then
local flutter_path = os.getenv 'FLUTTER_SDK'
return util.path.join(flutter_path, 'cache', 'dart-sdk', 'bin', 'dart')
elseif vim.fn['executable'] 'flutter' == 1 then
local flutter_path = vim.fn['resolve'](vim.fn['exepath'] 'flutter')
local flutter_bin = vim.fn['fnamemodify'](flutter_path, ':h')
return util.path.join(flutter_bin, 'cache', 'dart-sdk', 'bin', 'dart')
elseif vim.fn['executable'] 'dart' == 1 then
return vim.fn['resolve'](vim.fn['exepath'] 'dart')
else
return ''
end
end
local analysis_server_snapshot_path = function()
local dart_sdk_root_path = vim.fn['fnamemodify'](find_dart_sdk_root_path(), ':h')
local snapshot = util.path.join(dart_sdk_root_path, 'snapshots', 'analysis_server.dart.snapshot')
if vim.fn['has'] 'win32' == 1 or vim.fn['has'] 'win64' == 1 then
snapshot = snapshot:gsub('/', '\\')
end
return snapshot
end
return { return {
default_config = { default_config = {
cmd = { bin_name, analysis_server_snapshot_path(), '--lsp' }, cmd = { 'dart', 'language-server', '--protocol=lsp' },
filetypes = { 'dart' }, filetypes = { 'dart' },
root_dir = util.root_pattern 'pubspec.yaml', root_dir = util.root_pattern 'pubspec.yaml',
init_options = { init_options = {

View File

@ -72,10 +72,9 @@ return {
'typescriptreact', 'typescriptreact',
'typescript.tsx', 'typescript.tsx',
}, },
root_dir = util.root_pattern('deno.json', 'deno.jsonc', 'tsconfig.json', '.git'), root_dir = util.root_pattern('deno.json', 'deno.jsonc', '.git'),
init_options = { init_options = {
enable = true, enable = true,
lint = false,
unstable = false, unstable = false,
}, },
handlers = { handlers = {
@ -108,7 +107,7 @@ vim.g.markdown_fenced_languages = {
]], ]],
default_config = { default_config = {
root_dir = [[root_pattern("deno.json", "deno.jsonc", "tsconfig.json", ".git")]], root_dir = [[root_pattern("deno.json", "deno.jsonc", ".git")]],
}, },
}, },
} }

View File

@ -20,7 +20,7 @@ cabal install dhall-lsp-server
prebuilt binaries can be found [here](https://github.com/dhall-lang/dhall-haskell/releases). prebuilt binaries can be found [here](https://github.com/dhall-lang/dhall-haskell/releases).
]], ]],
default_config = { default_config = {
root_dir = [[root_pattern(".git") or dirname]], root_dir = [[root_pattern(".git")]],
}, },
}, },
} }

View File

@ -2,7 +2,7 @@ local util = require 'lspconfig.util'
return { return {
default_config = { default_config = {
filetypes = { 'elixir', 'eelixir' }, filetypes = { 'elixir', 'eelixir', 'heex' },
root_dir = function(fname) root_dir = function(fname)
return util.root_pattern('mix.exs', '.git')(fname) or vim.loop.os_homedir() return util.root_pattern('mix.exs', '.git')(fname) or vim.loop.os_homedir()
end, end,

View File

@ -49,7 +49,7 @@ require'lspconfig'.esbonio.setup {
} }
``` ```
A full list and explanation of the available options can be found [here](https://swyddfa.github.io/esbonio/docs/lsp/editors/index.html) A full list and explanation of the available options can be found [here](https://swyddfa.github.io/esbonio/docs/latest/en/lsp/getting-started.html#configuration)
]], ]],
}, },
} }

View File

@ -63,6 +63,7 @@ return {
}, },
-- https://eslint.org/docs/user-guide/configuring/configuration-files#configuration-file-formats -- https://eslint.org/docs/user-guide/configuring/configuration-files#configuration-file-formats
root_dir = util.root_pattern( root_dir = util.root_pattern(
'.eslintrc',
'.eslintrc.js', '.eslintrc.js',
'.eslintrc.cjs', '.eslintrc.cjs',
'.eslintrc.yaml', '.eslintrc.yaml',
@ -151,22 +152,23 @@ return {
description = [[ description = [[
https://github.com/hrsh7th/vscode-langservers-extracted https://github.com/hrsh7th/vscode-langservers-extracted
vscode-eslint-language-server: A linting engine for JavaScript / Typescript `vscode-eslint-language-server` is a linting engine for JavaScript / Typescript.
It can be installed via `npm`:
`vscode-eslint-language-server` can be installed via `npm`:
```sh ```sh
npm i -g vscode-langservers-extracted npm i -g vscode-langservers-extracted
``` ```
vscode-eslint-language-server provides an EslintFixAll command that can be used to format document on save `vscode-eslint-language-server` provides an `EslintFixAll` command that can be used to format a document on save:
```vim ```vim
autocmd BufWritePre <buffer> <cmd>EslintFixAll<CR> autocmd BufWritePre *.tsx,*.ts,*.jsx,*.js EslintFixAll
``` ```
See [vscode-eslint](https://github.com/microsoft/vscode-eslint/blob/55871979d7af184bf09af491b6ea35ebd56822cf/server/src/eslintServer.ts#L216-L229) for configuration options. See [vscode-eslint](https://github.com/microsoft/vscode-eslint/blob/55871979d7af184bf09af491b6ea35ebd56822cf/server/src/eslintServer.ts#L216-L229) for configuration options.
Additional messages you can handle: eslint/noConfig Messages handled in lspconfig: `eslint/openDoc`, `eslint/confirmESLintExecution`, `eslint/probeFailed`, `eslint/noLibrary`
Messages already handled in lspconfig: eslint/openDoc, eslint/confirmESLintExecution, eslint/probeFailed, eslint/noLibrary
Additional messages you can handle: `eslint/noConfig`
]], ]],
}, },
} }

View File

@ -2,20 +2,32 @@ local util = require 'lspconfig.util'
return { return {
default_config = { default_config = {
cmd = { 'fortls' }, cmd = {
'fortls',
'--notify_init',
'--hover_signature',
'--hover_language=fortran',
'--use_signature_help',
},
filetypes = { 'fortran' }, filetypes = { 'fortran' },
root_dir = function(fname) root_dir = function(fname)
return util.root_pattern '.fortls'(fname) or util.find_git_ancestor(fname) return util.root_pattern '.fortls'(fname) or util.find_git_ancestor(fname)
end, end,
settings = { settings = {},
nthreads = 1,
},
}, },
docs = { docs = {
description = [[ description = [[
https://github.com/hansec/fortran-language-server https://github.com/gnikit/fortls
Fortran Language Server for the Language Server Protocol fortls is a Fortran Language Server, the server can be installed via pip
```sh
pip install fortls
```
Settings to the server can be passed either through the `cmd` option or through
a local configuration file e.g. `.fortls`. For more information
see the `fortls` [documentation](https://gnikit.github.io/fortls/options.html).
]], ]],
default_config = { default_config = {
root_dir = [[root_pattern(".fortls")]], root_dir = [[root_pattern(".fortls")]],

View File

@ -0,0 +1,22 @@
local util = require 'lspconfig.util'
return {
default_config = {
cmd = { 'ghdl-ls' },
filetypes = { 'vhdl' },
root_dir = function(fname)
return util.root_pattern 'hdl-prj.json'(fname) or util.find_git_ancestor(fname)
end,
single_file_support = true,
},
docs = {
description = [[
https://github.com/ghdl/ghdl-language-server
A language server for VHDL, using ghdl as its backend.
`ghdl-ls` is part of pyghdl, for installation instructions see
[the upstream README](https://github.com/ghdl/ghdl/tree/master/pyGHDL/lsp).
]],
},
}

View File

@ -0,0 +1,66 @@
local util = require 'lspconfig.util'
local bin_name = 'glint-language-server'
local cmd = { bin_name }
if vim.fn.has 'win32' == 1 then
cmd = { 'cmd.exe', '/C', bin_name }
end
return {
default_config = {
cmd = cmd,
on_new_config = function(config, new_root_dir)
local project_root = util.find_node_modules_ancestor(new_root_dir)
-- Glint should not be installed globally.
local node_bin_path = util.path.join(project_root, 'node_modules', '.bin')
local path = node_bin_path .. util.path.path_separator .. vim.env.PATH
if config.cmd_env then
config.cmd_env.PATH = path
else
config.cmd_env = { PATH = path }
end
end,
filetypes = {
'html.handlebars',
'handlebars',
'typescript',
'typescript.glimmer',
'javascript',
'javascript.glimmer',
},
root_dir = util.root_pattern(
'.glintrc.yml',
'.glintrc',
'.glintrc.json',
'.glintrc.js',
'glint.config.js',
'package.json'
),
},
docs = {
description = [[
https://github.com/typed-ember/glint
https://typed-ember.gitbook.io/glint/
`glint-language-server` is installed when adding `@glint/core` to your project's devDependencies:
```sh
npm install @glint/core --save-dev
```
or
```sh
yarn add -D @glint/core
```
or
```sh
pnpm add -D @glint/core
```
]],
},
}

View File

@ -1,6 +1,6 @@
local util = require 'lspconfig.util' local util = require 'lspconfig.util'
local bin_name = 'unofficial-grammarly-language-server' local bin_name = 'grammarly-languageserver'
local cmd = { bin_name, '--stdio' } local cmd = { bin_name, '--stdio' }
if vim.fn.has 'win32' == 1 then if vim.fn.has 'win32' == 1 then
@ -21,12 +21,12 @@ return {
}, },
docs = { docs = {
description = [[ description = [[
https://github.com/emacs-grammarly/unofficial-grammarly-language-server https://github.com/znck/grammarly
`unofficial-grammarly-language-server` can be installed via `npm`: `grammarly-languageserver` can be installed via `npm`:
```sh ```sh
npm i -g @emacs-grammarly/unofficial-grammarly-language-server npm i -g grammarly-languageserver
``` ```
WARNING: Since this language server uses Grammarly's API, any document you open with it running is shared with them. Please evaluate their [privacy policy](https://www.grammarly.com/privacy-policy) before using this. WARNING: Since this language server uses Grammarly's API, any document you open with it running is shared with them. Please evaluate their [privacy policy](https://www.grammarly.com/privacy-policy) before using this.

View File

@ -27,7 +27,7 @@ npm install -g graphql-language-service-cli
Note that you must also have [the graphql package](https://github.com/graphql/graphql-js) installed and create a [GraphQL config file](https://www.graphql-config.com/docs/user/user-introduction). Note that you must also have [the graphql package](https://github.com/graphql/graphql-js) installed and create a [GraphQL config file](https://www.graphql-config.com/docs/user/user-introduction).
]], ]],
default_config = { default_config = {
root_dir = [[root_pattern('.git', '.graphqlrc*', '.graphql.config.*')]], root_dir = [[util.root_pattern('.git', '.graphqlrc*', '.graphql.config.*', 'graphql.config.*')]],
}, },
}, },
} }

View File

@ -0,0 +1,29 @@
local util = require 'lspconfig.util'
local bin_name = 'hoon-language-server'
local cmd = { bin_name }
if vim.fn.has 'win32' == 1 then
cmd = { 'cmd.exe', '/C', bin_name }
end
return {
default_config = {
cmd = cmd,
filetypes = { 'hoon' },
root_dir = util.find_git_ancestor,
single_file_support = true,
},
docs = {
description = [[
https://github.com/urbit/hoon-language-server
A language server for Hoon.
The language server can be installed via `npm install -g @hoon-language-server`
Start a fake ~zod with `urbit -F zod`.
Start the language server at the Urbit Dojo prompt with: `|start %language-server`
]],
},
}

View File

@ -1,38 +1,35 @@
local util = require 'lspconfig.util' local util = require 'lspconfig.util'
local handlers = require 'vim.lsp.handlers' local handlers = require 'vim.lsp.handlers'
local sysname = vim.loop.os_uname().sysname
local env = { local env = {
HOME = vim.loop.os_homedir(), HOME = vim.loop.os_homedir(),
JAVA_HOME = os.getenv 'JAVA_HOME', XDG_CACHE_HOME = os.getenv 'XDG_CACHE_HOME',
JDTLS_HOME = os.getenv 'JDTLS_HOME', JDTLS_JVM_ARGS = os.getenv 'JDTLS_JVM_ARGS',
WORKSPACE = os.getenv 'WORKSPACE',
} }
local function get_java_executable() local function get_cache_dir()
local executable = env.JAVA_HOME and util.path.join(env.JAVA_HOME, 'bin', 'java') or 'java' return env.XDG_CACHE_HOME and env.XDG_CACHE_HOME or util.path.join(env.HOME, '.cache')
return sysname:match 'Windows' and executable .. '.exe' or executable
end end
local function get_workspace_dir() local function get_jdtls_cache_dir()
return env.WORKSPACE and env.WORKSPACE or util.path.join(env.HOME, 'workspace') return util.path.join(get_cache_dir(), 'jdtls')
end end
local function get_jdtls_jar() local function get_jdtls_config_dir()
return vim.fn.expand '$JDTLS_HOME/plugins/org.eclipse.equinox.launcher_*.jar' return util.path.join(get_jdtls_cache_dir(), 'config')
end end
local function get_jdtls_config() local function get_jdtls_workspace_dir()
if sysname:match 'Linux' then return util.path.join(get_jdtls_cache_dir(), 'workspace')
return util.path.join(env.JDTLS_HOME, 'config_linux')
elseif sysname:match 'Darwin' then
return util.path.join(env.JDTLS_HOME, 'config_mac')
elseif sysname:match 'Windows' then
return util.path.join(env.JDTLS_HOME, 'config_win')
else
return util.path.join(env.JDTLS_HOME, 'config_linux')
end end
local function get_jdtls_jvm_args()
local args = {}
for a in string.gmatch((env.JDTLS_JVM_ARGS or ''), '%S+') do
local arg = string.format('--jvm-arg=%s', a)
table.insert(args, arg)
end
return unpack(args)
end end
-- TextDocument version is reported as 0, override with nil so that -- TextDocument version is reported as 0, override with nil so that
@ -94,25 +91,12 @@ local root_files = {
return { return {
default_config = { default_config = {
cmd = { cmd = {
get_java_executable(), 'jdtls',
'-Declipse.application=org.eclipse.jdt.ls.core.id1',
'-Dosgi.bundles.defaultStartLevel=4',
'-Declipse.product=org.eclipse.jdt.ls.core.product',
'-Dlog.protocol=true',
'-Dlog.level=ALL',
'-Xms1g',
'-Xmx2G',
'--add-modules=ALL-SYSTEM',
'--add-opens',
'java.base/java.util=ALL-UNNAMED',
'--add-opens',
'java.base/java.lang=ALL-UNNAMED',
'-jar',
get_jdtls_jar(),
'-configuration', '-configuration',
get_jdtls_config(), get_jdtls_config_dir(),
'-data', '-data',
get_workspace_dir(), get_jdtls_workspace_dir(),
get_jdtls_jvm_args(),
}, },
filetypes = { 'java' }, filetypes = { 'java' },
root_dir = function(fname) root_dir = function(fname)
@ -125,7 +109,7 @@ return {
end, end,
single_file_support = true, single_file_support = true,
init_options = { init_options = {
workspace = get_workspace_dir(), workspace = get_jdtls_workspace_dir(),
jvm_args = {}, jvm_args = {},
os_config = nil, os_config = nil,
}, },
@ -150,25 +134,21 @@ you can keep reading here.
For manual installation you can download precompiled binaries from the For manual installation you can download precompiled binaries from the
[official downloads site](http://download.eclipse.org/jdtls/snapshots/?d) [official downloads site](http://download.eclipse.org/jdtls/snapshots/?d)
and ensure that the `PATH` variable contains the `bin` directory of the extracted archive.
Due to the nature of java, settings cannot be inferred. Please set the following
environmental variables to match your installation. If you need per-project configuration
[direnv](https://github.com/direnv/direnv) is highly recommended.
```bash
# Mandatory:
# .bashrc
export JDTLS_HOME=/path/to/jdtls_root # Directory with the plugin and configs directories
# Optional:
export JAVA_HOME=/path/to/java_home # In case you don't have java in path or want to use a version in particular
export WORKSPACE=/path/to/workspace # Defaults to $HOME/workspace
```
```lua ```lua
-- init.lua -- init.lua
require'lspconfig'.jdtls.setup{} require'lspconfig'.jdtls.setup{}
``` ```
You can also pass extra custom jvm arguments with the JDTLS_JVM_ARGS environment variable as a space separated list of arguments,
that will be converted to multiple --jvm-arg=<param> args when passed to the jdtls script. This will allow for example tweaking
the jvm arguments or integration with external tools like lombok:
```sh
export JDTLS_JVM_ARGS="-javaagent:$HOME/.local/share/java/lombok.jar"
```
For automatic installation you can use the following unofficial installers/launchers under your own risk: For automatic installation you can use the following unofficial installers/launchers under your own risk:
- [jdtls-launcher](https://github.com/eruizc-dev/jdtls-launcher) (Includes lombok support by default) - [jdtls-launcher](https://github.com/eruizc-dev/jdtls-launcher) (Includes lombok support by default)
```lua ```lua

View File

@ -17,9 +17,12 @@ return {
return util.root_pattern 'jsonnetfile.json'(fname) or util.find_git_ancestor(fname) return util.root_pattern 'jsonnetfile.json'(fname) or util.find_git_ancestor(fname)
end, end,
on_new_config = function(new_config, root_dir) on_new_config = function(new_config, root_dir)
new_config.cmd_env = { if not new_config.cmd_env then
JSONNET_PATH = jsonnet_path(root_dir), new_config.cmd_env = {}
} end
if not new_config.cmd_env.JSONNET_PATH then
new_config.cmd_env.JSONNET_PATH = jsonnet_path(root_dir)
end
end, end,
}, },
docs = { docs = {

View File

@ -48,7 +48,7 @@ that plugin fully handles the setup of the Lean language server,
and you shouldn't set up `lean3ls` both with it and `lspconfig`. and you shouldn't set up `lean3ls` both with it and `lspconfig`.
]], ]],
default_config = { default_config = {
root_dir = [[root_pattern("leanpkg.toml") or root_pattern(".git") or path.dirname]], root_dir = [[root_pattern("leanpkg.toml") or root_pattern(".git")]],
}, },
}, },
} }

View File

@ -0,0 +1,29 @@
local util = require 'lspconfig.util'
local bin_name = 'marksman'
local cmd = { bin_name, 'server' }
return {
default_config = {
cmd = cmd,
filetypes = { 'markdown' },
root_dir = function(fname)
local root_files = { '.marksman.toml' }
return util.root_pattern(unpack(root_files))(fname) or util.find_git_ancestor(fname)
end,
},
docs = {
description = [[
https://github.com/artempyanykh/marksman
Marksman is a Markdown LSP server providing completion, cross-references, diagnostics, and more.
Marksman works on MacOS, Linux, and Windows and is distributed as a self-contained binary for each OS.
Pre-built binaries can be downloaded from https://github.com/artempyanykh/marksman/releases
]],
default_config = {
root_dir = [[root_pattern(".git", ".marksman.toml")]],
},
},
}

View File

@ -22,21 +22,11 @@ Scala language server with rich IDE features.
See full instructions in the Metals documentation: See full instructions in the Metals documentation:
https://scalameta.org/metals/docs/editors/vim.html#using-an-alternative-lsp-client https://scalameta.org/metals/docs/editors/vim#using-an-alternative-lsp-client
Note: that if you're using [nvim-metals](https://github.com/scalameta/nvim-metals), that plugin fully handles the setup and installation of Metals, and you shouldn't set up Metals both with it and `lspconfig`. Note: that if you're using [nvim-metals](https://github.com/scalameta/nvim-metals), that plugin fully handles the setup and installation of Metals, and you shouldn't set up Metals both with it and `lspconfig`.
To install Metals, make sure to have [coursier](https://get-coursier.io/docs/cli-installation) installed, and once you do you can install the latest Metals with `cs install metals`. You can also manually bootstrap Metals with the following command. To install Metals, make sure to have [coursier](https://get-coursier.io/docs/cli-installation) installed, and once you do you can install the latest Metals with `cs install metals`.
```bash
cs bootstrap \
--java-opt -Xss4m \
--java-opt -Xms100m \
org.scalameta:metals_2.12:<enter-version-here> \
-r bintray:scalacenter/releases \
-r sonatype:snapshots \
-o /usr/local/bin/metals -f
```
]], ]],
default_config = { default_config = {
root_dir = [[util.root_pattern("build.sbt", "build.sc", "build.gradle", "pom.xml")]], root_dir = [[util.root_pattern("build.sbt", "build.sc", "build.gradle", "pom.xml")]],

View File

@ -6,6 +6,7 @@ local language_id_of = {
ocamlinterface = 'ocaml.interface', ocamlinterface = 'ocaml.interface',
ocamllex = 'ocaml.ocamllex', ocamllex = 'ocaml.ocamllex',
reason = 'reason', reason = 'reason',
dune = 'dune',
} }
local get_language_id = function(_, ftype) local get_language_id = function(_, ftype)
@ -15,8 +16,8 @@ end
return { return {
default_config = { default_config = {
cmd = { 'ocamllsp' }, cmd = { 'ocamllsp' },
filetypes = { 'ocaml', 'ocaml.menhir', 'ocaml.interface', 'ocaml.ocamllex', 'reason' }, filetypes = { 'ocaml', 'ocaml.menhir', 'ocaml.interface', 'ocaml.ocamllex', 'reason', 'dune' },
root_dir = util.root_pattern('*.opam', 'esy.json', 'package.json', '.git'), root_dir = util.root_pattern('*.opam', 'esy.json', 'package.json', '.git', 'dune-project', 'dune-workspace'),
get_language_id = get_language_id, get_language_id = get_language_id,
}, },
docs = { docs = {
@ -27,12 +28,11 @@ https://github.com/ocaml/ocaml-lsp
To install the lsp server in a particular opam switch: To install the lsp server in a particular opam switch:
```sh ```sh
opam pin add ocaml-lsp-server https://github.com/ocaml/ocaml-lsp.git
opam install ocaml-lsp-server opam install ocaml-lsp-server
``` ```
]], ]],
default_config = { default_config = {
root_dir = [[root_pattern("*.opam", "esy.json", "package.json", ".git")]], root_dir = [[root_pattern("*.opam", "esy.json", "package.json", ".git", "dune-project", "dune-workspace")]],
}, },
}, },
} }

View File

@ -0,0 +1,40 @@
local util = require 'lspconfig.util'
local cmd = {
'phan',
'-m',
'json',
'--no-color',
'--no-progress-bar',
'-x',
'-u',
'-S',
'--language-server-on-stdin',
'--allow-polyfill-parser',
}
return {
default_config = {
cmd = cmd,
filetypes = { 'php' },
single_file_support = true,
root_dir = function(pattern)
local cwd = vim.loop.cwd()
local root = util.root_pattern('composer.json', '.git')(pattern)
-- prefer cwd if root is a descendant
return util.path.is_descendant(cwd, root) and cwd or root
end,
},
docs = {
description = [[
https://github.com/phan/phan
Installation: https://github.com/phan/phan#getting-started
]],
default_config = {
cmd = cmd,
root_dir = [[root_pattern("composer.json", ".git")]],
},
},
}

View File

@ -0,0 +1,22 @@
local util = require 'lspconfig.util'
return {
default_config = {
cmd = { 'prosemd-lsp', '--stdio' },
filetypes = { 'markdown' },
root_dir = util.find_git_ancestor,
single_file_support = true,
},
docs = {
description = [[
https://github.com/kitten/prosemd-lsp
An experimental LSP for Markdown.
Please see the manual installation instructions: https://github.com/kitten/prosemd-lsp#manual-installation
]],
default_config = {
root_dir = util.find_git_ancestor,
},
},
}

View File

@ -11,18 +11,19 @@ return {
default_config = { default_config = {
cmd = cmd, cmd = cmd,
filetypes = { 'purescript' }, filetypes = { 'purescript' },
root_dir = util.root_pattern('bower.json', 'psc-package.json', 'spago.dhall'), root_dir = util.root_pattern('bower.json', 'psc-package.json', 'spago.dhall', 'flake.nix', 'shell.nix'),
}, },
docs = { docs = {
description = [[ description = [[
https://github.com/nwolverson/purescript-language-server https://github.com/nwolverson/purescript-language-server
`purescript-language-server` can be installed via `npm`
```sh The `purescript-language-server` can be added to your project and `$PATH` via
npm install -g purescript-language-server
``` * JavaScript package manager such as npm, pnpm, Yarn, et al.
* Nix under the `nodePackages` and `nodePackages_latest` package sets
]], ]],
default_config = { default_config = {
root_dir = [[root_pattern("spago.dhall, 'psc-package.json', bower.json")]], root_dir = [[root_pattern('spago.dhall', 'psc-package.json', 'bower.json', 'flake.nix', 'shell.nix'),]],
}, },
}, },
} }

View File

@ -10,14 +10,7 @@ return {
description = [[ description = [[
Reason language server Reason language server
**By default, reason_ls doesn't have a `cmd` set.** This is because nvim-lspconfig does not make assumptions about your path.
You have to install the language server manually.
You can install reason language server from [reason-language-server](https://github.com/jaredly/reason-language-server) repository. You can install reason language server from [reason-language-server](https://github.com/jaredly/reason-language-server) repository.
```lua
cmd = {'<path_to_reason_language_server>'}
```
]], ]],
}, },
} }

View File

@ -36,7 +36,7 @@ npm install [-g] rome
``` ```
]], ]],
default_config = { default_config = {
root_dir = [[root_pattern('package.json', 'node_modules', '.git') or dirname]], root_dir = [[root_pattern('package.json', 'node_modules', '.git')]],
}, },
}, },
} }

View File

@ -16,7 +16,7 @@ https://github.com/crystal-lang-tools/scry
Crystal language server. Crystal language server.
]], ]],
default_config = { default_config = {
root_dir = [[root_pattern('shard.yml', '.git') or dirname]], root_dir = [[root_pattern('shard.yml', '.git')]],
}, },
}, },
} }

View File

@ -0,0 +1,21 @@
local util = require 'lspconfig.util'
return {
default_config = {
cmd = { 'steep', 'langserver' },
filetypes = { 'ruby', 'eruby' },
root_dir = util.root_pattern('Steepfile', '.git'),
},
docs = {
description = [[
https://github.com/soutaro/steep
`steep` is a static type checker for Ruby.
You need `Steepfile` to make it work. Generate it with `steep init`.
]],
default_config = {
root_dir = [[root_pattern("Steepfile", ".git")]],
},
},
}

View File

@ -1,10 +1,18 @@
local util = require 'lspconfig.util' local util = require 'lspconfig.util'
local root_files = {
'.luarc.json',
'.luacheckrc',
'.stylua.toml',
'selene.toml',
}
return { return {
default_config = { default_config = {
cmd = { 'lua-language-server' }, cmd = { 'lua-language-server' },
filetypes = { 'lua' }, filetypes = { 'lua' },
root_dir = util.find_git_ancestor, root_dir = function(fname)
return util.root_pattern(unpack(root_files))(fname) or util.find_git_ancestor(fname)
end,
single_file_support = true, single_file_support = true,
log_level = vim.lsp.protocol.MessageType.Warning, log_level = vim.lsp.protocol.MessageType.Warning,
settings = { Lua = { telemetry = { enable = false } } }, settings = { Lua = { telemetry = { enable = false } } },
@ -15,21 +23,25 @@ https://github.com/sumneko/lua-language-server
Lua language server. Lua language server.
`lua-language-server` can be installed by following the instructions [here](https://github.com/sumneko/lua-language-server/wiki/Build-and-Run). The default `cmd` assumes that the `lua-language-server` binary can be found in `$PATH`. `lua-language-server` can be installed by following the instructions [here](https://github.com/sumneko/lua-language-server/wiki/Build-and-Run).
The default `cmd` assumes that the `lua-language-server` binary can be found in `$PATH`.
If you primarily use `lua-language-server` for Neovim, and want to provide completions,
analysis, and location handling for plugins on runtime path, you can use the following
settings.
Note: that these settings will meaningfully increase the time until `lua-language-server` can service
initial requests (completion, location) upon starting as well as time to first diagnostics.
Completion results will include a workspace indexing progress message until the server has finished indexing.
```lua ```lua
local runtime_path = vim.split(package.path, ';')
table.insert(runtime_path, "lua/?.lua")
table.insert(runtime_path, "lua/?/init.lua")
require'lspconfig'.sumneko_lua.setup { require'lspconfig'.sumneko_lua.setup {
settings = { settings = {
Lua = { Lua = {
runtime = { runtime = {
-- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim) -- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim)
version = 'LuaJIT', version = 'LuaJIT',
-- Setup your lua path
path = runtime_path,
}, },
diagnostics = { diagnostics = {
-- Get the language server to recognize the `vim` global -- Get the language server to recognize the `vim` global
@ -47,9 +59,14 @@ require'lspconfig'.sumneko_lua.setup {
}, },
} }
``` ```
See `lua-language-server`'s [documentation](https://github.com/sumneko/lua-language-server/blob/master/locale/en-us/setting.lua) for an explanation of the above fields:
* [Lua.runtime.path](https://github.com/sumneko/lua-language-server/blob/076dd3e5c4e03f9cef0c5757dfa09a010c0ec6bf/locale/en-us/setting.lua#L5-L13)
* [Lua.workspace.library](https://github.com/sumneko/lua-language-server/blob/076dd3e5c4e03f9cef0c5757dfa09a010c0ec6bf/locale/en-us/setting.lua#L77-L78)
]], ]],
default_config = { default_config = {
root_dir = [[root_pattern(".git") or bufdir]], root_dir = [[root_pattern(".luarc.json", ".luacheckrc", ".stylua.toml", "selene.toml", ".git")]],
}, },
}, },
} }

View File

@ -0,0 +1,65 @@
local util = require 'lspconfig.util'
local bin_name = 'svlangserver'
local cmd = { bin_name }
if vim.fn.has 'win32' == 1 then
cmd = { 'cmd.exe', '/C', bin_name }
end
local function build_index()
local params = {
command = 'systemverilog.build_index',
}
vim.lsp.buf.execute_command(params)
end
local function report_hierarchy()
local params = {
command = 'systemverilog.report_hierarchy',
arguments = { vim.fn.expand '<cword>' },
}
vim.lsp.buf.execute_command(params)
end
return {
default_config = {
cmd = cmd,
filetypes = { 'verilog', 'systemverilog' },
root_dir = function(fname)
return util.root_pattern '.svlangserver'(fname) or util.find_git_ancestor(fname)
end,
single_file_support = true,
settings = {
systemverilog = {
includeIndexing = { '*.{v,vh,sv,svh}', '**/*.{v,vh,sv,svh}' },
},
},
},
commands = {
SvlangserverBuildIndex = {
build_index,
description = 'Instructs language server to rerun indexing',
},
SvlangserverReportHierarchy = {
report_hierarchy,
description = 'Generates hierarchy for the given module',
},
},
docs = {
description = [[
https://github.com/imc-trading/svlangserver
Language server for SystemVerilog.
`svlangserver` can be installed via `npm`:
```sh
$ npm install -g @imc-trading/svlangserver
```
]],
default_config = {
root_dir = [[root_pattern(".svlangserver", ".git")]],
},
},
}

View File

@ -2,7 +2,7 @@ local util = require 'lspconfig.util'
return { return {
default_config = { default_config = {
cmd = { 'taplo-lsp', 'run' }, cmd = { 'taplo', 'lsp', 'stdio' },
filetypes = { 'toml' }, filetypes = { 'toml' },
root_dir = function(fname) root_dir = function(fname)
return util.root_pattern '*.toml'(fname) or util.find_git_ancestor(fname) return util.root_pattern '*.toml'(fname) or util.find_git_ancestor(fname)
@ -15,9 +15,9 @@ https://taplo.tamasfe.dev/lsp/
Language server for Taplo, a TOML toolkit. Language server for Taplo, a TOML toolkit.
`taplo-lsp` can be installed via `cargo`: `taplo-cli` can be installed via `cargo`:
```sh ```sh
cargo install --locked taplo-lsp cargo install --features lsp --locked taplo-cli
``` ```
]], ]],
default_config = { default_config = {

View File

@ -0,0 +1,26 @@
local util = require 'lspconfig.util'
return {
default_config = {
cmd = { 'tilt', 'lsp', 'start' },
filetypes = { 'tiltfile' },
root_dir = util.find_git_ancestor,
single_file_support = true,
},
docs = {
description = [[
https://github.com/tilt-dev/tilt
Tilt language server.
You might need to add filetype detection manually:
```vim
autocmd BufRead Tiltfile setf=tiltfile
```
]],
default_config = {
root_dir = [[root_pattern(".git")]],
},
},
}

View File

@ -11,10 +11,10 @@ return {
default_config = { default_config = {
cmd = cmd, cmd = cmd,
filetypes = { 'vim' }, filetypes = { 'vim' },
root_dir = function(fname) root_dir = util.find_git_ancestor,
return util.find_git_ancestor(fname) or vim.fn.getcwd() single_file_support = true,
end,
init_options = { init_options = {
isNeovim = true,
iskeyword = '@,48-57,_,192-255,-#', iskeyword = '@,48-57,_,192-255,-#',
vimruntime = '', vimruntime = '',
runtimepath = '', runtimepath = '',

View File

@ -0,0 +1,38 @@
local util = require 'lspconfig.util'
return {
default_config = {
filetypes = { 'visualforce' },
root_dir = util.root_pattern 'sfdx-project.json',
init_options = {
embeddedLanguages = {
css = true,
javascript = true,
},
},
},
docs = {
description = [[
https://github.com/forcedotcom/salesforcedx-vscode
Language server for Visualforce.
For manual installation, download the .vsix archive file from the
[forcedotcom/salesforcedx-vscode](https://github.com/forcedotcom/salesforcedx-vscode)
GitHub releases. Then, configure `cmd` to run the Node script at the unpacked location:
```lua
require'lspconfig'.visualforce_ls.setup {
cmd = {
'node',
'/path/to/unpacked/archive/extension/node_modules/@salesforce/salesforcedx-visualforce-language-server/out/src/visualforceServer.js',
'--stdio'
}
}
```
]],
default_config = {
root_dir = [[root_pattern('sfdx-project.json')]],
},
},
}

View File

@ -2,6 +2,7 @@ local util = require 'lspconfig.util'
return { return {
default_config = { default_config = {
cmd = { 'vls' },
filetypes = { 'vlang' }, filetypes = { 'vlang' },
root_dir = util.root_pattern('v.mod', '.git'), root_dir = util.root_pattern('v.mod', '.git'),
}, },
@ -12,17 +13,6 @@ https://github.com/vlang/vls
V language server. V language server.
`v-language-server` can be installed by following the instructions [here](https://github.com/vlang/vls#installation). `v-language-server` can be installed by following the instructions [here](https://github.com/vlang/vls#installation).
**By default, v-language-server doesn't have a `cmd` set.** This is because nvim-lspconfig does not make assumptions about your path. You must add the following to your init.vim or init.lua to set `cmd` to the absolute path ($HOME and ~ are not expanded) of your unzipped and compiled v-language-server.
```lua
-- set the path to the vls installation;
local vls_root_path = vim.fn.stdpath('cache')..'/lspconfig/vls'
local vls_binary = vls_root_path.."/cmd/vls/vls"
require'lspconfig'.vls.setup {
cmd = {vls_binary},
}
``` ```
]], ]],
default_config = { default_config = {

View File

@ -81,9 +81,11 @@ Volar can be installed via npm:
npm install -g @volar/vue-language-server npm install -g @volar/vue-language-server
``` ```
Volar by default supports Vue 3 projects. Vue 2 projects need [additional configuration](https://github.com/johnsoncodehk/volar/blob/master/extensions/vscode-vue-language-features/README.md?plain=1#L28-L63). Volar by default supports Vue 3 projects. Vue 2 projects need
[additional configuration](https://github.com/johnsoncodehk/volar/blob/master/extensions/vscode-vue-language-features/README.md?plain=1#L28-L63).
**Take Over Mode** **Take Over Mode**
Volar can serve as a language server for both Vue and TypeScript via [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471). Volar can serve as a language server for both Vue and TypeScript via [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471).
To enable Take Over Mode, override the default filetypes in `setup{}` as follows: To enable Take Over Mode, override the default filetypes in `setup{}` as follows:
@ -95,7 +97,9 @@ require'lspconfig'.volar.setup{
``` ```
**Overriding the default TypeScript Server used by Volar** **Overriding the default TypeScript Server used by Volar**
The default config looks for TS in the local node_modules. The alternatives are:
The default config looks for TS in the local `node_modules`. This can lead to issues
e.g. when working on a [monorepo](https://monorepo.tools/). The alternatives are:
- use a global TypeScript Server installation - use a global TypeScript Server installation
@ -104,26 +108,33 @@ require'lspconfig'.volar.setup{
init_options = { init_options = {
typescript = { typescript = {
serverPath = '/path/to/.npm/lib/node_modules/typescript/lib/tsserverlib.js' serverPath = '/path/to/.npm/lib/node_modules/typescript/lib/tsserverlib.js'
-- Alternative location if installed as root:
-- serverPath = '/usr/local/lib/node_modules/typescript/lib/tsserverlibrary.js'
} }
} }
} }
``` ```
- use a global TypeScript Server installation if a local server is not found - use a local server and fall back to a global TypeScript Server installation
```lua ```lua
local util = require 'lspconfig.util' local util = require 'lspconfig.util'
local function get_typescript_server_path(root_dir) local function get_typescript_server_path(root_dir)
local project_root = util.find_node_modules_ancestor(root_dir)
local local_tsserverlib = project_root ~= nil and util.path.join(project_root, 'node_modules', 'typescript', 'lib', 'tsserverlibrary.js') local global_ts = '/home/[yourusernamehere]/.npm/lib/node_modules/typescript/lib/tsserverlibrary.js'
local global_tsserverlib = '/home/[yourusernamehere]/.npm/lib/node_modules/typescript/lib/tsserverlibrary.js' -- Alternative location if installed as root:
-- local global_ts = '/usr/local/lib/node_modules/typescript/lib/tsserverlibrary.js'
if local_tsserverlib and util.path.exists(local_tsserverlib) then local found_ts = ''
return local_tsserverlib local function check_dir(path)
found_ts = util.path.join(path, 'node_modules', 'typescript', 'lib', 'tsserverlibrary.js')
if util.path.exists(found_ts) then
return path
end
end
if util.search_ancestors(root_dir, check_dir) then
return found_ts
else else
return global_tsserverlib return global_ts
end end
end end

View File

@ -0,0 +1,30 @@
local util = require 'lspconfig.util'
local bin_name = 'wgsl_analyzer'
local cmd = { bin_name }
if vim.fn.has 'win32' == 1 then
cmd = { 'cmd.exe', '/C', bin_name }
end
return {
default_config = {
cmd = cmd,
filetypes = { 'wgsl' },
root_dir = util.root_pattern '.git',
settings = {},
},
docs = {
description = [[
https://github.com/wgsl-analyzer/wgsl-analyzer
`wgsl_analyzer` can be installed via `cargo`:
```sh
cargo install --git https://github.com/wgsl-analyzer/wgsl-analyzer wgsl_analyzer
```
]],
default_config = {
root_dir = [[root_pattern(".git"]],
},
},
}

View File

@ -1,28 +0,0 @@
local util = require 'lspconfig.util'
return {
default_config = {
filetypes = { 'markdown' },
root_dir = util.root_pattern '.zeta.toml',
},
docs = {
description = [[
https://github.com/artempyanykh/zeta-note
Markdown LSP server for easy note-taking with cross-references and diagnostics.
Binaries can be downloaded from https://github.com/artempyanykh/zeta-note/releases
**By default, zeta-note doesn't have a `cmd` set.** This is because nvim-lspconfig does not make assumptions about your path. You must add the following to your init.vim or init.lua to set `cmd` to the absolute path ($HOME and ~ are not expanded) of your zeta-note binary.
```lua
require'lspconfig'.zeta_note.setup{
cmd = {'path/to/zeta-note'}
}
```
]],
default_config = {
root_dir = [[root_pattern(".zeta.toml")]],
},
},
}

View File

@ -11,10 +11,10 @@ return {
description = [[ description = [[
https://github.com/zigtools/zls https://github.com/zigtools/zls
`Zig LSP implementation + Zig Language Server`. Zig LSP implementation + Zig Language Server
]], ]],
default_config = { default_config = {
root_dir = [[util.root_pattern("zls.json", ".git") or current_file_dirname]], root_dir = [[util.root_pattern("zls.json", ".git")]],
}, },
}, },
} }

View File

@ -5,6 +5,12 @@ local util = require 'lspconfig.util'
local error_messages = { local error_messages = {
cmd_not_found = 'Unable to find executable. Please check your path and ensure the server is installed', cmd_not_found = 'Unable to find executable. Please check your path and ensure the server is installed',
no_filetype_defined = 'No filetypes defined, Please define filetypes in setup()', no_filetype_defined = 'No filetypes defined, Please define filetypes in setup()',
root_dir_not_found = 'Not found.',
}
local helptags = {
[error_messages.no_filetype_defined] = { 'lspconfig-setup' },
[error_messages.root_dir_not_found] = { 'lspconfig-root-detection' },
} }
local function trim_blankspace(cmd) local function trim_blankspace(cmd)
@ -33,6 +39,7 @@ end
local function make_config_info(config) local function make_config_info(config)
local config_info = {} local config_info = {}
config_info.name = config.name config_info.name = config.name
config_info.helptags = {}
if config.cmd then if config.cmd then
config_info.cmd = remove_newlines(config.cmd) config_info.cmd = remove_newlines(config.cmd)
if vim.fn.executable(config.cmd[1]) == 1 then if vim.fn.executable(config.cmd[1]) == 1 then
@ -46,7 +53,21 @@ local function make_config_info(config)
end end
local buffer_dir = vim.fn.expand '%:p:h' local buffer_dir = vim.fn.expand '%:p:h'
config_info.root_dir = config.get_root_dir(buffer_dir) or 'NA' local root_dir = config.get_root_dir(buffer_dir)
if root_dir then
config_info.root_dir = root_dir
else
config_info.root_dir = error_messages.root_dir_not_found
vim.list_extend(config_info.helptags, helptags[error_messages.root_dir_not_found])
local root_dir_pattern = vim.tbl_get(config, 'document_config', 'docs', 'default_config', 'root_dir')
if root_dir_pattern then
config_info.root_dir = config_info.root_dir
.. ' Searched for: '
.. remove_newlines(vim.split(root_dir_pattern, '\n'))
.. '.'
end
end
config_info.autostart = (config.autostart and 'true') or 'false' config_info.autostart = (config.autostart and 'true') or 'false'
config_info.handlers = table.concat(vim.tbl_keys(config.handlers), ', ') config_info.handlers = table.concat(vim.tbl_keys(config.handlers), ', ')
config_info.filetypes = table.concat(config.filetypes or {}, ', ') config_info.filetypes = table.concat(config.filetypes or {}, ', ')
@ -64,6 +85,15 @@ local function make_config_info(config)
'custom handlers: ' .. config_info.handlers, 'custom handlers: ' .. config_info.handlers,
} }
if vim.tbl_count(config_info.helptags) > 0 then
local help = vim.tbl_map(function(helptag)
return string.format(':h %s', helptag)
end, config_info.helptags)
info_lines = vim.list_extend({
'Refer to ' .. table.concat(help, ', ') .. ' for help.',
}, info_lines)
end
vim.list_extend(lines, indent_lines(info_lines, '\t')) vim.list_extend(lines, indent_lines(info_lines, '\t'))
return lines return lines
@ -209,8 +239,14 @@ return function()
vim.fn.matchadd( vim.fn.matchadd(
'Error', 'Error',
error_messages.no_filetype_defined .. '.\\|' .. 'cmd not defined\\|' .. error_messages.cmd_not_found error_messages.no_filetype_defined
.. '.\\|'
.. 'cmd not defined\\|'
.. error_messages.cmd_not_found
.. '\\|'
.. error_messages.root_dir_not_found
) )
vim.cmd 'let m=matchadd("string", "true")' vim.cmd 'let m=matchadd("string", "true")'
vim.cmd 'let m=matchadd("error", "false")' vim.cmd 'let m=matchadd("error", "false")'
for _, config in pairs(configs) do for _, config in pairs(configs) do

View File

@ -14,6 +14,7 @@ M.default_config = {
init_options = vim.empty_dict(), init_options = vim.empty_dict(),
handlers = {}, handlers = {},
autostart = true, autostart = true,
capabilities = lsp.protocol.make_client_capabilities(),
} }
-- global on_setup hook -- global on_setup hook
@ -206,6 +207,8 @@ M.path = (function()
return dir == root return dir == root
end end
local path_separator = is_windows and ';' or ':'
return { return {
is_dir = is_dir, is_dir = is_dir,
is_file = is_file, is_file = is_file,
@ -217,12 +220,13 @@ M.path = (function()
traverse_parents = traverse_parents, traverse_parents = traverse_parents,
iterate_parents = iterate_parents, iterate_parents = iterate_parents,
is_descendant = is_descendant, is_descendant = is_descendant,
path_separator = path_separator,
} }
end)() end)()
-- Returns a function(root_dir), which, when called with a root_dir it hasn't -- Returns a function(root_dir), which, when called with a root_dir it hasn't
-- seen before, will call make_config(root_dir) and start a new client. -- seen before, will call make_config(root_dir) and start a new client.
function M.server_per_root_dir_manager(_make_config) function M.server_per_root_dir_manager(make_config)
local clients = {} local clients = {}
local single_file_clients = {} local single_file_clients = {}
local manager = {} local manager = {}
@ -242,7 +246,7 @@ function M.server_per_root_dir_manager(_make_config)
-- Check if we have a client already or start and store it. -- Check if we have a client already or start and store it.
if not client_id then if not client_id then
local new_config = _make_config(root_dir) local new_config = make_config(root_dir)
-- do nothing if the client is not enabled -- do nothing if the client is not enabled
if new_config.enabled == false then if new_config.enabled == false then
return return
@ -291,9 +295,10 @@ function M.server_per_root_dir_manager(_make_config)
return client_id return client_id
end end
function manager.clients() function manager.clients(single_file)
local res = {} local res = {}
for _, id in pairs(clients) do local client_list = single_file and single_file_clients or clients
for _, id in pairs(client_list) do
local client = lsp.get_client_by_id(id) local client = lsp.get_client_by_id(id)
if client then if client then
table.insert(res, client) table.insert(res, client)
@ -418,6 +423,7 @@ function M.get_managed_clients()
for _, config in pairs(configs) do for _, config in pairs(configs) do
if config.manager then if config.manager then
vim.list_extend(clients, config.manager.clients()) vim.list_extend(clients, config.manager.clients())
vim.list_extend(clients, config.manager.clients(true))
end end
end end
return clients return clients

View File

@ -1,8 +1,9 @@
# Configurations # Configurations
<!-- *lspconfig-server-configurations* --> <!-- *lspconfig-all* *lspconfig-server-configurations* -->
The following LSP configs are included. This documentation is autogenerated from the lua files. Follow a link to find documentation for LSP configs provided by nvim-lspconfig are listed below. This documentation is
that config. This file is accessible in neovim via `:help lspconfig-server-configurations` autogenerated from the Lua files. You can view this file in Nvim by running
`:help lspconfig-all`.
{{implemented_servers_list}} {{implemented_servers_list}}

View File

@ -74,11 +74,10 @@ local lsp_section_template = [[
```lua ```lua
require'lspconfig'.{{template_name}}.setup{} require'lspconfig'.{{template_name}}.setup{}
``` ```
{{commands}}
**Commands and default values:** **Default values:**
```lua {{default_values}}
{{body}}
```
]] ]]
@ -101,16 +100,17 @@ local function make_lsp_sections()
local params = { local params = {
template_name = template_name, template_name = template_name,
preamble = '', preamble = '',
body = '', commands = '',
default_values = '',
} }
params.body = make_section(2, '\n\n', { params.commands = make_section(0, '\n\n', {
function() function()
if not template_def.commands then if not template_def.commands or #vim.tbl_keys(template_def.commands) == 0 then
return return
end end
return make_section(0, '\n', { return '**Commands:**\n'
'Commands:', .. make_section(0, '\n', {
sorted_map_table(template_def.commands, function(name, def) sorted_map_table(template_def.commands, function(name, def)
if def.description then if def.description then
return string.format('- %s: %s', name, def.description) return string.format('- %s: %s', name, def.description)
@ -119,35 +119,22 @@ local function make_lsp_sections()
end), end),
}) })
end, end,
})
params.default_values = make_section(2, '\n\n', {
function() function()
if not template_def.default_config then if not template_def.default_config then
return return
end end
return make_section(0, '\n', { return make_section(0, '\n', {
'Default Values:',
sorted_map_table(template_def.default_config, function(k, v) sorted_map_table(template_def.default_config, function(k, v)
local description = ((docs or {}).default_config or {})[k] local description = ((docs or {}).default_config or {})[k]
if description and type(description) ~= 'string' then if description and type(description) ~= 'string' then
description = inspect(description) description = inspect(description)
elseif not description and type(v) == 'function' then elseif not description and type(v) == 'function' then
local info = debug.getinfo(v) description = 'see source file'
local file = io.open(string.sub(info.source, 2), 'r')
local fileContent = {}
for line in file:lines() do
table.insert(fileContent, line)
end end
io.close(file) return string.format('- `%s` : \n```lua\n%s\n```', k, description or inspect(v))
local root_dir = {}
for i = info.linedefined, info.lastlinedefined do
table.insert(root_dir, fileContent[i])
end
description = table.concat(root_dir, '\n')
description = string.gsub(description, '.*function', 'function')
end
return indent(2, string.format('%s = %s', k, description or inspect(v)))
end), end),
}) })
end, end,

View File

@ -191,4 +191,65 @@ describe('lspconfig', function()
end) end)
end) end)
end) end)
describe('config', function()
it('normalizes user, server, and base default configs', function()
eq(
exec_lua [[
local lspconfig = require("lspconfig")
local configs = require("lspconfig.configs")
local actual = nil
lspconfig.util.on_setup = function(config)
actual = config
end
lspconfig.util.default_config = {
foo = {
bar = {
val1 = 'base1',
val2 = 'base2',
},
},
}
local server_config = {
default_config = {
foo = {
bar = {
val2 = 'server2',
val3 = 'server3',
},
baz = 'baz',
},
},
}
local user_config = {
foo = {
bar = {
val3 = 'user3',
val4 = 'user4',
}
},
}
configs['test'] = server_config
configs['test'].setup(user_config)
return actual
]],
{
foo = {
bar = {
val1 = 'base1',
val2 = 'server2',
val3 = 'user3',
val4 = 'user4',
},
baz = 'baz',
},
name = 'test',
}
)
end)
end)
end) end)

View File

@ -36,9 +36,6 @@ _G.load_config = function()
end end
local nvim_lsp = require 'lspconfig' local nvim_lsp = require 'lspconfig'
local on_attach = function(_, bufnr) local on_attach = function(_, bufnr)
local function buf_set_keymap(...)
vim.api.nvim_buf_set_keymap(bufnr, ...)
end
local function buf_set_option(...) local function buf_set_option(...)
vim.api.nvim_buf_set_option(bufnr, ...) vim.api.nvim_buf_set_option(bufnr, ...)
end end
@ -46,22 +43,24 @@ _G.load_config = function()
buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc') buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc')
-- Mappings. -- Mappings.
local opts = { noremap = true, silent = true } local opts = { buffer = bufnr, noremap = true, silent = true }
buf_set_keymap('n', 'gD', '<Cmd>lua vim.lsp.buf.declaration()<CR>', opts) vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, opts)
buf_set_keymap('n', 'gd', '<Cmd>lua vim.lsp.buf.definition()<CR>', opts) vim.keymap.set('n', 'gd', vim.lsp.buf.definition, opts)
buf_set_keymap('n', 'K', '<Cmd>lua vim.lsp.buf.hover()<CR>', opts) vim.keymap.set('n', 'K', vim.lsp.buf.hover, opts)
buf_set_keymap('n', 'gi', '<cmd>lua vim.lsp.buf.implementation()<CR>', opts) vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, opts)
buf_set_keymap('n', '<C-k>', '<cmd>lua vim.lsp.buf.signature_help()<CR>', opts) vim.keymap.set('n', '<C-k>', vim.lsp.buf.signature_help, opts)
buf_set_keymap('n', '<space>wa', '<cmd>lua vim.lsp.buf.add_workspace_folder()<CR>', opts) vim.keymap.set('n', '<space>wa', vim.lsp.buf.add_workspace_folder, opts)
buf_set_keymap('n', '<space>wr', '<cmd>lua vim.lsp.buf.remove_workspace_folder()<CR>', opts) vim.keymap.set('n', '<space>wr', vim.lsp.buf.remove_workspace_folder, opts)
buf_set_keymap('n', '<space>wl', '<cmd>lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))<CR>', opts) vim.keymap.set('n', '<space>wl', function()
buf_set_keymap('n', '<space>D', '<cmd>lua vim.lsp.buf.type_definition()<CR>', opts) print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
buf_set_keymap('n', '<space>rn', '<cmd>lua vim.lsp.buf.rename()<CR>', opts) end, opts)
buf_set_keymap('n', 'gr', '<cmd>lua vim.lsp.buf.references()<CR>', opts) vim.keymap.set('n', '<space>D', vim.lsp.buf.type_definition, opts)
buf_set_keymap('n', '<space>e', '<cmd>lua require("spacevim.diagnostic").show_line_diagnostics()<CR>', opts) vim.keymap.set('n', '<space>rn', vim.lsp.buf.rename, opts)
buf_set_keymap('n', '[d', '<cmd>lua require("spacevim.diagnostic").goto_prev()<CR>', opts) vim.keymap.set('n', 'gr', vim.lsp.buf.references, opts)
buf_set_keymap('n', ']d', '<cmd>lua require("spacevim.diagnostic").goto_next()<CR>', opts) vim.keymap.set('n', '<space>e', vim.diagnostic.open_float, opts)
buf_set_keymap('n', '<space>q', '<cmd>lua require("spacevim.diagnostic").set_loclist()<CR>', opts) vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, opts)
vim.keymap.set('n', ']d', vim.diagnostic.goto_next, opts)
vim.keymap.set('n', '<space>q', vim.diagnostic.setloclist, opts)
end end
-- Add the server that troubles you here -- Add the server that troubles you here