Merge pull request #962 from horriblename/language-overhaul-part

[skip ci] Language overhaul part 2
This commit is contained in:
Ching Pei Yang 2025-08-01 12:12:34 +02:00 committed by GitHub
commit 69659e078b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
38 changed files with 769 additions and 369 deletions

2
.github/typos.toml vendored
View file

@ -5,6 +5,8 @@ default.extend-ignore-words-re = [
"befores",
"annote",
"viw",
"edn",
"esy",
"BA", # somehow "BANanaD3V" is valid, but BA is not...
]

View file

@ -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 oneOf;
inherit (lib.types) listOf bool str submodule attrsOf anything either nullOr uniq;
inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.types) luaInline;
in {
@ -62,7 +62,7 @@ in {
};
cmd = mkOption {
type = nullOr (either luaInline (listOf str));
type = nullOr (either luaInline (uniq (listOf str)));
default = null;
description = "Command used to start the LSP server";
};

View file

@ -1,7 +1,8 @@
{lib}: let
inherit (lib.options) mergeEqualOption;
inherit (lib.lists) singleton;
inherit (lib.strings) isString stringLength match;
inherit (lib.types) listOf mkOptionType;
inherit (lib.types) listOf mkOptionType coercedTo;
in {
mergelessListOf = elemType: let
super = listOf elemType;
@ -27,4 +28,6 @@ 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);
}

View file

@ -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;
inherit (customTypes) char hexColor mergelessListOf singleOrListOf;
}

View file

