plugins.lsp: alias onAttach to new lsp.onAttach

This simplifies the impl by doing global on-attach logic in a
`LspAttach` autocmd instead of adding lua lines to each server's
individual `on_attach` callback.

This is effectively a `mkAliasOptionModule` alias, other than the alias
only being applied when `plugins.lsp.enable`.
This commit is contained in:
Matt Sturgeon 2025-05-07 14:13:13 +01:00
parent c26f5c2e31
commit 5c52e8f9e4
No known key found for this signature in database
GPG key ID: 4F91844CED1A8299
5 changed files with 53 additions and 53 deletions

View file

@ -173,7 +173,6 @@ in
server = { server = {
inherit (cfg.server) standalone; inherit (cfg.server) standalone;
settings.rust-analyzer = lib.filterAttrs (n: v: n != "standalone") cfg.server; settings.rust-analyzer = lib.filterAttrs (n: v: n != "standalone") cfg.server;
on_attach = lib.nixvim.mkRaw "__lspOnAttach";
}; };
} // cfg.extraOptions; } // cfg.extraOptions;
in in

View file

@ -53,43 +53,30 @@ lib.nixvim.plugins.mkNeovimPlugin {
callSetup = false; callSetup = false;
hasLuaConfig = false; hasLuaConfig = false;
extraConfig = extraConfig = cfg: {
cfg: globals.rustaceanvim = cfg.settings;
mkMerge [
{
globals.rustaceanvim = cfg.settings;
assertions = lib.nixvim.mkAssertions "plugins.rustaceanvim" { assertions = lib.nixvim.mkAssertions "plugins.rustaceanvim" {
assertion = cfg.enable -> !config.plugins.lsp.servers.rust_analyzer.enable; assertion = cfg.enable -> !config.plugins.lsp.servers.rust_analyzer.enable;
message = '' message = ''
Both `plugins.rustaceanvim.enable` and `plugins.lsp.servers.rust_analyzer.enable` are true. Both `plugins.rustaceanvim.enable` and `plugins.lsp.servers.rust_analyzer.enable` are true.
Disable one of them otherwise you will have multiple clients attached to each buffer. Disable one of them otherwise you will have multiple clients attached to each buffer.
''; '';
}; };
# TODO: remove after 24.11 # TODO: remove after 24.11
warnings = lib.nixvim.mkWarnings "plugins.rustaceanvim" { warnings = lib.nixvim.mkWarnings "plugins.rustaceanvim" {
when = hasAttrByPath [ when = hasAttrByPath [
"settings" "settings"
"server" "server"
"settings" "settings"
] cfg; ] cfg;
message = '' message = ''
The `settings.server.settings' option has been renamed to `settings.server.default_settings'. The `settings.server.settings' option has been renamed to `settings.server.default_settings'.
Note that if you supplied an attrset and not a function you need to set this attr set in: Note that if you supplied an attrset and not a function you need to set this attr set in:
`settings.server.default_settings.rust-analyzer'. `settings.server.default_settings.rust-analyzer'.
''; '';
}; };
} };
# If nvim-lspconfig is enabled:
(mkIf config.plugins.lsp.enable {
# Use the same `on_attach` callback as for the other LSP servers
plugins.rustaceanvim.settings.server.on_attach = mkDefault ''
function(client, bufnr)
return _M.lspOnAttach(client, bufnr)
end
'';
})
];
} }

View file

@ -234,11 +234,7 @@ with lib;
``` ```
''; '';
on_attach = helpers.mkNullOrLuaFn '' on_attach = helpers.defaultNullOpts.mkLuaFn null "Function to call when rustaceanvim attaches to a buffer.";
Function to call on attach.
If `plugins.lsp` is enabled, it defaults to the Nixvim global `__lspOnAttach` function.
Otherwise it defaults to `null`.
'';
cmd = helpers.mkNullOrStrLuaFnOr (with types; listOf str) '' cmd = helpers.mkNullOrStrLuaFnOr (with types; listOf str) ''
Command and arguments for starting rust-analyzer. Command and arguments for starting rust-analyzer.

View file

