1
0
Fork 0
nix-flake-base/languages/en-us/default.nix

308 lines
10 KiB
Nix

# SPDX-FileCopyrightText: 2025 Ethan Reece <contact@ethanreece.com>
#
# SPDX-License-Identifier: LGPL-3.0-or-later
{ module-name, ... }:
{ flake-parts-lib, lib, ... }:
{
options.perSystem = flake-parts-lib.mkPerSystemOption (
{ pkgs, config, ... }:
let
valePackages = rec {
# SPDX-SnippetBegin
# SPDX-License-Identifier: MIT
# SPDX-SnippetCopyrightText: 2003-2025 Eelco Dolstra and the Nixpkgs/NixOS contributors <https://github.com/NixOS/nixpkgs/blob/92c2e04a475523e723c67ef872d8037379073681/pkgs/by-name/va/vale/styles.nix#L9>
buildStyle =
{
name,
stylePath ? name,
...
}@args:
pkgs.stdenvNoCC.mkDerivation (
{
pname = "vale-style-${lib.toLower name}";
dontConfigure = true;
dontBuild = true;
doCheck = false;
dontFixup = true;
installPhase = ''
runHook preInstall
mkdir -p $out/share/vale/styles
cp -R ${stylePath} "$out/share/vale/styles/${name}"
runHook postInstall
'';
# passthru.updateScript = nix-update-script { };
# TODO: https://github.com/Mic92/nix-update
meta = {
platforms = lib.platforms.all;
maintainers = with lib.maintainers; [ katexochen ];
} // (args.meta or { });
}
// removeAttrs args [
"meta"
"name"
]
);
# SPDX-SnippetEnd
# https://vale.sh/explorer
packages = {
Google = pkgs.valeStyles.google;
Joblint = pkgs.valeStyles.joblint;
Microsoft = pkgs.valeStyles.microsoft;
proselint = pkgs.valeStyles.proselint;
write-good = pkgs.valeStyles.write-good;
alex = pkgs.valeStyles.alex;
Readability = pkgs.valeStyles.readability;
RedHat = buildStyle rec {
name = "RedHat";
version = "608";
stylePath = ".vale/styles/${name}";
src = pkgs.fetchFromGitHub {
owner = "redhat-documentation";
repo = "vale-at-red-hat";
rev = "v${version}";
hash = "sha256-jAAWb0QHhk7UyfqKa9tUByyG11W/hlHESgywqinFiT4=";
};
meta = {
description = "Vale-compatible implementation of the Red Hat Style Guide";
homepage = "https://github.com/vale-at-red-hat/redhat-documentation";
license = lib.licenses.mit;
};
};
};
};
in
{
options.languages.${module-name} = {
enable = lib.mkEnableOption "en_US";
dictionary = lib.mkOption {
description = ''
Words to add to dictionary.
'';
type = lib.types.listOf lib.types.string;
default = [ ];
};
excludes = lib.mkOption {
description = ''
Files to exclude from `typos`.
'';
type = lib.types.listOf lib.types.string;
default = [ ];
};
vale = lib.mkOption {
description = ''
Per-glob options for Vale.
'';
default = { };
type = lib.types.attrsOf (
lib.types.submodule {
options = {
packages = lib.mkOption {
description = ''
Vale packages to enable.
'';
default = { };
type = lib.types.submodule {
options = builtins.mapAttrs (
name: value:
lib.mkOption {
description = ''
Options for ${name} Vale package.
'';
default = { };
type = lib.types.submodule {
options = {
enable = lib.mkEnableOption name;
};
};
}
) valePackages.packages;
};
};
};
}
);
};
};
config = lib.mkIf config.languages.${module-name}.enable (
let
tomlFormatter = pkgs.formats.toml { };
vale = {
dictionary = rec {
name = "accept.txt";
text = builtins.concatStringsSep "\n" config.languages.${module-name}.dictionary;
path = pkgs.writeTextFile { inherit name text; };
};
styles = builtins.mapAttrs (name: value: rec {
enabled = builtins.attrNames (lib.filterAttrs (_: pkg: pkg.enable) value.packages);
text = ''
[${name}]
BasedOnStyles = Vale${
lib.optionalString (enabled != [ ]) (", " + lib.concatStringsSep ", " enabled)
}
'';
}) config.languages.${module-name}.vale;
config = rec {
name = ".vale.ini";
text = ''
StylesPath = styles
MinAlertLevel = suggestion
Vocab = General
Packages = ${builtins.concatStringsSep ", " (builtins.attrNames valePackages.packages)}
${lib.foldlAttrs (
acc: _name: value:
acc + value.text
) "" vale.styles}
'';
path = pkgs.writeTextFile { inherit name text; };
};
directory = {
name = "share/vale";
path = pkgs.buildEnv {
name = "vale-config";
paths = [
(pkgs.linkFarm vale.directory.name [
{
name = "${vale.directory.name}/${vale.config.name}";
path = vale.config.path;
}
{
name = "${vale.directory.name}/styles/config/vocabularies/General/${vale.dictionary.name}";
path = vale.dictionary.path;
}
])
] ++ (lib.mapAttrsToList (name: value: value) valePackages.packages);
};
};
};
typos = rec {
# https://github.com/crate-ci/typos/blob/master/docs/reference.md
content = {
default = {
extend-words = builtins.listToAttrs (
builtins.map (x: {
name = x;
value = x;
}) config.languages.${module-name}.dictionary
);
extend-ignore-re = [
"(?Rm)^.*(#|//)\\s*spellchecker:disable-line$"
"(?s)(#|//)\\s*spellchecker:off.*?\\n\\s*(#|//)\\s*spellchecker:on"
"(#|//)\\s*spellchecker:ignore-next-line\\n.*"
"(?Rm)^.*<!--\\s*spellchecker:disable-line\\s*-->.*$"
"(?s)<!--\\s*spellchecker:off\\s*-->.*?<!--\\s*spellchecker:on\\s*-->"
"<!--\\s*spellchecker:ignore-next-line\\s*-->\\n.*"
];
};
files.extend-exclude = config.languages.${module-name}.excludes;
};
file = tomlFormatter.generate "typos.toml" content;
};
harper = {
dictionary = rec {
name = "dictionary.txt";
text = builtins.concatStringsSep "\n" config.languages.${module-name}.dictionary;
path = pkgs.writeTextFile { inherit name text; };
};
};
in
{
languages.${module-name}.dictionary = [
"aarch64"
"Asahi"
"Catppuccin"
"Devshell"
"Dolstra"
"Eelco"
"FileCopyrightText"
"Flake"
"formatters"
"https"
"GmbH"
"Jujutsu"
"LanguageTool"
"LLMs"
"LTeX"
"Nix"
"NixOS"
"Nixpkgs"
"Nushell"
"qutebrowser"
"REUSE"
"SnippetBegin"
"SnippetCopyrightText"
"SnippetEnd"
"SOPS"
"SPDX"
"spellchecker"
"Stylix"
"TODO"
];
editors.helix.languages.language-server = {
# https://ltex-plus.github.io/ltex-plus/supported-languages.html
ltex-ls-plus = {
command = "${pkgs.ltex-ls-plus}/bin/ltex-ls-plus";
config.ltex = {
dictionary.en-US = config.languages.${module-name}.dictionary;
additionalRules.enablePickyRules = true;
};
};
# https://vale.sh/docs/formats/code
vale-ls = {
command = "${pkgs.vale-ls}/bin/vale-ls";
config.configPath = "${vale.directory.path}/${vale.directory.name}/${vale.config.name}";
};
# https://writewithharper.com/docs/integrations/language-server#Supported-Languages
harper-ls = {
command = "${pkgs.harper}/bin/harper-ls";
config.harper-ls.userDictPath = harper.dictionary.path;
};
typos = {
command = "${pkgs.typos-lsp}/bin/typos-lsp";
config.config = typos.file.outPath;
};
};
pre-commit.settings = {
hooks = {
typos = {
enable = true;
settings = {
configPath = typos.file.outPath;
locale = "en-us";
};
excludes = config.languages.${module-name}.excludes;
};
vale = {
enable = true;
settings.configPath = "${vale.directory.path}/${vale.directory.name}/${vale.config.name}";
};
};
excludes = [ "languages/en-us/.vale" ]; # TODO: Move this to only this flake
};
treefmt = {
# TODO: https://github.com/numtide/treefmt/issues/596
# programs.typos = {
# enable = true;
# configFile = typos.file.outPath;
# locale = "en-us";
# excludes = config.languages.${module-name}.excludes;
# };
settings = {
global.excludes = [ "languages/en-us/.vale/*" ];
# formatter.typos.options = [ "--force-exclude" ];
};
};
}
);
}
);
}