spellcheck: allow adding arbitrary spellfiles from name-value pairs

This commit is contained in:
NotAShelf 2024-10-21 17:20:02 +03:00
parent 21fcace3ed
commit 688bb8d9ba
No known key found for this signature in database
GPG key ID: AF26552424E53993

View file

@ -1,11 +1,14 @@
{
config,
pkgs,
lib,
...
}: let
inherit (lib.modules) mkIf mkRenamedOptionModule;
inherit (lib.options) mkOption mkEnableOption literalExpression;
inherit (lib.types) listOf str;
inherit (lib.strings) concatLines;
inherit (lib.attrsets) mapAttrsToList;
inherit (lib.types) listOf str attrsOf;
inherit (lib.nvim.lua) listToLuaTable;
inherit (lib.nvim.dag) entryAfter;
@ -24,10 +27,43 @@ in {
description = ''
A list of languages that should be used for spellchecking.
To add your own language files, you may place your `spell`
directory in either `~/.config/nvim` or the
[additionalRuntimePaths](#opt-vim.additionalRuntimePaths)
directory provided by **nvf**.
To add your own language files, you may place your `spell` directory in either
{file}`$XDG_CONFIG_HOME/nvf` or in a path that is included in the
[additionalRuntimePaths](#opt-vim.additionalRuntimePaths) list provided by nvf.
'';
};
extraSpellWords = mkOption {
type = attrsOf (listOf str);
default = {};
example = literalExpression ''{"en.utf-8" = ["nvf" "word_you_want_to_add"];}'';
description = ''
Additional words to be used for spellchecking. The names of each key will be
used as the language code for the spell file. For example
```nix
"en.utf-8" = [ ... ];
```
will result in `en.utf-8.add.spl` being added to Neovim's runtime in the
{file}`spell` directory.
::: {.warning}
The attribute keys must be in `"<name>.<encoding>"` format for Neovim to
compile your spellfiles without mangling the resulting file names. Please
make sure that you enter the correct value, as nvf does not do any kind of
internal checking. Please see {command}`:help mkspell` for more details.
Example:
```nix
# "en" is the name, and "utf-8" is the encoding. For most use cases, utf-8
# will be enough, however, you may change it to any encoding format Neovim
# accepts, e.g., utf-16.
"en.utf-8" = ["nvf" "word_you_want_to_add"];
=> $out/spell/en-utf-8.add.spl
```
:::
'';
};
@ -38,8 +74,10 @@ in {
description = ''
A list of filetypes for which spellchecking will be disabled.
You may use `echo &filetype` in Neovim to find out the
::: {.tip}
You may use {command}`:echo &filetype` in Neovim to find out the
filetype for a specific buffer.
:::
'';
};
@ -58,18 +96,53 @@ in {
};
config = mkIf cfg.enable {
vim.luaConfigRC.spellcheck = entryAfter ["basic"] ''
vim.opt.spell = true
vim.opt.spelllang = ${listToLuaTable cfg.languages}
vim = {
additionalRuntimePaths = let
spellfilesJoined = pkgs.symlinkJoin {
name = "nvf-spellfiles-joined";
paths = mapAttrsToList (name: value: pkgs.writeTextDir "spell/${name}.add" (concatLines value)) cfg.extraSpellWords;
postBuild = ''
echo "Spellfiles joined"
'';
};
-- Disable spellchecking for certain filetypes
-- as configured by `vim.spellcheck.ignoredFiletypes`
vim.api.nvim_create_autocmd({ "FileType" }, {
pattern = ${listToLuaTable cfg.ignoredFiletypes},
callback = function()
vim.opt_local.spell = false
end,
})
'';
compileJoinedSpellfiles =
pkgs.runCommandLocal "nvf-compile-spellfiles" {
# Use the same version of Neovim as the user's configuration
nativeBuildInputs = [config.vim.package];
} ''
mkdir -p "$out/spell"
spellfilesJoined=$(find -L "${spellfilesJoined}/spell" -type f)
for spellfile in $spellfilesJoined; do
# Hacky way to ensure that the mangled extensions are omitted from the
# joined spellfiles. E.g.
local name=$(basename "$spellfile" ".add")
echo "Compiling spellfile: $spellfile"
nvim --headless --clean \
--cmd "mkspell $out/spell/$name.add.spl $spellfile" -Es -n
done
'';
in
mkIf (cfg.extraSpellWords != {}) [
# If .outPath is missing, additionalRuntimePaths receives the *function*
# instead of a path, causing errors.
compileJoinedSpellfiles.outPath
];
luaConfigRC.spellcheck = entryAfter ["basic"] ''
vim.opt.spell = true
vim.opt.spelllang = ${listToLuaTable cfg.languages}
-- Disable spellchecking for certain filetypes
-- as configured by `vim.spellcheck.ignoredFiletypes`
vim.api.nvim_create_autocmd({ "FileType" }, {
pattern = ${listToLuaTable cfg.ignoredFiletypes},
callback = function()
vim.opt_local.spell = false
end,
})
'';
};
};
}