@ -1,5 +1,6 @@
{lib, ...}: let
inherit (lib.modules) mkRemovedOptionModule mkRenamedOptionModule;
inherit (builtins) head warn;
inherit (lib.modules) mkRemovedOptionModule mkRenamedOptionModule doRename;
inherit (lib.lists) concatLists;
inherit (lib.nvim.config) batchRenameOptions;
@ -20,6 +21,27 @@
# 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.<server_name>.init_options`
'');
mkRemovedLspPackage = lang: (mkRemovedOptionModule ["vim" "languages" lang "lsp" "package"] ''
`vim.languages.${lang}.lsp.package` is now moved to `vim.lsp.servers.<server_name>.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 [
[
@ -120,6 +142,123 @@ 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.<server_name>.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.

View file

@ -7,8 +7,8 @@
inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.types) package enum listOf;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.types) enum;
inherit (lib.nvim.types) mkGrammarOption singleOrListOf;
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 = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "Assembly LSP server to use";
};

View file

@ -7,12 +7,10 @@
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 either listOf package str;
inherit (lib.nvim.lua) expToLua;
inherit (lib.types) enum package;
inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.types) mkGrammarOption diagnostics;
inherit (lib.nvim.types) mkGrammarOption diagnostics singleOrListOf;
inherit (lib.generators) mkLuaInline;
cfg = config.vim.languages.astro;
@ -91,7 +89,7 @@ in {
lsp = {
enable = mkEnableOption "Astro LSP support" // {default = config.vim.lsp.enable;};
servers = mkOption {
type = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "Astro LSP server to use";
};

View file

@ -5,14 +5,12 @@
...
}: let
inherit (builtins) attrNames;
inherit (lib.options) mkOption mkEnableOption literalExpression;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.meta) getExe;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList;
inherit (lib.types) enum either package listOf str bool;
inherit (lib.types) enum package bool;
inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.types) diagnostics mkGrammarOption;
inherit (lib.nvim.lua) expToLua;
inherit (lib.nvim.types) diagnostics mkGrammarOption singleOrListOf;
inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.bash;
@ -57,7 +55,7 @@ in {
lsp = {
enable = mkEnableOption "Bash LSP support" // {default = config.vim.lsp.enable;};
servers = mkOption {
type = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "Bash LSP server to use";
};

View file

@ -5,47 +5,143 @@
...
}: let
inherit (builtins) attrNames;
inherit (lib.lists) isList;
inherit (lib.strings) optionalString;
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.types) bool enum package either listOf str nullOr;
inherit (lib.types) bool enum package;
inherit (lib.meta) getExe;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.nvim.lua) expToLua;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.types) mkGrammarOption singleOrListOf;
inherit (lib.nvim.attrsets) mapListToAttrs;
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;
defaultServer = "clangd";
defaultServers = ["clangd"];
servers = {
ccls = {
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}"}
}
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
'';
};
clangd = {
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}"}
}
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
'';
};
};
@ -100,23 +196,10 @@ in {
lsp = {
enable = mkEnableOption "clang LSP support" // {default = config.vim.lsp.enable;};
server = mkOption {
servers = mkOption {
description = "The clang LSP server to use";
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;
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
};
};
@ -150,9 +233,12 @@ in {
})
(mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true;
vim.lsp.lspconfig.sources.clang-lsp = servers.${cfg.lsp.server}.lspConfig;
vim.lsp.servers =
mapListToAttrs (name: {
inherit name;
value = servers.${name};
})
cfg.lsp.servers;
})
(mkIf cfg.dap.enable {

View file

@ -5,14 +5,16 @@
options,
...
}: let
inherit (builtins) attrNames;
inherit (builtins) attrNames concatMap;
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.types) either listOf package str enum;
inherit (lib.types) enum;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList;
inherit (lib.meta) getExe;
inherit (lib.generators) mkLuaInline;
inherit (lib.strings) optionalString;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.nvim.lua) expToLua;
inherit (lib.nvim.types) mkGrammarOption singleOrListOf;
inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.attrsets) mapListToAttrs;
lspKeyConfig = config.vim.lsp.mappings;
lspKeyOptions = options.vim.lsp.mappings;
@ -25,52 +27,104 @@
# 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.
defaultServer = "csharp_ls";
defaultServers = ["csharp_ls"];
servers = {
omnisharp = {
package = pkgs.omnisharp-roslyn;
internalFormatter = true;
lspConfig = ''
lspconfig.omnisharp.setup {
capabilities = capabilities,
on_attach = function(client, bufnr)
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)
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,
cmd = ${
if isList cfg.lsp.package
then expToLua cfg.lsp.package
else "{'${cfg.lsp.package}/bin/OmniSharp'}"
}
}
end
'';
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 = {
package = pkgs.csharp-ls;
internalFormatter = true;
lspConfig = ''
local extended_handler = require("csharpls_extended").handler
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
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'}"
}
}
local fname = vim.api.nvim_buf_get_name(bufnr)
on_dir(find_root_pattern(fname, "%.sln$") or find_root_pattern(fname, "%.csproj$"))
end
'';
init_options = {
AutomaticWorkspaceInit = true;
};
};
};
@ -92,16 +146,10 @@ in {
lsp = {
enable = mkEnableOption "C# LSP support" // {default = config.vim.lsp.enable;};
server = mkOption {
servers = mkOption {
description = "C# LSP server to use";
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;
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
};
};
};
@ -114,9 +162,13 @@ in {
})
(mkIf cfg.lsp.enable {
vim.startPlugins = extraServerPlugins.${cfg.lsp.server} or [];
vim.lsp.lspconfig.enable = true;
vim.lsp.lspconfig.sources.csharp-lsp = servers.${cfg.lsp.server}.lspConfig;
vim.startPlugins = concatMap (server: extraServerPlugins.${server}) cfg.lsp.servers;
vim.lsp.servers =
mapListToAttrs (name: {
inherit name;
value = servers.${name};
})
cfg.lsp.servers;
})
]);
}

View file

@ -8,34 +8,25 @@
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.meta) getExe;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList;
inherit (lib.types) enum either listOf package str;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.nvim.lua) expToLua;
inherit (lib.types) enum package;
inherit (lib.nvim.types) mkGrammarOption singleOrListOf;
inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.css;
defaultServer = "vscode-langservers-extracted";
defaultServer = ["cssls"];
servers = {
vscode-langservers-extracted = {
package = pkgs.vscode-langservers-extracted;
lspConfig = ''
-- enable (broadcasting) snippet capability for completion
-- see <https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#cssls>
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"}''
}
}
'';
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;
};
};
};
@ -82,17 +73,10 @@ in {
lsp = {
enable = mkEnableOption "CSS LSP support" // {default = config.vim.lsp.enable;};
server = mkOption {
description = "CSS LSP server to use";
type = enum (attrNames servers);
servers = mkOption {
type = singleOrListOf (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;
description = "CSS LSP server to use";
};
};
@ -120,8 +104,12 @@ in {
})
(mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true;
vim.lsp.lspconfig.sources.css-lsp = servers.${cfg.lsp.server}.lspConfig;
vim.lsp.servers =
mapListToAttrs (name: {
inherit name;
value = servers.${name};
})
cfg.lsp.servers;
})
(mkIf cfg.format.enable {

View file

@ -4,11 +4,17 @@
lib,
...
}: let
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.options) mkEnableOption;
inherit (lib.meta) getExe;
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 = {
@ -22,12 +28,6 @@ in {
lsp = {
enable = mkEnableOption "CUE LSP support" // {default = config.vim.lsp.enable;};
package = mkOption {
type = package;
default = pkgs.cue;
description = "cue lsp implementation";
};
};
};
@ -38,14 +38,7 @@ in {
})
(mkIf cfg.lsp.enable {
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"},
}
'';
vim.lsp.servers.cue = lspOptions;
})
]);
}

View file

@ -8,12 +8,10 @@
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 either listOf package nullOr str bool;
inherit (lib.types) enum package nullOr str bool;
inherit (lib.strings) optionalString;
inherit (lib.nvim.lua) expToLua;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.nvim.types) mkGrammarOption singleOrListOf;
inherit (lib.nvim.dag) entryAfter;
inherit (lib.nvim.attrsets) mapListToAttrs;
@ -54,7 +52,7 @@ in {
lsp = {
enable = mkEnableOption "Dart LSP support" // {default = config.vim.lsp.enable;};
servers = mkOption {
type = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "Dart LSP server to use";
};

View file

@ -7,12 +7,10 @@
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 either listOf package str;
inherit (lib.types) enum package;
inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.nvim.lua) expToLua;
inherit (lib.nvim.types) mkGrammarOption singleOrListOf;
inherit (lib.nvim.dag) entryAnywhere;
inherit (lib.nvim.attrsets) mapListToAttrs;
@ -63,7 +61,7 @@ in {
lsp = {
enable = mkEnableOption "Elixir LSP support" // {default = config.vim.lsp.enable;};
servers = mkOption {
type = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "Elixir LSP server to use";
};

View file

@ -6,29 +6,48 @@
}: let
inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.types) either listOf package str enum;
inherit (lib.types) package enum;
inherit (lib.meta) getExe;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.nvim.lua) expToLua;
inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.types) mkGrammarOption singleOrListOf;
inherit (lib.nvim.attrsets) mapListToAttrs;
defaultServer = "fsautocomplete";
defaultServer = ["fsautocomplete"];
servers = {
fsautocomplete = {
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'}"
},
}
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
'';
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;
};
};
};
};
@ -52,18 +71,11 @@ in {
lsp = {
enable = mkEnableOption "F# LSP support" // {default = config.vim.lsp.enable;};
server = mkOption {
type = enum (attrNames servers);
servers = mkOption {
type = singleOrListOf (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;};
@ -90,8 +102,12 @@ in {
})
(mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true;
vim.lsp.lspconfig.sources.fsharp-lsp = servers.${cfg.lsp.server}.lspConfig;
vim.lsp.servers =
mapListToAttrs (name: {
inherit name;
value = servers.${name};
})
cfg.lsp.servers;
})
(mkIf cfg.format.enable {

View file

@ -7,11 +7,9 @@
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 either listOf package str;
inherit (lib.nvim.lua) expToLua;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.types) enum;
inherit (lib.nvim.types) mkGrammarOption singleOrListOf;
inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.gleam;
@ -37,7 +35,7 @@ in {
lsp = {
enable = mkEnableOption "Gleam LSP support" // {default = config.vim.lsp.enable;};
servers = mkOption {
type = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "Gleam LSP server to use";
};

View file

@ -8,28 +8,53 @@
inherit (lib.options) mkEnableOption mkOption literalMD;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.meta) getExe;
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.generators) mkLuaInline;
inherit (lib.types) bool enum package;
inherit (lib.nvim.types) mkGrammarOption singleOrListOf;
inherit (lib.nvim.dag) entryAfter;
inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.go;
defaultServer = "gopls";
defaultServers = ["gopls"];
servers = {
gopls = {
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"}''
},
}
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
'';
};
};
@ -69,17 +94,10 @@ in {
lsp = {
enable = mkEnableOption "Go LSP support" // {default = config.vim.lsp.enable;};
server = mkOption {
servers = mkOption {
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
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;
};
};
@ -134,8 +152,12 @@ in {
})
(mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true;
vim.lsp.lspconfig.sources.go-lsp = servers.${cfg.lsp.server}.lspConfig;
vim.lsp.servers =
mapListToAttrs (name: {
inherit name;
value = servers.${name};
})
cfg.lsp.servers;
})
(mkIf cfg.format.enable {

View file

@ -8,8 +8,8 @@
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.meta) getExe;
inherit (lib.types) enum listOf;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.types) enum;
inherit (lib.nvim.types) mkGrammarOption singleOrListOf;
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 = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "Helm LSP server to use";
};

View file

@ -6,17 +6,17 @@
}: let
inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.types) listOf enum;
inherit (lib.types) enum;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.meta) getExe;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.nvim.types) mkGrammarOption singleOrListOf;
inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.dag) entryBefore;
defaultServers = ["jdtls"];
defaultServers = ["julials"];
servers = {
jdtls = {
julials = {
enable = true;
cmd =
mkLuaInline
@ -95,9 +95,9 @@ in {
};
lsp = {
enable = mkEnableOption "Java LSP support" // {default = config.vim.lsp.enable;};
enable = mkEnableOption "Julia LSP support" // {default = config.vim.lsp.enable;};
servers = mkOption {
type = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = ''
Julia LSP Server to Use
@ -107,9 +107,11 @@ in {
option, since there is no way to provide only the LSP server.
If you want to avoid that, you have to change
[](#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.
[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`.
:::
'';
};

