nix-community.nixvim/plugins/languages/lint.nix

271 lines
6.7 KiB
Nix
Raw Normal View History

2023-11-14 19:24:59 +01:00
{
lib,
helpers,
config,
pkgs,
...
}:
2024-05-05 19:39:35 +02:00
with lib;
let
2023-11-14 19:24:59 +01:00
cfg = config.plugins.lint;
linterOptions = with types; {
cmd = {
type = str;
description = "The command to call the linter";
example = "linter_cmd";
mandatory = true;
};
stdin = {
type = bool;
description = ''
Whether this parser supports content input via stdin.
In that case the filename is automatically added to the arguments.
Default: `true`
'';
example = false;
};
append_fname = {
type = bool;
description = ''
Automatically append the file name to `args` if `stdin = false`
Whether this parser supports content input via stdin.
In that case the filename is automatically added to the arguments.
Default: `true`
'';
example = false;
};
args = {
type = listOf (either str helpers.nixvimTypes.rawLua);
2023-11-14 19:24:59 +01:00
description = ''
List of arguments.
Can contain functions with zero arguments that will be evaluated once the linter is used.
Default: `[]`
'';
};
stream = {
2024-05-05 19:39:35 +02:00
type = enum [
"stdout"
"stderr"
"both"
];
2023-11-14 19:24:59 +01:00
description = ''
configure the stream to which the linter outputs the linting result.
Default: `"stdout"`
'';
example = "stderr";
};
ignore_exitcode = {
type = bool;
description = ''
Whether the linter exiting with a code !=0 should be considered normal.
Default: `false`
'';
example = true;
};
env = {
type = attrsOf str;
description = ''
Custom environment table to use with the external process.
Note that this replaces the **entire** environment, it is not additive.
'';
example = {
FOO = "bar";
};
};
parser = {
type = helpers.nixvimTypes.strLuaFn;
2023-11-14 19:24:59 +01:00
description = "The code for your parser function.";
example = ''
require('lint.parser').from_pattern(pattern, groups, severity_map, defaults, opts)
'';
apply = helpers.mkRaw;
2023-11-14 19:24:59 +01:00
mandatory = true;
};
};
2024-05-05 19:39:35 +02:00
mkLinterOpts =
noDefaults:
2023-11-14 19:24:59 +01:00
types.submodule {
freeformType = types.attrs;
2024-05-05 19:39:35 +02:00
options = mapAttrs (
optionName:
2023-11-14 19:24:59 +01:00
(
2024-05-05 19:39:35 +02:00
{
mandatory ? false,
apply ? x: x,
example ? null,
type,
description,
}:
mkOption (
2023-11-14 19:24:59 +01:00
{
2024-05-05 19:39:35 +02:00
inherit apply description example;
}
// (
if
noDefaults && mandatory
# Make this option mandatory
then
{ inherit type; }
# make it optional
else
2023-11-14 19:24:59 +01:00
{
2024-05-05 19:39:35 +02:00
type = types.nullOr type;
default = null;
2023-11-14 19:24:59 +01:00
}
2024-05-05 19:39:35 +02:00
)
2023-11-14 19:24:59 +01:00
)
)
2024-05-05 19:39:35 +02:00
) linterOptions;
2023-11-14 19:24:59 +01:00
};
2024-05-05 19:39:35 +02:00
in
{
options.plugins.lint = helpers.neovim-plugin.extraOptionsOptions // {
enable = mkEnableOption "nvim-lint";
2023-11-14 19:24:59 +01:00
package = helpers.mkPluginPackageOption "nvim-lint" pkgs.vimPlugins.nvim-lint;
2023-11-14 19:24:59 +01:00
2024-05-05 19:39:35 +02:00
lintersByFt = mkOption {
type = with types; attrsOf (listOf str);
default = { };
description = ''
Configure the linters you want to run per file type.
2023-11-14 19:24:59 +01:00
2024-05-05 19:39:35 +02:00
Default:
```nix
{
text = ["vale"];
json = ["jsonlint"];
markdown = ["vale"];
rst = ["vale"];
ruby = ["ruby"];
janet = ["janet"];
inko = ["inko"];
clojure = ["clj-kondo"];
dockerfile = ["hadolint"];
terraform = ["tflint"];
}
```
'';
example = {
markdown = [ "vale" ];
2023-11-14 19:24:59 +01:00
};
2024-05-05 19:39:35 +02:00
};
2023-11-14 19:24:59 +01:00
2024-05-05 19:39:35 +02:00
linters = mkOption {
type = with types; attrsOf (mkLinterOpts false);
default = { };
description = ''
Customize the existing linters by overriding some of their properties.
'';
example = {
phpcs.args = [
"-q"
"--report=json"
"-"
];
2023-11-14 19:24:59 +01:00
};
2024-05-05 19:39:35 +02:00
};
2023-11-14 19:24:59 +01:00
2024-05-05 19:39:35 +02:00
customLinters = mkOption {
type = with types; attrsOf (either str (mkLinterOpts true));
default = { };
description = ''
Configure the linters you want to run per file type.
It can be both an attrs or a string containing the lua code that returns the appropriate
table.
'';
example = { };
};
2023-11-14 19:24:59 +01:00
2024-05-05 19:39:35 +02:00
autoCmd =
let
2023-11-14 19:24:59 +01:00
defaultEvent = "BufWritePost";
defaultCallback = helpers.mkRaw ''
function()
require('lint').try_lint()
end
'';
in
2024-05-05 19:39:35 +02:00
mkOption {
type =
with types;
nullOr (submodule {
options = helpers.autocmd.autoCmdOptions // {
event = mkOption {
type = with types; nullOr (either str (listOf str));
default = defaultEvent;
description = "The event or events that should trigger linting.";
};
2023-11-14 19:24:59 +01:00
2024-05-05 19:39:35 +02:00
callback = mkOption {
type = with types; nullOr (either str helpers.nixvimTypes.rawLua);
default = defaultCallback;
description = "What action to perform for linting";
};
};
});
description = ''
The configuration for the linting autocommand.
You can disable it by setting this option to `null`.
'';
default = {
event = defaultEvent;
callback = defaultCallback;
2023-11-14 19:24:59 +01:00
};
2024-05-05 19:39:35 +02:00
};
};
2023-11-14 19:24:59 +01:00
config = mkIf cfg.enable {
2024-05-05 19:39:35 +02:00
extraPlugins = [ cfg.package ];
2023-11-14 19:24:59 +01:00
extraConfigLua =
''
__lint = require('lint')
__lint.linters_by_ft = ${helpers.toLuaObject cfg.lintersByFt}
''
2024-05-05 19:39:35 +02:00
+ (optionalString (cfg.linters != { }) (
concatLines (
flatten (
mapAttrsToList (
linter: linterConfig:
mapAttrsToList (
propName: propValue:
optionalString (
propValue != null
) ''__lint.linters["${linter}"]["${propName}"] = ${helpers.toLuaObject propValue}''
2024-05-05 19:39:35 +02:00
) linterConfig
) cfg.linters
2023-11-14 19:24:59 +01:00
)
)
2024-05-05 19:39:35 +02:00
))
+ (optionalString (cfg.customLinters != { }) (
concatLines (
mapAttrsToList (
customLinter: linterConfig:
let
linterConfig' = if isString linterConfig then helpers.mkRaw linterConfig else linterConfig;
in
''__lint.linters["${customLinter}"] = ${helpers.toLuaObject linterConfig'}''
2024-05-05 19:39:35 +02:00
) cfg.customLinters
2023-11-14 19:24:59 +01:00
)
2024-05-05 19:39:35 +02:00
));
2023-11-14 19:24:59 +01:00
autoCmd = optional (cfg.autoCmd != null) cfg.autoCmd;
2023-11-14 19:24:59 +01:00
};
}