From bc93d67416d2a8d125828e092f6c70304404ed40 Mon Sep 17 00:00:00 2001 From: sjcobb Date: Tue, 20 May 2025 15:44:57 +0100 Subject: [PATCH] Initialize changes for nix --- lib/languages.nix | 41 ++++++++- modules/neovim/init/lsp.nix | 47 ++++++++-- modules/plugins/languages/nix.nix | 140 ++++++++---------------------- 3 files changed, 116 insertions(+), 112 deletions(-) diff --git a/lib/languages.nix b/lib/languages.nix index c4074144..556c38cf 100644 --- a/lib/languages.nix +++ b/lib/languages.nix @@ -1,9 +1,13 @@ {lib}: let inherit (builtins) isString getAttr; inherit (lib.options) mkOption; - inherit (lib.types) listOf bool str submodule attrsOf anything either nullOr; + inherit (lib.strings) concatStringsSep; + inherit (lib.types) listOf bool str submodule attrsOf anything either nullOr oneOf enum; + inherit (lib.attrsets) attrNames; inherit (lib.nvim.attrsets) mapListToAttrs; inherit (lib.nvim.types) luaInline; + inherit (lib.lists) isList; + inherit (lib) genAttrs recursiveUpdate; in { # TODO: remove diagnosticsToLua = { @@ -34,6 +38,18 @@ in { description = "Turn on ${desc} for enabled languages by default"; }; + # resolveLspOptions + # servers: AttrsOf lspOptions + # selected: AttrsOf lspOptions | List of string keys from servers + # Returns: AttrsOf lspOptions + resolveLspOptions = { + servers, + selected, + }: + if isList selected + then genAttrs selected (name: servers.${name}) + else selected; + lspOptions = submodule { freeformType = attrsOf anything; options = { @@ -77,4 +93,27 @@ in { }; }; }; + + mkLspOption = {servers, ...} @ args: let + serverNames = attrNames servers; + defaultAttrs = { + type = oneOf [ + (attrsOf lib.nvim.languages.lspOptions) + (listOf (enum serverNames)) + ]; + description = '' + Either a full set of selected LSP options as an attribute set, + or a list of server names from: ${concatStringsSep ", " serverNames}. + ''; + default = {}; + example = { + clangd = { + filetypes = ["c"]; + root_markers = ["CMakeLists.txt"]; + }; + }; + }; + cleanedArgs = removeAttrs args ["servers"]; + in + mkOption (recursiveUpdate defaultAttrs cleanedArgs); } diff --git a/modules/neovim/init/lsp.nix b/modules/neovim/init/lsp.nix index b89c3fde..1b22388c 100644 --- a/modules/neovim/init/lsp.nix +++ b/modules/neovim/init/lsp.nix @@ -18,12 +18,36 @@ lspConfigurations = mapAttrsToList ( - name: value: '' - vim.lsp.config["${name}"] = ${toLuaObject value} - '' + # 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 = { @@ -81,13 +105,18 @@ in { } (mkIf (cfg.servers != {}) { - vim.luaConfigRC.lsp-servers = entryAnywhere '' - -- Individual LSP configurations managed by nvf. - ${concatLines lspConfigurations} + 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))}) - ''; + -- Enable configured LSPs explicitly + vim.lsp.enable(${toLuaObject (filter (name: name != "*") (attrNames enabledServers))}); + ''; }) ]; } diff --git a/modules/plugins/languages/nix.nix b/modules/plugins/languages/nix.nix index 29715162..39f2a76b 100644 --- a/modules/plugins/languages/nix.nix +++ b/modules/plugins/languages/nix.nix @@ -2,99 +2,54 @@ config, pkgs, lib, - inputs, ... }: let inherit (builtins) attrNames; inherit (lib) concatStringsSep; + inherit (lib.generators) mkLuaInline; inherit (lib.meta) getExe; inherit (lib.options) mkEnableOption mkOption; inherit (lib.modules) mkIf mkMerge; inherit (lib.lists) isList; - inherit (lib.strings) optionalString; - inherit (lib.types) anything attrsOf enum either listOf nullOr package str oneOf; + inherit (lib.types) enum package; inherit (lib.nvim.types) mkGrammarOption diagnostics; - inherit (lib.nvim.lua) expToLua toLuaObject; - inherit (lib.nvim.languages) lspOptions; + inherit (lib.nvim.lua) expToLua; + inherit (lib.nvim.languages) resolveLspOptions mkLspOption; cfg = config.vim.languages.nix; - useFormat = "on_attach = default_on_attach"; - noFormat = "on_attach = attach_keymaps"; - - defaultServer = "nil"; packageToCmd = package: defaultCmd: if isList package then expToLua package else ''{"${package}/bin/${defaultCmd}"}''; + + formattingCmd = lib.mkIf (cfg.format.enable && cfg.lsp.enable) { + formatting = lib.mkMerge [ + (lib.mkIf (cfg.format.type == "alejandra") { + command = ["${cfg.format.package}/bin/alejandra" "--quiet"]; + }) + (lib.mkIf (cfg.format.type == "nixfmt") { + command = ["${cfg.format.package}/bin/nixfmt"]; + }) + ]; + }; + + defaultServers = ["nil_ls"] servers = { - nil = { - package = inputs.nil.packages.${pkgs.stdenv.system}.nil; - internalFormatter = true; - # lspConfig = '' - # lspconfig.nil_ls.setup{ - # capabilities = capabilities, - # ${ - # if cfg.format.enable - # then useFormat - # else noFormat - # }, - # cmd = ${packageToCmd cfg.lsp.package "nil"}, - # ${optionalString cfg.format.enable '' - # settings = { - # ["nil"] = { - # ${optionalString (cfg.format.type == "alejandra") - # '' - # formatting = { - # command = {"${cfg.format.package}/bin/alejandra", "--quiet"}, - # }, - # ''} - # ${optionalString (cfg.format.type == "nixfmt") - # '' - # formatting = { - # command = {"${cfg.format.package}/bin/nixfmt"}, - # }, - # ''} - # }, - # }, - # ''} - # } - # ''; + nil_ls = { + enable = true; + cmd = ["${pkgs.nil}/bin/nil"]; + settings = { + nil = formattingCmd; + }; }; nixd = { - package = pkgs.nixd; - internalFormatter = true; - # lspConfig = '' - # lspconfig.nixd.setup{ - # capabilities = capabilities, - # ${ - # if cfg.format.enable - # then useFormat - # else noFormat - # }, - # cmd = ${packageToCmd cfg.lsp.package "nixd"}, - # ${optionalString cfg.format.enable '' - # settings = { - # nixd = { - # ${optionalString (cfg.format.type == "alejandra") - # '' - # formatting = { - # command = {"${cfg.format.package}/bin/alejandra", "--quiet"}, - # }, - # ''} - # ${optionalString (cfg.format.type == "nixfmt") - # '' - # formatting = { - # command = {"${cfg.format.package}/bin/nixfmt"}, - # }, - # ''} - # options = ${toLuaObject cfg.lsp.options}, - # }, - # }, - # ''} - # } - # ''; + enable = true; + cmd = ["${pkgs.nixd}/bin/nixd"]; + settings = { + nixd = formattingCmd; + }; }; }; @@ -146,26 +101,9 @@ in { lsp = { enable = mkEnableOption "Nix LSP support" // {default = config.vim.lsp.enable;}; - server = mkOption { - description = "Nix LSP server(s) to use"; - type = listOf oneOf [ - (attrsOf lspOptions) - (enum (attrNames servers)) - ]; - default = defaultServer; - }; - - package = mkOption { - description = "Nix LSP server package, or the command to run as a list of strings"; - example = ''[lib.getExe pkgs.jdt-language-server "-data" "~/.cache/jdtls/workspace"]''; - type = either package (listOf str); - default = servers.${cfg.lsp.server}.package; - }; - - options = mkOption { - type = nullOr (attrsOf anything); - default = null; - description = "Options to pass to nixd LSP server"; + servers = mkLspOption { + inherit servers; + default = defaultServers; }; }; @@ -206,13 +144,6 @@ in { ${concatStringsSep ", " (attrNames formats)} ''; } - { - assertion = cfg.lsp.server != "rnix"; - message = '' - rnix-lsp has been archived upstream. Please use one of the following available language servers: - ${concatStringsSep ", " (attrNames servers)} - ''; - } ]; } @@ -222,10 +153,15 @@ in { }) (mkIf cfg.lsp.enable { - vim.lsp.servers = cfg.lsp.server; + # TODO: Map this to include lspconfig stuff so that we can do + vim.lsp.servers = resolveLspOptions { + inherit servers; + selected = cfg.lsp.servers; + }; }) - (mkIf (cfg.format.enable && (!cfg.lsp.enable || !servers.${cfg.lsp.server}.internalFormatter)) { + # TODO: Figure out what do here. This is not necessarily correct as other lsps might not have formatting by default + (mkIf (cfg.format.enable && !cfg.lsp.enable) { vim.formatter.conform-nvim = { enable = true; setupOpts.formatters_by_ft.nix = [cfg.format.type];