diff --git a/.github/typos.toml b/.github/typos.toml index 378d3e2d..2cd18dde 100644 --- a/.github/typos.toml +++ b/.github/typos.toml @@ -5,8 +5,6 @@ default.extend-ignore-words-re = [ "befores", "annote", "viw", - "edn", - "esy", "BA", # somehow "BANanaD3V" is valid, but BA is not... ] diff --git a/lib/languages.nix b/lib/languages.nix index d66880a1..f4ab1cca 100644 --- a/lib/languages.nix +++ b/lib/languages.nix @@ -1,7 +1,7 @@ {lib}: let inherit (builtins) isString getAttr; inherit (lib.options) mkOption; - inherit (lib.types) listOf bool str submodule attrsOf anything either nullOr uniq; + inherit (lib.types) listOf bool str submodule attrsOf anything either nullOr oneOf; inherit (lib.nvim.attrsets) mapListToAttrs; inherit (lib.nvim.types) luaInline; in { @@ -62,7 +62,7 @@ in { }; cmd = mkOption { - type = nullOr (either luaInline (uniq (listOf str))); + type = nullOr (either luaInline (listOf str)); default = null; description = "Command used to start the LSP server"; }; diff --git a/lib/types/custom.nix b/lib/types/custom.nix index ae509f59..c42cd2ce 100644 --- a/lib/types/custom.nix +++ b/lib/types/custom.nix @@ -1,8 +1,7 @@ {lib}: let inherit (lib.options) mergeEqualOption; - inherit (lib.lists) singleton; inherit (lib.strings) isString stringLength match; - inherit (lib.types) listOf mkOptionType coercedTo; + inherit (lib.types) listOf mkOptionType; in { mergelessListOf = elemType: let super = listOf elemType; @@ -28,6 +27,4 @@ in { description = "RGB color in hex format"; check = v: isString v && (match "#?[0-9a-fA-F]{6}" v) != null; }; - - singleOrListOf = t: coercedTo t singleton (listOf t); } diff --git a/lib/types/default.nix b/lib/types/default.nix index c91473a2..044a8221 100644 --- a/lib/types/default.nix +++ b/lib/types/default.nix @@ -10,5 +10,5 @@ in { inherit (typesDag) dagOf; inherit (typesPlugin) pluginsOpt extraPluginType mkPluginSetupOption luaInline pluginType borderType; inherit (typesLanguage) diagnostics mkGrammarOption; - inherit (customTypes) char hexColor mergelessListOf singleOrListOf; + inherit (customTypes) char hexColor mergelessListOf; } diff --git a/modules/extra/deprecations.nix b/modules/extra/deprecations.nix index 77f4bcc6..0a5733ab 100644 --- a/modules/extra/deprecations.nix +++ b/modules/extra/deprecations.nix @@ -1,6 +1,5 @@ {lib, ...}: let - inherit (builtins) head warn; - inherit (lib.modules) mkRemovedOptionModule mkRenamedOptionModule doRename; + inherit (lib.modules) mkRemovedOptionModule mkRenamedOptionModule; inherit (lib.lists) concatLists; inherit (lib.nvim.config) batchRenameOptions; @@ -21,27 +20,6 @@ # 2025-02-07 scrollOffset = "scrolloff"; }; - - mkRemovedLspOpt = lang: (mkRemovedOptionModule ["vim" "languages" lang "lsp" "opts"] '' - `vim.languages.${lang}.lsp.opts` is now moved to `vim.lsp.servers..init_options` - ''); - - mkRemovedLspPackage = lang: (mkRemovedOptionModule ["vim" "languages" lang "lsp" "package"] '' - `vim.languages.${lang}.lsp.package` is now moved to `vim.lsp.servers..cmd` - ''); - - mkRenamedLspServer = lang: - doRename - { - from = ["vim" "languages" lang "lsp" "server"]; - to = ["vim" "languages" lang "lsp" "servers"]; - visible = false; - warn = true; - use = x: - warn - "Obsolete option `vim.languages.${lang}.lsp.server` used, use `vim.languages.${lang}.lsp.servers` instead." - (head x); - }; in { imports = concatLists [ [ @@ -142,123 +120,6 @@ in { in 'vim.clipboard.registers'. Please see the documentation for the new module for more details, or open an issue if you are confused. '') - - # 2025-07-12 - (mkRenamedLspServer "assembly") - - (mkRenamedLspServer "astro") - (mkRemovedLspPackage "astro") - - (mkRenamedLspServer "bash") - (mkRemovedLspPackage "bash") - - (mkRemovedLspOpt "clang") - (mkRemovedLspPackage "clang") - (mkRenamedLspServer "clang") - - (mkRemovedLspPackage "clojure") - - (mkRenamedLspServer "csharp") - (mkRemovedLspPackage "csharp") - - (mkRenamedLspServer "css") - (mkRemovedLspPackage "css") - - (mkRemovedLspPackage "cue") - - (mkRenamedLspServer "dart") - (mkRemovedLspPackage "dart") - (mkRemovedLspOpt "dart") - - (mkRenamedLspServer "elixir") - (mkRemovedLspPackage "elixir") - - (mkRenamedLspServer "fsharp") - (mkRemovedLspPackage "fsharp") - - (mkRenamedLspServer "gleam") - (mkRemovedLspPackage "gleam") - - (mkRenamedLspServer "go") - (mkRemovedLspPackage "go") - - (mkRemovedLspPackage "haskell") - - (mkRemovedLspPackage "hcl") - - (mkRenamedLspServer "helm") - (mkRemovedLspPackage "helm") - - (mkRemovedLspPackage "java") - - (mkRenamedLspServer "julia") - (mkRemovedLspPackage "julia") - - (mkRemovedLspPackage "kotlin") - - (mkRemovedLspPackage "lua") - - (mkRenamedLspServer "markdown") - (mkRemovedLspPackage "markdown") - - (mkRenamedLspServer "nim") - (mkRemovedLspPackage "nim") - - (mkRenamedLspServer "nix") - (mkRemovedLspPackage "nix") - (mkRemovedOptionModule ["vim" "languages" "nix" "lsp" "options"] '' - `vim.languages.nix.lsp.options` has been moved to `vim.lsp.servers..init_options`. - '') - - (mkRenamedLspServer "nu") - (mkRemovedLspPackage "nu") - - (mkRenamedLspServer "ocaml") - (mkRemovedLspPackage "ocaml") - - (mkRenamedLspServer "odin") - (mkRemovedLspPackage "odin") - - (mkRenamedLspServer "php") - (mkRemovedLspPackage "php") - - (mkRenamedLspServer "python") - (mkRemovedLspPackage "python") - - (mkRenamedLspServer "r") - (mkRemovedLspPackage "r") - - (mkRenamedLspServer "ruby") - (mkRemovedLspPackage "ruby") - - (mkRenamedLspServer "sql") - (mkRemovedLspPackage "sql") - - (mkRenamedLspServer "svelte") - (mkRemovedLspPackage "svelte") - - (mkRenamedLspServer "tailwind") - (mkRemovedLspPackage "tailwind") - - (mkRemovedLspPackage "terraform") - - (mkRenamedLspServer "ts") - (mkRemovedLspPackage "ts") - - (mkRenamedLspServer "typst") - (mkRemovedLspPackage "typst") - - (mkRenamedLspServer "vala") - (mkRemovedLspPackage "vala") - - (mkRenamedLspServer "wgsl") - (mkRemovedLspPackage "wgsl") - - (mkRenamedLspServer "yaml") - (mkRemovedLspPackage "yaml") - - (mkRenamedLspServer "zig") - (mkRemovedLspPackage "zig") ] # Migrated via batchRenameOptions. Further batch renames must be below this line. diff --git a/modules/plugins/languages/asm.nix b/modules/plugins/languages/asm.nix index 9d296755..c0887d77 100644 --- a/modules/plugins/languages/asm.nix +++ b/modules/plugins/languages/asm.nix @@ -7,8 +7,8 @@ inherit (builtins) attrNames; inherit (lib.options) mkEnableOption mkOption; inherit (lib.modules) mkIf mkMerge; - inherit (lib.types) enum; - inherit (lib.nvim.types) mkGrammarOption singleOrListOf; + inherit (lib.types) package enum listOf; + inherit (lib.nvim.types) mkGrammarOption; inherit (lib.meta) getExe; inherit (lib.nvim.attrsets) mapListToAttrs; @@ -34,7 +34,7 @@ in { lsp = { enable = mkEnableOption "Assembly LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "Assembly LSP server to use"; }; diff --git a/modules/plugins/languages/astro.nix b/modules/plugins/languages/astro.nix index a16f286e..35de328b 100644 --- a/modules/plugins/languages/astro.nix +++ b/modules/plugins/languages/astro.nix @@ -7,10 +7,12 @@ inherit (builtins) attrNames; inherit (lib.options) mkEnableOption mkOption; inherit (lib.modules) mkIf mkMerge; + inherit (lib.lists) isList; inherit (lib.meta) getExe; - inherit (lib.types) enum package; + inherit (lib.types) enum either listOf package str; + inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.attrsets) mapListToAttrs; - inherit (lib.nvim.types) mkGrammarOption diagnostics singleOrListOf; + inherit (lib.nvim.types) mkGrammarOption diagnostics; inherit (lib.generators) mkLuaInline; cfg = config.vim.languages.astro; @@ -89,7 +91,7 @@ in { lsp = { enable = mkEnableOption "Astro LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "Astro LSP server to use"; }; diff --git a/modules/plugins/languages/bash.nix b/modules/plugins/languages/bash.nix index 4597666a..e34edccb 100644 --- a/modules/plugins/languages/bash.nix +++ b/modules/plugins/languages/bash.nix @@ -5,12 +5,14 @@ ... }: let inherit (builtins) attrNames; - inherit (lib.options) mkOption mkEnableOption; + inherit (lib.options) mkOption mkEnableOption literalExpression; inherit (lib.meta) getExe; inherit (lib.modules) mkIf mkMerge; - inherit (lib.types) enum package bool; + inherit (lib.lists) isList; + inherit (lib.types) enum either package listOf str bool; inherit (lib.generators) mkLuaInline; - inherit (lib.nvim.types) diagnostics mkGrammarOption singleOrListOf; + inherit (lib.nvim.types) diagnostics mkGrammarOption; + inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.attrsets) mapListToAttrs; cfg = config.vim.languages.bash; @@ -55,7 +57,7 @@ in { lsp = { enable = mkEnableOption "Bash LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "Bash LSP server to use"; }; diff --git a/modules/plugins/languages/clang.nix b/modules/plugins/languages/clang.nix index 487bc151..2db178e9 100644 --- a/modules/plugins/languages/clang.nix +++ b/modules/plugins/languages/clang.nix @@ -5,143 +5,47 @@ ... }: let inherit (builtins) attrNames; + inherit (lib.lists) isList; + inherit (lib.strings) optionalString; inherit (lib.options) mkEnableOption mkOption; - inherit (lib.types) bool enum package; - inherit (lib.meta) getExe; + inherit (lib.types) bool enum package either listOf str nullOr; inherit (lib.modules) mkIf mkMerge; - inherit (lib.generators) mkLuaInline; - inherit (lib.nvim.types) mkGrammarOption singleOrListOf; - inherit (lib.nvim.attrsets) mapListToAttrs; + inherit (lib.nvim.lua) expToLua; + inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.dag) entryAfter; + packageToCmd = package: defaultCmd: + if isList cfg.lsp.package + then expToLua cfg.lsp.package + else ''{ "${cfg.lsp.package}/bin/${defaultCmd}" }''; + cfg = config.vim.languages.clang; - defaultServers = ["clangd"]; + defaultServer = "clangd"; servers = { ccls = { - cmd = [(getExe pkgs.ccls)]; - filetypes = ["c" "cpp" "objc" "objcpp" "cuda"]; - offset_encoding = "utf-32"; - root_markers = ["compile_commands.json" ".ccls" ".git"]; - workspace_required = true; - on_attach = mkLuaInline '' - function(client, bufnr) - default_on_attach(client, bufnr) - - local function switch_source_header(bufnr) - local method_name = "textDocument/switchSourceHeader" - local params = vim.lsp.util.make_text_document_params(bufnr) - client:request(method_name, params, function(err, result) - if err then - error(tostring(err)) - end - if not result then - vim.notify('corresponding file cannot be determined') - return - end - vim.cmd.edit(vim.uri_to_fname(result)) - end, bufnr) - end - - vim.api.nvim_buf_create_user_command( - bufnr, - "LspCclsSwitchSourceHeader", - function(arg) - switch_source_header(client, 0) - end, - {desc = "Switch between source/header"} - ) - end + package = pkgs.ccls; + lspConfig = '' + lspconfig.ccls.setup{ + capabilities = capabilities; + on_attach=default_on_attach; + cmd = ${packageToCmd cfg.lsp.package "ccls"}; + ${optionalString (cfg.lsp.opts != null) "init_options = ${cfg.lsp.opts}"} + } ''; }; - clangd = { - cmd = ["${pkgs.clang-tools}/bin/clangd"]; - filetypes = ["c" "cpp" "objc" "objcpp" "cuda" "proto"]; - root_markers = [ - ".clangd" - ".clang-tidy" - ".clang-format" - "compile_commands.json" - "compile_flags.txt" - "configure.ac" - ".git" - ]; - capabilities = { - textDocument = { - completion = { - editsNearCursor = true; - }; - }; - offsetEncoding = ["utf-8" "utf-16"]; - }; - on_attach = mkLuaInline '' - function(client, bufnr) - default_on_attach(client, bufnr) - - local function switch_source_header(bufnr) - local method_name = "textDocument/switchSourceHeader" - local client = vim.lsp.get_clients({ bufnr = bufnr, name = "clangd", })[1] - if not client then - return vim.notify(('method %s is not supported by any servers active on the current buffer'):format(method_name)) - end - local params = vim.lsp.util.make_text_document_params(bufnr) - client.request(method_name, params, function(err, result) - if err then - error(tostring(err)) - end - if not result then - vim.notify('corresponding file cannot be determined') - return - end - vim.cmd.edit(vim.uri_to_fname(result)) - end, bufnr) - end - - local function symbol_info() - local bufnr = vim.api.nvim_get_current_buf() - local clangd_client = vim.lsp.get_clients({ bufnr = bufnr, name = "clangd" })[1] - if not clangd_client or not clangd_client.supports_method 'textDocument/symbolInfo' then - return vim.notify('Clangd client not found', vim.log.levels.ERROR) - end - local win = vim.api.nvim_get_current_win() - local params = vim.lsp.util.make_position_params(win, clangd_client.offset_encoding) - clangd_client:request('textDocument/symbolInfo', params, function(err, res) - if err or #res == 0 then - -- Clangd always returns an error, there is not reason to parse it - return - end - local container = string.format('container: %s', res[1].containerName) ---@type string - local name = string.format('name: %s', res[1].name) ---@type string - vim.lsp.util.open_floating_preview({ name, container }, "", { - height = 2, - width = math.max(string.len(name), string.len(container)), - focusable = false, - focus = false, - border = 'single', - title = 'Symbol Info', - }) - end, bufnr) - end - - vim.api.nvim_buf_create_user_command( - bufnr, - "ClangdSwitchSourceHeader", - function(arg) - switch_source_header(0) - end, - {desc = "Switch between source/header"} - ) - - vim.api.nvim_buf_create_user_command( - bufnr, - "ClangdShowSymbolInfo", - function(arg) - symbol_info() - end, - {desc = "Show symbol info"} - ) - end + package = pkgs.clang-tools; + lspConfig = '' + local clangd_cap = capabilities + -- use same offsetEncoding as null-ls + clangd_cap.offsetEncoding = {"utf-16"} + lspconfig.clangd.setup{ + capabilities = clangd_cap; + on_attach=default_on_attach; + cmd = ${packageToCmd cfg.lsp.package "clangd"}; + ${optionalString (cfg.lsp.opts != null) "init_options = ${cfg.lsp.opts}"} + } ''; }; }; @@ -196,10 +100,23 @@ in { lsp = { enable = mkEnableOption "clang LSP support" // {default = config.vim.lsp.enable;}; - servers = mkOption { + server = mkOption { description = "The clang LSP server to use"; - type = singleOrListOf (enum (attrNames servers)); - default = defaultServers; + type = enum (attrNames servers); + default = defaultServer; + }; + + package = mkOption { + description = "clang 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; + }; + + opts = mkOption { + description = "Options to pass to clang LSP server"; + type = nullOr str; + default = null; }; }; @@ -233,12 +150,9 @@ in { }) (mkIf cfg.lsp.enable { - vim.lsp.servers = - mapListToAttrs (name: { - inherit name; - value = servers.${name}; - }) - cfg.lsp.servers; + vim.lsp.lspconfig.enable = true; + + vim.lsp.lspconfig.sources.clang-lsp = servers.${cfg.lsp.server}.lspConfig; }) (mkIf cfg.dap.enable { diff --git a/modules/plugins/languages/csharp.nix b/modules/plugins/languages/csharp.nix index a9708cae..49ae4985 100644 --- a/modules/plugins/languages/csharp.nix +++ b/modules/plugins/languages/csharp.nix @@ -5,16 +5,14 @@ options, ... }: let - inherit (builtins) attrNames concatMap; + inherit (builtins) attrNames; inherit (lib.options) mkEnableOption mkOption; - inherit (lib.types) enum; + inherit (lib.types) either listOf package str enum; inherit (lib.modules) mkIf mkMerge; - inherit (lib.meta) getExe; - inherit (lib.generators) mkLuaInline; + inherit (lib.lists) isList; inherit (lib.strings) optionalString; - inherit (lib.nvim.types) mkGrammarOption singleOrListOf; - inherit (lib.nvim.lua) toLuaObject; - inherit (lib.nvim.attrsets) mapListToAttrs; + inherit (lib.nvim.types) mkGrammarOption; + inherit (lib.nvim.lua) expToLua; lspKeyConfig = config.vim.lsp.mappings; lspKeyOptions = options.vim.lsp.mappings; @@ -27,104 +25,52 @@ # Omnisharp doesn't have colors in popup docs for some reason, and I've also # seen mentions of it being way slower, so until someone finds missing # functionality, this will be the default. - defaultServers = ["csharp_ls"]; + defaultServer = "csharp_ls"; servers = { omnisharp = { - cmd = mkLuaInline '' - { - ${toLuaObject (getExe pkgs.omnisharp-roslyn)}, - '-z', -- https://github.com/OmniSharp/omnisharp-vscode/pull/4300 - '--hostPID', - tostring(vim.fn.getpid()), - 'DotNet:enablePackageRestore=false', - '--encoding', - 'utf-8', - '--languageserver', - } - ''; - filetypes = ["cs" "vb"]; - root_markers = [".sln" ".csproj" "omnisharp.json" "function.json"]; - init_options = {}; - capabilities = { - workspace = { - workspaceFolders = false; # https://github.com/OmniSharp/omnisharp-roslyn/issues/909 - }; - }; - on_attach = mkLuaInline '' - function(client, bufnr) - default_on_attach(client, bufnr) + package = pkgs.omnisharp-roslyn; + internalFormatter = true; + lspConfig = '' + lspconfig.omnisharp.setup { + capabilities = capabilities, + on_attach = function(client, bufnr) + default_on_attach(client, bufnr) + local oe = require("omnisharp_extended") ${mkLspBinding "goToDefinition" "oe.lsp_definition"} ${mkLspBinding "goToType" "oe.lsp_type_definition"} ${mkLspBinding "listReferences" "oe.lsp_references"} ${mkLspBinding "listImplementations" "oe.lsp_implementation"} - end + end, + cmd = ${ + if isList cfg.lsp.package + then expToLua cfg.lsp.package + else "{'${cfg.lsp.package}/bin/OmniSharp'}" + } + } ''; - settings = { - FormattingOptions = { - # Enables support for reading code style, naming convention and analyzer - # settings from .editorconfig. - EnableEditorConfigSupport = true; - # Specifies whether 'using' directives should be grouped and sorted during - # document formatting. - OrganizeImports = null; - }; - MsBuild = { - # If true, MSBuild project system will only load projects for files that - # were opened in the editor. This setting is useful for big C# codebases - # and allows for faster initialization of code navigation features only - # for projects that are relevant to code that is being edited. With this - # setting enabled OmniSharp may load fewer projects and may thus display - # incomplete reference lists for symbols. - LoadProjectsOnDemand = null; - }; - RoslynExtensionsOptions = { - # Enables support for roslyn analyzers, code fixes and rulesets. - EnableAnalyzersSupport = null; - # Enables support for showing unimported types and unimported extension - # methods in completion lists. When committed, the appropriate using - # directive will be added at the top of the current file. This option can - # have a negative impact on initial completion responsiveness; - # particularly for the first few completion sessions after opening a - # solution. - EnableImportCompletion = null; - # Only run analyzers against open files when 'enableRoslynAnalyzers' is - # true - AnalyzeOpenDocumentsOnly = null; - # Enables the possibility to see the code in external nuget dependencies - EnableDecompilationSupport = null; - }; - RenameOptions = { - RenameInComments = null; - RenameOverloads = null; - RenameInStrings = null; - }; - Sdk = { - # Specifies whether to include preview versions of the .NET SDK when - # determining which version to use for project loading. - IncludePrereleases = true; - }; - }; }; csharp_ls = { - cmd = [(lib.getExe pkgs.csharp-ls)]; - filetypes = ["cs"]; - root_dir = mkLuaInline '' - function(bufnr, on_dir) - local function find_root_pattern(fname, lua_pattern) - return vim.fs.root(0, function(name, path) - return name:match(lua_pattern) - end) - end + package = pkgs.csharp-ls; + internalFormatter = true; + lspConfig = '' + local extended_handler = require("csharpls_extended").handler - local fname = vim.api.nvim_buf_get_name(bufnr) - on_dir(find_root_pattern(fname, "%.sln$") or find_root_pattern(fname, "%.csproj$")) - end + lspconfig.csharp_ls.setup { + capabilities = capabilities, + on_attach = default_on_attach, + handlers = { + ["textDocument/definition"] = extended_handler, + ["textDocument/typeDefinition"] = extended_handler + }, + cmd = ${ + if isList cfg.lsp.package + then expToLua cfg.lsp.package + else "{'${cfg.lsp.package}/bin/csharp-ls'}" + } + } ''; - init_options = { - AutomaticWorkspaceInit = true; - }; }; }; @@ -146,10 +92,16 @@ in { lsp = { enable = mkEnableOption "C# LSP support" // {default = config.vim.lsp.enable;}; - servers = mkOption { + server = mkOption { description = "C# LSP server to use"; - type = singleOrListOf (enum (attrNames servers)); - default = defaultServers; + type = enum (attrNames servers); + default = defaultServer; + }; + + package = mkOption { + description = "C# LSP server package, or the command to run as a list of strings"; + type = either package (listOf str); + default = servers.${cfg.lsp.server}.package; }; }; }; @@ -162,13 +114,9 @@ in { }) (mkIf cfg.lsp.enable { - vim.startPlugins = concatMap (server: extraServerPlugins.${server}) cfg.lsp.servers; - vim.lsp.servers = - mapListToAttrs (name: { - inherit name; - value = servers.${name}; - }) - cfg.lsp.servers; + vim.startPlugins = extraServerPlugins.${cfg.lsp.server} or []; + vim.lsp.lspconfig.enable = true; + vim.lsp.lspconfig.sources.csharp-lsp = servers.${cfg.lsp.server}.lspConfig; }) ]); } diff --git a/modules/plugins/languages/css.nix b/modules/plugins/languages/css.nix index 2d767ffc..1075bbc7 100644 --- a/modules/plugins/languages/css.nix +++ b/modules/plugins/languages/css.nix @@ -8,25 +8,34 @@ inherit (lib.options) mkEnableOption mkOption; inherit (lib.meta) getExe; inherit (lib.modules) mkIf mkMerge; - inherit (lib.types) enum package; - inherit (lib.nvim.types) mkGrammarOption singleOrListOf; - inherit (lib.nvim.attrsets) mapListToAttrs; + inherit (lib.lists) isList; + inherit (lib.types) enum either listOf package str; + inherit (lib.nvim.types) mkGrammarOption; + inherit (lib.nvim.lua) expToLua; cfg = config.vim.languages.css; - defaultServer = ["cssls"]; + defaultServer = "vscode-langservers-extracted"; servers = { - cssls = { - cmd = ["${pkgs.vscode-langservers-extracted}/bin/vscode-css-language-server" "--stdio"]; - filetypes = ["css" "scss" "less"]; - # needed to enable formatting - init_options = {provideFormatter = true;}; - root_markers = [".git" "package.json"]; - settings = { - css.validate = true; - scss.validate = true; - less.validate = true; - }; + vscode-langservers-extracted = { + package = pkgs.vscode-langservers-extracted; + lspConfig = '' + -- enable (broadcasting) snippet capability for completion + -- see + local css_capabilities = vim.lsp.protocol.make_client_capabilities() + css_capabilities.textDocument.completion.completionItem.snippetSupport = true + + -- cssls setup + lspconfig.cssls.setup { + capabilities = css_capabilities; + on_attach = default_on_attach; + cmd = ${ + if isList cfg.lsp.package + then expToLua cfg.lsp.package + else ''{"${cfg.lsp.package}/bin/vscode-css-language-server", "--stdio"}'' + } + } + ''; }; }; @@ -73,10 +82,17 @@ in { lsp = { enable = mkEnableOption "CSS LSP support" // {default = config.vim.lsp.enable;}; - servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); - default = defaultServer; + server = mkOption { description = "CSS LSP server to use"; + type = enum (attrNames servers); + default = defaultServer; + }; + + package = mkOption { + description = "CSS 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; }; }; @@ -104,12 +120,8 @@ in { }) (mkIf cfg.lsp.enable { - vim.lsp.servers = - mapListToAttrs (name: { - inherit name; - value = servers.${name}; - }) - cfg.lsp.servers; + vim.lsp.lspconfig.enable = true; + vim.lsp.lspconfig.sources.css-lsp = servers.${cfg.lsp.server}.lspConfig; }) (mkIf cfg.format.enable { diff --git a/modules/plugins/languages/cue.nix b/modules/plugins/languages/cue.nix index a22ff91c..bd446cbf 100644 --- a/modules/plugins/languages/cue.nix +++ b/modules/plugins/languages/cue.nix @@ -4,17 +4,11 @@ lib, ... }: let - inherit (lib.options) mkEnableOption; - inherit (lib.meta) getExe; + inherit (lib.options) mkEnableOption mkOption; inherit (lib.modules) mkIf mkMerge; + inherit (lib.types) package; inherit (lib.nvim.types) mkGrammarOption; - lspOptions = { - cmd = [(getExe pkgs.cue) "lsp"]; - filetypes = ["cue"]; - root_markers = ["cue.mod" ".git"]; - }; - cfg = config.vim.languages.cue; in { options.vim.languages.cue = { @@ -28,6 +22,12 @@ in { lsp = { enable = mkEnableOption "CUE LSP support" // {default = config.vim.lsp.enable;}; + + package = mkOption { + type = package; + default = pkgs.cue; + description = "cue lsp implementation"; + }; }; }; @@ -38,7 +38,14 @@ in { }) (mkIf cfg.lsp.enable { - vim.lsp.servers.cue = lspOptions; + vim.lsp.lspconfig.enable = true; + vim.lsp.lspconfig.sources.cue-lsp = '' + lspconfig.cue.setup { + capabilities = capabilities, + on_attach = default_on_attach, + cmd = {"${cfg.lsp.package}/bin/cue", "lsp"}, + } + ''; }) ]); } diff --git a/modules/plugins/languages/dart.nix b/modules/plugins/languages/dart.nix index 52dcd560..de267e7c 100644 --- a/modules/plugins/languages/dart.nix +++ b/modules/plugins/languages/dart.nix @@ -8,10 +8,12 @@ inherit (lib.modules) mkIf mkMerge; inherit (lib.meta) getExe; inherit (lib.trivial) boolToString; + inherit (lib.lists) isList; inherit (lib.options) mkEnableOption mkOption; - inherit (lib.types) enum package nullOr str bool; + inherit (lib.types) enum either listOf package nullOr str bool; inherit (lib.strings) optionalString; - inherit (lib.nvim.types) mkGrammarOption singleOrListOf; + inherit (lib.nvim.lua) expToLua; + inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.dag) entryAfter; inherit (lib.nvim.attrsets) mapListToAttrs; @@ -52,7 +54,7 @@ in { lsp = { enable = mkEnableOption "Dart LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "Dart LSP server to use"; }; diff --git a/modules/plugins/languages/elixir.nix b/modules/plugins/languages/elixir.nix index 20d6c668..5204c96b 100644 --- a/modules/plugins/languages/elixir.nix +++ b/modules/plugins/languages/elixir.nix @@ -7,10 +7,12 @@ inherit (builtins) attrNames; inherit (lib.options) mkEnableOption mkOption; inherit (lib.modules) mkIf mkMerge; + inherit (lib.lists) isList; inherit (lib.meta) getExe; - inherit (lib.types) enum package; + inherit (lib.types) enum either listOf package str; inherit (lib.generators) mkLuaInline; - inherit (lib.nvim.types) mkGrammarOption singleOrListOf; + inherit (lib.nvim.types) mkGrammarOption; + inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.dag) entryAnywhere; inherit (lib.nvim.attrsets) mapListToAttrs; @@ -61,7 +63,7 @@ in { lsp = { enable = mkEnableOption "Elixir LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "Elixir LSP server to use"; }; diff --git a/modules/plugins/languages/fsharp.nix b/modules/plugins/languages/fsharp.nix index 9ead9a48..6ed0ccab 100644 --- a/modules/plugins/languages/fsharp.nix +++ b/modules/plugins/languages/fsharp.nix @@ -6,48 +6,29 @@ }: let inherit (builtins) attrNames; inherit (lib.options) mkEnableOption mkOption; - inherit (lib.types) package enum; + inherit (lib.types) either listOf package str enum; inherit (lib.meta) getExe; inherit (lib.modules) mkIf mkMerge; - inherit (lib.generators) mkLuaInline; - inherit (lib.nvim.types) mkGrammarOption singleOrListOf; - inherit (lib.nvim.attrsets) mapListToAttrs; + inherit (lib.lists) isList; + inherit (lib.nvim.types) mkGrammarOption; + inherit (lib.nvim.lua) expToLua; - defaultServer = ["fsautocomplete"]; + defaultServer = "fsautocomplete"; servers = { fsautocomplete = { - cmd = [(getExe pkgs.fsautocomplete) "--adaptive-lsp-server-enabled"]; - filetypes = ["fsharp"]; - root_dir = mkLuaInline '' - function(bufnr, on_dir) - on_dir(vim.fs.root(bufnr, function(name, path) - return name == ".git" or name:match("%.sln$") or name:match("%.fsproj$") - end)) - end + package = pkgs.fsautocomplete; + internalFormatter = false; + lspConfig = '' + lspconfig.fsautocomplete.setup { + capabilities = capabilities; + on_attach = default_on_attach; + cmd = ${ + if isList cfg.lsp.package + then expToLua cfg.lsp.package + else "{'${cfg.lsp.package}/bin/fsautocomplete'}" + }, + } ''; - init_options = { - AutomaticWorkspaceInit = true; - }; - settings = { - FSharp = { - keywordsAutocomplete = true; - ExternalAutocomplete = false; - Linter = true; - UnionCaseStubGeneration = true; - UnionCaseStubGenerationBody = ''failwith "Not Implemented"''; - RecordStubGeneration = true; - RecordStubGenerationBody = ''failwith "Not Implemented"''; - InterfaceStubGeneration = true; - InterfaceStubGenerationObjectIdentifier = "this"; - InterfaceStubGenerationMethodBody = ''failwith "Not Implemented"''; - UnusedOpensAnalyzer = true; - UnusedDeclarationsAnalyzer = true; - UseSdkScripts = true; - SimplifyNameAnalyzer = true; - ResolveNamespaces = true; - EnableReferenceCodeLens = true; - }; - }; }; }; @@ -71,11 +52,18 @@ in { lsp = { enable = mkEnableOption "F# LSP support" // {default = config.vim.lsp.enable;}; - servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + server = mkOption { + type = enum (attrNames servers); default = defaultServer; description = "F# LSP server to use"; }; + + package = mkOption { + type = either package (listOf str); + default = servers.${cfg.lsp.server}.package; + example = ''[lib.getExe pkgs.fsautocomplete "--state-directory" "~/.cache/fsautocomplete"]''; + description = "F# LSP server package, or the command to run as a list of strings"; + }; }; format = { enable = mkEnableOption "F# formatting" // {default = config.vim.languages.enableFormat;}; @@ -102,12 +90,8 @@ in { }) (mkIf cfg.lsp.enable { - vim.lsp.servers = - mapListToAttrs (name: { - inherit name; - value = servers.${name}; - }) - cfg.lsp.servers; + vim.lsp.lspconfig.enable = true; + vim.lsp.lspconfig.sources.fsharp-lsp = servers.${cfg.lsp.server}.lspConfig; }) (mkIf cfg.format.enable { diff --git a/modules/plugins/languages/gleam.nix b/modules/plugins/languages/gleam.nix index 984d21aa..26a001eb 100644 --- a/modules/plugins/languages/gleam.nix +++ b/modules/plugins/languages/gleam.nix @@ -7,9 +7,11 @@ inherit (builtins) attrNames; inherit (lib.options) mkEnableOption mkOption; inherit (lib.modules) mkIf mkMerge; + inherit (lib.lists) isList; inherit (lib.meta) getExe; - inherit (lib.types) enum; - inherit (lib.nvim.types) mkGrammarOption singleOrListOf; + inherit (lib.types) enum either listOf package str; + inherit (lib.nvim.lua) expToLua; + inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.attrsets) mapListToAttrs; cfg = config.vim.languages.gleam; @@ -35,7 +37,7 @@ in { lsp = { enable = mkEnableOption "Gleam LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "Gleam LSP server to use"; }; diff --git a/modules/plugins/languages/go.nix b/modules/plugins/languages/go.nix index 5b1aeebb..bab0ff4a 100644 --- a/modules/plugins/languages/go.nix +++ b/modules/plugins/languages/go.nix @@ -8,53 +8,28 @@ inherit (lib.options) mkEnableOption mkOption literalMD; inherit (lib.modules) mkIf mkMerge; inherit (lib.meta) getExe; - inherit (lib.generators) mkLuaInline; - inherit (lib.types) bool enum package; - inherit (lib.nvim.types) mkGrammarOption singleOrListOf; + inherit (lib.lists) isList; + inherit (lib.types) bool enum either listOf package str; + inherit (lib.nvim.types) mkGrammarOption; + inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.dag) entryAfter; - inherit (lib.nvim.attrsets) mapListToAttrs; cfg = config.vim.languages.go; - defaultServers = ["gopls"]; + defaultServer = "gopls"; servers = { gopls = { - cmd = [(getExe pkgs.gopls)]; - filetypes = ["go" "gomod" "gowork" "gotmpl"]; - root_dir = mkLuaInline '' - function(bufnr, on_dir) - local fname = vim.api.nvim_buf_get_name(bufnr) - - local function get_root(fname) - if _G.nvf_gopls_mod_cache and fname:sub(1, #_G.nvf_gopls_mod_cache) == _G.nvf_gopls_mod_cache then - local clients = vim.lsp.get_clients { name = 'gopls' } - if #clients > 0 then - return clients[#clients].config.root_dir - end - end - return vim.fs.root(fname, 'go.work') or vim.fs.root(fname, 'go.mod') or vim.fs.root(fname, '.git') - end - - -- see: https://github.com/neovim/nvim-lspconfig/issues/804 - if _G.nvf_gopls_mod_cache then - on_dir(get_root(fname)) - return - end - local cmd = { 'go', 'env', 'GOMODCACHE' } - local ok, err = pcall(vim.system, cmd, { text = true }, function(output) - if output.code == 0 then - if output.stdout then - _G.nvf_gopls_mod_cache = vim.trim(output.stdout) - end - on_dir(get_root(fname)) - else - vim.schedule(function() - vim.notify(('[gopls] cmd failed with code %d: %s\n%s'):format(output.code, cmd, output.stderr)) - end) - end - end) - if not ok then vim.notify(('[gopls] cmd failed: %s\n%s'):format(cmd, err)) end - end + package = pkgs.gopls; + lspConfig = '' + lspconfig.gopls.setup { + capabilities = capabilities; + on_attach = default_on_attach; + cmd = ${ + if isList cfg.lsp.package + then expToLua cfg.lsp.package + else ''{"${cfg.lsp.package}/bin/gopls", "serve"}'' + }, + } ''; }; }; @@ -94,10 +69,17 @@ in { lsp = { enable = mkEnableOption "Go LSP support" // {default = config.vim.lsp.enable;}; - servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); - default = defaultServers; + server = mkOption { description = "Go LSP server to use"; + type = enum (attrNames servers); + default = defaultServer; + }; + + package = mkOption { + description = "Go 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; }; }; @@ -152,12 +134,8 @@ in { }) (mkIf cfg.lsp.enable { - vim.lsp.servers = - mapListToAttrs (name: { - inherit name; - value = servers.${name}; - }) - cfg.lsp.servers; + vim.lsp.lspconfig.enable = true; + vim.lsp.lspconfig.sources.go-lsp = servers.${cfg.lsp.server}.lspConfig; }) (mkIf cfg.format.enable { diff --git a/modules/plugins/languages/helm.nix b/modules/plugins/languages/helm.nix index 1971eb31..f5fe7b64 100644 --- a/modules/plugins/languages/helm.nix +++ b/modules/plugins/languages/helm.nix @@ -8,8 +8,8 @@ inherit (lib.options) mkEnableOption mkOption; inherit (lib.modules) mkIf mkMerge; inherit (lib.meta) getExe; - inherit (lib.types) enum; - inherit (lib.nvim.types) mkGrammarOption singleOrListOf; + inherit (lib.types) enum listOf; + inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.attrsets) mapListToAttrs; cfg = config.vim.languages.helm; @@ -49,7 +49,7 @@ in { lsp = { enable = mkEnableOption "Helm LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "Helm LSP server to use"; }; diff --git a/modules/plugins/languages/julia.nix b/modules/plugins/languages/julia.nix index c9be8d49..d5310613 100644 --- a/modules/plugins/languages/julia.nix +++ b/modules/plugins/languages/julia.nix @@ -6,17 +6,17 @@ }: let inherit (builtins) attrNames; inherit (lib.options) mkEnableOption mkOption; - inherit (lib.types) enum; + inherit (lib.types) listOf enum; inherit (lib.modules) mkIf mkMerge; inherit (lib.meta) getExe; - inherit (lib.nvim.types) mkGrammarOption singleOrListOf; + inherit (lib.nvim.types) mkGrammarOption; inherit (lib.generators) mkLuaInline; inherit (lib.nvim.attrsets) mapListToAttrs; inherit (lib.nvim.dag) entryBefore; - defaultServers = ["julials"]; + defaultServers = ["jdtls"]; servers = { - julials = { + jdtls = { enable = true; cmd = mkLuaInline @@ -95,9 +95,9 @@ in { }; lsp = { - enable = mkEnableOption "Julia LSP support" // {default = config.vim.lsp.enable;}; + enable = mkEnableOption "Java LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = '' Julia LSP Server to Use @@ -107,11 +107,9 @@ in { option, since there is no way to provide only the LSP server. If you want to avoid that, you have to change - [vim.lsp.servers.julials.cmd](#opt-vim.lsp.servers._name_.cmd) to use - the Julia binary in {env}`PATH`, and add the `LanguageServer` - package to Julia in your devshells. - - Check the source file of this option for the full `cmd`. + [](#opt-vim.languages.julia.lsp.package) to use the Julia binary + in {env}`PATH` (set it to `null`), and add the `LanguageServer` package to + Julia in your devshells. ::: ''; }; diff --git a/modules/plugins/languages/markdown.nix b/modules/plugins/languages/markdown.nix index 0a3f0945..78e9d67b 100644 --- a/modules/plugins/languages/markdown.nix +++ b/modules/plugins/languages/markdown.nix @@ -10,7 +10,7 @@ inherit (lib.options) mkEnableOption mkOption; inherit (lib.types) bool enum package listOf str nullOr; inherit (lib.nvim.lua) toLuaObject; - inherit (lib.nvim.types) diagnostics mkGrammarOption mkPluginSetupOption singleOrListOf; + inherit (lib.nvim.types) diagnostics mkGrammarOption mkPluginSetupOption; inherit (lib.nvim.dag) entryAnywhere; inherit (lib.nvim.attrsets) mapListToAttrs; @@ -63,7 +63,7 @@ in { servers = mkOption { description = "Markdown LSP server to use"; - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; }; }; diff --git a/modules/plugins/languages/nim.nix b/modules/plugins/languages/nim.nix index b4fab356..289c9691 100644 --- a/modules/plugins/languages/nim.nix +++ b/modules/plugins/languages/nim.nix @@ -8,8 +8,8 @@ inherit (lib.options) mkEnableOption mkOption; inherit (lib.meta) getExe'; inherit (lib.modules) mkIf mkMerge; - inherit (lib.types) enum package; - inherit (lib.nvim.types) mkGrammarOption singleOrListOf; + inherit (lib.types) enum listOf package; + inherit (lib.nvim.types) mkGrammarOption; inherit (lib.generators) mkLuaInline; inherit (lib.nvim.attrsets) mapListToAttrs; @@ -59,7 +59,7 @@ in { enable = mkEnableOption "Nim LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "Nim LSP server to use"; }; diff --git a/modules/plugins/languages/nix.nix b/modules/plugins/languages/nix.nix index 6127f78e..c460ca50 100644 --- a/modules/plugins/languages/nix.nix +++ b/modules/plugins/languages/nix.nix @@ -9,8 +9,8 @@ inherit (lib.meta) getExe; inherit (lib.options) mkEnableOption mkOption; inherit (lib.modules) mkIf mkMerge; - inherit (lib.types) enum package; - inherit (lib.nvim.types) mkGrammarOption diagnostics singleOrListOf; + inherit (lib.types) enum package listOf; + inherit (lib.nvim.types) mkGrammarOption diagnostics; inherit (lib.nvim.attrsets) mapListToAttrs; cfg = config.vim.languages.nix; @@ -98,7 +98,7 @@ in { lsp = { enable = mkEnableOption "Nix LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "Nix LSP server to use"; }; diff --git a/modules/plugins/languages/nu.nix b/modules/plugins/languages/nu.nix index d58e39a3..55711104 100644 --- a/modules/plugins/languages/nu.nix +++ b/modules/plugins/languages/nu.nix @@ -5,9 +5,9 @@ ... }: let inherit (lib.options) mkEnableOption mkOption; - inherit (lib.types) enum; + inherit (lib.types) enum listOf; inherit (lib.modules) mkIf mkMerge; - inherit (lib.nvim.types) mkGrammarOption singleOrListOf; + inherit (lib.nvim.types) mkGrammarOption; inherit (lib.meta) getExe; inherit (lib.generators) mkLuaInline; inherit (lib.nvim.attrsets) mapListToAttrs; @@ -46,7 +46,7 @@ in { enable = mkEnableOption "Nu LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "Nu LSP server to use"; }; diff --git a/modules/plugins/languages/ocaml.nix b/modules/plugins/languages/ocaml.nix index cf9fdd93..a8f964e9 100644 --- a/modules/plugins/languages/ocaml.nix +++ b/modules/plugins/languages/ocaml.nix @@ -8,8 +8,8 @@ inherit (lib.options) mkEnableOption mkOption; inherit (lib.modules) mkIf mkMerge; inherit (lib.meta) getExe; - inherit (lib.types) enum package; - inherit (lib.nvim.types) mkGrammarOption singleOrListOf; + inherit (lib.types) enum listOf package; + inherit (lib.nvim.types) mkGrammarOption; inherit (lib.generators) mkLuaInline; inherit (lib.nvim.attrsets) mapListToAttrs; @@ -74,7 +74,7 @@ in { enable = mkEnableOption "OCaml LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "OCaml LSP server to use"; }; diff --git a/modules/plugins/languages/odin.nix b/modules/plugins/languages/odin.nix index f18a3383..1b1bd751 100644 --- a/modules/plugins/languages/odin.nix +++ b/modules/plugins/languages/odin.nix @@ -7,9 +7,9 @@ inherit (builtins) attrNames; inherit (lib.options) mkEnableOption mkOption; inherit (lib.modules) mkIf mkMerge; - inherit (lib.types) enum; + inherit (lib.types) listOf enum; inherit (lib.meta) getExe; - inherit (lib.nvim.types) mkGrammarOption singleOrListOf; + inherit (lib.nvim.types) mkGrammarOption; inherit (lib.generators) mkLuaInline; inherit (lib.nvim.attrsets) mapListToAttrs; @@ -46,7 +46,7 @@ in { enable = mkEnableOption "Odin LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "Odin LSP server to use"; }; diff --git a/modules/plugins/languages/php.nix b/modules/plugins/languages/php.nix index 353b1137..9eaae168 100644 --- a/modules/plugins/languages/php.nix +++ b/modules/plugins/languages/php.nix @@ -8,8 +8,8 @@ inherit (lib.options) mkEnableOption mkOption; inherit (lib.meta) getExe; inherit (lib.modules) mkIf mkMerge; - inherit (lib.types) enum; - inherit (lib.nvim.types) mkGrammarOption singleOrListOf; + inherit (lib.types) enum listOf; + inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.attrsets) mapListToAttrs; inherit (lib.generators) mkLuaInline; @@ -77,7 +77,7 @@ in { enable = mkEnableOption "PHP LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "PHP LSP server to use"; }; diff --git a/modules/plugins/languages/python.nix b/modules/plugins/languages/python.nix index 6f97f70c..aba4cd7e 100644 --- a/modules/plugins/languages/python.nix +++ b/modules/plugins/languages/python.nix @@ -8,9 +8,8 @@ inherit (lib.options) mkEnableOption mkOption literalExpression; inherit (lib.meta) getExe; inherit (lib.modules) mkIf mkMerge; - inherit (lib.types) enum package bool; + inherit (lib.types) enum listOf package str bool; inherit (lib.nvim.attrsets) mapListToAttrs; - inherit (lib.nvim.types) singleOrListOf; inherit (lib.generators) mkLuaInline; inherit (lib.nvim.dag) entryBefore; @@ -230,7 +229,7 @@ in { enable = mkEnableOption "Python LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "Python LSP server to use"; }; diff --git a/modules/plugins/languages/r.nix b/modules/plugins/languages/r.nix index 873edaa3..9f28900a 100644 --- a/modules/plugins/languages/r.nix +++ b/modules/plugins/languages/r.nix @@ -5,11 +5,11 @@ ... }: let inherit (builtins) attrNames; - inherit (lib.options) mkEnableOption mkOption; + inherit (lib.options) mkEnableOption mkOption literalExpression; inherit (lib.modules) mkIf mkMerge; - inherit (lib.types) enum package; + inherit (lib.types) enum listOf package; inherit (lib.meta) getExe; - inherit (lib.nvim.types) mkGrammarOption singleOrListOf; + inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.attrsets) mapListToAttrs; inherit (lib.generators) mkLuaInline; @@ -77,7 +77,7 @@ in { enable = mkEnableOption "R LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "R LSP server to use"; }; diff --git a/modules/plugins/languages/ruby.nix b/modules/plugins/languages/ruby.nix index 94e27277..6b2e63da 100644 --- a/modules/plugins/languages/ruby.nix +++ b/modules/plugins/languages/ruby.nix @@ -8,8 +8,8 @@ inherit (lib.options) mkEnableOption mkOption; inherit (lib.meta) getExe; inherit (lib.modules) mkIf mkMerge; - inherit (lib.nvim.types) mkGrammarOption diagnostics singleOrListOf; - inherit (lib.types) package enum; + inherit (lib.nvim.types) mkGrammarOption diagnostics; + inherit (lib.types) listOf package enum; inherit (lib.nvim.attrsets) mapListToAttrs; cfg = config.vim.languages.ruby; @@ -77,7 +77,7 @@ in { enable = mkEnableOption "Ruby LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "Ruby LSP server to use"; }; diff --git a/modules/plugins/languages/sql.nix b/modules/plugins/languages/sql.nix index c1ea6678..7321dcf5 100644 --- a/modules/plugins/languages/sql.nix +++ b/modules/plugins/languages/sql.nix @@ -8,8 +8,8 @@ inherit (lib.options) mkEnableOption mkOption; inherit (lib.meta) getExe; inherit (lib.modules) mkIf mkMerge; - inherit (lib.types) enum package str; - inherit (lib.nvim.types) diagnostics singleOrListOf; + inherit (lib.types) enum listOf package str; + inherit (lib.nvim.types) diagnostics; inherit (lib.nvim.attrsets) mapListToAttrs; inherit (lib.generators) mkLuaInline; @@ -78,7 +78,7 @@ in { enable = mkEnableOption "SQL LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "SQL LSP server to use"; }; diff --git a/modules/plugins/languages/svelte.nix b/modules/plugins/languages/svelte.nix index 42e6d320..a876f65d 100644 --- a/modules/plugins/languages/svelte.nix +++ b/modules/plugins/languages/svelte.nix @@ -8,8 +8,8 @@ inherit (lib.options) mkEnableOption mkOption; inherit (lib.modules) mkIf mkMerge; inherit (lib.meta) getExe; - inherit (lib.types) enum package; - inherit (lib.nvim.types) mkGrammarOption diagnostics singleOrListOf; + inherit (lib.types) enum listOf package; + inherit (lib.nvim.types) mkGrammarOption diagnostics; inherit (lib.nvim.attrsets) mapListToAttrs; inherit (lib.generators) mkLuaInline; @@ -90,7 +90,7 @@ in { enable = mkEnableOption "Svelte LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "Svelte LSP server to use"; }; diff --git a/modules/plugins/languages/tailwind.nix b/modules/plugins/languages/tailwind.nix index 4e63a8d8..601f0f88 100644 --- a/modules/plugins/languages/tailwind.nix +++ b/modules/plugins/languages/tailwind.nix @@ -8,9 +8,8 @@ inherit (lib.options) mkEnableOption mkOption; inherit (lib.modules) mkIf mkMerge; inherit (lib.meta) getExe; - inherit (lib.types) enum; + inherit (lib.types) enum listOf; inherit (lib.nvim.attrsets) mapListToAttrs; - inherit (lib.nvim.types) singleOrListOf; inherit (lib.generators) mkLuaInline; cfg = config.vim.languages.tailwind; @@ -121,6 +120,7 @@ workspace_required = true; root_dir = mkLuaInline '' function(bufnr, on_dir) + local util = require 'lspconfig.util' local root_files = { -- Generic 'tailwind.config.js', @@ -154,7 +154,7 @@ in { enable = mkEnableOption "Tailwindcss LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "Tailwindcss LSP server to use"; }; diff --git a/modules/plugins/languages/ts.nix b/modules/plugins/languages/ts.nix index 9f15ff24..6064da98 100644 --- a/modules/plugins/languages/ts.nix +++ b/modules/plugins/languages/ts.nix @@ -4,177 +4,73 @@ lib, ... }: let - inherit (builtins) attrNames elem; + inherit (builtins) attrNames; inherit (lib.options) mkEnableOption mkOption; inherit (lib.modules) mkIf mkMerge; + inherit (lib.lists) isList; inherit (lib.meta) getExe; - inherit (lib.types) enum package bool; - inherit (lib.generators) mkLuaInline; - inherit (lib.nvim.attrsets) mapListToAttrs; - inherit (lib.nvim.lua) toLuaObject; - inherit (lib.nvim.types) mkGrammarOption diagnostics mkPluginSetupOption singleOrListOf; - inherit (lib.nvim.dag) entryAnywhere entryBefore; + inherit (lib.types) enum either listOf package str bool; + inherit (lib.nvim.lua) expToLua toLuaObject; + inherit (lib.nvim.types) mkGrammarOption diagnostics mkPluginSetupOption; + inherit (lib.nvim.dag) entryAnywhere; cfg = config.vim.languages.ts; - defaultServers = ["ts_ls"]; - servers = let + defaultServer = "ts_ls"; + servers = { ts_ls = { - cmd = [(getExe pkgs.typescript-language-server) "--stdio"]; - init_options = {hostInfo = "neovim";}; - filetypes = [ - "javascript" - "javascriptreact" - "javascript.jsx" - "typescript" - "typescriptreact" - "typescript.tsx" - ]; - root_markers = ["tsconfig.json" "jsconfig.json" "package.json" ".git"]; - handlers = { - # handle rename request for certain code actions like extracting functions / types - "_typescript.rename" = mkLuaInline '' - function(_, result, ctx) - local client = assert(vim.lsp.get_client_by_id(ctx.client_id)) - vim.lsp.util.show_document({ - uri = result.textDocument.uri, - range = { - start = result.position, - ['end'] = result.position, - }, - }, client.offset_encoding) - vim.lsp.buf.rename() - return vim.NIL - end - ''; - }; - on_attach = mkLuaInline '' - function(client, bufnr) - default_on_attach(client, bufnr); - - -- ts_ls provides `source.*` code actions that apply to the whole file. These only appear in - -- `vim.lsp.buf.code_action()` if specified in `context.only`. - vim.api.nvim_buf_create_user_command(0, 'LspTypescriptSourceAction', function() - local source_actions = vim.tbl_filter(function(action) - return vim.startswith(action, 'source.') - end, client.server_capabilities.codeActionProvider.codeActionKinds) - - vim.lsp.buf.code_action({ - context = { - only = source_actions, - }, - }) - end, {}) - end + package = pkgs.typescript-language-server; + lspConfig = '' + lspconfig.ts_ls.setup { + capabilities = capabilities, + on_attach = function(client, bufnr) + attach_keymaps(client, bufnr); + client.server_capabilities.documentFormattingProvider = false; + end, + cmd = ${ + if isList cfg.lsp.package + then expToLua cfg.lsp.package + else ''{"${cfg.lsp.package}/bin/typescript-language-server", "--stdio"}'' + } + } ''; }; - in { - inherit ts_ls; + + denols = { + package = pkgs.deno; + lspConfig = '' + vim.g.markdown_fenced_languages = { "ts=typescript" } + lspconfig.denols.setup { + capabilities = capabilities; + on_attach = attach_keymaps, + cmd = ${ + if isList cfg.lsp.package + then expToLua cfg.lsp.package + else ''{"${cfg.lsp.package}/bin/deno", "lsp"}'' + } + } + ''; + }; + # Here for backwards compatibility. Still consider tsserver a valid # configuration in the enum, but assert if it's set to *properly* # redirect the user to the correct server. - tsserver = ts_ls; - - denols = { - cmd = [(getExe pkgs.deno) "lsp"]; - cmd_env = {NO_COLOR = true;}; - filetypes = [ - "javascript" - "javascriptreact" - "javascript.jsx" - "typescript" - "typescriptreact" - "typescript.tsx" - ]; - root_markers = ["deno.json" "deno.jsonc" ".git"]; - settings = { - deno = { - enable = true; - suggest = { - imports = { - hosts = { - "https://deno.land" = true; - }; - }; - }; - }; - }; - handlers = { - "textDocument/definition" = mkLuaInline "nvf_denols_handler"; - "textDocument/typeDefinition" = mkLuaInline "nvf_denols_handler"; - "textDocument/references" = mkLuaInline "nvf_denols_handler"; - }; - on_attach = mkLuaInline '' - function(client, bufnr) - default_on_attach(client, bufnr) - vim.api.nvim_buf_create_user_command(0, 'LspDenolsCache', function() - client:exec_cmd({ - command = 'deno.cache', - arguments = { {}, vim.uri_from_bufnr(bufnr) }, - }, { bufnr = bufnr }, function(err, _result, ctx) - if err then - local uri = ctx.params.arguments[2] - vim.api.nvim_err_writeln('cache command failed for ' .. vim.uri_to_fname(uri)) - end - end) - end, { - desc = 'Cache a module and all of its dependencies.', - }) - end + tsserver = { + package = pkgs.typescript-language-server; + lspConfig = '' + lspconfig.ts_ls.setup { + capabilities = capabilities; + on_attach = attach_keymaps, + cmd = ${ + if isList cfg.lsp.package + then expToLua cfg.lsp.package + else ''{"${cfg.lsp.package}/bin/typescript-language-server", "--stdio"}'' + } + } ''; }; }; - denols_handlers = '' - local function nvf_denols_virtual_text_document_handler(uri, res, client) - if not res then - return nil - end - - local lines = vim.split(res.result, '\n') - local bufnr = vim.uri_to_bufnr(uri) - - local current_buf = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false) - if #current_buf ~= 0 then - return nil - end - - vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines) - vim.api.nvim_set_option_value('readonly', true, { buf = bufnr }) - vim.api.nvim_set_option_value('modified', false, { buf = bufnr }) - vim.api.nvim_set_option_value('modifiable', false, { buf = bufnr }) - vim.lsp.buf_attach_client(bufnr, client.id) - end - - local function nvf_denols_virtual_text_document(uri, client) - local params = { - textDocument = { - uri = uri, - }, - } - local result = client.request_sync('deno/virtualTextDocument', params) - nvf_denols_virtual_text_document_handler(uri, result, client) - end - - local function nvf_denols_handler(err, result, ctx, config) - if not result or vim.tbl_isempty(result) then - return nil - end - - local client = vim.lsp.get_client_by_id(ctx.client_id) - for _, res in pairs(result) do - local uri = res.uri or res.targetUri - if uri:match '^deno:' then - nvf_denols_virtual_text_document(uri, client) - res['uri'] = uri - res['targetUri'] = uri - end - end - - vim.lsp.handlers[ctx.method](err, result, ctx, config) - end - ''; - # TODO: specify packages defaultFormat = "prettier"; formats = { @@ -226,10 +122,17 @@ in { lsp = { enable = mkEnableOption "Typescript/Javascript LSP support" // {default = config.vim.lsp.enable;}; - servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); - default = defaultServers; + server = mkOption { description = "Typescript/Javascript LSP server to use"; + type = enum (attrNames servers); + default = defaultServer; + }; + + package = mkOption { + description = "Typescript/Javascript 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; }; }; @@ -287,17 +190,8 @@ in { }) (mkIf cfg.lsp.enable { - vim.lsp.servers = - mapListToAttrs (name: { - inherit name; - value = servers.${name}; - }) - cfg.lsp.servers; - }) - - (mkIf (cfg.lsp.enable && elem "denols" cfg.lsp.servers) { - vim.globals.markdown_fenced_languages = ["ts=typescript"]; - vim.luaConfigRC.denols_handlers = entryBefore ["lsp-servers"] denols_handlers; + vim.lsp.lspconfig.enable = true; + vim.lsp.lspconfig.sources.ts-lsp = servers.${cfg.lsp.server}.lspConfig; }) (mkIf cfg.format.enable { @@ -340,7 +234,7 @@ in { { assertions = [ { - assertion = cfg.lsp.enable -> !(elem "tsserver" cfg.lsp.servers); + assertion = cfg.lsp.enable -> cfg.lsp.server != "tsserver"; message = '' As of a recent lspconfig update, the `tsserver` configuration has been renamed to `ts_ls` to match upstream behaviour of `lspconfig`, and the name `tsserver` diff --git a/modules/plugins/languages/typst.nix b/modules/plugins/languages/typst.nix index fbeb0ce2..2bc4af42 100644 --- a/modules/plugins/languages/typst.nix +++ b/modules/plugins/languages/typst.nix @@ -9,7 +9,7 @@ inherit (lib.types) nullOr enum attrsOf listOf package str; inherit (lib.attrsets) attrNames; inherit (lib.meta) getExe; - inherit (lib.nvim.types) mkGrammarOption mkPluginSetupOption singleOrListOf; + inherit (lib.nvim.types) mkGrammarOption mkPluginSetupOption; inherit (lib.nvim.dag) entryAnywhere; inherit (lib.nvim.lua) toLuaObject; inherit (lib.nvim.attrsets) mapListToAttrs; @@ -114,7 +114,7 @@ in { enable = mkEnableOption "Typst LSP support (typst-lsp)" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "Typst LSP server to use"; }; diff --git a/modules/plugins/languages/vala.nix b/modules/plugins/languages/vala.nix index 722b0d3b..85058e32 100644 --- a/modules/plugins/languages/vala.nix +++ b/modules/plugins/languages/vala.nix @@ -8,8 +8,8 @@ inherit (lib.options) mkEnableOption mkOption; inherit (lib.modules) mkIf mkMerge; inherit (lib.meta) getExe; - inherit (lib.types) enum; - inherit (lib.nvim.types) mkGrammarOption singleOrListOf; + inherit (lib.types) enum listOf; + inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.attrsets) mapListToAttrs; inherit (lib.generators) mkLuaInline; @@ -73,7 +73,7 @@ in { lsp = { enable = mkEnableOption "Vala LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "Vala LSP server to use"; }; diff --git a/modules/plugins/languages/wgsl.nix b/modules/plugins/languages/wgsl.nix index 8c33e581..0af350b5 100644 --- a/modules/plugins/languages/wgsl.nix +++ b/modules/plugins/languages/wgsl.nix @@ -6,9 +6,9 @@ }: let inherit (builtins) attrNames; inherit (lib.modules) mkIf mkMerge; - inherit (lib.nvim.types) mkGrammarOption singleOrListOf; + inherit (lib.nvim.types) mkGrammarOption; inherit (lib.options) mkEnableOption mkOption; - inherit (lib.types) enum; + inherit (lib.types) enum listOf; inherit (lib.meta) getExe; inherit (lib.nvim.attrsets) mapListToAttrs; @@ -37,7 +37,7 @@ in { enable = mkEnableOption "WGSL LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "WGSL LSP server to use"; }; diff --git a/modules/plugins/languages/yaml.nix b/modules/plugins/languages/yaml.nix index 1869b1c1..de503e9c 100644 --- a/modules/plugins/languages/yaml.nix +++ b/modules/plugins/languages/yaml.nix @@ -8,8 +8,8 @@ inherit (lib.options) mkEnableOption mkOption; inherit (lib.modules) mkIf mkMerge; inherit (lib.meta) getExe; - inherit (lib.types) enum; - inherit (lib.nvim.types) mkGrammarOption singleOrListOf; + inherit (lib.types) enum listOf; + inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.attrsets) mapListToAttrs; cfg = config.vim.languages.yaml; @@ -56,7 +56,7 @@ in { lsp = { enable = mkEnableOption "Yaml LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "Yaml LSP server to use"; }; diff --git a/modules/plugins/languages/zig.nix b/modules/plugins/languages/zig.nix index 966e9369..db38cc51 100644 --- a/modules/plugins/languages/zig.nix +++ b/modules/plugins/languages/zig.nix @@ -7,8 +7,8 @@ inherit (builtins) attrNames; inherit (lib.options) mkEnableOption mkOption; inherit (lib.modules) mkIf mkMerge mkDefault; - inherit (lib.types) bool package enum; - inherit (lib.nvim.types) mkGrammarOption singleOrListOf; + inherit (lib.types) bool listOf package enum; + inherit (lib.nvim.types) mkGrammarOption; inherit (lib.meta) getExe; inherit (lib.nvim.attrsets) mapListToAttrs; @@ -67,7 +67,7 @@ in { enable = mkEnableOption "Zig LSP support" // {default = config.vim.lsp.enable;}; servers = mkOption { - type = singleOrListOf (enum (attrNames servers)); + type = listOf (enum (attrNames servers)); default = defaultServers; description = "Zig LSP server to use"; };