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.runCommand "lesskey"
28 { src = pkgs.writeText "lessconfig" configText; }
29 "${pkgs.less}/bin/lesskey -o $out $src";
30
31in
32
33{
34 options = {
35
36 programs.less = {
37
38 enable = mkEnableOption "less";
39
40 configFile = mkOption {
41 type = types.nullOr types.path;
42 default = null;
43 example = literalExample "$${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 example = {
86 LESS = "--quit-if-one-screen";
87 };
88 description = "Defines environment variables.";
89 };
90
91 lessopen = mkOption {
92 type = types.nullOr types.str;
93 default = "|${pkgs.lesspipe}/bin/lesspipe.sh %s";
94 description = ''
95 Before less opens a file, it first gives your input preprocessor a chance to modify the way the contents of the file are displayed.
96 '';
97 };
98
99 lessclose = mkOption {
100 type = types.nullOr types.str;
101 default = null;
102 description = ''
103 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).
104 '';
105 };
106 };
107 };
108
109 config = mkIf cfg.enable {
110
111 environment.systemPackages = [ pkgs.less ];
112
113 environment.variables = {
114 "LESSKEY_SYSTEM" = toString lessKey;
115 } // optionalAttrs (cfg.lessopen != null) {
116 "LESSOPEN" = cfg.lessopen;
117 } // optionalAttrs (cfg.lessclose != null) {
118 "LESSCLOSE" = cfg.lessclose;
119 };
120
121 warnings = optional (
122 cfg.clearDefaultCommands && (all (x: x != "quit") (attrValues cfg.commands))
123 ) ''
124 config.programs.less.clearDefaultCommands clears all default commands of less but there is no alternative binding for exiting.
125 Consider adding a binding for 'quit'.
126 '';
127 };
128
129 meta.maintainers = with maintainers; [ johnazoidberg ];
130
131}