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:
parent
7313258b45
commit
98d030f723
6 changed files with 156 additions and 32 deletions
|
@ -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 ];
|
||||||
|
|
6
tests/modules/programs/rofi/custom-theme-config.rasi
Normal file
6
tests/modules/programs/rofi/custom-theme-config.rasi
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
configuration {
|
||||||
|
location: 0;
|
||||||
|
theme: "custom";
|
||||||
|
xoffset: 0;
|
||||||
|
yoffset: 0;
|
||||||
|
}
|
39
tests/modules/programs/rofi/custom-theme.nix
Normal file
39
tests/modules/programs/rofi/custom-theme.nix
Normal 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}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
13
tests/modules/programs/rofi/custom-theme.rasi
Normal file
13
tests/modules/programs/rofi/custom-theme.rasi
Normal 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;
|
||||||
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
Loading…
Reference in a new issue