1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.programs.less;
8
9 configFile = ''
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" configFile; }
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 commands = mkOption {
41 type = types.attrsOf types.str;
42 default = {};
43 example = {
44 "h" = "noaction 5\e(";
45 "l" = "noaction 5\e)";
46 };
47 description = "Defines new command keys.";
48 };
49
50 clearDefaultCommands = mkOption {
51 type = types.bool;
52 default = false;
53 description = ''
54 Clear all default commands.
55 You should remember to set the quit key.
56 Otherwise you will not be able to leave less without killing it.
57 '';
58 };
59
60 lineEditingKeys = mkOption {
61 type = types.attrsOf types.str;
62 default = {};
63 example = {
64 "\e" = "abort";
65 };
66 description = "Defines new line-editing keys.";
67 };
68
69 envVariables = mkOption {
70 type = types.attrsOf types.str;
71 default = {};
72 example = {
73 LESS = "--quit-if-one-screen";
74 };
75 description = "Defines environment variables.";
76 };
77
78 lessopen = mkOption {
79 type = types.nullOr types.str;
80 default = "|${pkgs.lesspipe}/bin/lesspipe.sh %s";
81 description = ''
82 Before less opens a file, it first gives your input preprocessor a chance to modify the way the contents of the file are displayed.
83 '';
84 };
85
86 lessclose = mkOption {
87 type = types.nullOr types.str;
88 default = null;
89 description = ''
90 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).
91 '';
92 };
93 };
94 };
95
96 config = mkIf cfg.enable {
97
98 environment.systemPackages = [ pkgs.less ];
99
100 environment.variables = {
101 "LESSKEY_SYSTEM" = toString lessKey;
102 } // optionalAttrs (cfg.lessopen != null) {
103 "LESSOPEN" = cfg.lessopen;
104 } // optionalAttrs (cfg.lessclose != null) {
105 "LESSCLOSE" = cfg.lessclose;
106 };
107
108 warnings = optional (
109 cfg.clearDefaultCommands && (all (x: x != "quit") (attrValues cfg.commands))
110 ) ''
111 config.programs.less.clearDefaultCommands clears all default commands of less but there is no alternative binding for exiting.
112 Consider adding a binding for 'quit'.
113 '';
114 };
115
116 meta.maintainers = with maintainers; [ johnazoidberg ];
117
118}