mirror of
https://github.com/nix-community/home-manager
synced 2024-11-14 15:19:45 +01:00
115 lines
3.3 KiB
Nix
115 lines
3.3 KiB
Nix
|
{ config, lib, pkgs, ... }:
|
||
|
|
||
|
with lib;
|
||
|
|
||
|
let
|
||
|
|
||
|
cfg = config.programs.i3blocks;
|
||
|
|
||
|
# Re-make the atom type for the INI files.
|
||
|
# For some reason, the normal INI type seems to be incompatible with
|
||
|
# DAG
|
||
|
configAtomType = let
|
||
|
# Keep the INI atom type here
|
||
|
optType = with types; (nullOr (oneOf [ int bool str float ]));
|
||
|
in types.mkOptionType {
|
||
|
name = "INI config atom";
|
||
|
description = "INI atom (null, int, bool, string, or float)";
|
||
|
check = x: optType.check x;
|
||
|
merge = (loc: defs: (optType.merge loc defs));
|
||
|
};
|
||
|
|
||
|
# Create the type of the actual config type
|
||
|
configType = types.attrsOf configAtomType;
|
||
|
|
||
|
# The INI generator
|
||
|
mkIni = generators.toINI { };
|
||
|
|
||
|
in {
|
||
|
meta.maintainers = [ maintainers.noodlez1232 ];
|
||
|
|
||
|
options.programs.i3blocks = {
|
||
|
enable = mkEnableOption "i3blocks i3 status command scheduler";
|
||
|
|
||
|
package = mkOption {
|
||
|
type = types.package;
|
||
|
default = pkgs.i3blocks;
|
||
|
defaultText = literalExpression "pkgs.i3blocks";
|
||
|
description = "Package providing {command}`i3blocks`.";
|
||
|
};
|
||
|
|
||
|
bars = mkOption {
|
||
|
type = with types; attrsOf (hm.types.dagOf configType);
|
||
|
description = "Configuration written to i3blocks config";
|
||
|
example = literalExpression ''
|
||
|
{
|
||
|
top = {
|
||
|
# The title block
|
||
|
title = {
|
||
|
interval = "persist";
|
||
|
command = "xtitle -s";
|
||
|
};
|
||
|
};
|
||
|
bottom = {
|
||
|
time = {
|
||
|
command = "date +%r";
|
||
|
interval = 1;
|
||
|
};
|
||
|
# Make sure this block comes after the time block
|
||
|
date = lib.hm.dag.entryAfter [ "time" ] {
|
||
|
command = "date +%d";
|
||
|
interval = 5;
|
||
|
};
|
||
|
# And this block after the example block
|
||
|
example = lib.hm.dag.entryAfter [ "date" ] {
|
||
|
command = "echo hi $(date +%s)";
|
||
|
interval = 3;
|
||
|
};
|
||
|
};
|
||
|
}'';
|
||
|
};
|
||
|
};
|
||
|
|
||
|
config = let
|
||
|
# A function to create the file that will be put into the XDG config home.
|
||
|
makeFile = config:
|
||
|
let
|
||
|
# Takes a singular name value pair and turns it into an attrset
|
||
|
nameValuePairToAttr = value: (builtins.listToAttrs [ value ]);
|
||
|
# Converts a dag entry to a name-value pair
|
||
|
dagEntryToNameValue = entry: (nameValuePair entry.name entry.data);
|
||
|
|
||
|
# Try to sort the blocks
|
||
|
trySortedBlocks = hm.dag.topoSort config;
|
||
|
|
||
|
# Get the blocks if successful, abort if not
|
||
|
blocks = if trySortedBlocks ? result then
|
||
|
trySortedBlocks.result
|
||
|
else
|
||
|
abort
|
||
|
"Dependency cycle in i3blocks: ${builtins.toJSON trySortedBlocks}";
|
||
|
|
||
|
# Turn the blocks back into their name value pairs
|
||
|
orderedBlocks =
|
||
|
(map (value: (nameValuePairToAttr (dagEntryToNameValue value)))
|
||
|
blocks);
|
||
|
in {
|
||
|
# We create an "INI" file for each bar, then append them all in order
|
||
|
text = concatStringsSep "\n" (map (value: (mkIni value)) orderedBlocks);
|
||
|
};
|
||
|
|
||
|
# Make our config (if enabled
|
||
|
in mkIf cfg.enable {
|
||
|
assertions = [
|
||
|
(lib.hm.assertions.assertPlatform "programs.i3blocks" pkgs
|
||
|
lib.platforms.linux)
|
||
|
];
|
||
|
|
||
|
home.packages = [ cfg.package ];
|
||
|
|
||
|
xdg.configFile = (mapAttrs'
|
||
|
(name: value: nameValuePair "i3blocks/${name}" (makeFile value))
|
||
|
cfg.bars);
|
||
|
};
|
||
|
}
|