1
0
Fork 0
mirror of https://github.com/nix-community/home-manager synced 2024-11-26 21:19:45 +01:00

rofi: add support to custom themes

If this commit now it is possible to define a custom theme directly
using Nix, like this:

```nix
{
   programs.rofi.theme = {
      "*" = {
         background-color = "#000000";
         border-color = "FFFFFF";
         width = 512;
      };
      listview = {
         cycle = true;
      };
   };
}
```

And this will be converted to the proper rasi format to be used in
rofi.
This commit is contained in:
Thiago Kenji Okada 2021-01-23 14:13:38 -03:00 committed by Robert Helgesson
parent 7313258b45
commit 98d030f723
No known key found for this signature in database
GPG key ID: 36BDAA14C2797E89
6 changed files with 156 additions and 32 deletions

View file

@ -1,7 +1,6 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with lib;
with builtins;
let let
@ -109,21 +108,31 @@ let
if value then "true" else "false" if value then "true" else "false"
else if isInt value then else if isInt value then
toString value toString value
else if value._type or "" == "literal" then
value.value
else if isString value then
''"${value}"''
else else
''"${toString value}"''; abort "Unhandled value type ${builtins.typeOf value}";
mkKeyValue = name: value: "${name}: ${mkValueString value};"; mkKeyValue = name: value: "${name}: ${mkValueString value};";
toRasi = section: config: mkRasiSection = section: config:
let let
toRasiKeyValue = generators.toKeyValue { inherit mkKeyValue; };
# Remove null values so the resulting config does not have empty lines # Remove null values so the resulting config does not have empty lines
configStr = generators.toKeyValue { inherit mkKeyValue; } configStr = toRasiKeyValue (filterAttrs (_: v: v != null) config);
(attrsets.filterAttrs (m: v: v != null) config);
in '' in ''
${section} { ${section} {
${configStr}} ${configStr}}
''; '';
toRasi = attrsOfAttrs:
let
mkSection = mkRasiSection;
sections = mapAttrsToList mkSection attrsOfAttrs;
in concatStringsSep "\n" sections;
locationsMap = { locationsMap = {
center = 0; center = 0;
top-left = 1; top-left = 1;
@ -136,14 +145,41 @@ let
left = 8; left = 8;
}; };
configType = with types; attrsOf (oneOf [ str int bool rasiLiteral ]);
rasiLiteral = types.submodule {
options = {
_type = mkOption {
type = types.enum [ "literal" ];
internal = true;
};
value = mkOption {
type = types.str;
internal = true;
};
};
} // {
description = "Rasi literal string";
};
themeType = with types; attrsOf configType;
themeName = if (cfg.theme == null) then themeName = if (cfg.theme == null) then
null null
else if (isString cfg.theme) then else if (isString cfg.theme) then
cfg.theme cfg.theme
else if (isAttrs cfg.theme) then
"custom"
else else
removeSuffix ".rasi" (baseNameOf cfg.theme); removeSuffix ".rasi" (baseNameOf cfg.theme);
themePath = if (isString cfg.theme) then null else cfg.theme; themePath = if (isString cfg.theme) then
null
else if (isAttrs cfg.theme) then
"custom"
else
cfg.theme;
in { in {
options.programs.rofi = { options.programs.rofi = {
@ -293,11 +329,28 @@ in {
theme = mkOption { theme = mkOption {
default = null; default = null;
type = with types; nullOr (either str path); type = with types; nullOr (oneOf [ str path themeType ]);
example = "Arc"; example = literalExample ''
with config.lib.formats.rasi; {
"*" = {
# config.lib.formats.rasi.mkLiteral unquotes the value
background-color = mkLiteral "#000000";
foreground-color = mkLiteral "rgba ( 250, 251, 252, 100 % )";
border-color = mkLiteral "#FFFFFF";
width = 512;
};
"#textbox-prompt-colon" = {
expand = false;
str = ":";
margin = mkLiteral "0px 0.3em 0em 0em";
text-color = mkLiteral "@foreground-color";
};
}
'';
description = '' description = ''
Name of theme or path to theme file in rasi format. Available Name of theme or path to theme file in rasi format or attribute set with
named themes can be viewed using the theme configuration. Available named themes can be viewed using the
<command>rofi-theme-selector</command> tool. <command>rofi-theme-selector</command> tool.
''; '';
}; };
@ -318,7 +371,7 @@ in {
kb-secondary-paste = "Control+v,Insert"; kb-secondary-paste = "Control+v,Insert";
} }
''; '';
type = with types; attrsOf (oneOf [ int str bool ]); type = configType;
description = "Additional configuration to add."; description = "Additional configuration to add.";
}; };
@ -332,30 +385,39 @@ in {
''; '';
}]; }];
lib.formats.rasi.mkLiteral = value: {
_type = "literal";
inherit value;
};
home.packages = [ cfg.package ]; home.packages = [ cfg.package ];
home.file."${cfg.configPath}".text = toRasi "configuration" ({ home.file."${cfg.configPath}".text = toRasi {
width = cfg.width; configuration = ({
lines = cfg.lines; width = cfg.width;
font = cfg.font; lines = cfg.lines;
bw = cfg.borderWidth; font = cfg.font;
eh = cfg.rowHeight; bw = cfg.borderWidth;
padding = cfg.padding; eh = cfg.rowHeight;
separator-style = cfg.separator; padding = cfg.padding;
hide-scrollbar = separator-style = cfg.separator;
if (cfg.scrollbar != null) then (!cfg.scrollbar) else null; hide-scrollbar =
terminal = cfg.terminal; if (cfg.scrollbar != null) then (!cfg.scrollbar) else null;
cycle = cfg.cycle; terminal = cfg.terminal;
fullscreen = cfg.fullscreen; cycle = cfg.cycle;
location = (getAttr cfg.location locationsMap); fullscreen = cfg.fullscreen;
xoffset = cfg.xoffset; location = (getAttr cfg.location locationsMap);
yoffset = cfg.yoffset; xoffset = cfg.xoffset;
theme = themeName; yoffset = cfg.yoffset;
} // (mkColorScheme cfg.colors) // cfg.extraConfig); theme = themeName;
} // (mkColorScheme cfg.colors) // cfg.extraConfig);
xdg.dataFile = mkIf (themePath != null) {
"rofi/themes/${themeName}.rasi".source = themePath;
}; };
xdg.dataFile = mkIf (themePath != null) (if themePath == "custom" then {
"rofi/themes/${themeName}.rasi".text = toRasi cfg.theme;
} else {
"rofi/themes/${themeName}.rasi".source = themePath;
});
}; };
meta.maintainers = with maintainers; [ thiagokokada ]; meta.maintainers = with maintainers; [ thiagokokada ];

