1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.programs.less;
8
9 configText = if (cfg.configFile != null) then (builtins.readFile cfg.configFile) else ''
10 #command
11 ${concatStringsSep "\n"
12 (mapAttrsToList (command: action: "${command} ${action}") cfg.commands)
13 }
14 ${if cfg.clearDefaultCommands then "#stop" else ""}
15
16 #line-edit
17 ${concatStringsSep "\n"
18 (mapAttrsToList (command: action: "${command} ${action}") cfg.lineEditingKeys)
19 }
20
21 #env
22 ${concatStringsSep "\n"
23 (mapAttrsToList (variable: values: "${variable}=${values}") cfg.envVariables)
24 }
25 '';
26
27 lessKey = pkgs.writeText "lessconfig" configText;
28
29in
30
31{
32 options = {
33
34 programs.less = {
35
36 # note that environment.nix sets PAGER=less, and
37 # therefore also enables this module
38 enable = mkEnableOption "less";
39
40 configFile = mkOption {
41 type = types.nullOr types.path;
42 default = null;
43 example = literalExpression ''"''${pkgs.my-configs}/lesskey"'';
44 description = ''
45 Path to lesskey configuration file.
46
47 <option>configFile</option> takes precedence over <option>commands</option>,
48 <option>clearDefaultCommands</option>, <option>lineEditingKeys</option>, and
49 <option>envVariables</option>.
50 '';
51 };
52
53 commands = mkOption {
54 type = types.attrsOf types.str;
55 default = {};
56 example = {
57 h = "noaction 5\\e(";
58 l = "noaction 5\\e)";
59 };
60 description = "Defines new command keys.";
61 };
62
63 clearDefaultCommands = mkOption {
64 type = types.bool;
65 default = false;
66 description = ''
67 Clear all default commands.
68 You should remember to set the quit key.
69 Otherwise you will not be able to leave less without killing it.
70 '';
71 };
72
73 lineEditingKeys = mkOption {
74 type = types.attrsOf types.str;
75 default = {};
76 example = {
77 e = "abort";
78 };
79 description = "Defines new line-editing keys.";
80 };
81
82 envVariables = mkOption {
83 type = types.attrsOf types.str;
84 default = {
85 LESS = "-R";
86 };
87 example = {
88 LESS = "--quit-if-one-screen";
89 };
90 description = "Defines environment variables.";
91 };
92
93 lessopen = mkOption {
94 type = types.nullOr types.str;
95 default = "|${pkgs.lesspipe}/bin/lesspipe.sh %s";
96 defaultText = literalExpression ''"|''${pkgs.lesspipe}/bin/lesspipe.sh %s"'';
97 description = ''
98 Before less opens a file, it first gives your input preprocessor a chance to modify the way the contents of the file are displayed.
99 '';
100 };
101
102 lessclose = mkOption {
103 type = types.nullOr types.str;
104 default = null;
105 description = ''
106 When less closes a file opened in such a way, it will call another program, called the input postprocessor, which may perform any desired clean-up action (such as deleting the replacement file created by LESSOPEN).
107 '';
108 };
109 };
110 };
111
112 config = mkIf cfg.enable {
113
114 environment.systemPackages = [ pkgs.less ];
115
116 environment.variables = {
117 LESSKEYIN_SYSTEM = toString lessKey;
118 } // optionalAttrs (cfg.lessopen != null) {
119 LESSOPEN = cfg.lessopen;
120 } // optionalAttrs (cfg.lessclose != null) {
121 LESSCLOSE = cfg.lessclose;
122 };
123
124 warnings = optional (
125 cfg.clearDefaultCommands && (all (x: x != "quit") (attrValues cfg.commands))
126 ) ''
127 config.programs.less.clearDefaultCommands clears all default commands of less but there is no alternative binding for exiting.
128 Consider adding a binding for 'quit'.
129 '';
130 };
131
132 meta.maintainers = with maintainers; [ johnazoidberg ];
133
134}