View file

@ -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;
inherit (lib.nvim.types) diagnostics mkGrammarOption mkPluginSetupOption singleOrListOf;
inherit (lib.nvim.dag) entryAnywhere;
inherit (lib.nvim.attrsets) mapListToAttrs;
@ -63,7 +63,7 @@ in {
servers = mkOption {
description = "Markdown LSP server to use";
type = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
};
};

View file

@ -8,8 +8,8 @@
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.meta) getExe';
inherit (lib.modules) mkIf mkMerge;
inherit (lib.types) enum listOf package;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.types) enum package;
inherit (lib.nvim.types) mkGrammarOption singleOrListOf;
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 = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "Nim LSP server to use";
};

View file

@ -9,8 +9,8 @@
inherit (lib.meta) getExe;
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.types) enum package listOf;
inherit (lib.nvim.types) mkGrammarOption diagnostics;
inherit (lib.types) enum package;
inherit (lib.nvim.types) mkGrammarOption diagnostics singleOrListOf;
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 = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "Nix LSP server to use";
};

View file

@ -5,9 +5,9 @@
...
}: let
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.types) enum listOf;
inherit (lib.types) enum;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.nvim.types) mkGrammarOption singleOrListOf;
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 = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "Nu LSP server to use";
};

View file

@ -8,8 +8,8 @@
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.meta) getExe;
inherit (lib.types) enum listOf package;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.types) enum package;
inherit (lib.nvim.types) mkGrammarOption singleOrListOf;
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 = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "OCaml LSP server to use";
};