View file

@ -0,0 +1,6 @@
configuration {
location: 0;
theme: "custom";
xoffset: 0;
yoffset: 0;
}

View file

@ -0,0 +1,39 @@
{ config, lib, pkgs, ... }:
with lib;
{
config = {
programs.rofi = {
enable = true;
theme = with config.lib.formats.rasi; {
"*" = {
background-color = mkLiteral "#000000";
foreground-color = mkLiteral "rgba ( 250, 251, 252, 100 % )";
border-color = mkLiteral "#FFFFFF";
width = 512;
};
"#textbox-prompt-colon" = {
expand = false;
str = ":";
margin = mkLiteral "0px 0.3em 0em 0em";
text-color = mkLiteral "@foreground-color";
};
};
};
nixpkgs.overlays =
[ (self: super: { rofi = pkgs.writeScriptBin "dummy-rofi" ""; }) ];
nmt.script = ''
assertFileContent \
home-files/.config/rofi/config.rasi \
${./custom-theme-config.rasi}
assertFileContent \
home-files/.local/share/rofi/themes/custom.rasi \
${./custom-theme.rasi}
'';
};
}

View file

@ -0,0 +1,13 @@
#textbox-prompt-colon {
expand: false;
margin: 0px 0.3em 0em 0em;
str: ":";
text-color: @foreground-color;
}
* {
background-color: #000000;
border-color: #FFFFFF;
foreground-color: rgba ( 250, 251, 252, 100 % );
width: 512;
}

View file

@ -1,4 +1,5 @@
{ {
rofi-valid-config = ./valid-config.nix; rofi-valid-config = ./valid-config.nix;
rofi-custom-theme = ./custom-theme.nix;
rofi-assert-on-both-theme-and-colors = ./assert-on-both-theme-and-colors.nix; rofi-assert-on-both-theme-and-colors = ./assert-on-both-theme-and-colors.nix;
} }

View file

@ -48,6 +48,9 @@ with lib;
}; };
}; };
nixpkgs.overlays =
[ (self: super: { rofi = pkgs.writeScriptBin "dummy-rofi" ""; }) ];
nmt.script = '' nmt.script = ''
assertFileContent \ assertFileContent \
home-files/.config/rofi/config.rasi \ home-files/.config/rofi/config.rasi \