AstroLSP provides a simple API for configuring and setting up language servers in Neovim. This is the LSP configuration engine that AstroNvim uses, but can be used by itself as well.
Install the plugin with your plugin manager of choice:
{
"AstroNvim/astrolsp",
opts = {
-- set configuration options as described below
}
}
use {
"AstroNvim/astrolsp",
}
require("astrolsp").setup {
-- set configuration options as described below
}
AstroLSP comes with the no defaults, but can be configured fully through the opts
table in lazy or through calling require("astrolsp").setup({})
. Here are descriptions of the options and some example usages:
---@type AstroLSPConfig
local opts = {
-- Configuration table of features provided by AstroLSP
features = {
codelens = true, -- enable/disable codelens refresh on start
inlay_hints = false, -- enable/disable inlay hints on start
semantic_tokens = true, -- enable/disable semantic token highlighting
},
-- Configure buffer local auto commands to add when attaching a language server
autocmds = {
-- first key is the `augroup` (:h augroup)
lsp_document_highlight = {
-- condition to create/delete auto command group
-- can either be a string of a client capability or a function of `fun(client, bufnr): boolean`
-- condition will be resolved for each client on each execution and if it ever fails for all clients,
-- the auto commands will be deleted for that buffer
cond = "textDocument/documentHighlight",
-- list of auto commands to set
{
-- events to trigger
event = { "CursorHold", "CursorHoldI" },
-- the rest of the autocmd options (:h nvim_create_autocmd)
desc = "Document Highlighting",
callback = function() vim.lsp.buf.document_highlight() end,
},
{
event = { "CursorMoved", "CursorMovedI", "BufLeave" },
desc = "Document Highlighting Clear",
callback = function() vim.lsp.buf.clear_references() end,
},
},
},
-- Configure buffer local user commands to add when attaching a language server
commands = {
Format = {
function() vim.lsp.buf.format() end,
-- condition to create the user command
-- can either be a string of a client capability or a function of `fun(client, bufnr): boolean`
cond = "textDocument/formatting",
-- the rest of the user command options (:h nvim_create_user_command)
desc = "Format file with LSP",
},
},
-- Configure default capabilities for language servers (`:h vim.lsp.protocol.make_client.capabilities()`)
capabilities = {
textDocument = {
foldingRange = { dynamicRegistration = false },
},
},
-- Configure language servers for `lspconfig` (`:h lspconfig-setup`)
config = {
lua_ls = {
settings = {
Lua = {
hint = { enable = true, arrayIndex = "Disable" },
},
},
},
clangd = {
capabilities = {
offsetEncoding = "utf-8",
},
},
},
-- A custom flags table to be passed to all language servers (`:h lspconfig-setup`)
flags = {
exit_timeout = 5000,
},
-- Configuration options for controlling formatting with language servers
formatting = {
-- control auto formatting on save
format_on_save = {
-- enable or disable format on save globally
enabled = true,
-- enable format on save for specified filetypes only
allow_filetypes = {
"go",
},
-- disable format on save for specified filetypes
ignore_filetypes = {
"python",
},
},
-- disable formatting capabilities for specific language servers
disabled = {
"lua_ls",
},
-- default format timeout
timeout_ms = 1000,
-- fully override the default formatting function
filter = function(client) return true end,
},
-- Configure how language servers get set up
handlers = {
-- default handler, first entry with no key
function(server, opts) require("lspconfig")[server].setup(opts) end,
-- custom function handler for pyright
pyright = function(_, opts) require("lspconfig").pyright.setup(opts) end,
-- set to false to disable the setup of a language server
rust_analyzer = false,
},
-- Configure `vim.lsp.handlers`
lsp_handlers = {
["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, { border = "rounded", silent = true }),
["textDocument/signatureHelp"] = false, -- set to false to disable any custom handlers
},
-- Configuration of mappings added when attaching a language server during the core `on_attach` function
-- The first key into the table is the vim map mode (`:h map-modes`), and the value is a table of entries to be passed to `vim.keymap.set` (`:h vim.keymap.set`):
-- - The key is the first parameter or the vim mode (only a single mode supported) and the value is a table of keymaps within that mode:
-- - The first element with no key in the table is the action (the 2nd parameter) and the rest of the keys/value pairs are options for the third parameter.
-- There is also a special `cond` key which can either be a string of a language server capability or a function with `client` and `bufnr` parameters that returns a boolean of whether or not the mapping is added.
mappings = {
-- map mode (:h map-modes)
n = {
-- a binding with no condition and therefore is always added
gl = {
function() vim.diagnostic.open_float() end,
desc = "Hover diagnostics",
},
-- condition for only server with declaration capabilities
gD = {
function() vim.lsp.buf.declaration() end,
desc = "Declaration of current symbol",
cond = "textDocument/declaration",
},
-- condition with a full function with `client` and `bufnr`
["<leader>uY"] = {
function() require("astrolsp.toggles").buffer_semantic_tokens() end,
desc = "Toggle LSP semantic highlight (buffer)",
cond = function(client, bufnr)
return client.server_capabilities.semanticTokensProvider and vim.lsp.semantic_tokens
end,
},
},
},
-- A list like table of servers that should be setup, useful for enabling language servers not installed with Mason.
servers = { "dartls" },
-- A custom `on_attach` function to be run after the default `on_attach` function, takes two parameters `client` and `bufnr` (`:h lspconfig-setup`)
on_attach = function(client, bufnr) client.server_capabilities.semanticTokensProvider = nil end,
}
AstroLSP can be used as the basis for configuring plugins such as nvim-lspconfig
and mason-lspconfig
. Here are a few examples (using lazy.nvim
plugin manager):
{
"neovim/nvim-lspconfig",
dependencies = {
{ "AstroNvim/astrolsp", opts = {} },
},
config = function()
-- set up servers configured with AstroLSP
vim.tbl_map(require("astrolsp").lsp_setup, require("astrolsp").config.servers)
end,
}
{
"neovim/nvim-lspconfig",
dependencies = {
{ "AstroNvim/astrolsp", opts = {} },
{
"williamboman/mason-lspconfig.nvim", -- MUST be set up before `nvim-lspconfig`
dependencies = { "williamboman/mason.nvim" },
opts = function()
return {
-- use AstroLSP setup for mason-lspconfig
handlers = { function(server) require("astrolsp").lsp_setup(server) end },
}
end,
},
},
config = function()
-- set up servers configured with AstroLSP
vim.tbl_map(require("astrolsp").lsp_setup, require("astrolsp").config.servers)
end,
}
{
"nvimtools/none-ls.nvim",
dependencies = {
{ "AstroNvim/astrolsp", opts = {} },
},
opts = function() return { on_attach = require("astrolsp").on_attach } end,
}
AstroLSP provides a Lua API with utility functions. This can be viewed with :h astrolsp
or in the repository at doc/api.md
If you plan to contribute, please check the contribution guidelines first.