From 5c52e8f9e438b6850f2c7a6e4bf3f967a3a699fd Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Wed, 7 May 2025 14:13:13 +0100 Subject: [PATCH] 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`. --- plugins/by-name/rust-tools/default.nix | 1 - plugins/by-name/rustaceanvim/default.nix | 59 ++++++++----------- .../by-name/rustaceanvim/settings-options.nix | 6 +- plugins/by-name/typescript-tools/default.nix | 2 +- plugins/lsp/default.nix | 38 ++++++++---- 5 files changed, 53 insertions(+), 53 deletions(-) diff --git a/plugins/by-name/rust-tools/default.nix b/plugins/by-name/rust-tools/default.nix index 951dcc77..6cb56168 100644 --- a/plugins/by-name/rust-tools/default.nix +++ b/plugins/by-name/rust-tools/default.nix @@ -173,7 +173,6 @@ in server = { inherit (cfg.server) standalone; settings.rust-analyzer = lib.filterAttrs (n: v: n != "standalone") cfg.server; - on_attach = lib.nixvim.mkRaw "__lspOnAttach"; }; } // cfg.extraOptions; in diff --git a/plugins/by-name/rustaceanvim/default.nix b/plugins/by-name/rustaceanvim/default.nix index 2775a063..e81f5b6b 100644 --- a/plugins/by-name/rustaceanvim/default.nix +++ b/plugins/by-name/rustaceanvim/default.nix @@ -53,43 +53,30 @@ lib.nixvim.plugins.mkNeovimPlugin { callSetup = false; hasLuaConfig = false; - extraConfig = - cfg: - mkMerge [ - { - globals.rustaceanvim = cfg.settings; + extraConfig = cfg: { + globals.rustaceanvim = cfg.settings; - assertions = lib.nixvim.mkAssertions "plugins.rustaceanvim" { - assertion = cfg.enable -> !config.plugins.lsp.servers.rust_analyzer.enable; - message = '' - 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. - ''; - }; + assertions = lib.nixvim.mkAssertions "plugins.rustaceanvim" { + assertion = cfg.enable -> !config.plugins.lsp.servers.rust_analyzer.enable; + message = '' + 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. + ''; + }; - # TODO: remove after 24.11 - warnings = lib.nixvim.mkWarnings "plugins.rustaceanvim" { - when = hasAttrByPath [ - "settings" - "server" - "settings" - ] cfg; - message = '' - The `settings.server.settings' option has been renamed to `settings.server.default_settings'. + # TODO: remove after 24.11 + warnings = lib.nixvim.mkWarnings "plugins.rustaceanvim" { + when = hasAttrByPath [ + "settings" + "server" + "settings" + ] cfg; + message = '' + 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: - `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 - ''; - }) - ]; + 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'. + ''; + }; + }; } diff --git a/plugins/by-name/rustaceanvim/settings-options.nix b/plugins/by-name/rustaceanvim/settings-options.nix index 9a41765b..57133d11 100644 --- a/plugins/by-name/rustaceanvim/settings-options.nix +++ b/plugins/by-name/rustaceanvim/settings-options.nix @@ -234,11 +234,7 @@ with lib; ``` ''; - on_attach = helpers.mkNullOrLuaFn '' - Function to call on attach. - If `plugins.lsp` is enabled, it defaults to the Nixvim global `__lspOnAttach` function. - Otherwise it defaults to `null`. - ''; + on_attach = helpers.defaultNullOpts.mkLuaFn null "Function to call when rustaceanvim attaches to a buffer."; cmd = helpers.mkNullOrStrLuaFnOr (with types; listOf str) '' Command and arguments for starting rust-analyzer. diff --git a/plugins/by-name/typescript-tools/default.nix b/plugins/by-name/typescript-tools/default.nix index 04fdb14e..d09d30fe 100644 --- a/plugins/by-name/typescript-tools/default.nix +++ b/plugins/by-name/typescript-tools/default.nix @@ -19,7 +19,7 @@ lib.nixvim.plugins.mkNeovimPlugin { ]; 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 { type = with lib.types; nullOr (attrsOf strLuaFn); diff --git a/plugins/lsp/default.nix b/plugins/lsp/default.nix index 30573b1f..e6851de5 100644 --- a/plugins/lsp/default.nix +++ b/plugins/lsp/default.nix @@ -1,4 +1,4 @@ -{ lib, ... }: +{ lib, config, ... }: let inherit (lib) mkOption types; in @@ -114,6 +114,9 @@ lib.nixvim.plugins.mkNeovimPlugin { 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 = ""; + # 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 { @@ -141,7 +144,7 @@ lib.nixvim.plugins.mkNeovimPlugin { }; }; - extraConfig = cfg: { + extraConfig = cfg: opts: { keymapsOnEvents.LspAttach = let mkMaps = @@ -173,6 +176,27 @@ lib.nixvim.plugins.mkNeovimPlugin { ++ mkMaps "vim.lsp.buf." "Lsp buf" cfg.keymaps.lspBuf ++ 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 = let runWrappers = @@ -188,10 +212,7 @@ lib.nixvim.plugins.mkNeovimPlugin { ${lib.optionalString cfg.inlayHints "vim.lsp.inlay_hint.enable(true)"} 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() capabilities = vim.lsp.protocol.make_client_capabilities() @@ -200,10 +221,7 @@ lib.nixvim.plugins.mkNeovimPlugin { return capabilities end - local __setup = ${runWrappers cfg.setupWrappers "{ - on_attach = _M.lspOnAttach, - capabilities = __lspCapabilities(), - }"} + local __setup = ${runWrappers cfg.setupWrappers "{ capabilities = __lspCapabilities() }"} for i, server in ipairs(__lspServers) do local options = ${runWrappers cfg.setupWrappers "server.extraOptions"}