diff --git a/modules/neovim/init/spellcheck.nix b/modules/neovim/init/spellcheck.nix index d8957ef..5de7400 100644 --- a/modules/neovim/init/spellcheck.nix +++ b/modules/neovim/init/spellcheck.nix @@ -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.options) mkOption mkEnableOption literalExpression literalMarkdown; + inherit (lib.strings) concatStringsSep; + inherit (lib.attrsets) mapAttrsToList; + inherit (lib.types) listOf str attrsOf; inherit (lib.nvim.lua) listToLuaTable; inherit (lib.nvim.dag) entryAfter; @@ -25,9 +28,45 @@ in { 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 + directory in either {file}`~/.config/nvim` or the [additionalRuntimePaths](#opt-vim.additionalRuntimePaths) - directory provided by **nvf**. + directory provided by nvf. + ''; + }; + + extraSpellFiles = mkOption { + type = attrsOf (listOf str); + default = {"en.utf-8" = ["nvf" "word_you_want_to_add"];}; + example = literalExpression {"en.utf-8" = ["nvf" "word_you_want_to_add"];}; + description = literalMarkdown '' + Additional words to be used for spellchecking. The names of each key + will be used as the language code for the spell file. E.g: + + ```nix + "en.utf-8" = [ ... ]; + ``` + + will result in `en.utf-8.add.spl` being added to Neovim's runtime + in the `after/spell` ."` 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 `: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/after/spell/en-utf-8.add.spl + ``` + ::: ''; }; @@ -38,7 +77,7 @@ in { description = '' A list of filetypes for which spellchecking will be disabled. - You may use `echo &filetype` in Neovim to find out the + You may use {command}`:echo &filetype` in Neovim to find out the filetype for a specific buffer. ''; }; @@ -58,18 +97,52 @@ 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" (concatStringsSep "\n" value)) cfg.extraSpellFiles; + 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.runCommand "nvf-compile-spellfiles" { + nativeBuildInputs = [config.vim.package]; + } '' + mkdir -p $out/after/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 extension=".add" + local name=$(basename $spellfile "$extension") + echo "Compiling spellfile: $spellfile" + nvim --headless --clean \ + --cmd "mkspell $out/after/spell/"$name".add.spl $spellfile" -Es -n + + ls -lah $out/after/spell + done + ''; + in [ + 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, + }) + ''; + }; }; }