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

267 lines
7.9 KiB
Nix
Raw Normal View History

2024-12-17 14:48:03 -03:00
{ lib, ... }:
2024-05-05 19:39:35 +02:00
let
2024-12-17 14:48:03 -03:00
inherit (lib) mkOption types;
2024-05-05 19:39:35 +02:00
in
2024-12-17 14:48:03 -03:00
lib.nixvim.plugins.mkNeovimPlugin {
name = "lsp";
packPathName = "nvim-lspconfig";
package = "nvim-lspconfig";
2021-02-01 15:54:53 +00:00
2024-12-17 14:48:03 -03:00
callSetup = false;
hasSettings = false;
2021-02-01 15:54:53 +00:00
2024-12-17 14:48:03 -03:00
maintainers = [ lib.maintainers.HeitorAugustoLN ];
2024-09-13 22:37:52 -05:00
2024-12-17 14:48:03 -03:00
imports = [ ./language-servers ];
2024-12-17 14:48:03 -03:00
extraOptions = {
keymaps = {
silent = mkOption {
type = types.bool;
description = "Whether nvim-lsp keymaps should be silent";
default = false;
};
2024-12-17 14:48:03 -03:00
diagnostic = mkOption {
type = with types; attrsOf (either str (attrsOf anything));
description = "Mappings for `vim.diagnostic.<action>` functions to be added when an LSP is attached.";
example = {
"<leader>k" = "goto_prev";
"<leader>j" = "goto_next";
};
2024-12-17 14:48:03 -03:00
default = { };
};
2024-03-25 21:39:21 +00:00
2024-12-17 14:48:03 -03:00
lspBuf = mkOption {
type = with types; attrsOf (either str (attrsOf anything));
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";
2024-03-25 21:39:21 +00:00
};
2024-12-17 14:48:03 -03:00
default = { };
};
2024-12-17 14:48:03 -03:00
extra = mkOption {
type = types.listOf lib.nixvim.keymaps.deprecatedMapOptionSubmodule;
apply = map lib.nixvim.keymaps.removeDeprecatedMapAttrs;
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.
'';
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.__raw = "require('telescope.builtin').lsp_definitions";
}
{
key = "K";
action = "<CMD>Lspsaga hover_doc<Enter>";
}
];
default = [ ];
};
};
2021-02-01 15:54:53 +00:00
2024-12-17 14:48:03 -03:00
enabledServers = mkOption {
type =
with types;
listOf (submodule {
options = {
name = mkOption {
type = str;
description = "The server's name";
};
capabilities = mkOption {
type = nullOr (attrsOf bool);
description = "Control resolved capabilities for the language server.";
default = null;
example = {
documentFormattingProvider = false;
};
};
2021-02-01 15:54:53 +00:00
extraOptions = mkOption {
type = attrsOf anything;
description = "Extra options for the server";
2024-12-17 14:48:03 -03:00
};
};
});
2024-12-17 14:48:03 -03:00
description = "A list of enabled LSP servers. Don't use this directly.";
default = [ ];
internal = true;
visible = false;
};
2024-12-17 14:48:03 -03:00
inlayHints = mkOption {
type = types.bool;
default = false;
description = ''
Whether to enable LSP inlay-hints.
Only affects language servers with inlay-hints support.
2024-12-17 14:48:03 -03:00
See [`:h lsp-inlay_hint`](https://neovim.io/doc/user/lsp.html#lsp-inlay_hint).
'';
};
2021-11-23 15:39:57 +01:00
2024-12-17 14:48:03 -03: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.";
default = "";
};
2024-12-17 14:48:03 -03:00
capabilities = mkOption {
type = types.lines;
description = "Lua code that modifies inplace the `capabilities` table.";
default = "";
};
2024-12-17 14:48:03 -03:00
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 = [ ];
};
2024-12-17 14:48:03 -03:00
preConfig = mkOption {
type = types.lines;
description = "Code to be run before loading the LSP. Useful for requiring plugins";
default = "";
2021-02-01 15:54:53 +00:00
};
2024-12-17 14:48:03 -03:00
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
2024-12-17 14:48:03 -03:00
extraConfig = cfg: {
keymapsOnEvents.LspAttach =
let
mkMaps =
prefix: descPrefix:
lib.mapAttrsToList (
key: action:
let
actionStr = action.action or action;
mode = action.mode or "n";
2024-12-17 14:48:03 -03:00
actionProps = lib.optionalAttrs (builtins.isAttrs action) (
builtins.removeAttrs action [
"action"
"mode"
]
2024-12-17 14:48:03 -03:00
);
in
{
inherit key mode;
2024-12-17 14:48:03 -03:00
action = lib.nixvim.mkRaw (prefix + actionStr);
2024-12-17 14:48:03 -03:00
options = {
inherit (cfg.keymaps) silent;
desc = "${descPrefix} ${actionStr}";
} // actionProps;
}
);
in
mkMaps "vim.diagnostic." "Lsp diagnostic" cfg.keymaps.diagnostic
++ mkMaps "vim.lsp.buf." "Lsp buf" cfg.keymaps.lspBuf
++ cfg.keymaps.extra;
2025-04-22 16:49:30 +02:00
# Since https://github.com/nix-community/nixvim/pull/3204, we are now using the native vim.lsp
# API for configuring language servers with nvim-lspconfig.
# For some mysterious reason, `performance.combinePlugins` now prevent language servers from
# being properly configured (missing some keys: `cmd`, `filetypes`, `root_markers` etc.)
performance.combinePlugins.standalonePlugins = [ cfg.package ];
2024-12-17 14:48:03 -03:00
plugins.lsp.onAttach = lib.mkIf cfg.inlayHints ''
-- LSP Inlay Hints {{{
if client.server_capabilities.inlayHintProvider and vim.lsp.inlay_hint then
vim.lsp.inlay_hint.enable(true, { bufnr = bufnr })
end
-- }}}
'';
2024-12-17 14:48:03 -03:00
plugins.lsp.luaConfig.content =
let
runWrappers =
wrappers: s:
if wrappers == [ ] then s else (builtins.head wrappers) (runWrappers (builtins.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} = ${lib.nixvim.toLuaObject server.capabilities.${name}}
'') (builtins.attrNames server.capabilities);
in
''
if client.name == "${server.name}" then
${updates}
end
''
) servers;
in
''
2021-02-01 15:54:53 +00:00
-- LSP {{{
do
${cfg.preConfig}
local __lspServers = ${lib.nixvim.toLuaObject cfg.enabledServers}
-- Adding lspOnAttach function to nixvim module lua table so other plugins can hook into it.
_M.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 = _M.lspOnAttach,
2024-12-17 14:48:03 -03:00
capabilities = __lspCapabilities(),
}"}
2021-02-01 15:54:53 +00:00
2024-12-17 14:48:03 -03:00
for i, server in ipairs(__lspServers) do
2025-04-22 16:49:30 +02:00
vim.lsp.enable(server.name)
2025-04-22 16:49:30 +02:00
vim.lsp.config(server.name, __setup)
if server.extraOptions then
vim.lsp.config(server.name, server.extraOptions)
end
2021-02-01 15:54:53 +00:00
end
${cfg.postConfig}
2021-02-01 15:54:53 +00:00
end
-- }}}
'';
2024-12-17 14:48:03 -03:00
};
2021-02-01 15:54:53 +00:00
}