View file

@ -7,9 +7,9 @@
inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.types) listOf enum;
inherit (lib.types) enum;
inherit (lib.meta) getExe;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.nvim.types) mkGrammarOption singleOrListOf;
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 = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "Odin LSP server to use";
};

View file

@ -8,8 +8,8 @@
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.meta) getExe;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.types) enum listOf;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.types) enum;
inherit (lib.nvim.types) mkGrammarOption singleOrListOf;
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 = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "PHP LSP server to use";
};

View file

@ -8,8 +8,9 @@
inherit (lib.options) mkEnableOption mkOption literalExpression;
inherit (lib.meta) getExe;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.types) enum listOf package str bool;
inherit (lib.types) enum package bool;
inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.types) singleOrListOf;
inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.dag) entryBefore;
@ -229,7 +230,7 @@ in {
enable = mkEnableOption "Python LSP support" // {default = config.vim.lsp.enable;};
servers = mkOption {
type = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "Python LSP server to use";
};

View file

@ -5,11 +5,11 @@
...
}: let
inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption literalExpression;
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.types) enum listOf package;
inherit (lib.types) enum package;
inherit (lib.meta) getExe;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.nvim.types) mkGrammarOption singleOrListOf;
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 = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "R LSP server to use";
};

View file

@ -8,8 +8,8 @@
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.meta) getExe;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.nvim.types) mkGrammarOption diagnostics;
inherit (lib.types) listOf package enum;
inherit (lib.nvim.types) mkGrammarOption diagnostics singleOrListOf;
inherit (lib.types) 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 = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "Ruby LSP server to use";
};

