{ config, lib, ... }: let cfg = config.filetype; mkFiletypeDetect = ft: pattern: lib.nameValuePair "filetype-detect-${ft}" { event = [ "BufNewFile" "BufRead" ]; inherit pattern; command = "setfiletype ${ft}"; }; in { options.filetype = with lib; with types; { enable = mkOption { type = bool; default = true; description = '' Vim can detect the type of file that is edited. This is done by checking the file name and sometimes by inspecting the contents of the file for specific text. `:help filetypes` `:help filetype-off` `:help filetype-overview` ''; }; plugin = mkOption { type = bool; default = true; description = '' Enable loading the plugin files for specific file types `:help :filetype-plugin-on` `:help :filetype-plugin-off` ''; }; indent = mkOption { type = bool; default = true; description = '' Enable loading the indent file for specific file types `:help :filetype-indent-on` `:help :filetype-indent-off` ''; }; ignore = mkOption { type = uniq (listOf str); default = [ "Z" "gz" "bz2" "zip" "tgz" ]; description = '' To avoid that certain files are being inspected, the g:ft_ignore_pat variable is used. The default value is set like this: `:help filetype-ignore` ''; }; extraIgnore = mkOption { type = uniq (listOf str); default = [ ]; }; detect = mkOption { type = attrsOf extCommas; default = { }; }; }; config = { vim.namedCmd.filetype = lib.concatLines (lib.flip lib.mapAttrsToList { inherit (cfg) enable plugin indent; } (k: v: ''filetype ${if k == "enable" then "" else k} ${if v then "on" else "off"}'') ); vim.g.ft_ignore_pat = "\\\\.(${lib.concatStringsSep "|" (cfg.ignore ++ cfg.extraIgnore)})$"; vim.augroup = lib.mkIf (cfg.detect != { }) (lib.listToAttrs (lib.mapAttrsToList mkFiletypeDetect cfg.detect)); }; }