|
| 1 | +{ |
| 2 | + config, |
| 3 | + lib, |
| 4 | + osConfig, |
| 5 | + pkgs, |
| 6 | + ... |
| 7 | +}: let |
| 8 | + inherit (lib.attrsets) mapAttrs' nameValuePair; |
| 9 | + inherit (lib.meta) getExe; |
| 10 | + inherit (lib.modules) mkIf; |
| 11 | + inherit (lib.options) literalExpression mkOption mkEnableOption mkPackageOption; |
| 12 | + inherit (lib.strings) optionalString; |
| 13 | + inherit (lib.types) attrsOf lines listOf; |
| 14 | + |
| 15 | + json = pkgs.formats.json {}; |
| 16 | + |
| 17 | + cfg = config.rum.desktops.i3; |
| 18 | +in { |
| 19 | + options.rum.desktops.i3 = { |
| 20 | + enable = mkEnableOption "i3"; |
| 21 | + |
| 22 | + package = |
| 23 | + mkPackageOption pkgs "i3" { |
| 24 | + nullable = true; |
| 25 | + extraDescription = '' |
| 26 | + Only used to validate the generated config file. Set to `null` to |
| 27 | + disable the check phase. |
| 28 | + ''; |
| 29 | + } |
| 30 | + // { |
| 31 | + # This is not above because mkPackageOption's implementation will evaluate `osConfig`, causing eval failures for documentation and checks. |
| 32 | + default = osConfig.services.xserver.windowManager.i3.package; |
| 33 | + defaultText = literalExpression "osConfig.services.xserver.windowManager.i3.package"; |
| 34 | + }; |
| 35 | + |
| 36 | + commands = mkOption { |
| 37 | + type = lines; |
| 38 | + default = ""; |
| 39 | + example = '' |
| 40 | + # Launch on startup |
| 41 | + exec --no-startup-id i3-msg 'workspace 1; exec ''${lib.getExe pkgs.firefox}' |
| 42 | +
|
| 43 | + # Key bindings - Workspaces |
| 44 | + ''${lib.concatStrings ( |
| 45 | + map (n: ''' |
| 46 | + bindsym $mod+''${toString n} workspace number ''${if n == 0 then "10" else toString n} |
| 47 | + bindsym $mod+Shift+''${toString n} move container to workspace number ''${ |
| 48 | + if n == 0 then "10" else toString n |
| 49 | + } |
| 50 | + ''') (builtins.genList (i: i) 10) |
| 51 | + )} |
| 52 | + ''; |
| 53 | + description = '' |
| 54 | + Commands that will be run to configure i3 written to |
| 55 | + {file}`$HOME/.config/i3/config`. Please reference [i3's documentation] |
| 56 | + for possible commands. |
| 57 | +
|
| 58 | + [i3's documentation]: https://i3wm.org/docs/userguide.html#configuring |
| 59 | + ''; |
| 60 | + }; |
| 61 | + |
| 62 | + layouts = mkOption { |
| 63 | + type = attrsOf (listOf json.type); |
| 64 | + default = {}; |
| 65 | + example = { |
| 66 | + main = [ |
| 67 | + { |
| 68 | + layout = "splitv"; |
| 69 | + percent = 0.4; |
| 70 | + type = "con"; |
| 71 | + nodes = [ |
| 72 | + { |
| 73 | + border = "none"; |
| 74 | + name = "irssi"; |
| 75 | + percent = 0.5; |
| 76 | + type = "con"; |
| 77 | + swallows = [ |
| 78 | + { |
| 79 | + class = "^URxvt$"; |
| 80 | + instance = "^irssi$"; |
| 81 | + } |
| 82 | + ]; |
| 83 | + } |
| 84 | + { |
| 85 | + layout = "stacked"; |
| 86 | + percent = 0.5; |
| 87 | + type = "con"; |
| 88 | + nodes = [ |
| 89 | + { |
| 90 | + name = "notmuch"; |
| 91 | + percent = 0.5; |
| 92 | + type = "con"; |
| 93 | + swallows = [ |
| 94 | + { |
| 95 | + class = "^Emacs$"; |
| 96 | + instance = "^notmuch$"; |
| 97 | + } |
| 98 | + ]; |
| 99 | + } |
| 100 | + { |
| 101 | + name = "midna: -"; |
| 102 | + percent = 0.5; |
| 103 | + type = "con"; |
| 104 | + } |
| 105 | + ]; |
| 106 | + } |
| 107 | + ]; |
| 108 | + } |
| 109 | + { |
| 110 | + layout = "stacked"; |
| 111 | + percent = 0.6; |
| 112 | + type = "con"; |
| 113 | + nodes = [ |
| 114 | + { |
| 115 | + name = "chrome"; |
| 116 | + type = "con"; |
| 117 | + swallows = [ |
| 118 | + { |
| 119 | + class = "^Google-chrome$"; |
| 120 | + } |
| 121 | + ]; |
| 122 | + } |
| 123 | + ]; |
| 124 | + } |
| 125 | + ]; |
| 126 | + }; |
| 127 | + description = '' |
| 128 | + Workspace layouts written to {file}`$HOME/.config/i3/*.json`. |
| 129 | + Read more about i3's layouts [here]. |
| 130 | +
|
| 131 | + Setting this option doesn't automatically load the defined layouts |
| 132 | + allowing users to load them in their preferred way. Reference i3's |
| 133 | + documentation on [restoring the layout] for possible options. |
| 134 | +
|
| 135 | + [here]: https://i3wm.org/docs/layout-saving.html |
| 136 | + [restoring the layout]: https://i3wm.org/docs/layout-saving.html#_restoring_the_layout |
| 137 | + ''; |
| 138 | + }; |
| 139 | + }; |
| 140 | + |
| 141 | + config = mkIf cfg.enable { |
| 142 | + xdg.config.files = |
| 143 | + { |
| 144 | + "i3/config" = mkIf (cfg.commands != "") { |
| 145 | + source = pkgs.writeTextFile { |
| 146 | + name = "i3-config"; |
| 147 | + text = cfg.commands; |
| 148 | + checkPhase = optionalString (cfg.package != null) '' |
| 149 | + ${getExe cfg.package} -c "$target" -C -d all |
| 150 | + ''; |
| 151 | + }; |
| 152 | + }; |
| 153 | + } |
| 154 | + // (mapAttrs' (name: value: |
| 155 | + nameValuePair "i3/${name}.json" { |
| 156 | + source = json.generate "i3-${name}-layout.json" value; |
| 157 | + }) |
| 158 | + cfg.layouts); |
| 159 | + }; |
| 160 | +} |
0 commit comments