{ config, lib, pkgs, ... }: with lib; let cfg = config.programs.lf; knownSettings = { anchorfind = types.bool; color256 = types.bool; dircounts = types.bool; dirfirst = types.bool; drawbox = types.bool; globsearch = types.bool; icons = types.bool; hidden = types.bool; ignorecase = types.bool; ignoredia = types.bool; incsearch = types.bool; preview = types.bool; reverse = types.bool; smartcase = types.bool; smartdia = types.bool; wrapscan = types.bool; wrapscroll = types.bool; number = types.bool; relativenumber = types.bool; findlen = types.int; period = types.int; scrolloff = types.int; tabstop = types.int; errorfmt = types.str; filesep = types.str; ifs = types.str; promptfmt = types.str; shell = types.str; sortby = types.str; timefmt = types.str; ratios = types.str; info = types.str; shellopts = types.str; }; lfSettingsType = types.submodule { options = let opt = name: type: mkOption { type = types.nullOr type; default = null; visible = false; }; in mapAttrs opt knownSettings; }; in { meta.maintainers = [ hm.maintainers.owm111 ]; options = { programs.lf = { enable = mkEnableOption (lib.mdDoc "lf"); package = mkOption { type = types.package; default = pkgs.lf; defaultText = literalExpression "pkgs.lf"; description = lib.mdDoc '' lf package to use. ''; }; settings = mkOption { type = lfSettingsType; default = { }; example = { tabstop = 4; number = true; ratios = "1:1:2"; }; description = lib.mdDoc '' An attribute set of lf settings. The attribute names and corresponding values must be among the following supported options. ${concatStringsSep "\n" (mapAttrsToList (n: v: '' {var}`${n}` : ${v.description} '') knownSettings)} See the lf documentation for detailed descriptions of these options. Use {option}`programs.lf.previewer.*` to set lf's {var}`previewer` option, and [](#opt-programs.lf.extraConfig) for any other option not listed above. All string options are quoted with double quotes. ''; }; commands = mkOption { type = with types; attrsOf (nullOr str); default = { }; example = { get-mime-type = ''%xdg-mime query filetype "$f"''; open = "$$OPENER $f"; }; description = lib.mdDoc '' Commands to declare. Commands set to null or an empty string are deleted. ''; }; keybindings = mkOption { type = with types; attrsOf (nullOr str); default = { }; example = { gh = "cd ~"; D = "trash"; i = "$less $f"; U = "!du -sh"; gg = null; }; description = lib.mdDoc "Keys to bind. Keys set to null or an empty string are deleted."; }; cmdKeybindings = mkOption { type = with types; attrsOf (nullOr str); default = { }; example = literalExpression ''{ "" = "cmd-escape"; }''; description = lib.mdDoc '' Keys to bind to command line commands which can only be one of the builtin commands. Keys set to null or an empty string are deleted. ''; }; previewer.source = mkOption { type = with types; nullOr path; default = null; example = literalExpression '' pkgs.writeShellScript "pv.sh" ''' #!/bin/sh case "$1" in *.tar*) tar tf "$1";; *.zip) unzip -l "$1";; *.rar) unrar l "$1";; *.7z) 7z l "$1";; *.pdf) pdftotext "$1" -;; *) highlight -O ansi "$1" || cat "$1";; esac ''' ''; description = lib.mdDoc '' Script or executable to use to preview files. Sets lf's {var}`previewer` option. ''; }; previewer.keybinding = mkOption { type = with types; nullOr str; default = null; example = "i"; description = lib.mdDoc '' Key to bind to the script at {var}`previewer.source` and pipe through less. Setting to null will not bind any key. ''; }; extraConfig = mkOption { type = types.lines; default = ""; example = '' $mkdir -p ~/.trash ''; description = lib.mdDoc "Custom lfrc lines."; }; }; }; config = mkIf cfg.enable { home.packages = [ cfg.package ]; xdg.configFile."lf/lfrc".text = let fmtSetting = k: v: optionalString (v != null) "set ${ if isBool v then "${optionalString (!v) "no"}${k}" else "${k} ${if isInt v then toString v else ''"${v}"''}" }"; settingsStr = concatStringsSep "\n" (remove "" (mapAttrsToList fmtSetting (builtins.intersectAttrs knownSettings cfg.settings))); fmtCmdMap = before: k: v: "${before} ${k}${optionalString (v != null && v != "") " ${v}"}"; fmtCmd = fmtCmdMap "cmd"; fmtMap = fmtCmdMap "map"; fmtCmap = fmtCmdMap "cmap"; commandsStr = concatStringsSep "\n" (mapAttrsToList fmtCmd cfg.commands); keybindingsStr = concatStringsSep "\n" (mapAttrsToList fmtMap cfg.keybindings); cmdKeybindingsStr = concatStringsSep "\n" (mapAttrsToList fmtCmap cfg.cmdKeybindings); previewerStr = optionalString (cfg.previewer.source != null) '' set previewer ${cfg.previewer.source} ${optionalString (cfg.previewer.keybinding != null) '' map ${cfg.previewer.keybinding} ''$${cfg.previewer.source} "$f" | less -R ''} ''; in '' ${settingsStr} ${commandsStr} ${keybindingsStr} ${cmdKeybindingsStr} ${previewerStr} ${cfg.extraConfig} ''; }; }