mirror of
https://github.com/nix-community/nixvim.git
synced 2025-06-23 09:18:38 +02:00
plugins/nvim-lsp: internal rename (nvim-lsp -> lsp)
This commit is contained in:
parent
079b0c30cd
commit
859ae3a843
17 changed files with 8 additions and 8 deletions
181
plugins/lsp/default.nix
Normal file
181
plugins/lsp/default.nix
Normal file
|
@ -0,0 +1,181 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
cfg = config.plugins.lsp;
|
||||
helpers = import ../helpers.nix {inherit lib;};
|
||||
in {
|
||||
imports = [
|
||||
./language-servers
|
||||
];
|
||||
|
||||
options = {
|
||||
plugins.lsp = {
|
||||
enable = mkEnableOption "neovim's built-in LSP";
|
||||
|
||||
keymaps = {
|
||||
silent = mkOption {
|
||||
type = types.bool;
|
||||
description = "Whether nvim-lsp keymaps should be silent";
|
||||
default = false;
|
||||
};
|
||||
|
||||
diagnostic = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
description = "Mappings for `vim.diagnostic.<action>` functions.";
|
||||
example = {
|
||||
"<leader>k" = "goto_prev";
|
||||
"<leader>j" = "goto_next";
|
||||
};
|
||||
default = {};
|
||||
};
|
||||
|
||||
lspBuf = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
description = "Mappings for `vim.lsp.buf.<action>` functions.";
|
||||
example = {
|
||||
"gd" = "definition";
|
||||
"gD" = "references";
|
||||
"gt" = "type_definition";
|
||||
"gi" = "implementation";
|
||||
"K" = "hover";
|
||||
};
|
||||
default = {};
|
||||
};
|
||||
};
|
||||
|
||||
enabledServers = mkOption {
|
||||
type = with types;
|
||||
listOf (oneOf [
|
||||
str
|
||||
(submodule {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = str;
|
||||
description = "The server's name";
|
||||
};
|
||||
|
||||
extraOptions = mkOption {
|
||||
type = attrs;
|
||||
description = "Extra options for the server";
|
||||
};
|
||||
};
|
||||
})
|
||||
]);
|
||||
description = "A list of enabled LSP servers. Don't use this directly.";
|
||||
default = [];
|
||||
};
|
||||
|
||||
onAttach = mkOption {
|
||||
type = types.lines;
|
||||
description = "A lua function to be run when a new LSP buffer is attached. The argument `client` and `bufnr` is provided.";
|
||||
default = "";
|
||||
};
|
||||
|
||||
capabilities = mkOption {
|
||||
type = types.lines;
|
||||
description = "Lua code that modifies inplace the `capabilities` table.";
|
||||
default = "";
|
||||
};
|
||||
|
||||
setupWrappers = mkOption {
|
||||
type = with types; listOf (functionTo str);
|
||||
description = "Code to be run to wrap the setup args. Takes in an argument containing the previous results, and returns a new string of code.";
|
||||
default = [];
|
||||
};
|
||||
|
||||
preConfig = mkOption {
|
||||
type = types.lines;
|
||||
description = "Code to be run before loading the LSP. Useful for requiring plugins";
|
||||
default = "";
|
||||
};
|
||||
|
||||
postConfig = mkOption {
|
||||
type = types.lines;
|
||||
description = "Code to be run after loading the LSP. This is an internal option";
|
||||
default = "";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
runWrappers = wrappers: s:
|
||||
if wrappers == []
|
||||
then s
|
||||
else (head wrappers) (runWrappers (tail wrappers) s);
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
extraPlugins = [pkgs.vimPlugins.nvim-lspconfig];
|
||||
|
||||
maps.normal = let
|
||||
diagnosticMaps =
|
||||
mapAttrs
|
||||
(key: action: {
|
||||
silent = cfg.keymaps.silent;
|
||||
action = "vim.diagnostic.${action}";
|
||||
lua = true;
|
||||
})
|
||||
cfg.keymaps.diagnostic;
|
||||
|
||||
lspBuf =
|
||||
mapAttrs
|
||||
(key: action: {
|
||||
silent = cfg.keymaps.silent;
|
||||
action = "vim.lsp.buf.${action}";
|
||||
lua = true;
|
||||
})
|
||||
cfg.keymaps.lspBuf;
|
||||
in
|
||||
mkMerge [
|
||||
diagnosticMaps
|
||||
lspBuf
|
||||
];
|
||||
|
||||
# Enable all LSP servers
|
||||
extraConfigLua = ''
|
||||
-- LSP {{{
|
||||
do
|
||||
${cfg.preConfig}
|
||||
|
||||
local __lspServers = ${helpers.toLuaObject cfg.enabledServers}
|
||||
local __lspOnAttach = function(client, bufnr)
|
||||
${cfg.onAttach}
|
||||
end
|
||||
local __lspCapabilities = function()
|
||||
capabilities = vim.lsp.protocol.make_client_capabilities()
|
||||
|
||||
${cfg.capabilities}
|
||||
|
||||
return capabilities
|
||||
end
|
||||
|
||||
local __setup = ${runWrappers cfg.setupWrappers "{
|
||||
on_attach = __lspOnAttach,
|
||||
capabilities = __lspCapabilities()
|
||||
}"}
|
||||
|
||||
for i,server in ipairs(__lspServers) do
|
||||
if type(server) == "string" then
|
||||
require('lspconfig')[server].setup(__setup)
|
||||
else
|
||||
local options = ${runWrappers cfg.setupWrappers "server.extraOptions"}
|
||||
|
||||
if options == nil then
|
||||
options = __setup
|
||||
else
|
||||
options = vim.tbl_extend("keep", options, __setup)
|
||||
end
|
||||
|
||||
require('lspconfig')[server.name].setup(options)
|
||||
end
|
||||
end
|
||||
|
||||
${cfg.postConfig}
|
||||
end
|
||||
-- }}}
|
||||
'';
|
||||
};
|
||||
}
|
144
plugins/lsp/helpers.nix
Normal file
144
plugins/lsp/helpers.nix
Normal file
|
@ -0,0 +1,144 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
mkLsp = {
|
||||
name,
|
||||
description ? "Enable ${name}.",
|
||||
serverName ? name,
|
||||
package ? pkgs.${name},
|
||||
extraPackages ? {},
|
||||
cmd ? (cfg: null),
|
||||
settings ? (cfg: cfg),
|
||||
settingsOptions ? {},
|
||||
...
|
||||
}:
|
||||
# returns a module
|
||||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
options,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
cfg = config.plugins.lsp.servers.${name};
|
||||
helpers = import ../helpers.nix {inherit lib;};
|
||||
|
||||
packageOption =
|
||||
if package != null
|
||||
then {
|
||||
package = mkOption {
|
||||
default = package;
|
||||
type = types.nullOr types.package;
|
||||
};
|
||||
}
|
||||
else {};
|
||||
in {
|
||||
options = {
|
||||
plugins.lsp.servers.${name} =
|
||||
{
|
||||
enable = mkEnableOption description;
|
||||
|
||||
cmd = mkOption {
|
||||
type = with types; nullOr (listOf str);
|
||||
default = cmd cfg;
|
||||
};
|
||||
|
||||
filetypes = helpers.mkNullOrOption (types.listOf types.str) ''
|
||||
Set of filetypes for which to attempt to resolve {root_dir}.
|
||||
May be empty, or server may specify a default value.
|
||||
'';
|
||||
|
||||
autostart = helpers.defaultNullOpts.mkBool true ''
|
||||
Controls if the `FileType` autocommand that launches a language server is created.
|
||||
If `false`, allows for deferring language servers until manually launched with
|
||||
`:LspStart` (|lspconfig-commands|).
|
||||
'';
|
||||
|
||||
onAttach =
|
||||
helpers.mkCompositeOption "Server specific on_attach behavior."
|
||||
{
|
||||
override = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Override the global `plugins.lsp.onAttach` function.";
|
||||
};
|
||||
|
||||
function = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Body of the on_attach function.
|
||||
The argument `client` and `bufnr` is provided.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
settings = settingsOptions;
|
||||
|
||||
extraSettings = mkOption {
|
||||
type = types.attrs;
|
||||
description = ''
|
||||
Extra settings for the ${name} language server.
|
||||
'';
|
||||
};
|
||||
|
||||
extraOptions = mkOption {
|
||||
default = {};
|
||||
type = types.attrs;
|
||||
description = "Extra options for the ${name} language server.";
|
||||
};
|
||||
}
|
||||
// packageOption;
|
||||
};
|
||||
|
||||
config = let
|
||||
extraSettingsOption = options.plugins.lsp.servers.${name}.extraSettings;
|
||||
extraSettingsAreDefined = extraSettingsOption.isDefined;
|
||||
in
|
||||
mkIf cfg.enable
|
||||
{
|
||||
extraPackages =
|
||||
(optional (package != null) cfg.package)
|
||||
++ (mapAttrsToList (name: _: cfg."${name}Package") extraPackages);
|
||||
|
||||
plugins.lsp.enabledServers = [
|
||||
{
|
||||
name = serverName;
|
||||
extraOptions =
|
||||
{
|
||||
inherit (cfg) cmd filetypes autostart;
|
||||
on_attach =
|
||||
helpers.ifNonNull' cfg.onAttach
|
||||
(
|
||||
helpers.mkRaw ''
|
||||
function(client, bufnr)
|
||||
${optionalString (!cfg.onAttach.override) config.plugins.lsp.onAttach}
|
||||
${cfg.onAttach.function}
|
||||
end
|
||||
''
|
||||
);
|
||||
settings =
|
||||
(settings cfg.settings)
|
||||
// (
|
||||
if extraSettingsAreDefined
|
||||
then cfg.extraSettings
|
||||
else {}
|
||||
);
|
||||
}
|
||||
// cfg.extraOptions;
|
||||
}
|
||||
];
|
||||
|
||||
warnings =
|
||||
optional extraSettingsAreDefined
|
||||
(
|
||||
let
|
||||
optionPrefix = "plugins.lsp.servers.${name}";
|
||||
in "The `${optionPrefix}.extraSettings` option is deprecated in favor of `${optionPrefix}.extraOptions.settings`."
|
||||
);
|
||||
};
|
||||
};
|
||||
}
|
57
plugins/lsp/inc-rename.nix
Normal file
57
plugins/lsp/inc-rename.nix
Normal file
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
} @ args:
|
||||
with lib; let
|
||||
helpers = import ../helpers.nix args;
|
||||
in {
|
||||
options.plugins.inc-rename = {
|
||||
enable = mkEnableOption "inc-rename, a plugin previewing LSP renaming";
|
||||
|
||||
package = helpers.mkPackageOption "inc-rename" pkgs.vimPlugins.inc-rename-nvim;
|
||||
|
||||
cmdName = helpers.defaultNullOpts.mkStr "IncRename" "the name of the command";
|
||||
|
||||
hlGroup =
|
||||
helpers.defaultNullOpts.mkStr "Substitute"
|
||||
"the highlight group used for highlighting the identifier's new name";
|
||||
|
||||
previewEmptyName = helpers.defaultNullOpts.mkBool false ''
|
||||
whether an empty new name should be previewed; if false the command preview will be cancelled
|
||||
instead
|
||||
'';
|
||||
|
||||
showMessage = helpers.defaultNullOpts.mkBool true ''
|
||||
whether to display a `Renamed m instances in n files` message after a rename operation
|
||||
'';
|
||||
|
||||
inputBufferType = helpers.defaultNullOpts.mkNullable (types.enum ["dressing"]) "null" ''
|
||||
the type of the external input buffer to use
|
||||
'';
|
||||
|
||||
postHook = helpers.defaultNullOpts.mkNullable types.str "null" ''
|
||||
callback to run after renaming, receives the result table (from LSP handler) as an argument
|
||||
'';
|
||||
};
|
||||
|
||||
config = let
|
||||
cfg = config.plugins.inc-rename;
|
||||
setupOptions = {
|
||||
cmd_name = cfg.cmdName;
|
||||
hl_group = cfg.hlGroup;
|
||||
preview_empty_name = cfg.previewEmptyName;
|
||||
show_message = cfg.showMessage;
|
||||
input_buffer_type = cfg.inputBufferType;
|
||||
post_hook = helpers.ifNonNull' cfg.postHook (helpers.mkRaw cfg.postHook);
|
||||
};
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
extraPlugins = [cfg.package];
|
||||
|
||||
extraConfigLua = ''
|
||||
require("inc_rename").setup(${helpers.toLuaObject setupOptions})
|
||||
'';
|
||||
};
|
||||
}
|
359
plugins/lsp/language-servers/default.nix
Normal file
359
plugins/lsp/language-servers/default.nix
Normal file
|
@ -0,0 +1,359 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
} @ args:
|
||||
with lib; let
|
||||
lspHelpers = import ../helpers.nix args;
|
||||
helpers = import ../../helpers.nix {inherit lib;};
|
||||
|
||||
optionWarnings = import ../../../lib/option-warnings.nix args;
|
||||
basePluginPath = ["plugins" "lsp" "servers"];
|
||||
|
||||
servers = [
|
||||
{
|
||||
name = "astro";
|
||||
description = "Enable astrols, for Astro";
|
||||
package = pkgs.nodePackages."@astrojs/language-server";
|
||||
cmd = cfg: ["${cfg.package}/bin/astro-ls" "--stdio"];
|
||||
}
|
||||
{
|
||||
name = "bashls";
|
||||
description = "Enable bashls, for bash.";
|
||||
package = pkgs.nodePackages.bash-language-server;
|
||||
}
|
||||
{
|
||||
name = "clangd";
|
||||
description = "Enable clangd LSP, for C/C++.";
|
||||
package = pkgs.clang-tools;
|
||||
}
|
||||
{
|
||||
name = "cssls";
|
||||
description = "Enable cssls, for CSS";
|
||||
package = pkgs.nodePackages.vscode-langservers-extracted;
|
||||
cmd = cfg: ["${cfg.package}/bin/vscode-css-language-server" "--stdio"];
|
||||
}
|
||||
{
|
||||
name = "dartls";
|
||||
description = "Enable dart language-server, for dart";
|
||||
package = pkgs.dart;
|
||||
settingsOptions = {
|
||||
analysisExcludedFolders = mkOption {
|
||||
type = types.nullOr (types.listOf types.str);
|
||||
default = null;
|
||||
description = ''
|
||||
An array of paths (absolute or relative to each workspace folder) that should be
|
||||
excluded from analysis.
|
||||
'';
|
||||
};
|
||||
enableSdkFormatter = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
description = ''
|
||||
When set to false, prevents registration (or unregisters) the SDK formatter. When set
|
||||
to true or not supplied, will register/reregister the SDK formatter
|
||||
'';
|
||||
};
|
||||
lineLength = mkOption {
|
||||
type = types.nullOr types.int;
|
||||
default = null;
|
||||
description = ''
|
||||
The number of characters the formatter should wrap code at. If unspecified, code will
|
||||
be wrapped at 80 characters.
|
||||
'';
|
||||
};
|
||||
completeFunctionCalls = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
When set to true, completes functions/methods with their required parameters.
|
||||
'';
|
||||
};
|
||||
showTodos = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to generate diagnostics for TODO comments. If unspecified, diagnostics will not
|
||||
be generated.
|
||||
'';
|
||||
};
|
||||
renameFilesWithClasses = mkOption {
|
||||
type = types.nullOr (types.enum ["always" "prompt"]);
|
||||
default = null;
|
||||
description = ''
|
||||
When set to "always", will include edits to rename files when classes are renamed if the
|
||||
filename matches the class name (but in snake_form). When set to "prompt", a prompt will
|
||||
be shown on each class rename asking to confirm the file rename. Otherwise, files will
|
||||
not be renamed. Renames are performed using LSP's ResourceOperation edits - that means
|
||||
the rename is simply included in the resulting WorkspaceEdit and must be handled by the
|
||||
client.
|
||||
'';
|
||||
};
|
||||
enableSnippets = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
description = ''
|
||||
Whether to include code snippets (such as class, stful, switch) in code completion. When
|
||||
unspecified, snippets will be included.
|
||||
'';
|
||||
};
|
||||
updateImportsOnRename = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
description = ''
|
||||
Whether to update imports and other directives when files are renamed. When unspecified,
|
||||
imports will be updated if the client supports willRenameFiles requests
|
||||
'';
|
||||
};
|
||||
documentation = mkOption {
|
||||
type = types.nullOr (types.enum ["none" "summary" "full"]);
|
||||
default = null;
|
||||
description = ''
|
||||
The typekind of dartdocs to include in Hovers, Code Completion, Signature Help and other
|
||||
similar requests. If not set, defaults to full
|
||||
'';
|
||||
};
|
||||
includeDependenciesInWorkspaceSymbols = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
default = null;
|
||||
description = ''
|
||||
Whether to include symbols from dependencies and Dart/Flutter SDKs in Workspace Symbol
|
||||
results. If not set, defaults to true.
|
||||
'';
|
||||
};
|
||||
};
|
||||
settings = cfg: {dart = cfg;};
|
||||
}
|
||||
{
|
||||
name = "denols";
|
||||
description = "Enable denols, for Deno";
|
||||
package = pkgs.deno;
|
||||
}
|
||||
{
|
||||
name = "eslint";
|
||||
description = "Enable eslint";
|
||||
package = pkgs.nodePackages.vscode-langservers-extracted;
|
||||
cmd = cfg: ["${cfg.package}/bin/vscode-eslint-language-server" "--stdio"];
|
||||
}
|
||||
{
|
||||
name = "elixirls";
|
||||
description = "Enable elixirls";
|
||||
package = pkgs.elixir_ls;
|
||||
cmd = cfg: ["${cfg.package}/bin/elixir-ls"];
|
||||
}
|
||||
{
|
||||
name = "gdscript";
|
||||
description = "Enable gdscript, for Godot";
|
||||
package = null;
|
||||
}
|
||||
{
|
||||
name = "gopls";
|
||||
description = "Enable gopls, for Go.";
|
||||
}
|
||||
{
|
||||
name = "hls";
|
||||
description = "Enable haskell language server";
|
||||
package = pkgs.haskell-language-server;
|
||||
cmd = cfg: ["haskell-language-server-wrapper"];
|
||||
}
|
||||
{
|
||||
name = "html";
|
||||
description = "Enable html, for HTML";
|
||||
package = pkgs.nodePackages.vscode-langservers-extracted;
|
||||
cmd = cfg: ["${cfg.package}/bin/vscode-html-language-server" "--stdio"];
|
||||
}
|
||||
{
|
||||
name = "jsonls";
|
||||
description = "Enable jsonls, for JSON";
|
||||
package = pkgs.nodePackages.vscode-langservers-extracted;
|
||||
cmd = cfg: ["${cfg.package}/bin/vscode-json-language-server" "--stdio"];
|
||||
}
|
||||
{
|
||||
name = "lua-ls";
|
||||
description = "Enable lua LS, for lua";
|
||||
# Use the old name of the lua LS if the user is on a stable branch of nixpkgs
|
||||
# Rename occured here: https://github.com/NixOS/nixpkgs/pull/215057
|
||||
package =
|
||||
if (hasAttr "lua-language-server" pkgs)
|
||||
then pkgs.lua-language-server
|
||||
else pkgs.sumneko-lua-language-server;
|
||||
serverName = "lua_ls";
|
||||
|
||||
# All available settings are documented here:
|
||||
# https://github.com/LuaLS/lua-language-server/wiki/Settings
|
||||
settingsOptions = {
|
||||
runtime = {
|
||||
version = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
description = ''
|
||||
Tell the language server which version of Lua you're using
|
||||
(most likely LuaJIT in the case of Neovim)
|
||||
'';
|
||||
default = "LuaJIT";
|
||||
};
|
||||
};
|
||||
diagnostics = {
|
||||
globals = mkOption {
|
||||
type = types.nullOr (types.listOf types.str);
|
||||
description = ''
|
||||
An array of variable names that will be declared as global.
|
||||
'';
|
||||
default = ["vim"];
|
||||
};
|
||||
};
|
||||
workspace = {
|
||||
library = mkOption {
|
||||
type = types.nullOr (types.either types.str (helpers.rawType));
|
||||
description = ''
|
||||
An array of abosolute or workspace-relative paths that will be added to the workspace
|
||||
diagnosis - meaning you will get completion and context from these library files.
|
||||
Can be a file or directory.
|
||||
Files included here will have some features disabled such as renaming fields to
|
||||
prevent accidentally renaming your library files.
|
||||
'';
|
||||
default = helpers.mkRaw "vim.api.nvim_get_runtime_file('', true)";
|
||||
};
|
||||
checkThirdParty = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
description = ''
|
||||
Whether third party libraries can be automatically detected and applied.
|
||||
Third party libraries can set up the environment to be as close as possible to your
|
||||
target runtime environment.
|
||||
'';
|
||||
# prevents an annoying warning
|
||||
# https://github.com/LuaLS/lua-language-server/discussions/1688#discussioncomment-4185003
|
||||
default = false;
|
||||
};
|
||||
};
|
||||
telemetry = {
|
||||
enable = mkEnableOption "telemetry";
|
||||
};
|
||||
};
|
||||
settings = cfg: {Lua = cfg;};
|
||||
}
|
||||
{
|
||||
name = "metals";
|
||||
description = "Enable metals, for Scala";
|
||||
}
|
||||
{
|
||||
name = "nil_ls";
|
||||
description = "Enable nil, for Nix";
|
||||
package = pkgs.nil;
|
||||
settingsOptions = {
|
||||
formatting.command = mkOption {
|
||||
type = types.nullOr (types.listOf types.str);
|
||||
default = null;
|
||||
description = ''
|
||||
External formatter command (with arguments).
|
||||
It should accepts file content in stdin and print the formatted code into stdout.
|
||||
'';
|
||||
};
|
||||
diagnostics = {
|
||||
ignored = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = ''
|
||||
Ignored diagnostic kinds.
|
||||
The kind identifier is a snake_cased_string usually shown together
|
||||
with the diagnostic message.
|
||||
'';
|
||||
};
|
||||
excludedFiles = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = ''
|
||||
Files to exclude from showing diagnostics. Useful for generated files.
|
||||
It accepts an array of paths. Relative paths are joint to the workspace root.
|
||||
Glob patterns are currently not supported.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
settings = cfg: {nil = {inherit (cfg) formatting diagnostics;};};
|
||||
}
|
||||
{
|
||||
name = "pylsp";
|
||||
description = "Enable pylsp, for Python.";
|
||||
package = pkgs.python3Packages.python-lsp-server;
|
||||
settings = cfg: {pylsp = cfg;};
|
||||
}
|
||||
{
|
||||
name = "pyright";
|
||||
description = "Enable pyright, for Python.";
|
||||
}
|
||||
{
|
||||
name = "rnix-lsp";
|
||||
description = "Enable rnix LSP, for Nix";
|
||||
serverName = "rnix";
|
||||
}
|
||||
{
|
||||
name = "ruff-lsp";
|
||||
description = "Enable ruff-lsp, for Python.";
|
||||
package = pkgs.python3Packages.ruff-lsp;
|
||||
serverName = "ruff_lsp";
|
||||
}
|
||||
{
|
||||
name = "rust-analyzer";
|
||||
description = "Enable rust-analyzer, for Rust.";
|
||||
serverName = "rust_analyzer";
|
||||
|
||||
settingsOptions = import ./rust-analyzer-config.nix lib;
|
||||
settings = cfg: {rust-analyzer = cfg;};
|
||||
}
|
||||
{
|
||||
name = "sourcekit";
|
||||
description = "Enable the sourcekit language server, for Swift and C/C++/Objective-C";
|
||||
package = pkgs.sourcekit-lsp;
|
||||
}
|
||||
{
|
||||
name = "tailwindcss";
|
||||
description = "Enable tailwindcss language server, for tailwindcss";
|
||||
package = pkgs.nodePackages."@tailwindcss/language-server";
|
||||
}
|
||||
{
|
||||
name = "terraformls";
|
||||
description = "Enable terraform-ls, for terraform";
|
||||
package = pkgs.terraform-ls;
|
||||
}
|
||||
{
|
||||
name = "texlab";
|
||||
description = "Enable texlab language server, for LaTeX";
|
||||
}
|
||||
{
|
||||
name = "tsserver";
|
||||
description = "Enable tsserver for typescript";
|
||||
package = pkgs.nodePackages.typescript-language-server;
|
||||
}
|
||||
{
|
||||
name = "typst-lsp";
|
||||
serverName = "typst_lsp";
|
||||
description = "Enable typst-lsp for typst";
|
||||
package = pkgs.typst-lsp;
|
||||
}
|
||||
{
|
||||
name = "vuels";
|
||||
description = "Enable vuels, for Vue";
|
||||
package = pkgs.nodePackages.vls;
|
||||
}
|
||||
{
|
||||
name = "yamlls";
|
||||
description = "Enable yamlls, for yaml";
|
||||
package = pkgs.yaml-language-server;
|
||||
}
|
||||
{
|
||||
name = "zls";
|
||||
description = "Enable zls, for Zig.";
|
||||
}
|
||||
];
|
||||
in {
|
||||
imports =
|
||||
lib.lists.map (lspHelpers.mkLsp) servers
|
||||
++ [./pylsp.nix]
|
||||
++ [
|
||||
(optionWarnings.mkRenamedOption {
|
||||
option = basePluginPath ++ ["sumneko-lua"];
|
||||
newOption = basePluginPath ++ ["lua-ls"];
|
||||
})
|
||||
];
|
||||
}
|
447
plugins/lsp/language-servers/pylsp.nix
Normal file
447
plugins/lsp/language-servers/pylsp.nix
Normal file
|
@ -0,0 +1,447 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
helpers = import ../../helpers.nix {inherit lib;};
|
||||
cfg = config.plugins.lsp.servers.pylsp;
|
||||
in {
|
||||
# All settings are documented here:
|
||||
# https://github.com/python-lsp/python-lsp-server/blob/develop/CONFIGURATION.md
|
||||
|
||||
options.plugins.lsp.servers.pylsp.settings = {
|
||||
configurationSources = mkOption {
|
||||
type = lib.types.nullOr (types.enum ["pycodestyle" "flake8"]);
|
||||
description = "List of configuration sources to use.";
|
||||
default = null;
|
||||
apply = (
|
||||
value:
|
||||
if (value != null)
|
||||
then [value]
|
||||
else null
|
||||
);
|
||||
};
|
||||
|
||||
plugins = helpers.mkCompositeOption "pylsp plugins" {
|
||||
autopep8 = helpers.mkCompositeOption "autopep8 settings" {
|
||||
enabled = helpers.defaultNullOpts.mkBool true ''
|
||||
Enable or disable the plugin.
|
||||
Setting this explicitely to `true` will install the dependency for this plugin (autopep8).
|
||||
'';
|
||||
};
|
||||
|
||||
flake8 = helpers.mkCompositeOption "flake8 settings" {
|
||||
config = helpers.mkNullOrOption types.str ''
|
||||
Path to the config file that will be the authoritative config source.
|
||||
'';
|
||||
|
||||
enabled = helpers.defaultNullOpts.mkBool false ''
|
||||
Enable or disable the plugin.
|
||||
Setting this explicitely to `true` will install the dependency for this plugin (flake8).
|
||||
'';
|
||||
|
||||
exclude = helpers.defaultNullOpts.mkNullable (types.listOf types.str) "[]" ''
|
||||
List of files or directories to exclude.
|
||||
'';
|
||||
|
||||
executable = helpers.mkNullOrOption types.str ''
|
||||
Path to the flake8 executable.
|
||||
'';
|
||||
|
||||
filename = helpers.mkNullOrOption types.str ''
|
||||
Only check for filenames matching the patterns in this list.
|
||||
'';
|
||||
|
||||
hangClosing = helpers.mkNullOrOption types.bool ''
|
||||
Hang closing bracket instead of matching indentation of opening bracket's line.
|
||||
'';
|
||||
|
||||
ignore = helpers.defaultNullOpts.mkNullable (types.listOf types.str) "[]" ''
|
||||
List of errors and warnings to ignore (or skip).
|
||||
'';
|
||||
|
||||
maxComplexity = helpers.mkNullOrOption types.int ''
|
||||
Maximum allowed complexity threshold.
|
||||
'';
|
||||
|
||||
maxLineLength = helpers.mkNullOrOption types.int ''
|
||||
Maximum allowed line length for the entirety of this run.
|
||||
'';
|
||||
|
||||
indentSize = helpers.mkNullOrOption types.int ''
|
||||
Set indentation spaces.
|
||||
'';
|
||||
|
||||
perFileIgnores = helpers.defaultNullOpts.mkNullable (types.listOf types.str) "[]" ''
|
||||
A pairing of filenames and violation codes that defines which violations to ignore in a
|
||||
particular file.
|
||||
|
||||
For example: `["file_path.py:W305,W304"]`.
|
||||
'';
|
||||
|
||||
select = helpers.mkNullOrOption (types.listOf types.str) ''
|
||||
List of errors and warnings to enable.
|
||||
'';
|
||||
};
|
||||
|
||||
jedi = helpers.mkCompositeOption "jedi settings" {
|
||||
auto_import_modules =
|
||||
helpers.defaultNullOpts.mkNullable
|
||||
(types.listOf types.str)
|
||||
"[ \"numpy\" ]"
|
||||
"List of module names for `jedi.settings.auto_import_modules`.";
|
||||
|
||||
extra_paths = helpers.defaultNullOpts.mkNullable (types.listOf types.str) "[]" ''
|
||||
Define extra paths for jedi.Script.
|
||||
'';
|
||||
|
||||
environment = helpers.mkNullOrOption types.str ''
|
||||
Define environment for jedi.Script and Jedi.names.
|
||||
'';
|
||||
};
|
||||
|
||||
jedi_completion = helpers.mkCompositeOption "jedi_completion settings" {
|
||||
enabled = helpers.defaultNullOpts.mkBool true "Enable or disable the plugin.";
|
||||
|
||||
include_params = helpers.defaultNullOpts.mkBool true ''
|
||||
Auto-completes methods and classes with tabstops for each parameter.
|
||||
'';
|
||||
|
||||
include_class_objects = helpers.defaultNullOpts.mkBool false ''
|
||||
Adds class objects as a separate completion item.
|
||||
'';
|
||||
|
||||
include_function_objects = helpers.defaultNullOpts.mkBool false ''
|
||||
Adds function objects as a separate completion item.
|
||||
'';
|
||||
|
||||
fuzzy = helpers.defaultNullOpts.mkBool false ''
|
||||
Enable fuzzy when requesting autocomplete.
|
||||
'';
|
||||
|
||||
eager = helpers.defaultNullOpts.mkBool false ''
|
||||
Resolve documentation and detail eagerly.
|
||||
'';
|
||||
|
||||
resolve_at_most = helpers.defaultNullOpts.mkInt 25 ''
|
||||
How many labels and snippets (at most) should be resolved.
|
||||
'';
|
||||
|
||||
cache_for =
|
||||
helpers.defaultNullOpts.mkNullable
|
||||
(types.listOf types.str)
|
||||
"[ \"pandas\" \"numpy\" \"tensorflow\" \"matplotlib\" ]"
|
||||
"Modules for which labels and snippets should be cached.";
|
||||
};
|
||||
|
||||
jedi_definition = helpers.mkCompositeOption "jedi_definition settings" {
|
||||
enabled = helpers.defaultNullOpts.mkBool true "Enable or disable the plugin.";
|
||||
|
||||
follow_imports = helpers.defaultNullOpts.mkBool true ''
|
||||
The goto call will follow imports.
|
||||
'';
|
||||
|
||||
follow_builtin_imports = helpers.defaultNullOpts.mkBool true ''
|
||||
If follow_imports is true will decide if it follow builtin imports.
|
||||
'';
|
||||
|
||||
follow_builtin_definitions = helpers.defaultNullOpts.mkBool true ''
|
||||
Follow builtin and extension definitions to stubs.
|
||||
'';
|
||||
};
|
||||
|
||||
jedi_hover = helpers.mkCompositeOption "jedi_hover settings" {
|
||||
enabled = helpers.defaultNullOpts.mkBool true "Enable or disable the plugin.";
|
||||
};
|
||||
|
||||
jedi_references = helpers.mkCompositeOption "jedi_references settings" {
|
||||
enabled = helpers.defaultNullOpts.mkBool true "Enable or disable the plugin.";
|
||||
};
|
||||
|
||||
jedi_signature_help = helpers.mkCompositeOption "jedi_signature_help settings" {
|
||||
enabled = helpers.defaultNullOpts.mkBool true "Enable or disable the plugin.";
|
||||
};
|
||||
|
||||
jedi_symbols = helpers.mkCompositeOption "jedi_symbols settings" {
|
||||
enabled = helpers.defaultNullOpts.mkBool true "Enable or disable the plugin.";
|
||||
|
||||
all_scopes = helpers.defaultNullOpts.mkBool true ''
|
||||
If true lists the names of all scopes instead of only the module namespace.
|
||||
'';
|
||||
|
||||
include_import_symbols = helpers.defaultNullOpts.mkBool true ''
|
||||
If true includes symbols imported from other libraries.
|
||||
'';
|
||||
};
|
||||
|
||||
mccabe = helpers.mkCompositeOption "mccabe settings" {
|
||||
enabled = helpers.defaultNullOpts.mkBool true ''
|
||||
Enable or disable the plugin.
|
||||
Setting this explicitely to `true` will install the dependency for this plugin (mccabe).
|
||||
'';
|
||||
|
||||
threshold = helpers.defaultNullOpts.mkInt 15 ''
|
||||
The minimum threshold that triggers warnings about cyclomatic complexity.
|
||||
'';
|
||||
};
|
||||
|
||||
preload = helpers.mkCompositeOption "preload settings" {
|
||||
enabled = helpers.defaultNullOpts.mkBool true "Enable or disable the plugin.";
|
||||
|
||||
modules = helpers.defaultNullOpts.mkNullable (types.listOf types.str) "[]" ''
|
||||
List of modules to import on startup.
|
||||
'';
|
||||
};
|
||||
|
||||
pycodestyle = helpers.mkCompositeOption "pycodestyle settings" {
|
||||
enabled = helpers.defaultNullOpts.mkBool true ''
|
||||
Enable or disable the plugin.
|
||||
Setting this explicitely to `true` will install the dependency for this plugin
|
||||
(pycodestyle).
|
||||
'';
|
||||
|
||||
exclude = helpers.defaultNullOpts.mkNullable (types.listOf types.str) "[]" ''
|
||||
Exclude files or directories which match these patterns.
|
||||
'';
|
||||
|
||||
filename = helpers.defaultNullOpts.mkNullable (types.listOf types.str) "[]" ''
|
||||
When parsing directories, only check filenames matching these patterns.
|
||||
'';
|
||||
|
||||
ropeFolder = helpers.mkNullOrOption (types.listOf types.str) ''
|
||||
Select errors and warnings.
|
||||
'';
|
||||
|
||||
ignore = helpers.defaultNullOpts.mkNullable (types.listOf types.str) "[]" ''
|
||||
Ignore errors and warnings.
|
||||
'';
|
||||
|
||||
hangClosing = helpers.mkNullOrOption types.bool ''
|
||||
Hang closing bracket instead of matching indentation of opening bracket's line.
|
||||
'';
|
||||
|
||||
maxLineLength = helpers.mkNullOrOption types.int ''
|
||||
Set maximum allowed line length.
|
||||
'';
|
||||
|
||||
indentSize = helpers.mkNullOrOption types.int ''
|
||||
Set indentation spaces.
|
||||
'';
|
||||
};
|
||||
|
||||
pydocstyle = helpers.mkCompositeOption "pydocstyle settings" {
|
||||
enabled = helpers.defaultNullOpts.mkBool false ''
|
||||
Enable or disable the plugin.
|
||||
Setting this explicitely to `true` will install the dependency for this plugin
|
||||
(pydocstyle).
|
||||
'';
|
||||
|
||||
convention =
|
||||
helpers.mkNullOrOption
|
||||
(types.enum [
|
||||
"pep257"
|
||||
"numpy"
|
||||
"google"
|
||||
"None"
|
||||
])
|
||||
"Choose the basic list of checked errors by specifying an existing convention.";
|
||||
|
||||
addIgnore = helpers.defaultNullOpts.mkNullable (types.listOf types.str) "[]" ''
|
||||
Ignore errors and warnings in addition to the specified convention.
|
||||
'';
|
||||
|
||||
addSelect = helpers.defaultNullOpts.mkNullable (types.listOf types.str) "[]" ''
|
||||
Select errors and warnings in addition to the specified convention.
|
||||
'';
|
||||
|
||||
ignore = helpers.defaultNullOpts.mkNullable (types.listOf types.str) "[]" ''
|
||||
Ignore errors and warnings.
|
||||
'';
|
||||
|
||||
select = helpers.mkNullOrOption (types.listOf types.str) ''
|
||||
Select errors and warnings.
|
||||
'';
|
||||
|
||||
match = helpers.defaultNullOpts.mkStr "(?!test_).*\\.py" ''
|
||||
Check only files that exactly match the given regular expression;
|
||||
default is to match files that don't start with 'test_' but end with '.py'.
|
||||
'';
|
||||
|
||||
matchDir = helpers.defaultNullOpts.mkStr "[^\\.].*" ''
|
||||
Search only dirs that exactly match the given regular expression;
|
||||
default is to match dirs which do not begin with a dot.
|
||||
'';
|
||||
};
|
||||
|
||||
pyflakes = helpers.mkCompositeOption "pyflakes settings" {
|
||||
enabled = helpers.defaultNullOpts.mkBool true ''
|
||||
Enable or disable the plugin.
|
||||
Setting this explicitely to `true` will install the dependency for this plugin (pyflakes).
|
||||
'';
|
||||
};
|
||||
|
||||
pylint = helpers.mkCompositeOption "pylint settings" {
|
||||
enabled = helpers.defaultNullOpts.mkBool false ''
|
||||
Enable or disable the plugin.
|
||||
Setting this explicitely to `true` will install the dependency for this plugin (pylint).
|
||||
'';
|
||||
|
||||
args = helpers.defaultNullOpts.mkNullable (types.listOf types.str) "[]" ''
|
||||
Arguments to pass to pylint.
|
||||
'';
|
||||
|
||||
executable = helpers.mkNullOrOption types.str ''
|
||||
Executable to run pylint with.
|
||||
Enabling this will run pylint on unsaved files via stdin.
|
||||
Can slow down workflow. Only works with python3.
|
||||
'';
|
||||
};
|
||||
|
||||
rope_autoimport = helpers.mkCompositeOption "rope_autoimport settings" {
|
||||
enabled = helpers.defaultNullOpts.mkBool false ''
|
||||
Enable or disable the plugin.
|
||||
Setting this explicitely to `true` will install the dependency for this plugin (rope).
|
||||
'';
|
||||
|
||||
memory = helpers.defaultNullOpts.mkBool false ''
|
||||
Make the autoimport database memory only.
|
||||
Drastically increases startup time.
|
||||
'';
|
||||
};
|
||||
|
||||
rope_completion = helpers.mkCompositeOption "rope_completion settings" {
|
||||
enabled = helpers.defaultNullOpts.mkBool false ''
|
||||
Enable or disable the plugin.
|
||||
Setting this explicitely to `true` will install the dependency for this plugin (rope).
|
||||
'';
|
||||
|
||||
eager = helpers.defaultNullOpts.mkBool false ''
|
||||
Resolve documentation and detail eagerly.
|
||||
'';
|
||||
};
|
||||
|
||||
yapf = helpers.mkCompositeOption "yapf settings" {
|
||||
enabled = helpers.defaultNullOpts.mkBool true ''
|
||||
Enable or disable the plugin.
|
||||
Setting this explicitely to `true` will install the dependency for this plugin (yapf).
|
||||
'';
|
||||
};
|
||||
|
||||
### THIRD-PARTY PLUGINS
|
||||
pylsp_mypy = helpers.mkCompositeOption "pylsp_mypy settings" {
|
||||
enabled = helpers.defaultNullOpts.mkBool false ''
|
||||
Enable or disable the plugin.
|
||||
Setting this explicitely to `true` will install the dependency for this plugin
|
||||
(pylsp-mypy).
|
||||
'';
|
||||
|
||||
live_mode = helpers.defaultNullOpts.mkBool true ''
|
||||
Provides type checking as you type.
|
||||
This writes to a tempfile every time a check is done.
|
||||
Turning off live_mode means you must save your changes for mypy diagnostics to update
|
||||
correctly.
|
||||
'';
|
||||
|
||||
dmypy = helpers.defaultNullOpts.mkBool false ''
|
||||
Executes via dmypy run rather than mypy.
|
||||
This uses the dmypy daemon and may dramatically improve the responsiveness of the pylsp
|
||||
server, however this currently does not work in live_mode.
|
||||
Enabling this disables live_mode, even for conflicting configs.
|
||||
'';
|
||||
|
||||
strict = helpers.defaultNullOpts.mkBool false ''
|
||||
Refers to the strict option of mypy.
|
||||
This option often is too strict to be useful.
|
||||
'';
|
||||
|
||||
overrides =
|
||||
helpers.defaultNullOpts.mkNullable
|
||||
(with types; listOf (either bool str))
|
||||
"[true]"
|
||||
''
|
||||
Specifies a list of alternate or supplemental command-line options.
|
||||
This modifies the options passed to mypy or the mypy-specific ones passed to dmypy run.
|
||||
When present, the special boolean member true is replaced with the command-line options that
|
||||
would've been passed had overrides not been specified.
|
||||
Later options take precedence, which allows for replacing or negating individual default
|
||||
options (see mypy.main:process_options and mypy --help | grep inverse).
|
||||
'';
|
||||
|
||||
dmypy_status_file = helpers.defaultNullOpts.mkStr ".dmypy.json" ''
|
||||
Specifies which status file dmypy should use.
|
||||
This modifies the --status-file option passed to dmypy given dmypy is active.
|
||||
'';
|
||||
|
||||
config_sub_paths = helpers.defaultNullOpts.mkNullable (types.listOf types.str) "[]" ''
|
||||
Specifies sub paths under which the mypy configuration file may be found.
|
||||
For each directory searched for the mypy config file, this also searches the sub paths
|
||||
specified here.
|
||||
'';
|
||||
|
||||
report_progress = helpers.defaultNullOpts.mkBool false ''
|
||||
Report basic progress to the LSP client.
|
||||
With this option, pylsp-mypy will report when mypy is running, given your editor supports
|
||||
LSP progress reporting.
|
||||
For small files this might produce annoying flashing in your editor, especially in with
|
||||
live_mode.
|
||||
For large projects, enabling this can be helpful to assure yourself whether mypy is still
|
||||
running.
|
||||
'';
|
||||
};
|
||||
|
||||
### END OF THIRD-PARTY PLUGINS
|
||||
};
|
||||
|
||||
rope = helpers.mkCompositeOption "rope settings" {
|
||||
extensionModules = helpers.mkNullOrOption types.str ''
|
||||
Builtin and c-extension modules that are allowed to be imported and inspected by rope.
|
||||
'';
|
||||
|
||||
ropeFolder = helpers.mkNullOrOption (types.listOf types.str) ''
|
||||
The name of the folder in which rope stores project configurations and data.
|
||||
Pass null for not using such a folder at all.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config =
|
||||
mkIf cfg.enable
|
||||
{
|
||||
extraPackages = with cfg.settings; let
|
||||
isNotNullAndEnabled = x: (!isNull x) && x.enabled;
|
||||
in
|
||||
optionals (!isNull cfg.settings.plugins) (
|
||||
lists.flatten (map
|
||||
(
|
||||
pluginName: (
|
||||
optionals (isNotNullAndEnabled plugins.${pluginName})
|
||||
cfg.package.optional-dependencies.${pluginName}
|
||||
)
|
||||
)
|
||||
[
|
||||
"autopep8"
|
||||
"flake8"
|
||||
"mccabe"
|
||||
"pycodestyle"
|
||||
"pydocstyle"
|
||||
"pyflakes"
|
||||
"pylint"
|
||||
"yapf"
|
||||
])
|
||||
++ (
|
||||
optionals
|
||||
(
|
||||
(isNotNullAndEnabled plugins.rope_autoimport)
|
||||
|| (isNotNullAndEnabled plugins.rope_completion)
|
||||
)
|
||||
cfg.package.optional-dependencies.rope
|
||||
)
|
||||
++ (
|
||||
optional (isNotNullAndEnabled plugins.pylsp_mypy)
|
||||
pkgs.python3Packages.pylsp-mypy
|
||||
)
|
||||
);
|
||||
};
|
||||
}
|
1784
plugins/lsp/language-servers/rust-analyzer-config.nix
Normal file
1784
plugins/lsp/language-servers/rust-analyzer-config.nix
Normal file
File diff suppressed because it is too large
Load diff
13
plugins/lsp/language-servers/update_ra.md
Normal file
13
plugins/lsp/language-servers/update_ra.md
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Updating rust-analyzer options
|
||||
|
||||
Because there a large number of rust-analyzer options it's difficult to handle them by hand.
|
||||
|
||||
The options can be fetched from the [rust-analyzer package.json](https://github.com/rust-lang/rust-analyzer/blob/master/editors/code/package.json).
|
||||
|
||||
There is a derivation on the top-level flake that allows to build it easily, you just have to run:
|
||||
|
||||
```bash
|
||||
nix build .#rustAnalyzerOptions
|
||||
```
|
||||
|
||||
You can then copy the `result/share/rust-analyzer-config.nix` to the correct location.
|
47
plugins/lsp/lsp-lines.nix
Normal file
47
plugins/lsp/lsp-lines.nix
Normal file
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
cfg = config.plugins.lsp-lines;
|
||||
helpers = import ../helpers.nix {inherit lib;};
|
||||
in {
|
||||
options = {
|
||||
plugins.lsp-lines = {
|
||||
enable = mkEnableOption "lsp_lines.nvim";
|
||||
|
||||
package = helpers.mkPackageOption "lsp_lines.nvim" pkgs.vimPlugins.lsp_lines-nvim;
|
||||
|
||||
currentLine = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Show diagnostics only on current line";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
diagnosticConfig = {
|
||||
virtual_text = false;
|
||||
virtual_lines =
|
||||
if cfg.currentLine
|
||||
then {
|
||||
only_current_line = true;
|
||||
}
|
||||
else true;
|
||||
};
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
extraPlugins = [cfg.package];
|
||||
|
||||
extraConfigLua = ''
|
||||
do
|
||||
require("lsp_lines").setup()
|
||||
|
||||
vim.diagnostic.config(${helpers.toLuaObject diagnosticConfig})
|
||||
end
|
||||
'';
|
||||
};
|
||||
}
|
226
plugins/lsp/lspsaga.nix
Normal file
226
plugins/lsp/lspsaga.nix
Normal file
|
@ -0,0 +1,226 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
cfg = config.plugins.lspsaga;
|
||||
helpers = import ../helpers.nix {inherit lib;};
|
||||
in {
|
||||
options = {
|
||||
plugins.lspsaga = {
|
||||
enable = mkEnableOption "lspsaga.nvim";
|
||||
|
||||
package = helpers.mkPackageOption "lspsaga" pkgs.vimPlugins.lspsaga-nvim;
|
||||
|
||||
signs = {
|
||||
use = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = "Whether to use diagnostic signs";
|
||||
};
|
||||
|
||||
error = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Error diagnostic sign";
|
||||
};
|
||||
|
||||
warning = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Warning diagnostic sign";
|
||||
};
|
||||
|
||||
hint = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Hint diagnostic sign";
|
||||
};
|
||||
|
||||
info = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Info diagnostic sign";
|
||||
};
|
||||
};
|
||||
|
||||
headers = {
|
||||
error = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Error diagnostic header";
|
||||
};
|
||||
|
||||
warning = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Warning diagnostic header";
|
||||
};
|
||||
|
||||
hint = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Hint diagnostic header";
|
||||
};
|
||||
|
||||
info = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = " Info";
|
||||
description = "Info diagnostic header";
|
||||
};
|
||||
};
|
||||
|
||||
maxDialogWidth = mkOption {
|
||||
type = types.nullOr types.int;
|
||||
default = null;
|
||||
description = "Maximum dialog width";
|
||||
};
|
||||
|
||||
icons = {
|
||||
codeAction = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Code action icon";
|
||||
};
|
||||
|
||||
findDefinition = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Find definition icon";
|
||||
};
|
||||
|
||||
findReference = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Find reference icon";
|
||||
};
|
||||
|
||||
definitionPreview = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Definition preview icon";
|
||||
};
|
||||
};
|
||||
|
||||
maxFinderPreviewLines = mkOption {
|
||||
type = types.nullOr types.int;
|
||||
default = null;
|
||||
description = "Maximum finder preview lines";
|
||||
};
|
||||
|
||||
keys = let
|
||||
defaultKeyOpt = desc:
|
||||
mkOption {
|
||||
description = desc;
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
};
|
||||
in {
|
||||
finderAction = {
|
||||
open = defaultKeyOpt "Open from finder";
|
||||
vsplit = defaultKeyOpt "Vertical split in finder";
|
||||
split = defaultKeyOpt "Horizontal split in finder";
|
||||
quit = defaultKeyOpt "Quit finder";
|
||||
scrollDown = defaultKeyOpt "Scroll down finder";
|
||||
scrollUp = defaultKeyOpt "Scroll up finder";
|
||||
};
|
||||
|
||||
codeAction = {
|
||||
quit = defaultKeyOpt "Quit code actions menu";
|
||||
exec = defaultKeyOpt "Execute code action";
|
||||
};
|
||||
};
|
||||
|
||||
borderStyle = mkOption {
|
||||
type = types.nullOr (types.enum ["thin" "rounded" "thick"]);
|
||||
default = null;
|
||||
description = "Border style";
|
||||
};
|
||||
|
||||
renamePromptPrefix = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Rename prompt prefix";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
notDefault = default: opt:
|
||||
if (opt != default)
|
||||
then opt
|
||||
else null;
|
||||
notEmpty = opt:
|
||||
if ((filterAttrs (_: v: v != null) opt) != {})
|
||||
then opt
|
||||
else null;
|
||||
notNull = opt: opt;
|
||||
lspsagaConfig = {
|
||||
use_saga_diagnostic_sign = notDefault true cfg.signs.use;
|
||||
error_sign = notNull cfg.signs.error;
|
||||
warn_sign = notNull cfg.signs.warning;
|
||||
hint_sign = notNull cfg.signs.hint;
|
||||
infor_sign = notNull cfg.signs.info;
|
||||
|
||||
# TODO Fix this!
|
||||
# error_header = notNull cfg.headers.error;
|
||||
# warn_header = notNull cfg.headers.warning;
|
||||
# hint_header = notNull cfg.headers.hint;
|
||||
# infor_header = notNull cfg.headers.info;
|
||||
|
||||
max_diag_msg_width = notNull cfg.maxDialogWidth;
|
||||
|
||||
code_action_icon = notNull cfg.icons.codeAction;
|
||||
finder_definition_icon = notNull cfg.icons.findDefinition;
|
||||
finder_reference_icon = notNull cfg.icons.findReference;
|
||||
definition_preview_icon = notNull cfg.icons.definitionPreview;
|
||||
|
||||
max_finder_preview_lines = notNull cfg.maxFinderPreviewLines;
|
||||
|
||||
rename_prompt_prefix = notNull cfg.renamePromptPrefix;
|
||||
|
||||
border_style = let
|
||||
borderStyle =
|
||||
if cfg.borderStyle == "thin"
|
||||
then 1
|
||||
else if cfg.borderStyle == "rounded"
|
||||
then 2
|
||||
else if cfg.borderStyle == "thick"
|
||||
then 3
|
||||
else null;
|
||||
in
|
||||
borderStyle;
|
||||
|
||||
finder_action_keys = let
|
||||
keys = {
|
||||
open = notNull cfg.keys.finderAction.open;
|
||||
vsplit = notNull cfg.keys.finderAction.vsplit;
|
||||
split = notNull cfg.keys.finderAction.split;
|
||||
quit = notNull cfg.keys.finderAction.quit;
|
||||
scroll_down = notNull cfg.keys.finderAction.scrollDown;
|
||||
scroll_up = notNull cfg.keys.finderAction.scrollUp;
|
||||
};
|
||||
in
|
||||
notEmpty keys;
|
||||
|
||||
code_action_keys = let
|
||||
keys = {
|
||||
quit = notNull cfg.keys.codeAction.quit;
|
||||
exec = notNull cfg.keys.codeAction.exec;
|
||||
};
|
||||
in
|
||||
notEmpty keys;
|
||||
};
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
extraPlugins = [cfg.package];
|
||||
|
||||
extraConfigLua = ''
|
||||
local saga = require 'lspsaga'
|
||||
|
||||
saga.init_lsp_saga(${helpers.toLuaObject lspsagaConfig})
|
||||
'';
|
||||
};
|
||||
}
|
90
plugins/lsp/nvim-lightbulb.nix
Normal file
90
plugins/lsp/nvim-lightbulb.nix
Normal file
|
@ -0,0 +1,90 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
helpers = import ../helpers.nix {inherit lib;};
|
||||
in
|
||||
with lib; {
|
||||
options.plugins.nvim-lightbulb = {
|
||||
enable = mkEnableOption "nvim-lightbulb, showing available code actions";
|
||||
|
||||
package = helpers.mkPackageOption "nvim-lightbulb" pkgs.vimPlugins.nvim-lightbulb;
|
||||
|
||||
ignore = helpers.defaultNullOpts.mkNullable (types.listOf types.str) "[]" ''
|
||||
LSP client names to ignore
|
||||
'';
|
||||
|
||||
sign = {
|
||||
enabled = helpers.defaultNullOpts.mkBool true "";
|
||||
priority = helpers.defaultNullOpts.mkInt 10 "";
|
||||
};
|
||||
|
||||
float = {
|
||||
enabled = helpers.defaultNullOpts.mkBool false "";
|
||||
|
||||
text = helpers.defaultNullOpts.mkStr "💡" "Text to show in the popup float";
|
||||
|
||||
winOpts = helpers.defaultNullOpts.mkNullable (types.attrsOf types.anything) "{}" ''
|
||||
Options for the floating window (see |vim.lsp.util.open_floating_preview| for more information)
|
||||
'';
|
||||
};
|
||||
|
||||
virtualText = {
|
||||
enabled = helpers.defaultNullOpts.mkBool false "";
|
||||
|
||||
text = helpers.defaultNullOpts.mkStr "💡" "Text to show at virtual text";
|
||||
|
||||
hlMode = helpers.defaultNullOpts.mkStr "replace" ''
|
||||
highlight mode to use for virtual text (replace, combine, blend), see
|
||||
:help nvim_buf_set_extmark() for reference
|
||||
'';
|
||||
};
|
||||
|
||||
statusText = {
|
||||
enabled = helpers.defaultNullOpts.mkBool false "";
|
||||
|
||||
text = helpers.defaultNullOpts.mkStr "💡" "Text to provide when code actions are available";
|
||||
|
||||
textUnavailable = helpers.defaultNullOpts.mkStr "" ''
|
||||
Text to provide when no actions are available
|
||||
'';
|
||||
};
|
||||
|
||||
autocmd = {
|
||||
enabled = helpers.defaultNullOpts.mkBool false "";
|
||||
|
||||
pattern = helpers.defaultNullOpts.mkNullable (types.listOf types.str) ''["*"]'' "";
|
||||
|
||||
events =
|
||||
helpers.defaultNullOpts.mkNullable (types.listOf types.str)
|
||||
''["CursorHold" "CursorHoldI"]'' "";
|
||||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
cfg = config.plugins.nvim-lightbulb;
|
||||
setupOptions = {
|
||||
inherit (cfg) ignore sign autocmd;
|
||||
float = {
|
||||
inherit (cfg.float) enabled text;
|
||||
win_opts = cfg.float.winOpts;
|
||||
};
|
||||
virtual_text = {
|
||||
inherit (cfg.virtualText) enabled text;
|
||||
hl_mode = cfg.virtualText.hlMode;
|
||||
};
|
||||
status_text = {
|
||||
inherit (cfg.statusText) enabled text;
|
||||
text_unavailable = cfg.statusText.textUnavailable;
|
||||
};
|
||||
};
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
extraPlugins = [cfg.package];
|
||||
extraConfigLua = ''
|
||||
require("nvim-lightbulb").setup(${helpers.toLuaObject setupOptions})
|
||||
'';
|
||||
};
|
||||
}
|
235
plugins/lsp/trouble.nix
Normal file
235
plugins/lsp/trouble.nix
Normal file
|
@ -0,0 +1,235 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
cfg = config.plugins.trouble;
|
||||
helpers = import ../helpers.nix {inherit lib;};
|
||||
in
|
||||
with lib; {
|
||||
options.plugins.trouble =
|
||||
helpers.extraOptionsOptions
|
||||
// {
|
||||
enable = mkEnableOption "trouble.nvim";
|
||||
|
||||
package = helpers.mkPackageOption "trouble-nvim" pkgs.vimPlugins.trouble-nvim;
|
||||
|
||||
position = helpers.defaultNullOpts.mkEnum ["top" "left" "right" "bottom"] "bottom" ''
|
||||
Position of the list
|
||||
'';
|
||||
|
||||
height = helpers.defaultNullOpts.mkInt 10 ''
|
||||
Height of the trouble list when position is top or bottom
|
||||
'';
|
||||
|
||||
width = helpers.defaultNullOpts.mkInt 50 "Width of the list when position is left or right";
|
||||
|
||||
icons = helpers.defaultNullOpts.mkBool true "Use devicons for filenames";
|
||||
|
||||
mode =
|
||||
helpers.defaultNullOpts.mkEnum
|
||||
[
|
||||
"workspace_diagnostics"
|
||||
"document_diagnostics"
|
||||
"quickfix"
|
||||
"lsp_references"
|
||||
"loclist"
|
||||
]
|
||||
"workspace_diagnostics"
|
||||
"Use devicons for filenames";
|
||||
|
||||
foldOpen = helpers.defaultNullOpts.mkStr "" "Icon used for open folds";
|
||||
|
||||
foldClosed = helpers.defaultNullOpts.mkStr "" "Icon used for closed folds";
|
||||
|
||||
group = helpers.defaultNullOpts.mkBool true "Group results by file";
|
||||
|
||||
padding = helpers.defaultNullOpts.mkBool true "Add an extra new line on top of the list";
|
||||
|
||||
actionKeys =
|
||||
helpers.mkCompositeOption
|
||||
''
|
||||
Key mappings for actions in the trouble list.
|
||||
Map to `{}` to remove a mapping, for example:
|
||||
`close = {};`
|
||||
''
|
||||
(mapAttrs
|
||||
(
|
||||
action: config:
|
||||
helpers.defaultNullOpts.mkNullable
|
||||
(with types; either str (listOf str))
|
||||
config.default
|
||||
config.description
|
||||
)
|
||||
{
|
||||
close = {
|
||||
default = "q";
|
||||
description = "Close the list";
|
||||
};
|
||||
cancel = {
|
||||
default = "<esc>";
|
||||
description = "Cancel the preview and get back to your last window / buffer / cursor";
|
||||
};
|
||||
refresh = {
|
||||
default = "r";
|
||||
description = "Manually refresh";
|
||||
};
|
||||
jump = {
|
||||
default = "[ \"<cr>\" \"<tab>\" ]";
|
||||
description = "Jump to the diagnostic or open / close folds";
|
||||
};
|
||||
openSplit = {
|
||||
default = "[ \"<c-x>\" ]";
|
||||
description = "Open buffer in new split";
|
||||
};
|
||||
openVsplit = {
|
||||
default = "[ \"<c-v>\" ]";
|
||||
description = "Open buffer in new vsplit";
|
||||
};
|
||||
openTab = {
|
||||
default = "[ \"<c-t>\" ]";
|
||||
description = "Open buffer in new tab";
|
||||
};
|
||||
jumpClose = {
|
||||
default = "[ \"o\" ]";
|
||||
description = "Jump to the diagnostic and close the list";
|
||||
};
|
||||
toggleMode = {
|
||||
default = "m";
|
||||
description = "toggle between 'workspace' and 'document' diagnostics mode";
|
||||
};
|
||||
togglePreview = {
|
||||
default = "P";
|
||||
description = "Toggle auto_preview";
|
||||
};
|
||||
hover = {
|
||||
default = "K";
|
||||
description = "Opens a small popup with the full multiline message";
|
||||
};
|
||||
preview = {
|
||||
default = "p";
|
||||
description = "Preview the diagnostic location";
|
||||
};
|
||||
closeFolds = {
|
||||
default = "[ \"zM\" \"zm\" ]";
|
||||
description = "Close all folds";
|
||||
};
|
||||
openFolds = {
|
||||
default = "[ \"zR\" \"zr\" ]";
|
||||
description = "Open all folds";
|
||||
};
|
||||
toggleFold = {
|
||||
default = "[ \"zA\" \"za\" ]";
|
||||
description = "Toggle fold of current file";
|
||||
};
|
||||
previous = {
|
||||
default = "k";
|
||||
description = "Previous item";
|
||||
};
|
||||
next = {
|
||||
default = "j";
|
||||
description = "Next item";
|
||||
};
|
||||
});
|
||||
|
||||
indentLines = helpers.defaultNullOpts.mkBool true ''
|
||||
Add an indent guide below the fold icons.
|
||||
'';
|
||||
|
||||
autoOpen = helpers.defaultNullOpts.mkBool false ''
|
||||
Automatically open the list when you have diagnostics.
|
||||
'';
|
||||
|
||||
autoClose = helpers.defaultNullOpts.mkBool false ''
|
||||
Automatically close the list when you have no diagnostics.
|
||||
'';
|
||||
|
||||
autoPreview = helpers.defaultNullOpts.mkBool true ''
|
||||
Automatically preview the location of the diagnostic.
|
||||
<esc> to close preview and go back to last window.
|
||||
'';
|
||||
|
||||
autoFold = helpers.defaultNullOpts.mkBool false ''
|
||||
Automatically fold a file trouble list at creation.
|
||||
'';
|
||||
|
||||
autoJump =
|
||||
helpers.defaultNullOpts.mkNullable
|
||||
(types.listOf types.str)
|
||||
"[ \"lsp_definitions\" ]"
|
||||
"For the given modes, automatically jump if there is only a single result.";
|
||||
|
||||
signs =
|
||||
helpers.mkCompositeOption "Incons/text used for the different diagnostics."
|
||||
(
|
||||
mapAttrs
|
||||
(
|
||||
diagnostic: default:
|
||||
helpers.defaultNullOpts.mkStr default "Icon/text for ${diagnostic} diagnostics."
|
||||
)
|
||||
{
|
||||
error = "";
|
||||
warning = "";
|
||||
hint = "";
|
||||
information = "";
|
||||
other = "";
|
||||
}
|
||||
);
|
||||
|
||||
useDiagnosticSigns = helpers.defaultNullOpts.mkBool false ''
|
||||
Enabling this will use the signs defined in your lsp client
|
||||
'';
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
extraConfigLua = let
|
||||
options =
|
||||
{
|
||||
inherit
|
||||
(cfg)
|
||||
position
|
||||
height
|
||||
width
|
||||
icons
|
||||
mode
|
||||
;
|
||||
fold_open = cfg.foldOpen;
|
||||
fold_closed = cfg.foldClosed;
|
||||
inherit (cfg) group padding;
|
||||
action_keys =
|
||||
helpers.ifNonNull' cfg.actionKeys
|
||||
(with cfg.actionKeys; {
|
||||
inherit close cancel refresh jump;
|
||||
open_split = openSplit;
|
||||
open_vsplit = openVsplit;
|
||||
open_tab = openTab;
|
||||
jump_close = jumpClose;
|
||||
toggle_mode = toggleMode;
|
||||
toggle_preview = togglePreview;
|
||||
inherit hover preview;
|
||||
close_folds = closeFolds;
|
||||
open_folds = openFolds;
|
||||
toggle_fold = toggleFold;
|
||||
inherit next;
|
||||
});
|
||||
indent_lines = cfg.indentLines;
|
||||
auto_open = cfg.autoOpen;
|
||||
auto_close = cfg.autoClose;
|
||||
auto_preview = cfg.autoPreview;
|
||||
auto_fold = cfg.autoFold;
|
||||
auto_jump = cfg.autoJump;
|
||||
inherit (cfg) signs;
|
||||
use_diagnostic_signs = cfg.useDiagnosticSigns;
|
||||
}
|
||||
// cfg.extraOptions;
|
||||
in ''
|
||||
require('trouble').setup(${helpers.toLuaObject options})
|
||||
'';
|
||||
|
||||
extraPlugins = with pkgs.vimPlugins; [
|
||||
cfg.package
|
||||
nvim-web-devicons
|
||||
];
|
||||
};
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue