i3blocks: added configuration module

This commit is contained in:
~noodlez1232 2023-11-13 16:10:38 -08:00 committed by Robert Helgesson
parent f06edaf18b
commit 6e91c5df19
No known key found for this signature in database
GPG key ID: 96E745BD17AA17ED
6 changed files with 190 additions and 0 deletions

View file

@ -1371,6 +1371,14 @@ in
A new module is available: 'programs.bemenu'. A new module is available: 'programs.bemenu'.
''; '';
} }
{
time = "2024-01-01T09:09:42+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'programs.i3blocks'.
'';
}
]; ];
}; };
} }

View file

@ -110,6 +110,7 @@ let
./programs/hstr.nix ./programs/hstr.nix
./programs/htop.nix ./programs/htop.nix
./programs/hyfetch.nix ./programs/hyfetch.nix
./programs/i3blocks.nix
./programs/i3status-rust.nix ./programs/i3status-rust.nix
./programs/i3status.nix ./programs/i3status.nix
./programs/imv.nix ./programs/imv.nix

View file

@ -0,0 +1,114 @@
{ 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);
};
}

View file

@ -190,6 +190,7 @@ import nmt {
./modules/programs/getmail ./modules/programs/getmail
./modules/programs/gnome-terminal ./modules/programs/gnome-terminal
./modules/programs/hexchat ./modules/programs/hexchat
./modules/programs/i3blocks
./modules/programs/i3status-rust ./modules/programs/i3status-rust
./modules/programs/imv ./modules/programs/imv
./modules/programs/kodi ./modules/programs/kodi

View file

@ -0,0 +1 @@
{ i3blocks-with-ordered-blocks = ./with-ordered-blocks.nix; }

View file

@ -0,0 +1,65 @@
{ config, lib, pkgs, ... }:
with lib;
let
expectedConfig = pkgs.writeText "i3blocks-expected-config" ''
[block1first]
command=echo first
interval=1
[block3second]
command=echo second
interval=2
[block2third]
command=echo third
interval=3
'';
in {
config = {
programs.i3blocks = {
enable = true;
package = config.lib.test.mkStubPackage { };
bars = with lib; {
bar1 = {
block1first = {
command = "echo first";
interval = 1;
};
block2third = hm.dag.entryAfter [ "block3second" ] {
command = "echo third";
interval = 3;
};
block3second = hm.dag.entryAfter [ "block1first" ] {
command = "echo second";
interval = 2;
};
};
bar2 = {
block1first = {
command = "echo first";
interval = 1;
};
block2third = hm.dag.entryAfter [ "block3second" ] {
command = "echo third";
interval = 3;
};
block3second = hm.dag.entryAfter [ "block1first" ] {
command = "echo second";
interval = 2;
};
};
};
};
test.stubs.i3blocks = { };
nmt.script = ''
assertFileExists home-files/.config/i3blocks/bar1
assertFileExists home-files/.config/i3blocks/bar2
assertFileContent home-files/.config/i3blocks/bar1 ${expectedConfig}
assertFileContent home-files/.config/i3blocks/bar2 ${expectedConfig}
'';
};
}