View file

@ -8,8 +8,8 @@
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.meta) getExe;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.types) enum listOf package str;
inherit (lib.nvim.types) diagnostics;
inherit (lib.types) enum package str;
inherit (lib.nvim.types) diagnostics singleOrListOf;
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 = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "SQL LSP server to use";
};

View file

@ -8,8 +8,8 @@
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.meta) getExe;
inherit (lib.types) enum listOf package;
inherit (lib.nvim.types) mkGrammarOption diagnostics;
inherit (lib.types) enum package;
inherit (lib.nvim.types) mkGrammarOption diagnostics singleOrListOf;
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 = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "Svelte LSP server to use";
};

View file

@ -8,8 +8,9 @@
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.meta) getExe;
inherit (lib.types) enum listOf;
inherit (lib.types) enum;
inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.types) singleOrListOf;
inherit (lib.generators) mkLuaInline;
cfg = config.vim.languages.tailwind;
@ -120,7 +121,6 @@
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 = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "Tailwindcss LSP server to use";
};

View file

@ -4,73 +4,177 @@
lib,
...
}: let
inherit (builtins) attrNames;
inherit (builtins) attrNames elem;
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList;
inherit (lib.meta) getExe;
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;
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;
cfg = config.vim.languages.ts;
defaultServer = "ts_ls";
servers = {
defaultServers = ["ts_ls"];
servers = let
ts_ls = {
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"}''
}
}
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);
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"}''
}
}
-- 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
'';
};
in {
inherit ts_ls;
# 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 = {
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"}''
}
}
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
'';
};
};
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 = {
@ -122,17 +226,10 @@ in {
lsp = {
enable = mkEnableOption "Typescript/Javascript LSP support" // {default = config.vim.lsp.enable;};
server = mkOption {
servers = mkOption {
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
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;
};
};
@ -190,8 +287,17 @@ in {
})
(mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true;
vim.lsp.lspconfig.sources.ts-lsp = servers.${cfg.lsp.server}.lspConfig;
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;
})
(mkIf cfg.format.enable {
@ -234,7 +340,7 @@ in {
{
assertions = [
{
assertion = cfg.lsp.enable -> cfg.lsp.server != "tsserver";
assertion = cfg.lsp.enable -> !(elem "tsserver" cfg.lsp.servers);
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`

View file

@ -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;
inherit (lib.nvim.types) mkGrammarOption mkPluginSetupOption singleOrListOf;
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 = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "Typst LSP server to use";
};

View file

@ -8,8 +8,8 @@
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.meta) getExe;
inherit (lib.types) enum listOf;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.types) enum;
inherit (lib.nvim.types) mkGrammarOption singleOrListOf;
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 = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "Vala LSP server to use";
};

View file

@ -6,9 +6,9 @@
}: let
inherit (builtins) attrNames;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.nvim.types) mkGrammarOption singleOrListOf;
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.types) enum listOf;
inherit (lib.types) enum;
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 = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "WGSL LSP server to use";
};

View file

@ -8,8 +8,8 @@
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.meta) getExe;
inherit (lib.types) enum listOf;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.types) enum;
inherit (lib.nvim.types) mkGrammarOption singleOrListOf;
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 = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "Yaml LSP server to use";
};

View file

@ -7,8 +7,8 @@
inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge mkDefault;
inherit (lib.types) bool listOf package enum;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.types) bool package enum;
inherit (lib.nvim.types) mkGrammarOption singleOrListOf;
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 = listOf (enum (attrNames servers));
type = singleOrListOf (enum (attrNames servers));
default = defaultServers;
description = "Zig LSP server to use";
};