@ -19,7 +19,7 @@ lib.nixvim.plugins.mkNeovimPlugin {
]; ];
settingsOptions = { settingsOptions = {
on_attach = defaultNullOpts.mkLuaFn "__lspOnAttach" "Lua code to run when tsserver attaches to a buffer."; on_attach = defaultNullOpts.mkLuaFn null "Function to call when tsserver attaches to a buffer.";
handlers = lib.mkOption { handlers = lib.mkOption {
type = with lib.types; nullOr (attrsOf strLuaFn); type = with lib.types; nullOr (attrsOf strLuaFn);

View file

@ -1,4 +1,4 @@
{ lib, ... }: { lib, config, ... }:
let let
inherit (lib) mkOption types; inherit (lib) mkOption types;
in in
@ -114,6 +114,9 @@ lib.nixvim.plugins.mkNeovimPlugin {
type = types.lines; type = types.lines;
description = "A lua function to be run when a new LSP buffer is attached. The argument `client` and `bufnr` is provided."; description = "A lua function to be run when a new LSP buffer is attached. The argument `client` and `bufnr` is provided.";
default = ""; default = "";
# When `plugins.lsp` is enabled, definitions are aliased to `lsp.onAttach`; so read that final value here.
# The other half of this two-way alias is below in `extraConfig`.
apply = value: if config.plugins.lsp.enable then config.lsp.onAttach else value;
}; };
capabilities = mkOption { capabilities = mkOption {
@ -141,7 +144,7 @@ lib.nixvim.plugins.mkNeovimPlugin {
}; };
}; };
extraConfig = cfg: { extraConfig = cfg: opts: {
keymapsOnEvents.LspAttach = keymapsOnEvents.LspAttach =
let let
mkMaps = mkMaps =
@ -173,6 +176,27 @@ lib.nixvim.plugins.mkNeovimPlugin {
++ mkMaps "vim.lsp.buf." "Lsp buf" cfg.keymaps.lspBuf ++ mkMaps "vim.lsp.buf." "Lsp buf" cfg.keymaps.lspBuf
++ cfg.keymaps.extra; ++ cfg.keymaps.extra;
# Alias onAttach definitions to the new impl in the top-level lsp module.
#
# NOTE: While `mkDerivedConfig` creates an alias based on the final `value` and `highestPrio`,
# `mkAliasAndWrapDefinitions` and `mkAliasAndWrapDefsWithPriority` propagates the un-merged
# `definitions`.
#
# This assumes both options have compatible merge functions, but it allows override and order
# priorities to be merged correctly.
#
# E.g:
# lsp.onAttach = mkAfter "world";
# plugins.lsp.onAttach = mkBefore "hello"
# ⇒
# hello
# world
#
# This is equivalent to `mkAliasOptionModule`, except predicated on `plugins.lsp.enable`.
#
# The other half of this two-way alias is above in the option's `apply` function.
lsp.onAttach = lib.modules.mkAliasAndWrapDefsWithPriority lib.id opts.onAttach;
plugins.lsp.luaConfig.content = plugins.lsp.luaConfig.content =
let let
runWrappers = runWrappers =
@ -188,10 +212,7 @@ lib.nixvim.plugins.mkNeovimPlugin {
${lib.optionalString cfg.inlayHints "vim.lsp.inlay_hint.enable(true)"} ${lib.optionalString cfg.inlayHints "vim.lsp.inlay_hint.enable(true)"}
local __lspServers = ${lib.nixvim.toLuaObject cfg.enabledServers} 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)
${cfg.onAttach}
end
local __lspCapabilities = function() local __lspCapabilities = function()
capabilities = vim.lsp.protocol.make_client_capabilities() capabilities = vim.lsp.protocol.make_client_capabilities()
@ -200,10 +221,7 @@ lib.nixvim.plugins.mkNeovimPlugin {
return capabilities return capabilities
end end
local __setup = ${runWrappers cfg.setupWrappers "{ local __setup = ${runWrappers cfg.setupWrappers "{ capabilities = __lspCapabilities() }"}
on_attach = _M.lspOnAttach,
capabilities = __lspCapabilities(),
}"}
for i, server in ipairs(__lspServers) do for i, server in ipairs(__lspServers) do
local options = ${runWrappers cfg.setupWrappers "server.extraOptions"} local options = ${runWrappers cfg.setupWrappers "server.extraOptions"}