nvf/modules/neovim/init/lsp.nix
2025-05-20 15:45:04 +01:00

122 lines
3.6 KiB
Nix

{
config,
lib,
...
}: let
inherit (builtins) filter;
inherit (lib.modules) mkIf mkMerge mkDefault;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.types) attrsOf;
inherit (lib.strings) concatLines;
inherit (lib.attrsets) mapAttrsToList attrNames filterAttrs;
inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.languages) lspOptions;
inherit (lib.nvim.dag) entryAnywhere;
inherit (lib.nvim.lua) toLuaObject;
cfg = config.vim.lsp;
lspConfigurations =
mapAttrsToList (
# TODO: Determine the best thing to do about merging in lspconfig
name: value:
/*
lua
*/
''vim.lsp.config["${name}"] = ${toLuaObject value}''
)
cfg.servers;
# Approach 1:
# Create function perhaps called mkLspConfig
# mkLspConfig servers;
# that expands to something like
# vim.lsp.servers = cfg.lsp.servers......
# vim.luaConfigRC.lspconfigMerge = entryAfter ["lsp-servers"] ''vim.lsp.config["${name}"] = vim.tbl_deep_extend("force", lspconfig.${name}, vim.lsp.config["${name}"])''
# Approach 2:
# lspConfigurations =
# mapAttrsToList (
# name: value: ''vim.lsp.config["${name}"] = vim.tbl_deep_extend("force", lspconfig.${name}, ${toLuaObject value})''
# )
# (filterAttrs (n: _: n != "*") cfg.servers);
# Then also need to configure global * settings
# globalConfiguration =
# mapAttrsToList (
# name: value: ''vim.lsp.config["${name}"] = ${toLuaObject value}''
# )
# (filterAttrs (n: _: n == "*") cfg.servers);
enabledServers = filterAttrs (_: u: u.enable) cfg.servers;
in {
options = {
vim.lsp = {
enable = mkEnableOption ''
global LSP functionality for Neovim.
This option controls whether to enable LSP functionality within modules under
{option}`vim.languages`. You do not need to set this to `true` for language
servers defined in {option}`vim.lsp.servers` to take effect, since they are
enabled automatically.
'';
servers = mkOption {
type = attrsOf lspOptions;
default = {};
example = ''
{
"*" = {
root_markers = [".git"];
capabilities = {
textDocument = {
semanticTokens = {
multilineTokenSupport = true;
};
};
};
};
"clangd" = {
filetypes = ["c"];
};
}
'';
description = ''
LSP configurations that will be managed using `vim.lsp.config()` and related
utilities added in Neovim 0.11. LSPs defined here will be added to the
resulting {file}`init.lua` using `vim.lsp.config` and enabled through
`vim.lsp.enable()` API from Neovim below the configuration table.
You may review the generated configuration by running {command}`nvf-print-config`
in a shell. Please see {command}`:help lsp-config` for more details
on the underlying API.
'';
};
};
};
config = mkMerge [
{
vim.lsp.servers."*" = {
capabilities = mkDefault (mkLuaInline "capabilities");
on_attach = mkDefault (mkLuaInline "default_on_attach");
};
}
(mkIf (cfg.servers != {}) {
vim.luaConfigRC.lsp-servers =
entryAnywhere
# Or entryAfter ["lspconfig"] if we go with the second approach
/*
lua
*/
''
${concatLines lspConfigurations}
-- Enable configured LSPs explicitly
vim.lsp.enable(${toLuaObject (filter (name: name != "*") (attrNames enabledServers))});
'';
})
];
}