nix-community.nixvim/plugins/lsp/default.nix

343 lines
8.8 KiB
Nix
Raw Normal View History

2021-02-01 15:54:53 +00:00
{
lib,
helpers,
config,
pkgs,
...
}:
with lib; let
cfg = config.plugins.lsp;
in {
imports =
[
./language-servers
]
# TODO: introduced 2024-02-14, remove on 2024-03-14
++ (
map
(
serverName:
mkRemovedOptionModule
["plugins" "lsp" "servers" serverName "installLanguageServer"]
"If you want to not install the language server package, set `plugins.lsp.servers.${serverName}.package` to `null`."
)
[
"astro"
"bashls"
"beancount"
"biome"
"ccls"
"clangd"
"clojure-lsp"
"cmake"
"csharp-ls"
"cssls"
"dagger"
"dartls"
"denols"
"dhall-lsp-server"
"digestif"
"dockerls"
"efm"
"elixirls"
"elmls"
"emmet_ls"
"eslint"
"fsautocomplete"
"futhark-lsp"
"gdscript"
"gleam"
"gopls"
"graphql"
"helm-ls"
"hls"
"html"
"htmx"
"intelephense"
"java-language-server"
"jsonls"
"julials"
"kotlin-language-server"
"leanls"
"lemminx"
"ltex"
"lua-ls"
"marksman"
"metals"
"nil_ls"
"nixd"
"nushell"
"ocamllsp"
"ols"
"omnisharp"
"perlpls"
"pest_ls"
"phpactor"
"prismals"
"prolog-ls"
"purescriptls"
"pylsp"
"pylyzer"
"pyright"
"ruff-lsp"
"rnix-lsp"
"rust-analyzer"
"solargraph"
"sourcekit"
"svelte"
"tailwindcss"
"taplo"
"templ"
"terraformls"
"texlab"
"tsserver"
"typst-lsp"
"vala-ls"
"vls"
"volar"
"vuels"
"yamlls"
"zls"
]
);
2021-02-01 15:54:53 +00:00
options = {
plugins.lsp = {
2023-01-22 03:32:08 +00:00
enable = mkEnableOption "neovim's built-in LSP";
2021-02-01 15:54:53 +00:00
keymaps = {
silent = mkOption {
type = types.bool;
description = "Whether nvim-lsp keymaps should be silent";
default = false;
};
diagnostic = mkOption {
type = with types; attrsOf (either str attrs);
2024-04-03 13:11:18 +01:00
description = "Mappings for `vim.diagnostic.<action>` functions to be added when an LSP is attached.";
example = {
"<leader>k" = "goto_prev";
"<leader>j" = "goto_next";
};
default = {};
};
lspBuf = mkOption {
type = with types; attrsOf (either str attrs);
2024-04-03 13:11:18 +01:00
description = "Mappings for `vim.lsp.buf.<action>` functions to be added when an LSP it attached.";
example = {
"gd" = "definition";
"gD" = "references";
"gt" = "type_definition";
"gi" = "implementation";
"K" = "hover";
};
default = {};
};
2024-03-25 21:39:21 +00:00
extra = mkOption {
type = with types; listOf helpers.keymaps.mapOptionSubmodule;
2024-04-03 13:11:18 +01:00
description = ''
Extra keymaps to register when an LSP is attached.
This can be used to customise LSP behaviour, for example with "telescope" or the "Lspsaga" plugin, as seen in the examples.
'';
2024-03-25 21:39:21 +00:00
example = [
{
key = "<leader>lx";
action = "<CMD>LspStop<Enter>";
}
{
key = "<leader>ls";
action = "<CMD>LspStart<Enter>";
}
{
key = "<leader>lr";
action = "<CMD>LspRestart<Enter>";
}
{
key = "gd";
action = "require('telescope.builtin').lsp_definitions()";
lua = true;
}
{
key = "K";
action = "<CMD>Lspsaga hover_doc<Enter>";
}
];
default = [];
};
};
2021-02-01 15:54:53 +00:00
enabledServers = mkOption {
type = with types;
listOf (oneOf [
str
(submodule {
options = {
name = mkOption {
type = str;
description = "The server's name";
};
2021-02-01 15:54:53 +00:00
capabilities = mkOption {
type = types.nullOr (types.attrsOf types.bool);
description = "Control resolved capabilities for the language server.";
default = null;
example = {
documentFormattingProvider = false;
};
};
extraOptions = mkOption {
type = attrs;
description = "Extra options for the server";
};
};
})
]);
2021-02-01 15:54:53 +00:00
description = "A list of enabled LSP servers. Don't use this directly.";
default = [];
internal = true;
visible = false;
2021-02-01 15:54:53 +00:00
};
onAttach = mkOption {
type = types.lines;
description = "A lua function to be run when a new LSP buffer is attached. The argument `client` and `bufnr` is provided.";
2021-02-01 15:54:53 +00:00
default = "";
};
2021-11-23 15:39:57 +01:00
capabilities = mkOption {
type = types.lines;
description = "Lua code that modifies inplace the `capabilities` table.";
default = "";
};
setupWrappers = mkOption {
type = with types; listOf (functionTo str);
description = "Code to be run to wrap the setup args. Takes in an argument containing the previous results, and returns a new string of code.";
default = [];
};
preConfig = mkOption {
2021-11-23 15:39:57 +01:00
type = types.lines;
description = "Code to be run before loading the LSP. Useful for requiring plugins";
2021-11-23 15:39:57 +01:00
default = "";
};
postConfig = mkOption {
type = types.lines;
description = "Code to be run after loading the LSP. This is an internal option";
default = "";
};
2021-02-01 15:54:53 +00:00
};
};
config = let
runWrappers = wrappers: s:
if wrappers == []
then s
else (head wrappers) (runWrappers (tail wrappers) s);
updateCapabilities = let
servers =
builtins.filter
(server: server.capabilities != null && server.capabilities != {})
cfg.enabledServers;
in
lib.concatMapStringsSep "\n" (
server: let
updates =
lib.concatMapStringsSep "\n"
(name: ''
client.server_capabilities.${name} = ${helpers.toLuaObject server.capabilities.${name}}
'')
(builtins.attrNames server.capabilities);
in ''
if client.name == "${server.name}" then
${updates}
end
''
)
servers;
in
mkIf cfg.enable {
extraPlugins = [pkgs.vimPlugins.nvim-lspconfig];
2021-02-01 15:54:53 +00:00
keymapsOnEvents.LspAttach = let
mkMaps = prefix:
mapAttrsToList
(
key: action: let
actionStr =
if isString action
then action
else action.action;
actionProps =
if isString action
then {}
else filterAttrs (n: v: n != "action") action;
in {
mode = "n";
inherit key;
action = helpers.mkRaw (prefix + actionStr);
options =
{
inherit (cfg.keymaps) silent;
}
// actionProps;
}
);
in
(mkMaps "vim.diagnostic." cfg.keymaps.diagnostic)
++ (mkMaps "vim.lsp.buf." cfg.keymaps.lspBuf)
++ cfg.keymaps.extra;
2021-02-01 15:54:53 +00:00
# Enable all LSP servers
extraConfigLua = ''
-- LSP {{{
do
${cfg.preConfig}
local __lspServers = ${helpers.toLuaObject cfg.enabledServers}
local __lspOnAttach = function(client, bufnr)
${updateCapabilities}
${cfg.onAttach}
end
local __lspCapabilities = function()
capabilities = vim.lsp.protocol.make_client_capabilities()
${cfg.capabilities}
return capabilities
end
local __setup = ${runWrappers cfg.setupWrappers "{
on_attach = __lspOnAttach,
capabilities = __lspCapabilities()
}"}
2021-02-01 15:54:53 +00:00
for i,server in ipairs(__lspServers) do
if type(server) == "string" then
require('lspconfig')[server].setup(__setup)
else
local options = ${runWrappers cfg.setupWrappers "server.extraOptions"}
if options == nil then
options = __setup
else
options = vim.tbl_extend("keep", options, __setup)
end
require('lspconfig')[server.name].setup(options)
end
2021-02-01 15:54:53 +00:00
end
${cfg.postConfig}
2021-02-01 15:54:53 +00:00
end
-- }}}
'';
};
}