treewide: reformat nixfmt-rfc-style
Reformat repository using new nixfmt-rfc-style.
This commit is contained in:
parent
5df48c4255
commit
cba2f9ce95
1051 changed files with 37028 additions and 26594 deletions
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) types;
|
||||
|
|
@ -7,18 +12,23 @@ let
|
|||
|
||||
toDconfIni = lib.generators.toINI { mkKeyValue = mkIniKeyValue; };
|
||||
|
||||
mkIniKeyValue = key: value:
|
||||
"${key}=${toString (lib.hm.gvariant.mkValue value)}";
|
||||
mkIniKeyValue = key: value: "${key}=${toString (lib.hm.gvariant.mkValue value)}";
|
||||
|
||||
# The dconf keys managed by this configuration. We store this as part of the
|
||||
# generation state to be able to reset keys that become unmanaged during
|
||||
# switch.
|
||||
stateDconfKeys = pkgs.writeText "dconf-keys.json" (builtins.toJSON
|
||||
(lib.concatLists (lib.mapAttrsToList
|
||||
(dir: entries: lib.mapAttrsToList (key: _: "/${dir}/${key}") entries)
|
||||
cfg.settings)));
|
||||
stateDconfKeys = pkgs.writeText "dconf-keys.json" (
|
||||
builtins.toJSON (
|
||||
lib.concatLists (
|
||||
lib.mapAttrsToList (
|
||||
dir: entries: lib.mapAttrsToList (key: _: "/${dir}/${key}") entries
|
||||
) cfg.settings
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.rycee ];
|
||||
|
||||
options = {
|
||||
|
|
@ -84,8 +94,8 @@ in {
|
|||
ln -s ${stateDconfKeys} $out/state/${stateDconfKeys.name}
|
||||
'';
|
||||
|
||||
home.activation.dconfSettings = lib.hm.dag.entryAfter [ "installPackages" ]
|
||||
(let
|
||||
home.activation.dconfSettings = lib.hm.dag.entryAfter [ "installPackages" ] (
|
||||
let
|
||||
iniFile = pkgs.writeText "hm-dconf.ini" (toDconfIni cfg.settings);
|
||||
|
||||
statePath = "state/${stateDconfKeys.name}";
|
||||
|
|
@ -95,7 +105,12 @@ in {
|
|||
|
||||
${config.lib.bash.initHomeManagerLib}
|
||||
|
||||
PATH=${lib.makeBinPath [ pkgs.dconf pkgs.jq ]}''${PATH:+:}$PATH
|
||||
PATH=${
|
||||
lib.makeBinPath [
|
||||
pkgs.dconf
|
||||
pkgs.jq
|
||||
]
|
||||
}''${PATH:+:}$PATH
|
||||
|
||||
oldState="$1"
|
||||
newState="$2"
|
||||
|
|
@ -116,7 +131,8 @@ in {
|
|||
run $DCONF_DBUS_RUN_SESSION dconf reset "$key"
|
||||
done
|
||||
'';
|
||||
in ''
|
||||
in
|
||||
''
|
||||
if [[ -v DBUS_SESSION_BUS_ADDRESS ]]; then
|
||||
export DCONF_DBUS_RUN_SESSION=""
|
||||
else
|
||||
|
|
@ -132,6 +148,7 @@ in {
|
|||
run $DCONF_DBUS_RUN_SESSION ${pkgs.dconf}/bin/dconf load / < ${iniFile}
|
||||
|
||||
unset DCONF_DBUS_RUN_SESSION
|
||||
'');
|
||||
''
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
|
|
@ -6,7 +11,8 @@ let
|
|||
|
||||
iniFormat = pkgs.formats.ini { };
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ loicreynier ];
|
||||
|
||||
options.editorconfig = {
|
||||
|
|
@ -38,14 +44,18 @@ in {
|
|||
};
|
||||
|
||||
config = lib.mkIf (cfg.enable && cfg.settings != { }) {
|
||||
home.file.".editorconfig".text = let
|
||||
renderedSettings = lib.generators.toINIWithGlobalSection { } {
|
||||
globalSection = { root = true; };
|
||||
sections = cfg.settings;
|
||||
};
|
||||
in ''
|
||||
# Generated by Home Manager
|
||||
${renderedSettings}
|
||||
'';
|
||||
home.file.".editorconfig".text =
|
||||
let
|
||||
renderedSettings = lib.generators.toINIWithGlobalSection { } {
|
||||
globalSection = {
|
||||
root = true;
|
||||
};
|
||||
sections = cfg.settings;
|
||||
};
|
||||
in
|
||||
''
|
||||
# Generated by Home Manager
|
||||
${renderedSettings}
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,12 @@
|
|||
#
|
||||
# https://github.com/NixOS/nixpkgs/blob/23.11/nixos/modules/config/fonts/fontconfig.nix
|
||||
|
||||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
|
|
@ -10,15 +15,19 @@ let
|
|||
|
||||
profileDirectory = config.home.profileDirectory;
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.rycee ];
|
||||
|
||||
imports = [
|
||||
(lib.mkRenamedOptionModule [ "fonts" "fontconfig" "enableProfileFonts" ] [
|
||||
"fonts"
|
||||
"fontconfig"
|
||||
"enable"
|
||||
])
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "fonts" "fontconfig" "enableProfileFonts" ]
|
||||
[
|
||||
"fonts"
|
||||
"fontconfig"
|
||||
"enable"
|
||||
]
|
||||
)
|
||||
];
|
||||
|
||||
options = {
|
||||
|
|
@ -117,53 +126,58 @@ in {
|
|||
fi
|
||||
'';
|
||||
|
||||
xdg.configFile = let
|
||||
mkFontconfigConf = conf: ''
|
||||
<?xml version='1.0'?>
|
||||
xdg.configFile =
|
||||
let
|
||||
mkFontconfigConf = conf: ''
|
||||
<?xml version='1.0'?>
|
||||
|
||||
<!-- Generated by Home Manager. -->
|
||||
<!-- Generated by Home Manager. -->
|
||||
|
||||
<!DOCTYPE fontconfig SYSTEM 'urn:fontconfig:fonts.dtd'>
|
||||
<fontconfig>
|
||||
${conf}
|
||||
</fontconfig>
|
||||
'';
|
||||
in {
|
||||
"fontconfig/conf.d/10-hm-fonts.conf".text = mkFontconfigConf ''
|
||||
<description>Add fonts in the Nix user profile</description>
|
||||
<!DOCTYPE fontconfig SYSTEM 'urn:fontconfig:fonts.dtd'>
|
||||
<fontconfig>
|
||||
${conf}
|
||||
</fontconfig>
|
||||
'';
|
||||
in
|
||||
{
|
||||
"fontconfig/conf.d/10-hm-fonts.conf".text = mkFontconfigConf ''
|
||||
<description>Add fonts in the Nix user profile</description>
|
||||
|
||||
<include ignore_missing="yes">${config.home.path}/etc/fonts/conf.d</include>
|
||||
<include ignore_missing="yes">${config.home.path}/etc/fonts/fonts.conf</include>
|
||||
<include ignore_missing="yes">${config.home.path}/etc/fonts/conf.d</include>
|
||||
<include ignore_missing="yes">${config.home.path}/etc/fonts/fonts.conf</include>
|
||||
|
||||
<dir>${config.home.path}/lib/X11/fonts</dir>
|
||||
<dir>${config.home.path}/share/fonts</dir>
|
||||
<dir>${profileDirectory}/lib/X11/fonts</dir>
|
||||
<dir>${profileDirectory}/share/fonts</dir>
|
||||
<dir>${config.home.path}/lib/X11/fonts</dir>
|
||||
<dir>${config.home.path}/share/fonts</dir>
|
||||
<dir>${profileDirectory}/lib/X11/fonts</dir>
|
||||
<dir>${profileDirectory}/share/fonts</dir>
|
||||
|
||||
<cachedir>${config.home.path}/lib/fontconfig/cache</cachedir>
|
||||
'';
|
||||
<cachedir>${config.home.path}/lib/fontconfig/cache</cachedir>
|
||||
'';
|
||||
|
||||
"fontconfig/conf.d/52-hm-default-fonts.conf".text = let
|
||||
genDefault = fonts: name:
|
||||
lib.optionalString (fonts != [ ]) ''
|
||||
<alias binding="same">
|
||||
<family>${name}</family>
|
||||
<prefer>
|
||||
${
|
||||
lib.concatStringsSep "" (map (font: ''
|
||||
<family>${font}</family>
|
||||
'') fonts)
|
||||
}
|
||||
</prefer>
|
||||
</alias>
|
||||
"fontconfig/conf.d/52-hm-default-fonts.conf".text =
|
||||
let
|
||||
genDefault =
|
||||
fonts: name:
|
||||
lib.optionalString (fonts != [ ]) ''
|
||||
<alias binding="same">
|
||||
<family>${name}</family>
|
||||
<prefer>
|
||||
${lib.concatStringsSep "" (
|
||||
map (font: ''
|
||||
<family>${font}</family>
|
||||
'') fonts
|
||||
)}
|
||||
</prefer>
|
||||
</alias>
|
||||
'';
|
||||
in
|
||||
mkFontconfigConf ''
|
||||
<!-- Default fonts -->
|
||||
${genDefault cfg.defaultFonts.sansSerif "sans-serif"}
|
||||
${genDefault cfg.defaultFonts.serif "serif"}
|
||||
${genDefault cfg.defaultFonts.monospace "monospace"}
|
||||
${genDefault cfg.defaultFonts.emoji "emoji"}
|
||||
'';
|
||||
in mkFontconfigConf ''
|
||||
<!-- Default fonts -->
|
||||
${genDefault cfg.defaultFonts.sansSerif "sans-serif"}
|
||||
${genDefault cfg.defaultFonts.serif "serif"}
|
||||
${genDefault cfg.defaultFonts.monospace "monospace"}
|
||||
${genDefault cfg.defaultFonts.emoji "emoji"}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,12 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) literalExpression mkOption optionalAttrs types;
|
||||
inherit (lib)
|
||||
literalExpression
|
||||
mkOption
|
||||
optionalAttrs
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.gtk;
|
||||
cfg2 = config.gtk.gtk2;
|
||||
|
|
@ -9,22 +14,26 @@ let
|
|||
cfg4 = config.gtk.gtk4;
|
||||
|
||||
toGtk3Ini = lib.generators.toINI {
|
||||
mkKeyValue = key: value:
|
||||
mkKeyValue =
|
||||
key: value:
|
||||
let
|
||||
value' =
|
||||
if lib.isBool value then lib.boolToString value else toString value;
|
||||
in "${lib.escape [ "=" ] key}=${value'}";
|
||||
value' = if lib.isBool value then lib.boolToString value else toString value;
|
||||
in
|
||||
"${lib.escape [ "=" ] key}=${value'}";
|
||||
};
|
||||
|
||||
formatGtk2Option = n: v:
|
||||
formatGtk2Option =
|
||||
n: v:
|
||||
let
|
||||
v' = if lib.isBool v then
|
||||
lib.boolToString lib.value
|
||||
else if lib.isString v then
|
||||
''"${v}"''
|
||||
else
|
||||
toString v;
|
||||
in "${lib.escape [ "=" ] n} = ${v'}";
|
||||
v' =
|
||||
if lib.isBool v then
|
||||
lib.boolToString lib.value
|
||||
else if lib.isString v then
|
||||
''"${v}"''
|
||||
else
|
||||
toString v;
|
||||
in
|
||||
"${lib.escape [ "=" ] n} = ${v'}";
|
||||
|
||||
themeType = types.submodule {
|
||||
options = {
|
||||
|
|
@ -100,7 +109,8 @@ let
|
|||
};
|
||||
};
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.rycee ];
|
||||
|
||||
imports = [
|
||||
|
|
@ -153,10 +163,8 @@ in {
|
|||
configLocation = mkOption {
|
||||
type = types.path;
|
||||
default = "${config.home.homeDirectory}/.gtkrc-2.0";
|
||||
defaultText =
|
||||
literalExpression ''"''${config.home.homeDirectory}/.gtkrc-2.0"'';
|
||||
example =
|
||||
literalExpression ''"''${config.xdg.configHome}/gtk-2.0/gtkrc"'';
|
||||
defaultText = literalExpression ''"''${config.home.homeDirectory}/.gtkrc-2.0"'';
|
||||
example = literalExpression ''"''${config.xdg.configHome}/gtk-2.0/gtkrc"'';
|
||||
description = ''
|
||||
The location to put the GTK configuration file.
|
||||
'';
|
||||
|
|
@ -172,7 +180,13 @@ in {
|
|||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = with types; attrsOf (oneOf [ bool int str ]);
|
||||
type =
|
||||
with types;
|
||||
attrsOf (oneOf [
|
||||
bool
|
||||
int
|
||||
str
|
||||
]);
|
||||
default = { };
|
||||
example = {
|
||||
gtk-cursor-blink = false;
|
||||
|
|
@ -220,75 +234,86 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable (let
|
||||
gtkIni = optionalAttrs (cfg.font != null) {
|
||||
gtk-font-name =
|
||||
let fontSize = if cfg.font.size != null then cfg.font.size else 10;
|
||||
in "${cfg.font.name} ${toString fontSize}";
|
||||
} // optionalAttrs (cfg.theme != null) { gtk-theme-name = cfg.theme.name; }
|
||||
// optionalAttrs (cfg.iconTheme != null) {
|
||||
gtk-icon-theme-name = cfg.iconTheme.name;
|
||||
} // optionalAttrs (cfg.cursorTheme != null) {
|
||||
gtk-cursor-theme-name = cfg.cursorTheme.name;
|
||||
} // optionalAttrs
|
||||
(cfg.cursorTheme != null && cfg.cursorTheme.size != null) {
|
||||
gtk-cursor-theme-size = cfg.cursorTheme.size;
|
||||
config = lib.mkIf cfg.enable (
|
||||
let
|
||||
gtkIni =
|
||||
optionalAttrs (cfg.font != null) {
|
||||
gtk-font-name =
|
||||
let
|
||||
fontSize = if cfg.font.size != null then cfg.font.size else 10;
|
||||
in
|
||||
"${cfg.font.name} ${toString fontSize}";
|
||||
}
|
||||
// optionalAttrs (cfg.theme != null) { gtk-theme-name = cfg.theme.name; }
|
||||
// optionalAttrs (cfg.iconTheme != null) {
|
||||
gtk-icon-theme-name = cfg.iconTheme.name;
|
||||
}
|
||||
// optionalAttrs (cfg.cursorTheme != null) {
|
||||
gtk-cursor-theme-name = cfg.cursorTheme.name;
|
||||
}
|
||||
// optionalAttrs (cfg.cursorTheme != null && cfg.cursorTheme.size != null) {
|
||||
gtk-cursor-theme-size = cfg.cursorTheme.size;
|
||||
};
|
||||
|
||||
gtk4Css =
|
||||
lib.optionalString (cfg.theme != null && cfg.theme.package != null) ''
|
||||
/**
|
||||
* GTK 4 reads the theme configured by gtk-theme-name, but ignores it.
|
||||
* It does however respect user CSS, so import the theme from here.
|
||||
**/
|
||||
@import url("file://${cfg.theme.package}/share/themes/${cfg.theme.name}/gtk-4.0/gtk.css");
|
||||
''
|
||||
+ cfg4.extraCss;
|
||||
|
||||
dconfIni =
|
||||
optionalAttrs (cfg.font != null) {
|
||||
font-name =
|
||||
let
|
||||
fontSize = if cfg.font.size != null then cfg.font.size else 10;
|
||||
in
|
||||
"${cfg.font.name} ${toString fontSize}";
|
||||
}
|
||||
// optionalAttrs (cfg.theme != null) { gtk-theme = cfg.theme.name; }
|
||||
// optionalAttrs (cfg.iconTheme != null) {
|
||||
icon-theme = cfg.iconTheme.name;
|
||||
}
|
||||
// optionalAttrs (cfg.cursorTheme != null) {
|
||||
cursor-theme = cfg.cursorTheme.name;
|
||||
}
|
||||
// optionalAttrs (cfg.cursorTheme != null && cfg.cursorTheme.size != null) {
|
||||
cursor-size = cfg.cursorTheme.size;
|
||||
};
|
||||
|
||||
optionalPackage = opt: lib.optional (opt != null && opt.package != null) opt.package;
|
||||
in
|
||||
{
|
||||
home.packages = lib.concatMap optionalPackage [
|
||||
cfg.font
|
||||
cfg.theme
|
||||
cfg.iconTheme
|
||||
cfg.cursorTheme
|
||||
];
|
||||
|
||||
home.file.${cfg2.configLocation}.text =
|
||||
lib.concatMapStrings (l: l + "\n") (lib.mapAttrsToList formatGtk2Option gtkIni)
|
||||
+ cfg2.extraConfig
|
||||
+ "\n";
|
||||
|
||||
home.sessionVariables.GTK2_RC_FILES = cfg2.configLocation;
|
||||
|
||||
xdg.configFile."gtk-3.0/settings.ini".text = toGtk3Ini { Settings = gtkIni // cfg3.extraConfig; };
|
||||
|
||||
xdg.configFile."gtk-3.0/gtk.css" = lib.mkIf (cfg3.extraCss != "") { text = cfg3.extraCss; };
|
||||
|
||||
xdg.configFile."gtk-3.0/bookmarks" = lib.mkIf (cfg3.bookmarks != [ ]) {
|
||||
text = lib.concatMapStrings (l: l + "\n") cfg3.bookmarks;
|
||||
};
|
||||
|
||||
gtk4Css =
|
||||
lib.optionalString (cfg.theme != null && cfg.theme.package != null) ''
|
||||
/**
|
||||
* GTK 4 reads the theme configured by gtk-theme-name, but ignores it.
|
||||
* It does however respect user CSS, so import the theme from here.
|
||||
**/
|
||||
@import url("file://${cfg.theme.package}/share/themes/${cfg.theme.name}/gtk-4.0/gtk.css");
|
||||
'' + cfg4.extraCss;
|
||||
xdg.configFile."gtk-4.0/settings.ini".text = toGtk3Ini { Settings = gtkIni // cfg4.extraConfig; };
|
||||
|
||||
dconfIni = optionalAttrs (cfg.font != null) {
|
||||
font-name =
|
||||
let fontSize = if cfg.font.size != null then cfg.font.size else 10;
|
||||
in "${cfg.font.name} ${toString fontSize}";
|
||||
} // optionalAttrs (cfg.theme != null) { gtk-theme = cfg.theme.name; }
|
||||
// optionalAttrs (cfg.iconTheme != null) {
|
||||
icon-theme = cfg.iconTheme.name;
|
||||
} // optionalAttrs (cfg.cursorTheme != null) {
|
||||
cursor-theme = cfg.cursorTheme.name;
|
||||
} // optionalAttrs
|
||||
(cfg.cursorTheme != null && cfg.cursorTheme.size != null) {
|
||||
cursor-size = cfg.cursorTheme.size;
|
||||
};
|
||||
xdg.configFile."gtk-4.0/gtk.css" = lib.mkIf (gtk4Css != "") { text = gtk4Css; };
|
||||
|
||||
optionalPackage = opt:
|
||||
lib.optional (opt != null && opt.package != null) opt.package;
|
||||
in {
|
||||
home.packages = lib.concatMap optionalPackage [
|
||||
cfg.font
|
||||
cfg.theme
|
||||
cfg.iconTheme
|
||||
cfg.cursorTheme
|
||||
];
|
||||
|
||||
home.file.${cfg2.configLocation}.text = lib.concatMapStrings (l: l + "\n")
|
||||
(lib.mapAttrsToList formatGtk2Option gtkIni) + cfg2.extraConfig + "\n";
|
||||
|
||||
home.sessionVariables.GTK2_RC_FILES = cfg2.configLocation;
|
||||
|
||||
xdg.configFile."gtk-3.0/settings.ini".text =
|
||||
toGtk3Ini { Settings = gtkIni // cfg3.extraConfig; };
|
||||
|
||||
xdg.configFile."gtk-3.0/gtk.css" =
|
||||
lib.mkIf (cfg3.extraCss != "") { text = cfg3.extraCss; };
|
||||
|
||||
xdg.configFile."gtk-3.0/bookmarks" = lib.mkIf (cfg3.bookmarks != [ ]) {
|
||||
text = lib.concatMapStrings (l: l + "\n") cfg3.bookmarks;
|
||||
};
|
||||
|
||||
xdg.configFile."gtk-4.0/settings.ini".text =
|
||||
toGtk3Ini { Settings = gtkIni // cfg4.extraConfig; };
|
||||
|
||||
xdg.configFile."gtk-4.0/gtk.css" =
|
||||
lib.mkIf (gtk4Css != "") { text = gtk4Css; };
|
||||
|
||||
dconf.settings."org/gnome/desktop/interface" = dconfIni;
|
||||
});
|
||||
dconf.settings."org/gnome/desktop/interface" = dconfIni;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (pkgs.stdenv) isDarwin;
|
||||
|
|
@ -10,16 +15,16 @@ let
|
|||
(pkgs.writeTextDir "lib/mozilla/native-messaging-hosts/.keep" "")
|
||||
];
|
||||
|
||||
thunderbirdNativeMessagingHostsPath = if isDarwin then
|
||||
"Library/Mozilla/NativeMessagingHosts"
|
||||
else
|
||||
".mozilla/native-messaging-hosts";
|
||||
thunderbirdNativeMessagingHostsPath =
|
||||
if isDarwin then "Library/Mozilla/NativeMessagingHosts" else ".mozilla/native-messaging-hosts";
|
||||
|
||||
firefoxNativeMessagingHostsPath = if isDarwin then
|
||||
"Library/Application Support/Mozilla/NativeMessagingHosts"
|
||||
else
|
||||
".mozilla/native-messaging-hosts";
|
||||
in {
|
||||
firefoxNativeMessagingHostsPath =
|
||||
if isDarwin then
|
||||
"Library/Application Support/Mozilla/NativeMessagingHosts"
|
||||
else
|
||||
".mozilla/native-messaging-hosts";
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
booxter
|
||||
rycee
|
||||
|
|
@ -46,47 +51,45 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf (cfg.firefoxNativeMessagingHosts != [ ]
|
||||
|| cfg.thunderbirdNativeMessagingHosts != [ ]) {
|
||||
home.file = if isDarwin then
|
||||
let
|
||||
firefoxNativeMessagingHostsJoined = pkgs.symlinkJoin {
|
||||
name = "ff-native-messaging-hosts";
|
||||
paths = defaultPaths ++ cfg.firefoxNativeMessagingHosts;
|
||||
};
|
||||
thunderbirdNativeMessagingHostsJoined = pkgs.symlinkJoin {
|
||||
name = "th-native-messaging-hosts";
|
||||
paths = defaultPaths ++ cfg.thunderbirdNativeMessagingHosts;
|
||||
};
|
||||
in {
|
||||
"${thunderbirdNativeMessagingHostsPath}" =
|
||||
lib.mkIf (cfg.thunderbirdNativeMessagingHosts != [ ]) {
|
||||
source =
|
||||
"${thunderbirdNativeMessagingHostsJoined}/lib/mozilla/native-messaging-hosts";
|
||||
recursive = true;
|
||||
};
|
||||
config =
|
||||
lib.mkIf (cfg.firefoxNativeMessagingHosts != [ ] || cfg.thunderbirdNativeMessagingHosts != [ ])
|
||||
{
|
||||
home.file =
|
||||
if isDarwin then
|
||||
let
|
||||
firefoxNativeMessagingHostsJoined = pkgs.symlinkJoin {
|
||||
name = "ff-native-messaging-hosts";
|
||||
paths = defaultPaths ++ cfg.firefoxNativeMessagingHosts;
|
||||
};
|
||||
thunderbirdNativeMessagingHostsJoined = pkgs.symlinkJoin {
|
||||
name = "th-native-messaging-hosts";
|
||||
paths = defaultPaths ++ cfg.thunderbirdNativeMessagingHosts;
|
||||
};
|
||||
in
|
||||
{
|
||||
"${thunderbirdNativeMessagingHostsPath}" = lib.mkIf (cfg.thunderbirdNativeMessagingHosts != [ ]) {
|
||||
source = "${thunderbirdNativeMessagingHostsJoined}/lib/mozilla/native-messaging-hosts";
|
||||
recursive = true;
|
||||
};
|
||||
|
||||
"${firefoxNativeMessagingHostsPath}" =
|
||||
lib.mkIf (cfg.firefoxNativeMessagingHosts != [ ]) {
|
||||
source =
|
||||
"${firefoxNativeMessagingHostsJoined}/lib/mozilla/native-messaging-hosts";
|
||||
recursive = true;
|
||||
"${firefoxNativeMessagingHostsPath}" = lib.mkIf (cfg.firefoxNativeMessagingHosts != [ ]) {
|
||||
source = "${firefoxNativeMessagingHostsJoined}/lib/mozilla/native-messaging-hosts";
|
||||
recursive = true;
|
||||
};
|
||||
}
|
||||
else
|
||||
let
|
||||
nativeMessagingHostsJoined = pkgs.symlinkJoin {
|
||||
name = "mozilla-native-messaging-hosts";
|
||||
# on Linux, the directory is shared between Firefox and Thunderbird; merge both into one
|
||||
paths = defaultPaths ++ cfg.firefoxNativeMessagingHosts ++ cfg.thunderbirdNativeMessagingHosts;
|
||||
};
|
||||
in
|
||||
{
|
||||
"${firefoxNativeMessagingHostsPath}" = {
|
||||
source = "${nativeMessagingHostsJoined}/lib/mozilla/native-messaging-hosts";
|
||||
recursive = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
else
|
||||
let
|
||||
nativeMessagingHostsJoined = pkgs.symlinkJoin {
|
||||
name = "mozilla-native-messaging-hosts";
|
||||
# on Linux, the directory is shared between Firefox and Thunderbird; merge both into one
|
||||
paths = defaultPaths ++ cfg.firefoxNativeMessagingHosts
|
||||
++ cfg.thunderbirdNativeMessagingHosts;
|
||||
};
|
||||
in {
|
||||
"${firefoxNativeMessagingHostsPath}" = {
|
||||
source =
|
||||
"${nativeMessagingHostsJoined}/lib/mozilla/native-messaging-hosts";
|
||||
recursive = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
|
|
@ -7,58 +12,64 @@ let
|
|||
|
||||
hostPlatform = pkgs.stdenv.hostPlatform;
|
||||
|
||||
entryModule = types.submodule ({ config, ... }: {
|
||||
options = {
|
||||
id = mkOption {
|
||||
internal = true;
|
||||
type = types.str;
|
||||
description = ''
|
||||
A unique entry identifier. By default it is a base16
|
||||
formatted hash of the entry message.
|
||||
'';
|
||||
entryModule = types.submodule (
|
||||
{ config, ... }:
|
||||
{
|
||||
options = {
|
||||
id = mkOption {
|
||||
internal = true;
|
||||
type = types.str;
|
||||
description = ''
|
||||
A unique entry identifier. By default it is a base16
|
||||
formatted hash of the entry message.
|
||||
'';
|
||||
};
|
||||
|
||||
time = mkOption {
|
||||
internal = true;
|
||||
type = types.str;
|
||||
example = "2017-07-10T21:55:04+00:00";
|
||||
description = ''
|
||||
News entry time stamp in ISO-8601 format. Must be in UTC
|
||||
(ending in '+00:00').
|
||||
'';
|
||||
};
|
||||
|
||||
condition = mkOption {
|
||||
internal = true;
|
||||
default = true;
|
||||
description = "Whether the news entry should be active.";
|
||||
};
|
||||
|
||||
message = mkOption {
|
||||
internal = true;
|
||||
type = types.str;
|
||||
description = "The news entry content.";
|
||||
};
|
||||
};
|
||||
|
||||
time = mkOption {
|
||||
internal = true;
|
||||
type = types.str;
|
||||
example = "2017-07-10T21:55:04+00:00";
|
||||
description = ''
|
||||
News entry time stamp in ISO-8601 format. Must be in UTC
|
||||
(ending in '+00:00').
|
||||
'';
|
||||
config = {
|
||||
id = lib.mkDefault (builtins.hashString "sha256" config.message);
|
||||
};
|
||||
|
||||
condition = mkOption {
|
||||
internal = true;
|
||||
default = true;
|
||||
description = "Whether the news entry should be active.";
|
||||
};
|
||||
|
||||
message = mkOption {
|
||||
internal = true;
|
||||
type = types.str;
|
||||
description = "The news entry content.";
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
id = lib.mkDefault (builtins.hashString "sha256" config.message);
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
isNixFile = n: v: v == "regular" && lib.hasSuffix ".nix" n;
|
||||
# builtins.attrNames return the values in alphabetical order
|
||||
newsFiles =
|
||||
builtins.attrNames (lib.filterAttrs isNixFile (builtins.readDir ./news));
|
||||
newsEntries =
|
||||
builtins.map (newsFile: import (./news + "/${newsFile}")) newsFiles;
|
||||
in {
|
||||
newsFiles = builtins.attrNames (lib.filterAttrs isNixFile (builtins.readDir ./news));
|
||||
newsEntries = builtins.map (newsFile: import (./news + "/${newsFile}")) newsFiles;
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.rycee ];
|
||||
|
||||
options = {
|
||||
news = {
|
||||
display = mkOption {
|
||||
type = types.enum [ "silent" "notify" "show" ];
|
||||
type = types.enum [
|
||||
"silent"
|
||||
"notify"
|
||||
"show"
|
||||
];
|
||||
default = "notify";
|
||||
description = ''
|
||||
How unread and relevant news should be presented when
|
||||
|
|
@ -100,8 +111,9 @@ in {
|
|||
};
|
||||
|
||||
config = {
|
||||
news.json.output = pkgs.writeText "hm-news.json"
|
||||
(builtins.toJSON { inherit (cfg) display entries; });
|
||||
news.json.output = pkgs.writeText "hm-news.json" (
|
||||
builtins.toJSON { inherit (cfg) display entries; }
|
||||
);
|
||||
|
||||
# DO NOT define new entries here, instead use the `./create-news-entry.sh`
|
||||
# script and create an individual news file inside `news` sub-directory.
|
||||
|
|
@ -250,8 +262,7 @@ in {
|
|||
|
||||
{
|
||||
time = "2021-09-23T17:04:48+00:00";
|
||||
condition = hostPlatform.isLinux
|
||||
&& config.services.screen-locker.enable;
|
||||
condition = hostPlatform.isLinux && config.services.screen-locker.enable;
|
||||
message = ''
|
||||
'xautolock' is now optional in 'services.screen-locker', and the
|
||||
'services.screen-locker' options have been reorganized for clarity.
|
||||
|
|
@ -1699,9 +1710,12 @@ in {
|
|||
|
||||
{
|
||||
time = "2024-06-26T07:07:17+00:00";
|
||||
condition = with config.programs.yazi;
|
||||
enable && (enableBashIntegration || enableZshIntegration
|
||||
|| enableFishIntegration || enableNushellIntegration);
|
||||
condition =
|
||||
with config.programs.yazi;
|
||||
enable
|
||||
&& (
|
||||
enableBashIntegration || enableZshIntegration || enableFishIntegration || enableNushellIntegration
|
||||
);
|
||||
message = ''
|
||||
Yazi's shell integration wrappers have been renamed from 'ya' to 'yy'.
|
||||
|
||||
|
|
@ -1881,10 +1895,12 @@ in {
|
|||
|
||||
{
|
||||
time = "2024-12-04T20:00:00+00:00";
|
||||
condition = let
|
||||
sCfg = config.programs.starship;
|
||||
fCfg = config.programs.fish;
|
||||
in sCfg.enable && sCfg.enableFishIntegration && fCfg.enable;
|
||||
condition =
|
||||
let
|
||||
sCfg = config.programs.starship;
|
||||
fCfg = config.programs.fish;
|
||||
in
|
||||
sCfg.enable && sCfg.enableFishIntegration && fCfg.enable;
|
||||
message = ''
|
||||
A new option 'programs.starship.enableInteractive' is available for
|
||||
the Fish shell that only enables starship if the shell is interactive.
|
||||
|
|
@ -1894,10 +1910,11 @@ in {
|
|||
}
|
||||
{
|
||||
time = "2024-12-08T17:22:13+00:00";
|
||||
condition = let
|
||||
usingMbsync = lib.any (a: a.mbsync.enable)
|
||||
(lib.attrValues config.accounts.email.accounts);
|
||||
in usingMbsync;
|
||||
condition =
|
||||
let
|
||||
usingMbsync = lib.any (a: a.mbsync.enable) (lib.attrValues config.accounts.email.accounts);
|
||||
in
|
||||
usingMbsync;
|
||||
message = ''
|
||||
isync/mbsync 1.5.0 has changed several things.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,38 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
inherit (lib)
|
||||
boolToString concatStringsSep escape floatToString getVersion isBool
|
||||
isConvertibleWithToString isDerivation isFloat isInt isList isString
|
||||
literalExpression maintainers mapAttrsToList mkDefault mkEnableOption mkIf
|
||||
mkMerge mkOption optionalString toPretty types versionAtLeast;
|
||||
boolToString
|
||||
concatStringsSep
|
||||
escape
|
||||
floatToString
|
||||
getVersion
|
||||
isBool
|
||||
isConvertibleWithToString
|
||||
isDerivation
|
||||
isFloat
|
||||
isInt
|
||||
isList
|
||||
isString
|
||||
literalExpression
|
||||
maintainers
|
||||
mapAttrsToList
|
||||
mkDefault
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkMerge
|
||||
mkOption
|
||||
optionalString
|
||||
toPretty
|
||||
types
|
||||
versionAtLeast
|
||||
;
|
||||
|
||||
cfg = config.nix;
|
||||
|
||||
|
|
@ -16,29 +42,33 @@ let
|
|||
|
||||
nixPath = concatStringsSep ":" cfg.nixPath;
|
||||
|
||||
useXdg = config.nix.enable
|
||||
&& (config.nix.settings.use-xdg-base-directories or false);
|
||||
defexprDir = if useXdg then
|
||||
"${config.xdg.stateHome}/nix/defexpr"
|
||||
else
|
||||
"${config.home.homeDirectory}/.nix-defexpr";
|
||||
useXdg = config.nix.enable && (config.nix.settings.use-xdg-base-directories or false);
|
||||
defexprDir =
|
||||
if useXdg then
|
||||
"${config.xdg.stateHome}/nix/defexpr"
|
||||
else
|
||||
"${config.home.homeDirectory}/.nix-defexpr";
|
||||
|
||||
# The deploy path for declarative channels. The directory name is prefixed
|
||||
# with a number to make it easier for files in defexprDir to control the order
|
||||
# they'll be read relative to each other.
|
||||
channelPath = "${defexprDir}/50-home-manager";
|
||||
|
||||
channelsDrv = let
|
||||
mkEntry = name: drv: {
|
||||
inherit name;
|
||||
path = toString drv;
|
||||
};
|
||||
in pkgs.linkFarm "channels" (lib.mapAttrsToList mkEntry cfg.channels);
|
||||
channelsDrv =
|
||||
let
|
||||
mkEntry = name: drv: {
|
||||
inherit name;
|
||||
path = toString drv;
|
||||
};
|
||||
in
|
||||
pkgs.linkFarm "channels" (lib.mapAttrsToList mkEntry cfg.channels);
|
||||
|
||||
nixConf = assert isNixAtLeast "2.2";
|
||||
nixConf =
|
||||
assert isNixAtLeast "2.2";
|
||||
let
|
||||
|
||||
mkValueString = v:
|
||||
mkValueString =
|
||||
v:
|
||||
if v == null then
|
||||
""
|
||||
else if isInt v then
|
||||
|
|
@ -62,10 +92,10 @@ let
|
|||
|
||||
mkKeyValue = k: v: "${escape [ "=" ] k} = ${mkValueString v}";
|
||||
|
||||
mkKeyValuePairs = attrs:
|
||||
concatStringsSep "\n" (mapAttrsToList mkKeyValue attrs);
|
||||
mkKeyValuePairs = attrs: concatStringsSep "\n" (mapAttrsToList mkKeyValue attrs);
|
||||
|
||||
in pkgs.writeTextFile {
|
||||
in
|
||||
pkgs.writeTextFile {
|
||||
name = "nix.conf";
|
||||
text = ''
|
||||
# WARNING: this file is generated from the nix.settings option in
|
||||
|
|
@ -75,48 +105,58 @@ let
|
|||
${cfg.extraOptions}
|
||||
'';
|
||||
checkPhase =
|
||||
if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then ''
|
||||
echo "Ignoring validation for cross-compilation"
|
||||
'' else
|
||||
if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then
|
||||
''
|
||||
echo "Ignoring validation for cross-compilation"
|
||||
''
|
||||
else
|
||||
let
|
||||
showCommand =
|
||||
if isNixAtLeast "2.20pre" then "config show" else "show-config";
|
||||
in ''
|
||||
showCommand = if isNixAtLeast "2.20pre" then "config show" else "show-config";
|
||||
in
|
||||
''
|
||||
echo "Validating generated nix.conf"
|
||||
ln -s $out ./nix.conf
|
||||
set -e
|
||||
set +o pipefail
|
||||
NIX_CONF_DIR=$PWD \
|
||||
${cfg.package}/bin/nix ${showCommand} ${
|
||||
optionalString (isNixAtLeast "2.3pre")
|
||||
"--no-net --option experimental-features nix-command"
|
||||
} \
|
||||
${cfg.package}/bin/nix ${showCommand} ${optionalString (isNixAtLeast "2.3pre") "--no-net --option experimental-features nix-command"} \
|
||||
|& sed -e 's/^warning:/error:/' \
|
||||
| (! grep '${
|
||||
if cfg.checkConfig then "^error:" else "^error: unknown setting"
|
||||
}')
|
||||
| (! grep '${if cfg.checkConfig then "^error:" else "^error: unknown setting"}')
|
||||
set -o pipefail
|
||||
'';
|
||||
};
|
||||
|
||||
semanticConfType = with types;
|
||||
semanticConfType =
|
||||
with types;
|
||||
let
|
||||
confAtom = nullOr (oneOf [ bool int float str path package ]) // {
|
||||
description =
|
||||
"Nix config atom (null, bool, int, float, str, path or package)";
|
||||
};
|
||||
in attrsOf (either confAtom (listOf confAtom));
|
||||
confAtom =
|
||||
nullOr (oneOf [
|
||||
bool
|
||||
int
|
||||
float
|
||||
str
|
||||
path
|
||||
package
|
||||
])
|
||||
// {
|
||||
description = "Nix config atom (null, bool, int, float, str, path or package)";
|
||||
};
|
||||
in
|
||||
attrsOf (either confAtom (listOf confAtom));
|
||||
|
||||
jsonFormat = pkgs.formats.json { };
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.nix = {
|
||||
enable = mkEnableOption ''
|
||||
the Nix configuration module
|
||||
'' // {
|
||||
default = true;
|
||||
visible = false;
|
||||
};
|
||||
enable =
|
||||
mkEnableOption ''
|
||||
the Nix configuration module
|
||||
''
|
||||
// {
|
||||
default = true;
|
||||
visible = false;
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.nullOr types.package;
|
||||
|
|
@ -169,60 +209,74 @@ in {
|
|||
};
|
||||
|
||||
registry = mkOption {
|
||||
type = types.attrsOf (types.submodule (let
|
||||
inputAttrs = types.attrsOf
|
||||
(types.oneOf [ types.str types.int types.bool types.package ]);
|
||||
in { config, name, ... }: {
|
||||
options = {
|
||||
from = mkOption {
|
||||
type = inputAttrs;
|
||||
example = {
|
||||
type = "indirect";
|
||||
id = "nixpkgs";
|
||||
type = types.attrsOf (
|
||||
types.submodule (
|
||||
let
|
||||
inputAttrs = types.attrsOf (
|
||||
types.oneOf [
|
||||
types.str
|
||||
types.int
|
||||
types.bool
|
||||
types.package
|
||||
]
|
||||
);
|
||||
in
|
||||
{ config, name, ... }:
|
||||
{
|
||||
options = {
|
||||
from = mkOption {
|
||||
type = inputAttrs;
|
||||
example = {
|
||||
type = "indirect";
|
||||
id = "nixpkgs";
|
||||
};
|
||||
description = "The flake reference to be rewritten.";
|
||||
};
|
||||
to = mkOption {
|
||||
type = inputAttrs;
|
||||
example = {
|
||||
type = "github";
|
||||
owner = "my-org";
|
||||
repo = "my-nixpkgs";
|
||||
};
|
||||
description = "The flake reference to which {option}`from>` is to be rewritten.";
|
||||
};
|
||||
flake = mkOption {
|
||||
type = types.nullOr types.attrs;
|
||||
default = null;
|
||||
example = literalExpression "nixpkgs";
|
||||
description = ''
|
||||
The flake input to which {option}`from>` is to be rewritten.
|
||||
'';
|
||||
};
|
||||
exact = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether the {option}`from` reference needs to match exactly. If set,
|
||||
a {option}`from` reference like `nixpkgs` does not
|
||||
match with a reference like `nixpkgs/nixos-20.03`.
|
||||
'';
|
||||
};
|
||||
};
|
||||
description = "The flake reference to be rewritten.";
|
||||
};
|
||||
to = mkOption {
|
||||
type = inputAttrs;
|
||||
example = {
|
||||
type = "github";
|
||||
owner = "my-org";
|
||||
repo = "my-nixpkgs";
|
||||
config = {
|
||||
from = mkDefault {
|
||||
type = "indirect";
|
||||
id = name;
|
||||
};
|
||||
to = mkIf (config.flake != null) (
|
||||
{
|
||||
type = "path";
|
||||
path = config.flake.outPath;
|
||||
}
|
||||
// lib.filterAttrs (
|
||||
n: v: n == "lastModified" || n == "rev" || n == "revCount" || n == "narHash"
|
||||
) config.flake
|
||||
);
|
||||
};
|
||||
description =
|
||||
"The flake reference to which {option}`from>` is to be rewritten.";
|
||||
};
|
||||
flake = mkOption {
|
||||
type = types.nullOr types.attrs;
|
||||
default = null;
|
||||
example = literalExpression "nixpkgs";
|
||||
description = ''
|
||||
The flake input to which {option}`from>` is to be rewritten.
|
||||
'';
|
||||
};
|
||||
exact = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether the {option}`from` reference needs to match exactly. If set,
|
||||
a {option}`from` reference like `nixpkgs` does not
|
||||
match with a reference like `nixpkgs/nixos-20.03`.
|
||||
'';
|
||||
};
|
||||
};
|
||||
config = {
|
||||
from = mkDefault {
|
||||
type = "indirect";
|
||||
id = name;
|
||||
};
|
||||
to = mkIf (config.flake != null) ({
|
||||
type = "path";
|
||||
path = config.flake.outPath;
|
||||
} // lib.filterAttrs (n: v:
|
||||
n == "lastModified" || n == "rev" || n == "revCount" || n
|
||||
== "narHash") config.flake);
|
||||
};
|
||||
}));
|
||||
}
|
||||
)
|
||||
);
|
||||
default = { };
|
||||
description = ''
|
||||
User level flake registry.
|
||||
|
|
@ -290,22 +344,22 @@ in {
|
|||
})
|
||||
|
||||
(mkIf (cfg.registry != { }) {
|
||||
xdg.configFile."nix/registry.json".source =
|
||||
jsonFormat.generate "registry.json" {
|
||||
version = cfg.registryVersion;
|
||||
flakes =
|
||||
mapAttrsToList (n: v: { inherit (v) from to exact; }) cfg.registry;
|
||||
};
|
||||
xdg.configFile."nix/registry.json".source = jsonFormat.generate "registry.json" {
|
||||
version = cfg.registryVersion;
|
||||
flakes = mapAttrsToList (n: v: { inherit (v) from to exact; }) cfg.registry;
|
||||
};
|
||||
})
|
||||
|
||||
(mkIf (cfg.settings != { } || cfg.extraOptions != "") {
|
||||
assertions = [{
|
||||
assertion = cfg.package != null;
|
||||
message = ''
|
||||
A corresponding Nix package must be specified via `nix.package` for generating
|
||||
nix.conf.
|
||||
'';
|
||||
}];
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.package != null;
|
||||
message = ''
|
||||
A corresponding Nix package must be specified via `nix.package` for generating
|
||||
nix.conf.
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
xdg.configFile."nix/nix.conf".source = nixConf;
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,13 +1,23 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.nixGL;
|
||||
wrapperListMarkdown = with builtins;
|
||||
foldl' (list: name:
|
||||
list + ''
|
||||
wrapperListMarkdown =
|
||||
with builtins;
|
||||
foldl' (
|
||||
list: name:
|
||||
list
|
||||
+ ''
|
||||
- ${name}
|
||||
'') "" (attrNames config.lib.nixGL.wrappers);
|
||||
in {
|
||||
''
|
||||
) "" (attrNames config.lib.nixGL.wrappers);
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.smona ];
|
||||
|
||||
options.nixGL = {
|
||||
|
|
@ -93,7 +103,12 @@ in {
|
|||
};
|
||||
|
||||
prime.installScript = lib.mkOption {
|
||||
type = with lib.types; nullOr (enum [ "mesa" "nvidia" ]);
|
||||
type =
|
||||
with lib.types;
|
||||
nullOr (enum [
|
||||
"mesa"
|
||||
"nvidia"
|
||||
]);
|
||||
default = null;
|
||||
example = "mesa";
|
||||
description = ''
|
||||
|
|
@ -109,10 +124,12 @@ in {
|
|||
};
|
||||
|
||||
installScripts = lib.mkOption {
|
||||
type = with lib.types;
|
||||
nullOr (listOf (enum (builtins.attrNames config.lib.nixGL.wrappers)));
|
||||
type = with lib.types; nullOr (listOf (enum (builtins.attrNames config.lib.nixGL.wrappers)));
|
||||
default = null;
|
||||
example = [ "mesa" "mesaPrime" ];
|
||||
example = [
|
||||
"mesa"
|
||||
"mesaPrime"
|
||||
];
|
||||
description = ''
|
||||
For each wrapper `wrp` named in the provided list, a wrapper script
|
||||
named `nixGLWrp` is installed into the environment. These scripts are
|
||||
|
|
@ -137,168 +154,199 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
findWrapperPackage = packageAttr:
|
||||
# NixGL has wrapper packages in different places depending on how you
|
||||
# access it. We want HM configuration to be the same, regardless of how
|
||||
# NixGL is imported.
|
||||
#
|
||||
# First, let's see if we have a flake.
|
||||
if builtins.hasAttr pkgs.system cfg.packages then
|
||||
cfg.packages.${pkgs.system}.${packageAttr}
|
||||
else
|
||||
# Next, let's see if we have a channel.
|
||||
if builtins.hasAttr packageAttr cfg.packages then
|
||||
cfg.packages.${packageAttr}
|
||||
else
|
||||
# Lastly, with channels, some wrappers are grouped under "auto".
|
||||
if builtins.hasAttr "auto" cfg.packages then
|
||||
cfg.packages.auto.${packageAttr}
|
||||
else
|
||||
throw "Incompatible NixGL package layout";
|
||||
|
||||
getWrapperExe = vendor:
|
||||
let
|
||||
glPackage = findWrapperPackage "nixGL${vendor}";
|
||||
glExe = lib.getExe glPackage;
|
||||
vulkanPackage = findWrapperPackage "nixVulkan${vendor}";
|
||||
vulkanExe = if cfg.vulkan.enable then lib.getExe vulkanPackage else "";
|
||||
in "${glExe} ${vulkanExe}";
|
||||
|
||||
mesaOffloadEnv = { "DRI_PRIME" = "${cfg.prime.card}"; };
|
||||
|
||||
nvOffloadEnv = {
|
||||
"DRI_PRIME" = "${cfg.prime.card}";
|
||||
"__NV_PRIME_RENDER_OFFLOAD" = "1";
|
||||
"__GLX_VENDOR_LIBRARY_NAME" = "nvidia";
|
||||
"__VK_LAYER_NV_optimus" = "NVIDIA_only";
|
||||
} // (let provider = cfg.prime.nvidiaProvider;
|
||||
in if !isNull provider then {
|
||||
"__NV_PRIME_RENDER_OFFLOAD_PROVIDER" = "${provider}";
|
||||
} else
|
||||
{ });
|
||||
|
||||
makePackageWrapper = vendor: environment: pkg:
|
||||
if builtins.isNull cfg.packages then
|
||||
pkg
|
||||
else
|
||||
# Wrap the package's binaries with nixGL, while preserving the rest of
|
||||
# the outputs and derivation attributes.
|
||||
(pkg.overrideAttrs (old: {
|
||||
name = "nixGL-${pkg.name}";
|
||||
|
||||
# Make sure this is false for the wrapper derivation, so nix doesn't expect
|
||||
# a new debug output to be produced. We won't be producing any debug info
|
||||
# for the original package.
|
||||
separateDebugInfo = false;
|
||||
nativeBuildInputs = old.nativeBuildInputs or [ ]
|
||||
++ [ pkgs.makeWrapper ];
|
||||
buildCommand = let
|
||||
# We need an intermediate wrapper package because makeWrapper
|
||||
# requires a single executable as the wrapper.
|
||||
combinedWrapperPkg =
|
||||
pkgs.writeShellScriptBin "nixGLCombinedWrapper-${vendor}" ''
|
||||
exec ${getWrapperExe vendor} "$@"
|
||||
'';
|
||||
in ''
|
||||
set -eo pipefail
|
||||
|
||||
${ # Heavily inspired by https://stackoverflow.com/a/68523368/6259505
|
||||
lib.concatStringsSep "\n" (map (outputName: ''
|
||||
echo "Copying output ${outputName}"
|
||||
set -x
|
||||
cp -rs --no-preserve=mode "${
|
||||
pkg.${outputName}
|
||||
}" "''$${outputName}"
|
||||
set +x
|
||||
'') (old.outputs or [ "out" ]))}
|
||||
|
||||
rm -rf $out/bin/*
|
||||
shopt -s nullglob # Prevent loop from running if no files
|
||||
for file in ${pkg.out}/bin/*; do
|
||||
local prog="$(basename "$file")"
|
||||
makeWrapper \
|
||||
"${lib.getExe combinedWrapperPkg}" \
|
||||
"$out/bin/$prog" \
|
||||
--argv0 "$prog" \
|
||||
--add-flags "$file" \
|
||||
${
|
||||
lib.concatStringsSep " " (lib.attrsets.mapAttrsToList
|
||||
(var: val: "--set '${var}' '${val}'") environment)
|
||||
}
|
||||
done
|
||||
|
||||
# If .desktop files refer to the old package, replace the references
|
||||
for dsk in "$out/share/applications"/*.desktop ; do
|
||||
if ! grep -q "${pkg.out}" "$dsk"; then
|
||||
continue
|
||||
fi
|
||||
src="$(readlink "$dsk")"
|
||||
rm "$dsk"
|
||||
sed "s|${pkg.out}|$out|g" "$src" > "$dsk"
|
||||
done
|
||||
|
||||
shopt -u nullglob # Revert nullglob back to its normal default state
|
||||
'';
|
||||
})) // {
|
||||
# When the nixGL-wrapped package is given to a HM module, the module
|
||||
# might want to override the package arguments, but our wrapper
|
||||
# wouldn't know what to do with them. So, we rewrite the override
|
||||
# function to instead forward the arguments to the package's own
|
||||
# override function.
|
||||
override = args:
|
||||
makePackageWrapper vendor environment (pkg.override args);
|
||||
};
|
||||
|
||||
wrappers = {
|
||||
mesa = makePackageWrapper "Intel" { };
|
||||
mesaPrime = makePackageWrapper "Intel" mesaOffloadEnv;
|
||||
nvidia = makePackageWrapper "Nvidia" { };
|
||||
nvidiaPrime = makePackageWrapper "Nvidia" nvOffloadEnv;
|
||||
};
|
||||
in {
|
||||
lib.nixGL.wrap = wrappers.${cfg.defaultWrapper};
|
||||
lib.nixGL.wrapOffload = wrappers.${cfg.offloadWrapper};
|
||||
lib.nixGL.wrappers = wrappers;
|
||||
|
||||
home.packages = let
|
||||
wantsPrimeWrapper = (!isNull cfg.prime.installScript);
|
||||
wantsWrapper = wrapper:
|
||||
(!isNull cfg.packages) && (!isNull cfg.installScripts)
|
||||
&& (builtins.elem wrapper cfg.installScripts);
|
||||
envVarsAsScript = environment:
|
||||
lib.concatStringsSep "\n"
|
||||
(lib.attrsets.mapAttrsToList (var: val: "export ${var}=${val}")
|
||||
environment);
|
||||
in [
|
||||
(lib.mkIf wantsPrimeWrapper (pkgs.writeShellScriptBin "prime-offload" ''
|
||||
${if cfg.prime.installScript == "mesa" then
|
||||
(envVarsAsScript mesaOffloadEnv)
|
||||
config =
|
||||
let
|
||||
findWrapperPackage =
|
||||
packageAttr:
|
||||
# NixGL has wrapper packages in different places depending on how you
|
||||
# access it. We want HM configuration to be the same, regardless of how
|
||||
# NixGL is imported.
|
||||
#
|
||||
# First, let's see if we have a flake.
|
||||
if builtins.hasAttr pkgs.system cfg.packages then
|
||||
cfg.packages.${pkgs.system}.${packageAttr}
|
||||
else
|
||||
(envVarsAsScript nvOffloadEnv)}
|
||||
exec "$@"
|
||||
''))
|
||||
# Next, let's see if we have a channel.
|
||||
if builtins.hasAttr packageAttr cfg.packages then
|
||||
cfg.packages.${packageAttr}
|
||||
else
|
||||
# Lastly, with channels, some wrappers are grouped under "auto".
|
||||
if builtins.hasAttr "auto" cfg.packages then
|
||||
cfg.packages.auto.${packageAttr}
|
||||
else
|
||||
throw "Incompatible NixGL package layout";
|
||||
|
||||
(lib.mkIf (wantsWrapper "mesa") (pkgs.writeShellScriptBin "nixGLMesa" ''
|
||||
exec ${getWrapperExe "Intel"} "$@"
|
||||
''))
|
||||
getWrapperExe =
|
||||
vendor:
|
||||
let
|
||||
glPackage = findWrapperPackage "nixGL${vendor}";
|
||||
glExe = lib.getExe glPackage;
|
||||
vulkanPackage = findWrapperPackage "nixVulkan${vendor}";
|
||||
vulkanExe = if cfg.vulkan.enable then lib.getExe vulkanPackage else "";
|
||||
in
|
||||
"${glExe} ${vulkanExe}";
|
||||
|
||||
(lib.mkIf (wantsWrapper "mesaPrime")
|
||||
(pkgs.writeShellScriptBin "nixGLMesaPrime" ''
|
||||
${envVarsAsScript mesaOffloadEnv}
|
||||
exec ${getWrapperExe "Intel"} "$@"
|
||||
''))
|
||||
mesaOffloadEnv = {
|
||||
"DRI_PRIME" = "${cfg.prime.card}";
|
||||
};
|
||||
|
||||
(lib.mkIf (wantsWrapper "nvidia")
|
||||
(pkgs.writeShellScriptBin "nixGLNvidia" ''
|
||||
exec ${getWrapperExe "Nvidia"} "$@"
|
||||
''))
|
||||
nvOffloadEnv =
|
||||
{
|
||||
"DRI_PRIME" = "${cfg.prime.card}";
|
||||
"__NV_PRIME_RENDER_OFFLOAD" = "1";
|
||||
"__GLX_VENDOR_LIBRARY_NAME" = "nvidia";
|
||||
"__VK_LAYER_NV_optimus" = "NVIDIA_only";
|
||||
}
|
||||
// (
|
||||
let
|
||||
provider = cfg.prime.nvidiaProvider;
|
||||
in
|
||||
if !isNull provider then
|
||||
{
|
||||
"__NV_PRIME_RENDER_OFFLOAD_PROVIDER" = "${provider}";
|
||||
}
|
||||
else
|
||||
{ }
|
||||
);
|
||||
|
||||
(lib.mkIf (wantsWrapper "nvidia")
|
||||
(pkgs.writeShellScriptBin "nixGLNvidiaPrime" ''
|
||||
${envVarsAsScript nvOffloadEnv}
|
||||
exec ${getWrapperExe "Nvidia"} "$@"
|
||||
''))
|
||||
];
|
||||
};
|
||||
makePackageWrapper =
|
||||
vendor: environment: pkg:
|
||||
if builtins.isNull cfg.packages then
|
||||
pkg
|
||||
else
|
||||
# Wrap the package's binaries with nixGL, while preserving the rest of
|
||||
# the outputs and derivation attributes.
|
||||
(pkg.overrideAttrs (old: {
|
||||
name = "nixGL-${pkg.name}";
|
||||
|
||||
# Make sure this is false for the wrapper derivation, so nix doesn't expect
|
||||
# a new debug output to be produced. We won't be producing any debug info
|
||||
# for the original package.
|
||||
separateDebugInfo = false;
|
||||
nativeBuildInputs = old.nativeBuildInputs or [ ] ++ [ pkgs.makeWrapper ];
|
||||
buildCommand =
|
||||
let
|
||||
# We need an intermediate wrapper package because makeWrapper
|
||||
# requires a single executable as the wrapper.
|
||||
combinedWrapperPkg = pkgs.writeShellScriptBin "nixGLCombinedWrapper-${vendor}" ''
|
||||
exec ${getWrapperExe vendor} "$@"
|
||||
'';
|
||||
in
|
||||
''
|
||||
set -eo pipefail
|
||||
|
||||
${
|
||||
# Heavily inspired by https://stackoverflow.com/a/68523368/6259505
|
||||
lib.concatStringsSep "\n" (
|
||||
map (outputName: ''
|
||||
echo "Copying output ${outputName}"
|
||||
set -x
|
||||
cp -rs --no-preserve=mode "${pkg.${outputName}}" "''$${outputName}"
|
||||
set +x
|
||||
'') (old.outputs or [ "out" ])
|
||||
)
|
||||
}
|
||||
|
||||
rm -rf $out/bin/*
|
||||
shopt -s nullglob # Prevent loop from running if no files
|
||||
for file in ${pkg.out}/bin/*; do
|
||||
local prog="$(basename "$file")"
|
||||
makeWrapper \
|
||||
"${lib.getExe combinedWrapperPkg}" \
|
||||
"$out/bin/$prog" \
|
||||
--argv0 "$prog" \
|
||||
--add-flags "$file" \
|
||||
${lib.concatStringsSep " " (
|
||||
lib.attrsets.mapAttrsToList (var: val: "--set '${var}' '${val}'") environment
|
||||
)}
|
||||
done
|
||||
|
||||
# If .desktop files refer to the old package, replace the references
|
||||
for dsk in "$out/share/applications"/*.desktop ; do
|
||||
if ! grep -q "${pkg.out}" "$dsk"; then
|
||||
continue
|
||||
fi
|
||||
src="$(readlink "$dsk")"
|
||||
rm "$dsk"
|
||||
sed "s|${pkg.out}|$out|g" "$src" > "$dsk"
|
||||
done
|
||||
|
||||
shopt -u nullglob # Revert nullglob back to its normal default state
|
||||
'';
|
||||
}))
|
||||
// {
|
||||
# When the nixGL-wrapped package is given to a HM module, the module
|
||||
# might want to override the package arguments, but our wrapper
|
||||
# wouldn't know what to do with them. So, we rewrite the override
|
||||
# function to instead forward the arguments to the package's own
|
||||
# override function.
|
||||
override = args: makePackageWrapper vendor environment (pkg.override args);
|
||||
};
|
||||
|
||||
wrappers = {
|
||||
mesa = makePackageWrapper "Intel" { };
|
||||
mesaPrime = makePackageWrapper "Intel" mesaOffloadEnv;
|
||||
nvidia = makePackageWrapper "Nvidia" { };
|
||||
nvidiaPrime = makePackageWrapper "Nvidia" nvOffloadEnv;
|
||||
};
|
||||
in
|
||||
{
|
||||
lib.nixGL.wrap = wrappers.${cfg.defaultWrapper};
|
||||
lib.nixGL.wrapOffload = wrappers.${cfg.offloadWrapper};
|
||||
lib.nixGL.wrappers = wrappers;
|
||||
|
||||
home.packages =
|
||||
let
|
||||
wantsPrimeWrapper = (!isNull cfg.prime.installScript);
|
||||
wantsWrapper =
|
||||
wrapper:
|
||||
(!isNull cfg.packages)
|
||||
&& (!isNull cfg.installScripts)
|
||||
&& (builtins.elem wrapper cfg.installScripts);
|
||||
envVarsAsScript =
|
||||
environment:
|
||||
lib.concatStringsSep "\n" (
|
||||
lib.attrsets.mapAttrsToList (var: val: "export ${var}=${val}") environment
|
||||
);
|
||||
in
|
||||
[
|
||||
(lib.mkIf wantsPrimeWrapper (
|
||||
pkgs.writeShellScriptBin "prime-offload" ''
|
||||
${
|
||||
if cfg.prime.installScript == "mesa" then
|
||||
(envVarsAsScript mesaOffloadEnv)
|
||||
else
|
||||
(envVarsAsScript nvOffloadEnv)
|
||||
}
|
||||
exec "$@"
|
||||
''
|
||||
))
|
||||
|
||||
(lib.mkIf (wantsWrapper "mesa") (
|
||||
pkgs.writeShellScriptBin "nixGLMesa" ''
|
||||
exec ${getWrapperExe "Intel"} "$@"
|
||||
''
|
||||
))
|
||||
|
||||
(lib.mkIf (wantsWrapper "mesaPrime") (
|
||||
pkgs.writeShellScriptBin "nixGLMesaPrime" ''
|
||||
${envVarsAsScript mesaOffloadEnv}
|
||||
exec ${getWrapperExe "Intel"} "$@"
|
||||
''
|
||||
))
|
||||
|
||||
(lib.mkIf (wantsWrapper "nvidia") (
|
||||
pkgs.writeShellScriptBin "nixGLNvidia" ''
|
||||
exec ${getWrapperExe "Nvidia"} "$@"
|
||||
''
|
||||
))
|
||||
|
||||
(lib.mkIf (wantsWrapper "nvidia") (
|
||||
pkgs.writeShellScriptBin "nixGLNvidiaPrime" ''
|
||||
${envVarsAsScript nvOffloadEnv}
|
||||
exec ${getWrapperExe "Nvidia"} "$@"
|
||||
''
|
||||
))
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
|
|
@ -11,16 +16,22 @@ let
|
|||
optCall = f: x: if builtins.isFunction f then f x else f;
|
||||
|
||||
# Copied from nixpkgs.nix.
|
||||
mergeConfig = lhs_: rhs_:
|
||||
mergeConfig =
|
||||
lhs_: rhs_:
|
||||
let
|
||||
lhs = optCall lhs_ { inherit pkgs; };
|
||||
rhs = optCall rhs_ { inherit pkgs; };
|
||||
in lhs // rhs // lib.optionalAttrs (lhs ? packageOverrides) {
|
||||
packageOverrides = pkgs:
|
||||
optCall lhs.packageOverrides pkgs
|
||||
// optCall (lib.attrByPath [ "packageOverrides" ] { } rhs) pkgs;
|
||||
} // lib.optionalAttrs (lhs ? perlPackageOverrides) {
|
||||
perlPackageOverrides = pkgs:
|
||||
in
|
||||
lhs
|
||||
// rhs
|
||||
// lib.optionalAttrs (lhs ? packageOverrides) {
|
||||
packageOverrides =
|
||||
pkgs:
|
||||
optCall lhs.packageOverrides pkgs // optCall (lib.attrByPath [ "packageOverrides" ] { } rhs) pkgs;
|
||||
}
|
||||
// lib.optionalAttrs (lhs ? perlPackageOverrides) {
|
||||
perlPackageOverrides =
|
||||
pkgs:
|
||||
optCall lhs.perlPackageOverrides pkgs
|
||||
// optCall (lib.attrByPath [ "perlPackageOverrides" ] { } rhs) pkgs;
|
||||
};
|
||||
|
|
@ -29,9 +40,12 @@ let
|
|||
configType = lib.mkOptionType {
|
||||
name = "nixpkgs-config";
|
||||
description = "nixpkgs config";
|
||||
check = x:
|
||||
let traceXIfNot = c: if c x then true else lib.traceSeqN 1 x false;
|
||||
in traceXIfNot isConfig;
|
||||
check =
|
||||
x:
|
||||
let
|
||||
traceXIfNot = c: if c x then true else lib.traceSeqN 1 x false;
|
||||
in
|
||||
traceXIfNot isConfig;
|
||||
merge = args: lib.fold (def: mergeConfig def.value) { };
|
||||
};
|
||||
|
||||
|
|
@ -43,7 +57,8 @@ let
|
|||
merge = lib.mergeOneOption;
|
||||
};
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ thiagokokada ];
|
||||
|
||||
options.nixpkgs = {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
# Adapted from Nixpkgs.
|
||||
|
||||
{ config, lib, pkgs, pkgsPath, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
pkgsPath,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
|
|
@ -8,16 +14,22 @@ let
|
|||
|
||||
optCall = f: x: if builtins.isFunction f then f x else f;
|
||||
|
||||
mergeConfig = lhs_: rhs_:
|
||||
mergeConfig =
|
||||
lhs_: rhs_:
|
||||
let
|
||||
lhs = optCall lhs_ { inherit pkgs; };
|
||||
rhs = optCall rhs_ { inherit pkgs; };
|
||||
in lhs // rhs // lib.optionalAttrs (lhs ? packageOverrides) {
|
||||
packageOverrides = pkgs:
|
||||
optCall lhs.packageOverrides pkgs
|
||||
// optCall (lib.attrByPath [ "packageOverrides" ] { } rhs) pkgs;
|
||||
} // lib.optionalAttrs (lhs ? perlPackageOverrides) {
|
||||
perlPackageOverrides = pkgs:
|
||||
in
|
||||
lhs
|
||||
// rhs
|
||||
// lib.optionalAttrs (lhs ? packageOverrides) {
|
||||
packageOverrides =
|
||||
pkgs:
|
||||
optCall lhs.packageOverrides pkgs // optCall (lib.attrByPath [ "packageOverrides" ] { } rhs) pkgs;
|
||||
}
|
||||
// lib.optionalAttrs (lhs ? perlPackageOverrides) {
|
||||
perlPackageOverrides =
|
||||
pkgs:
|
||||
optCall lhs.perlPackageOverrides pkgs
|
||||
// optCall (lib.attrByPath [ "perlPackageOverrides" ] { } rhs) pkgs;
|
||||
};
|
||||
|
|
@ -25,9 +37,12 @@ let
|
|||
configType = lib.mkOptionType {
|
||||
name = "nixpkgs-config";
|
||||
description = "nixpkgs config";
|
||||
check = x:
|
||||
let traceXIfNot = c: if c x then true else lib.traceSeqN 1 x false;
|
||||
in traceXIfNot isConfig;
|
||||
check =
|
||||
x:
|
||||
let
|
||||
traceXIfNot = c: if c x then true else lib.traceSeqN 1 x false;
|
||||
in
|
||||
traceXIfNot isConfig;
|
||||
merge = args: lib.fold (def: mergeConfig def.value) { };
|
||||
};
|
||||
|
||||
|
|
@ -40,11 +55,14 @@ let
|
|||
|
||||
_pkgs = import pkgsPath (lib.filterAttrs (n: v: v != null) config.nixpkgs);
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.nixpkgs = {
|
||||
config = lib.mkOption {
|
||||
default = null;
|
||||
example = { allowBroken = true; };
|
||||
example = {
|
||||
allowBroken = true;
|
||||
};
|
||||
type = lib.types.nullOr configType;
|
||||
description = ''
|
||||
The configuration of the Nix Packages collection. (For
|
||||
|
|
@ -123,10 +141,7 @@ in {
|
|||
# `_pkgs`, see https://github.com/nix-community/home-manager/pull/993
|
||||
pkgs = lib.mkOverride lib.modules.defaultOverridePriority _pkgs;
|
||||
pkgs_i686 =
|
||||
if _pkgs.stdenv.isLinux && _pkgs.stdenv.hostPlatform.isx86 then
|
||||
_pkgs.pkgsi686Linux
|
||||
else
|
||||
{ };
|
||||
if _pkgs.stdenv.isLinux && _pkgs.stdenv.hostPlatform.isx86 then _pkgs.pkgsi686Linux else { };
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,25 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
cfg = config.xsession.numlock;
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.evanjs ];
|
||||
|
||||
options = { xsession.numlock.enable = lib.mkEnableOption "Num Lock"; };
|
||||
options = {
|
||||
xsession.numlock.enable = lib.mkEnableOption "Num Lock";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "xsession.numlock" pkgs
|
||||
lib.platforms.linux)
|
||||
(lib.hm.assertions.assertPlatform "xsession.numlock" pkgs lib.platforms.linux)
|
||||
];
|
||||
|
||||
systemd.user.services.numlockx = {
|
||||
|
|
@ -28,7 +35,9 @@ in {
|
|||
ExecStart = "${pkgs.numlockx}/bin/numlockx";
|
||||
};
|
||||
|
||||
Install = { WantedBy = [ "graphical-session.target" ]; };
|
||||
Install = {
|
||||
WantedBy = [ "graphical-session.target" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,14 +4,20 @@ let
|
|||
|
||||
cfg = config.pam;
|
||||
|
||||
in {
|
||||
meta.maintainers = with lib.maintainers; [ rycee veehaitch ];
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
rycee
|
||||
veehaitch
|
||||
];
|
||||
|
||||
options = {
|
||||
pam.sessionVariables = lib.mkOption {
|
||||
default = { };
|
||||
type = lib.types.attrs;
|
||||
example = { EDITOR = "vim"; };
|
||||
example = {
|
||||
EDITOR = "vim";
|
||||
};
|
||||
description = ''
|
||||
Environment variables that will be set for the PAM session.
|
||||
The variable values must be as described in
|
||||
|
|
@ -24,13 +30,15 @@ in {
|
|||
|
||||
pam.yubico.authorizedYubiKeys = {
|
||||
ids = lib.mkOption {
|
||||
type = with lib.types;
|
||||
type =
|
||||
with lib.types;
|
||||
let
|
||||
yubiKeyId = addCheck str (s: lib.stringLength s == 12) // {
|
||||
name = "yubiKeyId";
|
||||
description = "string of length 12";
|
||||
};
|
||||
in listOf yubiKeyId;
|
||||
in
|
||||
listOf yubiKeyId;
|
||||
default = [ ];
|
||||
description = ''
|
||||
List of authorized YubiKey token IDs. Refer to
|
||||
|
|
@ -52,15 +60,17 @@ in {
|
|||
|
||||
config = lib.mkMerge [
|
||||
(lib.mkIf (cfg.sessionVariables != { }) {
|
||||
home.file.".pam_environment".text = lib.concatStringsSep "\n"
|
||||
(lib.mapAttrsToList (n: v: ''${n} OVERRIDE="${toString v}"'')
|
||||
cfg.sessionVariables) + "\n";
|
||||
home.file.".pam_environment".text =
|
||||
lib.concatStringsSep "\n" (
|
||||
lib.mapAttrsToList (n: v: ''${n} OVERRIDE="${toString v}"'') cfg.sessionVariables
|
||||
)
|
||||
+ "\n";
|
||||
})
|
||||
|
||||
(lib.mkIf (cfg.yubico.authorizedYubiKeys.ids != [ ]) {
|
||||
home.file.${cfg.yubico.authorizedYubiKeys.path}.text =
|
||||
lib.concatStringsSep ":"
|
||||
([ config.home.username ] ++ cfg.yubico.authorizedYubiKeys.ids);
|
||||
home.file.${cfg.yubico.authorizedYubiKeys.path}.text = lib.concatStringsSep ":" (
|
||||
[ config.home.username ] ++ cfg.yubico.authorizedYubiKeys.ids
|
||||
);
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,27 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.qt;
|
||||
|
||||
# Map platform names to their packages.
|
||||
platformPackages = with pkgs; {
|
||||
gnome = [ qgnomeplatform qgnomeplatform-qt6 ];
|
||||
adwaita = [ qadwaitadecorations qadwaitadecorations-qt6 ];
|
||||
gtk = [ libsForQt5.qtstyleplugins qt6Packages.qt6gtk2 ];
|
||||
gnome = [
|
||||
qgnomeplatform
|
||||
qgnomeplatform-qt6
|
||||
];
|
||||
adwaita = [
|
||||
qadwaitadecorations
|
||||
qadwaitadecorations-qt6
|
||||
];
|
||||
gtk = [
|
||||
libsForQt5.qtstyleplugins
|
||||
qt6Packages.qt6gtk2
|
||||
];
|
||||
kde = [
|
||||
libsForQt5.kio
|
||||
libsForQt5.plasma-integration
|
||||
|
|
@ -18,8 +32,14 @@ let
|
|||
kdePackages.plasma-integration
|
||||
kdePackages.systemsettings
|
||||
];
|
||||
lxqt = [ lxqt.lxqt-qtplugin lxqt.lxqt-config ];
|
||||
qtct = [ libsForQt5.qt5ct qt6Packages.qt6ct ];
|
||||
lxqt = [
|
||||
lxqt.lxqt-qtplugin
|
||||
lxqt.lxqt-config
|
||||
];
|
||||
qtct = [
|
||||
libsForQt5.qt5ct
|
||||
qt6Packages.qt6ct
|
||||
];
|
||||
};
|
||||
|
||||
# Maps style names to their QT_QPA_PLATFORMTHEME, if necessary.
|
||||
|
|
@ -34,122 +54,181 @@ let
|
|||
bb10bright = libsForQt5.qtstyleplugins;
|
||||
bb10dark = libsForQt5.qtstyleplugins;
|
||||
cleanlooks = libsForQt5.qtstyleplugins;
|
||||
gtk2 = [ libsForQt5.qtstyleplugins qt6Packages.qt6gtk2 ];
|
||||
gtk2 = [
|
||||
libsForQt5.qtstyleplugins
|
||||
qt6Packages.qt6gtk2
|
||||
];
|
||||
motif = libsForQt5.qtstyleplugins;
|
||||
cde = libsForQt5.qtstyleplugins;
|
||||
plastique = libsForQt5.qtstyleplugins;
|
||||
|
||||
adwaita = [ adwaita-qt adwaita-qt6 ];
|
||||
adwaita-dark = [ adwaita-qt adwaita-qt6 ];
|
||||
adwaita-highcontrast = [ adwaita-qt adwaita-qt6 ];
|
||||
adwaita-highcontrastinverse = [ adwaita-qt adwaita-qt6 ];
|
||||
adwaita = [
|
||||
adwaita-qt
|
||||
adwaita-qt6
|
||||
];
|
||||
adwaita-dark = [
|
||||
adwaita-qt
|
||||
adwaita-qt6
|
||||
];
|
||||
adwaita-highcontrast = [
|
||||
adwaita-qt
|
||||
adwaita-qt6
|
||||
];
|
||||
adwaita-highcontrastinverse = [
|
||||
adwaita-qt
|
||||
adwaita-qt6
|
||||
];
|
||||
|
||||
breeze = libsForQt5.breeze-qt5;
|
||||
|
||||
kvantum =
|
||||
[ libsForQt5.qtstyleplugin-kvantum qt6Packages.qtstyleplugin-kvantum ];
|
||||
kvantum = [
|
||||
libsForQt5.qtstyleplugin-kvantum
|
||||
qt6Packages.qtstyleplugin-kvantum
|
||||
];
|
||||
};
|
||||
|
||||
in {
|
||||
meta.maintainers = with lib.maintainers; [ rycee thiagokokada ];
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
rycee
|
||||
thiagokokada
|
||||
];
|
||||
|
||||
imports = [
|
||||
(lib.mkChangedOptionModule [ "qt" "useGtkTheme" ] [ "qt" "platformTheme" ]
|
||||
(config:
|
||||
if lib.getAttrFromPath [ "qt" "useGtkTheme" ] config then
|
||||
"gtk"
|
||||
else
|
||||
null))
|
||||
(lib.mkChangedOptionModule [ "qt" "useGtkTheme" ] [ "qt" "platformTheme" ] (
|
||||
config: if lib.getAttrFromPath [ "qt" "useGtkTheme" ] config then "gtk" else null
|
||||
))
|
||||
];
|
||||
|
||||
options = {
|
||||
qt = {
|
||||
enable = lib.mkEnableOption "Qt 5 and 6 configuration";
|
||||
|
||||
platformTheme = let
|
||||
newOption = {
|
||||
name = lib.mkOption {
|
||||
type = with lib.types; nullOr str;
|
||||
default = null;
|
||||
example = "adwaita";
|
||||
relatedPackages = [
|
||||
"qgnomeplatform"
|
||||
"qgnomeplatform-qt6"
|
||||
"qadwaitadecorations"
|
||||
"qadwaitadecorations-qt6"
|
||||
[ "libsForQt5" "plasma-integration" ]
|
||||
[ "libsForQt5" "qt5ct" ]
|
||||
[ "libsForQt5" "qtstyleplugins" ]
|
||||
[ "libsForQt5" "systemsettings" ]
|
||||
[ "kdePackages" "plasma-integration" ]
|
||||
[ "kdePackages" "systemsettings" ]
|
||||
[ "lxqt" "lxqt-config" ]
|
||||
[ "lxqt" "lxqt-qtplugin" ]
|
||||
[ "qt6Packages" "qt6ct" ]
|
||||
[ "qt6Packages" "qt6gtk2" ]
|
||||
];
|
||||
description = ''
|
||||
Platform theme to use for Qt applications.
|
||||
platformTheme =
|
||||
let
|
||||
newOption = {
|
||||
name = lib.mkOption {
|
||||
type = with lib.types; nullOr str;
|
||||
default = null;
|
||||
example = "adwaita";
|
||||
relatedPackages = [
|
||||
"qgnomeplatform"
|
||||
"qgnomeplatform-qt6"
|
||||
"qadwaitadecorations"
|
||||
"qadwaitadecorations-qt6"
|
||||
[
|
||||
"libsForQt5"
|
||||
"plasma-integration"
|
||||
]
|
||||
[
|
||||
"libsForQt5"
|
||||
"qt5ct"
|
||||
]
|
||||
[
|
||||
"libsForQt5"
|
||||
"qtstyleplugins"
|
||||
]
|
||||
[
|
||||
"libsForQt5"
|
||||
"systemsettings"
|
||||
]
|
||||
[
|
||||
"kdePackages"
|
||||
"plasma-integration"
|
||||
]
|
||||
[
|
||||
"kdePackages"
|
||||
"systemsettings"
|
||||
]
|
||||
[
|
||||
"lxqt"
|
||||
"lxqt-config"
|
||||
]
|
||||
[
|
||||
"lxqt"
|
||||
"lxqt-qtplugin"
|
||||
]
|
||||
[
|
||||
"qt6Packages"
|
||||
"qt6ct"
|
||||
]
|
||||
[
|
||||
"qt6Packages"
|
||||
"qt6gtk2"
|
||||
]
|
||||
];
|
||||
description = ''
|
||||
Platform theme to use for Qt applications.
|
||||
|
||||
Some examples are
|
||||
Some examples are
|
||||
|
||||
`gtk`
|
||||
: Use GTK theme with
|
||||
[`qtstyleplugins`](https://github.com/qt/qtstyleplugins)
|
||||
`gtk`
|
||||
: Use GTK theme with
|
||||
[`qtstyleplugins`](https://github.com/qt/qtstyleplugins)
|
||||
|
||||
`gtk3`
|
||||
: Use [GTK3 integration](https://github.com/qt/qtbase/tree/dev/src/plugins/platformthemes/gtk3)
|
||||
for file picker dialogs, font and theme configuration
|
||||
`gtk3`
|
||||
: Use [GTK3 integration](https://github.com/qt/qtbase/tree/dev/src/plugins/platformthemes/gtk3)
|
||||
for file picker dialogs, font and theme configuration
|
||||
|
||||
`adwaita`
|
||||
: Use Adwaita theme with
|
||||
[`qadwaitadecorations`](https://github.com/FedoraQt/QAdwaitaDecorations)
|
||||
`adwaita`
|
||||
: Use Adwaita theme with
|
||||
[`qadwaitadecorations`](https://github.com/FedoraQt/QAdwaitaDecorations)
|
||||
|
||||
`gnome` (deprecated)
|
||||
: Use GNOME theme with
|
||||
[`qgnomeplatform`](https://github.com/FedoraQt/QGnomePlatform).
|
||||
Is no longer maintained so prefer `adwaita`.
|
||||
`gnome` (deprecated)
|
||||
: Use GNOME theme with
|
||||
[`qgnomeplatform`](https://github.com/FedoraQt/QGnomePlatform).
|
||||
Is no longer maintained so prefer `adwaita`.
|
||||
|
||||
`lxqt`
|
||||
: Use LXQt theme style set using the
|
||||
[`lxqt-config-appearance`](https://github.com/lxqt/lxqt-config)
|
||||
application
|
||||
`lxqt`
|
||||
: Use LXQt theme style set using the
|
||||
[`lxqt-config-appearance`](https://github.com/lxqt/lxqt-config)
|
||||
application
|
||||
|
||||
`qtct`
|
||||
: Use Qt style set using
|
||||
[`qt5ct`](https://github.com/desktop-app/qt5ct)
|
||||
and [`qt6ct`](https://github.com/trialuser02/qt6ct)
|
||||
applications
|
||||
`qtct`
|
||||
: Use Qt style set using
|
||||
[`qt5ct`](https://github.com/desktop-app/qt5ct)
|
||||
and [`qt6ct`](https://github.com/trialuser02/qt6ct)
|
||||
applications
|
||||
|
||||
`kde`
|
||||
: Use Qt settings from Plasma 5
|
||||
`kde`
|
||||
: Use Qt settings from Plasma 5
|
||||
|
||||
`kde6`
|
||||
: Use Qt settings from Plasma 6
|
||||
'';
|
||||
};
|
||||
package = lib.mkOption {
|
||||
type = with lib.types; nullOr (either package (listOf package));
|
||||
default = null;
|
||||
example =
|
||||
lib.literalExpression "[pkgs.adwaita-qt pkgs.adwaita-qt6]";
|
||||
description = ''
|
||||
Theme package to be used in Qt5/Qt6 applications.
|
||||
Auto-detected from {option}`qt.platformTheme.name` if possible.
|
||||
See its documentation for available options.
|
||||
'';
|
||||
`kde6`
|
||||
: Use Qt settings from Plasma 6
|
||||
'';
|
||||
};
|
||||
package = lib.mkOption {
|
||||
type = with lib.types; nullOr (either package (listOf package));
|
||||
default = null;
|
||||
example = lib.literalExpression "[pkgs.adwaita-qt pkgs.adwaita-qt6]";
|
||||
description = ''
|
||||
Theme package to be used in Qt5/Qt6 applications.
|
||||
Auto-detected from {option}`qt.platformTheme.name` if possible.
|
||||
See its documentation for available options.
|
||||
'';
|
||||
};
|
||||
};
|
||||
in
|
||||
lib.mkOption {
|
||||
type =
|
||||
with lib.types;
|
||||
nullOr (
|
||||
either (enum [
|
||||
"gtk"
|
||||
"gtk3"
|
||||
"gnome"
|
||||
"adwaita"
|
||||
"lxqt"
|
||||
"qtct"
|
||||
"kde"
|
||||
"kde6"
|
||||
]) (lib.types.submodule { options = newOption; })
|
||||
);
|
||||
default = null;
|
||||
description = ''
|
||||
Deprecated. Use {option}`qt.platformTheme.name` instead.
|
||||
'';
|
||||
};
|
||||
in lib.mkOption {
|
||||
type = with lib.types;
|
||||
nullOr (either
|
||||
(enum [ "gtk" "gtk3" "gnome" "adwaita" "lxqt" "qtct" "kde" "kde6" ])
|
||||
(lib.types.submodule { options = newOption; }));
|
||||
default = null;
|
||||
description = ''
|
||||
Deprecated. Use {option}`qt.platformTheme.name` instead.
|
||||
'';
|
||||
};
|
||||
style = {
|
||||
name = lib.mkOption {
|
||||
type = with lib.types; nullOr str;
|
||||
|
|
@ -158,11 +237,26 @@ in {
|
|||
relatedPackages = [
|
||||
"adwaita-qt"
|
||||
"adwaita-qt6"
|
||||
[ "libsForQt5" "breeze-qt5" ]
|
||||
[ "libsForQt5" "qtstyleplugin-kvantum" ]
|
||||
[ "libsForQt5" "qtstyleplugins" ]
|
||||
[ "qt6Packages" "qt6gtk2" ]
|
||||
[ "qt6Packages" "qtstyleplugin-kvantum" ]
|
||||
[
|
||||
"libsForQt5"
|
||||
"breeze-qt5"
|
||||
]
|
||||
[
|
||||
"libsForQt5"
|
||||
"qtstyleplugin-kvantum"
|
||||
]
|
||||
[
|
||||
"libsForQt5"
|
||||
"qtstyleplugins"
|
||||
]
|
||||
[
|
||||
"qt6Packages"
|
||||
"qt6gtk2"
|
||||
]
|
||||
[
|
||||
"qt6Packages"
|
||||
"qtstyleplugin-kvantum"
|
||||
]
|
||||
];
|
||||
description = ''
|
||||
Style to use for Qt5/Qt6 applications. Case-insensitive.
|
||||
|
|
@ -201,80 +295,103 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
platformTheme = if (builtins.isString cfg.platformTheme) then {
|
||||
option = "qt.platformTheme";
|
||||
name = cfg.platformTheme;
|
||||
package = null;
|
||||
} else if cfg.platformTheme == null then {
|
||||
option = null;
|
||||
name = null;
|
||||
package = null;
|
||||
} else {
|
||||
option = "qt.platformTheme.name";
|
||||
name = cfg.platformTheme.name;
|
||||
package = cfg.platformTheme.package;
|
||||
config =
|
||||
let
|
||||
platformTheme =
|
||||
if (builtins.isString cfg.platformTheme) then
|
||||
{
|
||||
option = "qt.platformTheme";
|
||||
name = cfg.platformTheme;
|
||||
package = null;
|
||||
}
|
||||
else if cfg.platformTheme == null then
|
||||
{
|
||||
option = null;
|
||||
name = null;
|
||||
package = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
option = "qt.platformTheme.name";
|
||||
name = cfg.platformTheme.name;
|
||||
package = cfg.platformTheme.package;
|
||||
};
|
||||
|
||||
# Necessary because home.sessionVariables doesn't support mkIf
|
||||
envVars = lib.filterAttrs (n: v: v != null) {
|
||||
QT_QPA_PLATFORMTHEME =
|
||||
if (platformTheme.name != null) then
|
||||
styleNames.${platformTheme.name} or platformTheme.name
|
||||
else
|
||||
null;
|
||||
QT_STYLE_OVERRIDE = cfg.style.name;
|
||||
};
|
||||
|
||||
envVarsExtra =
|
||||
let
|
||||
inherit (config.home) profileDirectory;
|
||||
qtVersions = with pkgs; [
|
||||
qt5
|
||||
qt6
|
||||
];
|
||||
makeQtPath = prefix: (map (qt: "${profileDirectory}/${qt.qtbase.${prefix}}") qtVersions);
|
||||
in
|
||||
{
|
||||
QT_PLUGIN_PATH = makeQtPath "qtPluginPrefix";
|
||||
QML2_IMPORT_PATH = makeQtPath "qtQmlPrefix";
|
||||
};
|
||||
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = platformTheme.name == "gnome" -> cfg.style.name != null && cfg.style.package != null;
|
||||
message = ''
|
||||
`qt.platformTheme.name` "gnome" must have `qt.style` set to a theme that
|
||||
supports both Qt and Gtk, for example "adwaita", "adwaita-dark", or "breeze".
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
warnings =
|
||||
(lib.lists.optional (
|
||||
platformTheme.option == "qt.platformTheme"
|
||||
) "The option `qt.platformTheme` has been renamed to `qt.platformTheme.name`.")
|
||||
++ (lib.lists.optional (
|
||||
platformTheme.name == "gnome" && platformTheme.package == null
|
||||
) "The value `gnome` for option `${platformTheme.option}` is deprecated. Use `adwaita` instead.");
|
||||
|
||||
qt.style.package = lib.mkIf (cfg.style.name != null) (
|
||||
lib.mkDefault (stylePackages.${lib.toLower cfg.style.name} or null)
|
||||
);
|
||||
|
||||
home = {
|
||||
sessionVariables = envVars;
|
||||
sessionSearchVariables = envVarsExtra;
|
||||
};
|
||||
|
||||
# Apply theming also to apps started by systemd.
|
||||
systemd.user.sessionVariables = envVars // {
|
||||
QT_PLUGIN_PATH = lib.concatStringsSep ":" envVarsExtra.QT_PLUGIN_PATH;
|
||||
QML2_IMPORT_PATH = lib.concatStringsSep ":" envVarsExtra.QML2_IMPORT_PATH;
|
||||
};
|
||||
|
||||
home.packages =
|
||||
(lib.findFirst (x: x != [ ])
|
||||
[ ]
|
||||
[
|
||||
(lib.optionals (platformTheme.package != null) (lib.toList platformTheme.package))
|
||||
(lib.optionals (platformTheme.name != null) platformPackages.${platformTheme.name} or [ ])
|
||||
]
|
||||
)
|
||||
++ (lib.optionals (cfg.style.package != null) (lib.toList cfg.style.package));
|
||||
|
||||
xsession.importedVariables =
|
||||
[
|
||||
"QT_PLUGIN_PATH"
|
||||
"QML2_IMPORT_PATH"
|
||||
]
|
||||
++ lib.optionals (platformTheme.name != null) [ "QT_QPA_PLATFORMTHEME" ]
|
||||
++ lib.optionals (cfg.style.name != null) [ "QT_STYLE_OVERRIDE" ];
|
||||
};
|
||||
|
||||
# Necessary because home.sessionVariables doesn't support mkIf
|
||||
envVars = lib.filterAttrs (n: v: v != null) {
|
||||
QT_QPA_PLATFORMTHEME = if (platformTheme.name != null) then
|
||||
styleNames.${platformTheme.name} or platformTheme.name
|
||||
else
|
||||
null;
|
||||
QT_STYLE_OVERRIDE = cfg.style.name;
|
||||
};
|
||||
|
||||
envVarsExtra = let
|
||||
inherit (config.home) profileDirectory;
|
||||
qtVersions = with pkgs; [ qt5 qt6 ];
|
||||
makeQtPath = prefix:
|
||||
(map (qt: "${profileDirectory}/${qt.qtbase.${prefix}}") qtVersions);
|
||||
in {
|
||||
QT_PLUGIN_PATH = makeQtPath "qtPluginPrefix";
|
||||
QML2_IMPORT_PATH = makeQtPath "qtQmlPrefix";
|
||||
};
|
||||
|
||||
in lib.mkIf cfg.enable {
|
||||
assertions = [{
|
||||
assertion = platformTheme.name == "gnome" -> cfg.style.name != null
|
||||
&& cfg.style.package != null;
|
||||
message = ''
|
||||
`qt.platformTheme.name` "gnome" must have `qt.style` set to a theme that
|
||||
supports both Qt and Gtk, for example "adwaita", "adwaita-dark", or "breeze".
|
||||
'';
|
||||
}];
|
||||
|
||||
warnings = (lib.lists.optional (platformTheme.option == "qt.platformTheme")
|
||||
"The option `qt.platformTheme` has been renamed to `qt.platformTheme.name`.")
|
||||
++ (lib.lists.optional
|
||||
(platformTheme.name == "gnome" && platformTheme.package == null)
|
||||
"The value `gnome` for option `${platformTheme.option}` is deprecated. Use `adwaita` instead.");
|
||||
|
||||
qt.style.package = lib.mkIf (cfg.style.name != null)
|
||||
(lib.mkDefault (stylePackages.${lib.toLower cfg.style.name} or null));
|
||||
|
||||
home = {
|
||||
sessionVariables = envVars;
|
||||
sessionSearchVariables = envVarsExtra;
|
||||
};
|
||||
|
||||
# Apply theming also to apps started by systemd.
|
||||
systemd.user.sessionVariables = envVars // {
|
||||
QT_PLUGIN_PATH = lib.concatStringsSep ":" envVarsExtra.QT_PLUGIN_PATH;
|
||||
QML2_IMPORT_PATH = lib.concatStringsSep ":" envVarsExtra.QML2_IMPORT_PATH;
|
||||
};
|
||||
|
||||
home.packages = (lib.findFirst (x: x != [ ]) [ ] [
|
||||
(lib.optionals (platformTheme.package != null)
|
||||
(lib.toList platformTheme.package))
|
||||
(lib.optionals (platformTheme.name != null)
|
||||
platformPackages.${platformTheme.name} or [ ])
|
||||
]) ++ (lib.optionals (cfg.style.package != null)
|
||||
(lib.toList cfg.style.package));
|
||||
|
||||
xsession.importedVariables = [ "QT_PLUGIN_PATH" "QML2_IMPORT_PATH" ]
|
||||
++ lib.optionals (platformTheme.name != null) [ "QT_QPA_PLATFORMTHEME" ]
|
||||
++ lib.optionals (cfg.style.name != null) [ "QT_STYLE_OVERRIDE" ];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,33 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
cfg = config.qt.kde.settings;
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.qt.kde.settings = lib.mkOption {
|
||||
type = with lib.types;
|
||||
type =
|
||||
with lib.types;
|
||||
let
|
||||
valueType =
|
||||
nullOr (oneOf [ bool int float str path (attrsOf valueType) ]) // {
|
||||
nullOr (oneOf [
|
||||
bool
|
||||
int
|
||||
float
|
||||
str
|
||||
path
|
||||
(attrsOf valueType)
|
||||
])
|
||||
// {
|
||||
description = "KDE option value";
|
||||
};
|
||||
in attrsOf valueType;
|
||||
in
|
||||
attrsOf valueType;
|
||||
default = { };
|
||||
example = {
|
||||
powermanagementprofilesrc.AC.HandleButtonEvents.lidAction = 32;
|
||||
|
|
@ -38,28 +54,32 @@ in {
|
|||
|
||||
config = lib.mkIf (cfg != { }) {
|
||||
home.activation.kconfig = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||
${let
|
||||
inherit (config.xdg) configHome;
|
||||
toValue = v:
|
||||
let t = builtins.typeOf v;
|
||||
in if v == null then
|
||||
"--delete"
|
||||
else if t == "bool" then
|
||||
"--type bool ${builtins.toJSON v}"
|
||||
else
|
||||
lib.escapeShellArg (toString v);
|
||||
toLine = file: path: value:
|
||||
if builtins.isAttrs value then
|
||||
lib.mapAttrsToList
|
||||
(group: value: toLine file (path ++ [ group ]) value) value
|
||||
else
|
||||
"run ${pkgs.kdePackages.kconfig}/bin/kwriteconfig6 --file '${configHome}/${file}' ${
|
||||
lib.concatMapStringsSep " " (x: "--group ${x}")
|
||||
(lib.lists.init path)
|
||||
} --key '${lib.lists.last path}' ${toValue value}";
|
||||
lines = lib.flatten
|
||||
(lib.mapAttrsToList (file: attrs: toLine file [ ] attrs) cfg);
|
||||
in builtins.concatStringsSep "\n" lines}
|
||||
${
|
||||
let
|
||||
inherit (config.xdg) configHome;
|
||||
toValue =
|
||||
v:
|
||||
let
|
||||
t = builtins.typeOf v;
|
||||
in
|
||||
if v == null then
|
||||
"--delete"
|
||||
else if t == "bool" then
|
||||
"--type bool ${builtins.toJSON v}"
|
||||
else
|
||||
lib.escapeShellArg (toString v);
|
||||
toLine =
|
||||
file: path: value:
|
||||
if builtins.isAttrs value then
|
||||
lib.mapAttrsToList (group: value: toLine file (path ++ [ group ]) value) value
|
||||
else
|
||||
"run ${pkgs.kdePackages.kconfig}/bin/kwriteconfig6 --file '${configHome}/${file}' ${
|
||||
lib.concatMapStringsSep " " (x: "--group ${x}") (lib.lists.init path)
|
||||
} --key '${lib.lists.last path}' ${toValue value}";
|
||||
lines = lib.flatten (lib.mapAttrsToList (file: attrs: toLine file [ ] attrs) cfg);
|
||||
in
|
||||
builtins.concatStringsSep "\n" lines
|
||||
}
|
||||
|
||||
# TODO: some way to only call the dbus calls needed
|
||||
run ${pkgs.kdePackages.qttools}/bin/qdbus org.kde.KWin /KWin reconfigure || echo "KWin reconfigure failed"
|
||||
|
|
|
|||
|
|
@ -1,36 +1,47 @@
|
|||
{ config, name, extendModules, lib, ... }:
|
||||
{
|
||||
config,
|
||||
name,
|
||||
extendModules,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ (lib.mkRenamedOptionModule [ "specialization" ] [ "specialisation" ]) ];
|
||||
imports = [ (lib.mkRenamedOptionModule [ "specialization" ] [ "specialisation" ]) ];
|
||||
|
||||
options.specialisation = lib.mkOption {
|
||||
type = lib.types.attrsOf (lib.types.submodule {
|
||||
options = {
|
||||
configuration = lib.mkOption {
|
||||
type = let
|
||||
extended = extendModules {
|
||||
modules = [{
|
||||
# Prevent infinite recursion
|
||||
specialisation = lib.mkOverride 0 { };
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule {
|
||||
options = {
|
||||
configuration = lib.mkOption {
|
||||
type =
|
||||
let
|
||||
extended = extendModules {
|
||||
modules = [
|
||||
{
|
||||
# Prevent infinite recursion
|
||||
specialisation = lib.mkOverride 0 { };
|
||||
|
||||
# If used inside the NixOS/nix-darwin module, we get conflicting definitions
|
||||
# of `name` inside the specialisation: one is the user name coming from the
|
||||
# NixOS module definition and the other is `configuration`, the name of this
|
||||
# option. Thus we need to explicitly wire the former into the module arguments.
|
||||
# See discussion at https://github.com/nix-community/home-manager/issues/3716
|
||||
_module.args.name = lib.mkForce name;
|
||||
}];
|
||||
};
|
||||
in extended.type;
|
||||
default = { };
|
||||
visible = "shallow";
|
||||
description = ''
|
||||
Arbitrary Home Manager configuration settings.
|
||||
'';
|
||||
# If used inside the NixOS/nix-darwin module, we get conflicting definitions
|
||||
# of `name` inside the specialisation: one is the user name coming from the
|
||||
# NixOS module definition and the other is `configuration`, the name of this
|
||||
# option. Thus we need to explicitly wire the former into the module arguments.
|
||||
# See discussion at https://github.com/nix-community/home-manager/issues/3716
|
||||
_module.args.name = lib.mkForce name;
|
||||
}
|
||||
];
|
||||
};
|
||||
in
|
||||
extended.type;
|
||||
default = { };
|
||||
visible = "shallow";
|
||||
description = ''
|
||||
Arbitrary Home Manager configuration settings.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
default = { };
|
||||
description = ''
|
||||
A set of named specialized configurations. These can be used to extend
|
||||
|
|
@ -71,18 +82,21 @@
|
|||
config = lib.mkIf (config.specialisation != { }) {
|
||||
assertions = map (n: {
|
||||
assertion = !lib.hasInfix "/" n;
|
||||
message =
|
||||
"<name> in specialisation.<name> cannot contain a forward slash.";
|
||||
message = "<name> in specialisation.<name> cannot contain a forward slash.";
|
||||
}) (lib.attrNames config.specialisation);
|
||||
|
||||
home.extraBuilderCommands = let
|
||||
link = n: v:
|
||||
let pkg = v.configuration.home.activationPackage;
|
||||
in "ln -s ${pkg} $out/specialisation/${lib.escapeShellArg n}";
|
||||
in ''
|
||||
mkdir $out/specialisation
|
||||
${lib.concatStringsSep "\n"
|
||||
(lib.mapAttrsToList link config.specialisation)}
|
||||
'';
|
||||
home.extraBuilderCommands =
|
||||
let
|
||||
link =
|
||||
n: v:
|
||||
let
|
||||
pkg = v.configuration.home.activationPackage;
|
||||
in
|
||||
"ln -s ${pkg} $out/specialisation/${lib.escapeShellArg n}";
|
||||
in
|
||||
''
|
||||
mkdir $out/specialisation
|
||||
${lib.concatStringsSep "\n" (lib.mapAttrsToList link config.specialisation)}
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
cfg = config.systemd.user.tmpfiles;
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.dawidsowa ];
|
||||
|
||||
options.systemd.user.tmpfiles.rules = lib.mkOption {
|
||||
|
|
@ -21,8 +27,7 @@ in {
|
|||
|
||||
config = lib.mkIf (cfg.rules != [ ]) {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "systemd.user.tmpfiles" pkgs
|
||||
lib.platforms.linux)
|
||||
(lib.hm.assertions.assertPlatform "systemd.user.tmpfiles" pkgs lib.platforms.linux)
|
||||
];
|
||||
|
||||
xdg.configFile = {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ let
|
|||
|
||||
inherit (lib) mkIf mkOption types;
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.uninstall = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
|
|
@ -26,25 +27,24 @@ in {
|
|||
manual.manpages.enable = lib.mkForce false;
|
||||
news.display = lib.mkForce "silent";
|
||||
|
||||
home.activation.uninstall =
|
||||
lib.hm.dag.entryAfter [ "installPackages" "linkGeneration" ] ''
|
||||
nixProfileRemove home-manager-path
|
||||
home.activation.uninstall = lib.hm.dag.entryAfter [ "installPackages" "linkGeneration" ] ''
|
||||
nixProfileRemove home-manager-path
|
||||
|
||||
if [[ -e $hmDataPath ]]; then
|
||||
run rm $VERBOSE_ARG -r "$hmDataPath"
|
||||
fi
|
||||
if [[ -e $hmDataPath ]]; then
|
||||
run rm $VERBOSE_ARG -r "$hmDataPath"
|
||||
fi
|
||||
|
||||
if [[ -e $hmStatePath ]]; then
|
||||
run rm $VERBOSE_ARG -r "$hmStatePath"
|
||||
fi
|
||||
if [[ -e $hmStatePath ]]; then
|
||||
run rm $VERBOSE_ARG -r "$hmStatePath"
|
||||
fi
|
||||
|
||||
if [[ -e $genProfilePath ]]; then
|
||||
run rm $VERBOSE_ARG "$genProfilePath"*
|
||||
fi
|
||||
if [[ -e $genProfilePath ]]; then
|
||||
run rm $VERBOSE_ARG "$genProfilePath"*
|
||||
fi
|
||||
|
||||
if [[ -e $legacyGenGcPath ]]; then
|
||||
run rm $VERBOSE_ARG "$legacyGenGcPath"
|
||||
fi
|
||||
'';
|
||||
if [[ -e $legacyGenGcPath ]]; then
|
||||
run rm $VERBOSE_ARG "$legacyGenGcPath"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ let
|
|||
|
||||
releaseInfo = lib.importJSON ../../release.json;
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
options = {
|
||||
home.stateVersion = lib.mkOption {
|
||||
type = types.enum [
|
||||
|
|
@ -44,11 +45,12 @@ in {
|
|||
internal = true;
|
||||
readOnly = true;
|
||||
type = types.str;
|
||||
default = let
|
||||
inherit (config.home.version) release revision;
|
||||
suffix = lib.optionalString (revision != null)
|
||||
"+${lib.substring 0 8 revision}";
|
||||
in "${release}${suffix}";
|
||||
default =
|
||||
let
|
||||
inherit (config.home.version) release revision;
|
||||
suffix = lib.optionalString (revision != null) "+${lib.substring 0 8 revision}";
|
||||
in
|
||||
"${release}${suffix}";
|
||||
example = "22.11+213a0629";
|
||||
description = "The full Home Manager version.";
|
||||
};
|
||||
|
|
@ -76,11 +78,11 @@ in {
|
|||
revision = lib.mkOption {
|
||||
internal = true;
|
||||
type = types.nullOr types.str;
|
||||
default = let gitRepo = "${toString ./../..}/.git";
|
||||
in if lib.pathIsGitRepo gitRepo then
|
||||
lib.commitIdFromGitRepo gitRepo
|
||||
else
|
||||
null;
|
||||
default =
|
||||
let
|
||||
gitRepo = "${toString ./../..}/.git";
|
||||
in
|
||||
if lib.pathIsGitRepo gitRepo then lib.commitIdFromGitRepo gitRepo else null;
|
||||
description = ''
|
||||
The Git revision from which this Home Manager configuration was built.
|
||||
'';
|
||||
|
|
|
|||
|
|
@ -1,23 +1,30 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.rycee ];
|
||||
|
||||
options.programs = let
|
||||
description = ''
|
||||
Whether to enable integration with terminals using the VTE
|
||||
library. This will let the terminal track the current working
|
||||
directory.
|
||||
'';
|
||||
in {
|
||||
bash.enableVteIntegration = lib.mkEnableOption "" // {
|
||||
inherit description;
|
||||
};
|
||||
options.programs =
|
||||
let
|
||||
description = ''
|
||||
Whether to enable integration with terminals using the VTE
|
||||
library. This will let the terminal track the current working
|
||||
directory.
|
||||
'';
|
||||
in
|
||||
{
|
||||
bash.enableVteIntegration = lib.mkEnableOption "" // {
|
||||
inherit description;
|
||||
};
|
||||
|
||||
zsh.enableVteIntegration = lib.mkEnableOption "" // {
|
||||
inherit description;
|
||||
zsh.enableVteIntegration = lib.mkEnableOption "" // {
|
||||
inherit description;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkMerge [
|
||||
(lib.mkIf config.programs.bash.enableVteIntegration {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,23 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (builtins) baseNameOf listToAttrs map unsafeDiscardStringContext;
|
||||
inherit (lib) literalExpression mkEnableOption mkIf mkOption types;
|
||||
inherit (builtins)
|
||||
baseNameOf
|
||||
listToAttrs
|
||||
map
|
||||
unsafeDiscardStringContext
|
||||
;
|
||||
inherit (lib)
|
||||
literalExpression
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.xdg.autostart;
|
||||
|
||||
|
|
@ -10,7 +26,8 @@ let
|
|||
${lib.concatMapStringsSep "\n" (e: "ln -s ${e} $out") cfg.entries}
|
||||
'';
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ Scrumplex ];
|
||||
|
||||
options.xdg.autostart = {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) literalExpression mkOption types;
|
||||
|
|
@ -6,9 +11,9 @@ let
|
|||
desktopEntry = {
|
||||
imports = [
|
||||
(lib.mkRemovedOptionModule [ "extraConfig" ]
|
||||
"The `extraConfig` option of `xdg.desktopEntries` has been removed following a change in Nixpkgs.")
|
||||
(lib.mkRemovedOptionModule [ "fileValidation" ]
|
||||
"Validation of the desktop file is always enabled.")
|
||||
"The `extraConfig` option of `xdg.desktopEntries` has been removed following a change in Nixpkgs."
|
||||
)
|
||||
(lib.mkRemovedOptionModule [ "fileValidation" ] "Validation of the desktop file is always enabled.")
|
||||
];
|
||||
options = {
|
||||
# Since this module uses the nixpkgs/pkgs/build-support/make-desktopitem function,
|
||||
|
|
@ -28,7 +33,11 @@ let
|
|||
type = mkOption {
|
||||
description = "The type of the desktop entry.";
|
||||
default = "Application";
|
||||
type = types.enum [ "Application" "Link" "Directory" ];
|
||||
type = types.enum [
|
||||
"Application"
|
||||
"Link"
|
||||
"Directory"
|
||||
];
|
||||
};
|
||||
|
||||
exec = mkOption {
|
||||
|
|
@ -73,8 +82,7 @@ let
|
|||
};
|
||||
|
||||
categories = mkOption {
|
||||
description =
|
||||
"Categories in which the entry should be shown in a menu.";
|
||||
description = "Categories in which the entry should be shown in a menu.";
|
||||
type = types.nullOr (types.listOf types.str);
|
||||
default = null;
|
||||
};
|
||||
|
|
@ -122,24 +130,29 @@ let
|
|||
};
|
||||
|
||||
actions = mkOption {
|
||||
type = types.attrsOf (types.submodule ({ name, ... }: {
|
||||
options.name = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
defaultText = literalExpression "<name>";
|
||||
description = "Name of the action.";
|
||||
};
|
||||
options.exec = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
description = "Program to execute, possibly with arguments.";
|
||||
default = null;
|
||||
};
|
||||
options.icon = mkOption {
|
||||
type = with types; nullOr (either str path);
|
||||
default = null;
|
||||
description = "Icon to display in file manager, menus, etc.";
|
||||
};
|
||||
}));
|
||||
type = types.attrsOf (
|
||||
types.submodule (
|
||||
{ name, ... }:
|
||||
{
|
||||
options.name = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
defaultText = literalExpression "<name>";
|
||||
description = "Name of the action.";
|
||||
};
|
||||
options.exec = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
description = "Program to execute, possibly with arguments.";
|
||||
default = null;
|
||||
};
|
||||
options.icon = mkOption {
|
||||
type = with types; nullOr (either str path);
|
||||
default = null;
|
||||
description = "Icon to display in file manager, menus, etc.";
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
default = { };
|
||||
defaultText = literalExpression "{ }";
|
||||
example = literalExpression ''
|
||||
|
|
@ -149,8 +162,7 @@ let
|
|||
};
|
||||
}
|
||||
'';
|
||||
description =
|
||||
"The set of actions made available to application launchers.";
|
||||
description = "The set of actions made available to application launchers.";
|
||||
};
|
||||
|
||||
# Required for the assertions
|
||||
|
|
@ -165,18 +177,29 @@ let
|
|||
};
|
||||
|
||||
#passes config options to makeDesktopItem in expected format
|
||||
makeFile = name: config:
|
||||
makeFile =
|
||||
name: config:
|
||||
pkgs.makeDesktopItem {
|
||||
inherit name;
|
||||
inherit (config)
|
||||
type exec icon comment terminal genericName startupNotify noDisplay
|
||||
prefersNonDefaultGPU actions;
|
||||
type
|
||||
exec
|
||||
icon
|
||||
comment
|
||||
terminal
|
||||
genericName
|
||||
startupNotify
|
||||
noDisplay
|
||||
prefersNonDefaultGPU
|
||||
actions
|
||||
;
|
||||
desktopName = config.name;
|
||||
mimeTypes = lib.optionals (config.mimeType != null) config.mimeType;
|
||||
categories = lib.optionals (config.categories != null) config.categories;
|
||||
extraConfig = config.settings;
|
||||
};
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.hm.maintainers.cwyc ];
|
||||
|
||||
options.xdg.desktopEntries = mkOption {
|
||||
|
|
@ -205,14 +228,13 @@ in {
|
|||
|
||||
config = lib.mkIf (config.xdg.desktopEntries != { }) {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "xdg.desktopEntries" pkgs
|
||||
lib.platforms.linux)
|
||||
] ++ lib.flatten
|
||||
(lib.catAttrs "assertions" (lib.attrValues config.xdg.desktopEntries));
|
||||
(lib.hm.assertions.assertPlatform "xdg.desktopEntries" pkgs lib.platforms.linux)
|
||||
] ++ lib.flatten (lib.catAttrs "assertions" (lib.attrValues config.xdg.desktopEntries));
|
||||
|
||||
home.packages =
|
||||
(map lib.hiPrio # we need hiPrio to override existing entries
|
||||
(lib.attrsets.mapAttrsToList makeFile config.xdg.desktopEntries));
|
||||
home.packages = (
|
||||
map lib.hiPrio # we need hiPrio to override existing entries
|
||||
(lib.attrsets.mapAttrsToList makeFile config.xdg.desktopEntries)
|
||||
);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,19 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
|
||||
cfg = config.xdg.mimeApps;
|
||||
|
||||
strListOrSingleton = with types;
|
||||
coercedTo (either (listOf str) str) lib.toList (listOf str);
|
||||
strListOrSingleton = with types; coercedTo (either (listOf str) str) lib.toList (listOf str);
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ euxane ];
|
||||
|
||||
options.xdg.mimeApps = {
|
||||
|
|
@ -44,7 +49,9 @@ in {
|
|||
associations.removed = mkOption {
|
||||
type = types.attrsOf strListOrSingleton;
|
||||
default = { };
|
||||
example = { "mimetype1" = "foo5.desktop"; };
|
||||
example = {
|
||||
"mimetype1" = "foo5.desktop";
|
||||
};
|
||||
description = ''
|
||||
Removes associations of applications with mimetypes, as if the
|
||||
.desktop file was *not* listing this
|
||||
|
|
@ -75,43 +82,47 @@ in {
|
|||
# Given a package that installs .desktop files in the usual location,
|
||||
# return a mapping from mime types to lists of desktop file names. This is
|
||||
# suitable for use with `xdg.mimeApps.defaultApplications`.
|
||||
lib.xdg.mimeAssociations = let
|
||||
processLines = str:
|
||||
lib.zipAttrs (lib.filter (e: e != null)
|
||||
(map processLine (lib.splitString "\n" str)));
|
||||
lib.xdg.mimeAssociations =
|
||||
let
|
||||
processLines =
|
||||
str: lib.zipAttrs (lib.filter (e: e != null) (map processLine (lib.splitString "\n" str)));
|
||||
|
||||
processLine = str:
|
||||
let
|
||||
entry = lib.splitString ";" str;
|
||||
k = lib.elemAt entry 0;
|
||||
v = lib.elemAt entry 1;
|
||||
in if lib.length entry == 2 then { ${k} = v; } else null;
|
||||
processLine =
|
||||
str:
|
||||
let
|
||||
entry = lib.splitString ";" str;
|
||||
k = lib.elemAt entry 0;
|
||||
v = lib.elemAt entry 1;
|
||||
in
|
||||
if lib.length entry == 2 then { ${k} = v; } else null;
|
||||
|
||||
associations = ps:
|
||||
pkgs.runCommand "mime-assoc" { inherit ps; } ''
|
||||
for p in $ps ; do
|
||||
for path in "$p"/share/applications/*.desktop ; do
|
||||
name="''${path##*/}"
|
||||
sed -n -E "/^MimeType=/ { s/.*=//; s/;?$|;/;$name\n/g; p; }" "$path"
|
||||
done
|
||||
done > "$out"
|
||||
'';
|
||||
in p: processLines (builtins.readFile (associations p));
|
||||
associations =
|
||||
ps:
|
||||
pkgs.runCommand "mime-assoc" { inherit ps; } ''
|
||||
for p in $ps ; do
|
||||
for path in "$p"/share/applications/*.desktop ; do
|
||||
name="''${path##*/}"
|
||||
sed -n -E "/^MimeType=/ { s/.*=//; s/;?$|;/;$name\n/g; p; }" "$path"
|
||||
done
|
||||
done > "$out"
|
||||
'';
|
||||
in
|
||||
p: processLines (builtins.readFile (associations p));
|
||||
}
|
||||
|
||||
(lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "xdg.mimeApps" pkgs
|
||||
lib.platforms.linux)
|
||||
(lib.hm.assertions.assertPlatform "xdg.mimeApps" pkgs lib.platforms.linux)
|
||||
];
|
||||
|
||||
# Deprecated but still used by some applications.
|
||||
xdg.dataFile."applications/mimeapps.list".source =
|
||||
config.xdg.configFile."mimeapps.list".source;
|
||||
xdg.dataFile."applications/mimeapps.list".source = config.xdg.configFile."mimeapps.list".source;
|
||||
|
||||
xdg.configFile."mimeapps.list".text =
|
||||
let joinValues = lib.mapAttrs (n: lib.concatStringsSep ";");
|
||||
in lib.generators.toINI { } {
|
||||
let
|
||||
joinValues = lib.mapAttrs (n: lib.concatStringsSep ";");
|
||||
in
|
||||
lib.generators.toINI { } {
|
||||
"Added Associations" = joinValues cfg.associations.added;
|
||||
"Removed Associations" = joinValues cfg.associations.removed;
|
||||
"Default Applications" = joinValues cfg.defaultApplications;
|
||||
|
|
|
|||
|
|
@ -1,19 +1,29 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
cfg = config.xdg.mime;
|
||||
|
||||
inherit (lib) getExe getExe' mkOption types;
|
||||
inherit (lib)
|
||||
getExe
|
||||
getExe'
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
options = {
|
||||
xdg.mime = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = pkgs.stdenv.hostPlatform.isLinux;
|
||||
defaultText = lib.literalExpression
|
||||
"true if host platform is Linux, false otherwise";
|
||||
defaultText = lib.literalExpression "true if host platform is Linux, false otherwise";
|
||||
description = ''
|
||||
Whether to install programs and files to support the
|
||||
XDG Shared MIME-info specification and XDG MIME Applications
|
||||
|
|
@ -36,8 +46,7 @@ in {
|
|||
type = types.package;
|
||||
default = pkgs.desktop-file-utils;
|
||||
defaultText = lib.literalExpression "pkgs.desktop-file-utils";
|
||||
description =
|
||||
"The package to use when running update-desktop-database.";
|
||||
description = "The package to use when running update-desktop-database.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -64,16 +73,14 @@ in {
|
|||
XDG_DATA_DIRS=$out/share \
|
||||
PKGSYSTEM_ENABLE_FSYNC=0 \
|
||||
${
|
||||
getExe
|
||||
(cfg.sharedMimeInfoPackage.__spliced.buildHost or cfg.sharedMimeInfoPackage)
|
||||
getExe (cfg.sharedMimeInfoPackage.__spliced.buildHost or cfg.sharedMimeInfoPackage)
|
||||
} -V $out/share/mime > /dev/null
|
||||
fi
|
||||
|
||||
if [[ -w $out/share/applications ]]; then
|
||||
${
|
||||
getExe'
|
||||
(cfg.desktopFileUtilsPackage.__spliced.buildHost or cfg.desktopFileUtilsPackage)
|
||||
"update-desktop-database"
|
||||
getExe' (cfg.desktopFileUtilsPackage.__spliced.buildHost or cfg.desktopFileUtilsPackage
|
||||
) "update-desktop-database"
|
||||
} $out/share/applications
|
||||
fi
|
||||
'';
|
||||
|
|
|
|||
|
|
@ -1,14 +1,26 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
inherit (lib) mkIf mkMerge mkOption optional types;
|
||||
inherit (lib)
|
||||
mkIf
|
||||
mkMerge
|
||||
mkOption
|
||||
optional
|
||||
types
|
||||
;
|
||||
|
||||
associationOptions = with types;
|
||||
attrsOf (coercedTo (either (listOf str) str)
|
||||
(x: lib.concatStringsSep ";" (lib.toList x)) str);
|
||||
associationOptions =
|
||||
with types;
|
||||
attrsOf (coercedTo (either (listOf str) str) (x: lib.concatStringsSep ";" (lib.toList x)) str);
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.misterio77 ];
|
||||
|
||||
options.xdg.portal = {
|
||||
|
|
@ -63,12 +75,22 @@ in {
|
|||
type = types.attrsOf associationOptions;
|
||||
default = { };
|
||||
example = {
|
||||
x-cinnamon = { default = [ "xapp" "gtk" ]; };
|
||||
x-cinnamon = {
|
||||
default = [
|
||||
"xapp"
|
||||
"gtk"
|
||||
];
|
||||
};
|
||||
pantheon = {
|
||||
default = [ "pantheon" "gtk" ];
|
||||
default = [
|
||||
"pantheon"
|
||||
"gtk"
|
||||
];
|
||||
"org.freedesktop.impl.portal.Secret" = [ "gnome-keyring" ];
|
||||
};
|
||||
common = { default = [ "gtk" ]; };
|
||||
common = {
|
||||
default = [ "gtk" ];
|
||||
};
|
||||
};
|
||||
description = ''
|
||||
Sets which portal backend should be used to provide the implementation
|
||||
|
|
@ -97,51 +119,53 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
cfg = config.xdg.portal;
|
||||
packages = [ pkgs.xdg-desktop-portal ] ++ cfg.extraPortals;
|
||||
portalsDir =
|
||||
"${config.home.profileDirectory}/share/xdg-desktop-portal/portals";
|
||||
in mkIf cfg.enable {
|
||||
warnings = optional (cfg.configPackages == [ ] && cfg.config == { }) ''
|
||||
xdg-desktop-portal 1.17 reworked how portal implementations are loaded, you
|
||||
should either set `xdg.portal.config` or `xdg.portal.configPackages`
|
||||
to specify which portal backend to use for the requested interface.
|
||||
config =
|
||||
let
|
||||
cfg = config.xdg.portal;
|
||||
packages = [ pkgs.xdg-desktop-portal ] ++ cfg.extraPortals;
|
||||
portalsDir = "${config.home.profileDirectory}/share/xdg-desktop-portal/portals";
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
warnings = optional (cfg.configPackages == [ ] && cfg.config == { }) ''
|
||||
xdg-desktop-portal 1.17 reworked how portal implementations are loaded, you
|
||||
should either set `xdg.portal.config` or `xdg.portal.configPackages`
|
||||
to specify which portal backend to use for the requested interface.
|
||||
|
||||
https://github.com/flatpak/xdg-desktop-portal/blob/1.18.1/doc/portals.conf.rst.in
|
||||
https://github.com/flatpak/xdg-desktop-portal/blob/1.18.1/doc/portals.conf.rst.in
|
||||
|
||||
If you simply want to keep the behaviour in < 1.17, which uses the first
|
||||
portal implementation found in lexicographical order, use the following:
|
||||
If you simply want to keep the behaviour in < 1.17, which uses the first
|
||||
portal implementation found in lexicographical order, use the following:
|
||||
|
||||
xdg.portal.config.common.default = "*";
|
||||
'';
|
||||
xdg.portal.config.common.default = "*";
|
||||
'';
|
||||
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "xdg.portal" pkgs lib.platforms.linux)
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "xdg.portal" pkgs lib.platforms.linux)
|
||||
|
||||
{
|
||||
assertion = cfg.extraPortals != [ ];
|
||||
message =
|
||||
"Setting xdg.portal.enable to true requires a portal implementation in xdg.portal.extraPortals such as xdg-desktop-portal-gtk or xdg-desktop-portal-kde.";
|
||||
}
|
||||
];
|
||||
|
||||
home = {
|
||||
packages = packages ++ cfg.configPackages;
|
||||
sessionVariables = mkMerge [
|
||||
(mkIf cfg.xdgOpenUsePortal { NIXOS_XDG_OPEN_USE_PORTAL = "1"; })
|
||||
{ NIX_XDG_DESKTOP_PORTAL_DIR = portalsDir; }
|
||||
{
|
||||
assertion = cfg.extraPortals != [ ];
|
||||
message = "Setting xdg.portal.enable to true requires a portal implementation in xdg.portal.extraPortals such as xdg-desktop-portal-gtk or xdg-desktop-portal-kde.";
|
||||
}
|
||||
];
|
||||
};
|
||||
systemd.user.sessionVariables = {
|
||||
NIX_XDG_DESKTOP_PORTAL_DIR = portalsDir;
|
||||
};
|
||||
|
||||
xdg.configFile = lib.concatMapAttrs (desktop: conf:
|
||||
lib.optionalAttrs (conf != { }) {
|
||||
"xdg-desktop-portal/${
|
||||
lib.optionalString (desktop != "common") "${desktop}-"
|
||||
}portals.conf".text = lib.generators.toINI { } { preferred = conf; };
|
||||
}) cfg.config;
|
||||
};
|
||||
home = {
|
||||
packages = packages ++ cfg.configPackages;
|
||||
sessionVariables = mkMerge [
|
||||
(mkIf cfg.xdgOpenUsePortal { NIXOS_XDG_OPEN_USE_PORTAL = "1"; })
|
||||
{ NIX_XDG_DESKTOP_PORTAL_DIR = portalsDir; }
|
||||
];
|
||||
};
|
||||
systemd.user.sessionVariables = {
|
||||
NIX_XDG_DESKTOP_PORTAL_DIR = portalsDir;
|
||||
};
|
||||
|
||||
xdg.configFile = lib.concatMapAttrs (
|
||||
desktop: conf:
|
||||
lib.optionalAttrs (conf != { }) {
|
||||
"xdg-desktop-portal/${lib.optionalString (desktop != "common") "${desktop}-"}portals.conf".text =
|
||||
lib.generators.toINI { }
|
||||
{ preferred = conf; };
|
||||
}
|
||||
) cfg.config;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) types;
|
||||
|
|
@ -9,7 +14,8 @@ let
|
|||
|
||||
dataDirs = lib.concatStringsSep ":" cfg.data;
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ tadfisher ];
|
||||
|
||||
options.xdg.systemDirs = {
|
||||
|
|
@ -37,25 +43,20 @@ in {
|
|||
config = lib.mkMerge [
|
||||
(lib.mkIf (cfg.config != [ ] || cfg.data != [ ]) {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "xdg.systemDirs" pkgs
|
||||
lib.platforms.linux)
|
||||
(lib.hm.assertions.assertPlatform "xdg.systemDirs" pkgs lib.platforms.linux)
|
||||
];
|
||||
})
|
||||
|
||||
(lib.mkIf (cfg.config != [ ]) {
|
||||
home.sessionVariables.XDG_CONFIG_DIRS =
|
||||
"${configDirs}\${XDG_CONFIG_DIRS:+:$XDG_CONFIG_DIRS}";
|
||||
home.sessionVariables.XDG_CONFIG_DIRS = "${configDirs}\${XDG_CONFIG_DIRS:+:$XDG_CONFIG_DIRS}";
|
||||
|
||||
systemd.user.sessionVariables.XDG_CONFIG_DIRS =
|
||||
"${configDirs}\${XDG_CONFIG_DIRS:+:$XDG_CONFIG_DIRS}";
|
||||
systemd.user.sessionVariables.XDG_CONFIG_DIRS = "${configDirs}\${XDG_CONFIG_DIRS:+:$XDG_CONFIG_DIRS}";
|
||||
})
|
||||
|
||||
(lib.mkIf (cfg.data != [ ]) {
|
||||
home.sessionVariables.XDG_DATA_DIRS =
|
||||
"${dataDirs}\${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}";
|
||||
home.sessionVariables.XDG_DATA_DIRS = "${dataDirs}\${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}";
|
||||
|
||||
systemd.user.sessionVariables.XDG_DATA_DIRS =
|
||||
"${dataDirs}\${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}";
|
||||
systemd.user.sessionVariables.XDG_DATA_DIRS = "${dataDirs}\${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}";
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,28 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) literalExpression mkOption types;
|
||||
|
||||
cfg = config.xdg.userDirs;
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ euxane ];
|
||||
|
||||
imports = [
|
||||
(lib.mkRenamedOptionModule [ "xdg" "userDirs" "publishShare" ] [
|
||||
"xdg"
|
||||
"userDirs"
|
||||
"publicShare"
|
||||
])
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "xdg" "userDirs" "publishShare" ]
|
||||
[
|
||||
"xdg"
|
||||
"userDirs"
|
||||
"publicShare"
|
||||
]
|
||||
)
|
||||
];
|
||||
|
||||
options.xdg.userDirs = {
|
||||
|
|
@ -33,64 +42,56 @@ in {
|
|||
desktop = mkOption {
|
||||
type = with types; nullOr (coercedTo path toString str);
|
||||
default = "${config.home.homeDirectory}/Desktop";
|
||||
defaultText =
|
||||
literalExpression ''"''${config.home.homeDirectory}/Desktop"'';
|
||||
defaultText = literalExpression ''"''${config.home.homeDirectory}/Desktop"'';
|
||||
description = "The Desktop directory.";
|
||||
};
|
||||
|
||||
documents = mkOption {
|
||||
type = with types; nullOr (coercedTo path toString str);
|
||||
default = "${config.home.homeDirectory}/Documents";
|
||||
defaultText =
|
||||
literalExpression ''"''${config.home.homeDirectory}/Documents"'';
|
||||
defaultText = literalExpression ''"''${config.home.homeDirectory}/Documents"'';
|
||||
description = "The Documents directory.";
|
||||
};
|
||||
|
||||
download = mkOption {
|
||||
type = with types; nullOr (coercedTo path toString str);
|
||||
default = "${config.home.homeDirectory}/Downloads";
|
||||
defaultText =
|
||||
literalExpression ''"''${config.home.homeDirectory}/Downloads"'';
|
||||
defaultText = literalExpression ''"''${config.home.homeDirectory}/Downloads"'';
|
||||
description = "The Downloads directory.";
|
||||
};
|
||||
|
||||
music = mkOption {
|
||||
type = with types; nullOr (coercedTo path toString str);
|
||||
default = "${config.home.homeDirectory}/Music";
|
||||
defaultText =
|
||||
literalExpression ''"''${config.home.homeDirectory}/Music"'';
|
||||
defaultText = literalExpression ''"''${config.home.homeDirectory}/Music"'';
|
||||
description = "The Music directory.";
|
||||
};
|
||||
|
||||
pictures = mkOption {
|
||||
type = with types; nullOr (coercedTo path toString str);
|
||||
default = "${config.home.homeDirectory}/Pictures";
|
||||
defaultText =
|
||||
literalExpression ''"''${config.home.homeDirectory}/Pictures"'';
|
||||
defaultText = literalExpression ''"''${config.home.homeDirectory}/Pictures"'';
|
||||
description = "The Pictures directory.";
|
||||
};
|
||||
|
||||
publicShare = mkOption {
|
||||
type = with types; nullOr (coercedTo path toString str);
|
||||
default = "${config.home.homeDirectory}/Public";
|
||||
defaultText =
|
||||
literalExpression ''"''${config.home.homeDirectory}/Public"'';
|
||||
defaultText = literalExpression ''"''${config.home.homeDirectory}/Public"'';
|
||||
description = "The Public share directory.";
|
||||
};
|
||||
|
||||
templates = mkOption {
|
||||
type = with types; nullOr (coercedTo path toString str);
|
||||
default = "${config.home.homeDirectory}/Templates";
|
||||
defaultText =
|
||||
literalExpression ''"''${config.home.homeDirectory}/Templates"'';
|
||||
defaultText = literalExpression ''"''${config.home.homeDirectory}/Templates"'';
|
||||
description = "The Templates directory.";
|
||||
};
|
||||
|
||||
videos = mkOption {
|
||||
type = with types; nullOr (coercedTo path toString str);
|
||||
default = "${config.home.homeDirectory}/Videos";
|
||||
defaultText =
|
||||
literalExpression ''"''${config.home.homeDirectory}/Videos"'';
|
||||
defaultText = literalExpression ''"''${config.home.homeDirectory}/Videos"'';
|
||||
description = "The Videos directory.";
|
||||
};
|
||||
|
||||
|
|
@ -106,41 +107,48 @@ in {
|
|||
description = "Other user directories.";
|
||||
};
|
||||
|
||||
createDirectories =
|
||||
lib.mkEnableOption "automatic creation of the XDG user directories";
|
||||
createDirectories = lib.mkEnableOption "automatic creation of the XDG user directories";
|
||||
};
|
||||
|
||||
config = let
|
||||
directories = (lib.filterAttrs (n: v: !isNull v) {
|
||||
XDG_DESKTOP_DIR = cfg.desktop;
|
||||
XDG_DOCUMENTS_DIR = cfg.documents;
|
||||
XDG_DOWNLOAD_DIR = cfg.download;
|
||||
XDG_MUSIC_DIR = cfg.music;
|
||||
XDG_PICTURES_DIR = cfg.pictures;
|
||||
XDG_PUBLICSHARE_DIR = cfg.publicShare;
|
||||
XDG_TEMPLATES_DIR = cfg.templates;
|
||||
XDG_VIDEOS_DIR = cfg.videos;
|
||||
}) // cfg.extraConfig;
|
||||
in lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "xdg.userDirs" pkgs lib.platforms.linux)
|
||||
];
|
||||
config =
|
||||
let
|
||||
directories =
|
||||
(lib.filterAttrs (n: v: !isNull v) {
|
||||
XDG_DESKTOP_DIR = cfg.desktop;
|
||||
XDG_DOCUMENTS_DIR = cfg.documents;
|
||||
XDG_DOWNLOAD_DIR = cfg.download;
|
||||
XDG_MUSIC_DIR = cfg.music;
|
||||
XDG_PICTURES_DIR = cfg.pictures;
|
||||
XDG_PUBLICSHARE_DIR = cfg.publicShare;
|
||||
XDG_TEMPLATES_DIR = cfg.templates;
|
||||
XDG_VIDEOS_DIR = cfg.videos;
|
||||
})
|
||||
// cfg.extraConfig;
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
(lib.hm.assertions.assertPlatform "xdg.userDirs" pkgs lib.platforms.linux)
|
||||
];
|
||||
|
||||
xdg.configFile."user-dirs.dirs".text = let
|
||||
# For some reason, these need to be wrapped with quotes to be valid.
|
||||
wrapped = lib.mapAttrs (_: value: ''"${value}"'') directories;
|
||||
in lib.generators.toKeyValue { } wrapped;
|
||||
xdg.configFile."user-dirs.dirs".text =
|
||||
let
|
||||
# For some reason, these need to be wrapped with quotes to be valid.
|
||||
wrapped = lib.mapAttrs (_: value: ''"${value}"'') directories;
|
||||
in
|
||||
lib.generators.toKeyValue { } wrapped;
|
||||
|
||||
xdg.configFile."user-dirs.conf".text = "enabled=False";
|
||||
xdg.configFile."user-dirs.conf".text = "enabled=False";
|
||||
|
||||
home.sessionVariables = directories;
|
||||
home.sessionVariables = directories;
|
||||
|
||||
home.activation.createXdgUserDirectories = lib.mkIf cfg.createDirectories
|
||||
(let
|
||||
directoriesList = lib.attrValues directories;
|
||||
mkdir =
|
||||
(dir: ''[[ -L "${dir}" ]] || run mkdir -p $VERBOSE_ARG "${dir}"'');
|
||||
in lib.hm.dag.entryAfter [ "linkGeneration" ]
|
||||
(lib.strings.concatMapStringsSep "\n" mkdir directoriesList));
|
||||
};
|
||||
home.activation.createXdgUserDirectories = lib.mkIf cfg.createDirectories (
|
||||
let
|
||||
directoriesList = lib.attrValues directories;
|
||||
mkdir = (dir: ''[[ -L "${dir}" ]] || run mkdir -p $VERBOSE_ARG "${dir}"'');
|
||||
in
|
||||
lib.hm.dag.entryAfter [ "linkGeneration" ] (
|
||||
lib.strings.concatMapStringsSep "\n" mkdir directoriesList
|
||||
)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,40 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) mkOptionDefault mkIf mkOption types;
|
||||
inherit (lib)
|
||||
mkOptionDefault
|
||||
mkIf
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.xdg;
|
||||
|
||||
fileType = (import ../lib/file-type.nix {
|
||||
inherit (config.home) homeDirectory;
|
||||
inherit lib pkgs;
|
||||
}).fileType;
|
||||
fileType =
|
||||
(import ../lib/file-type.nix {
|
||||
inherit (config.home) homeDirectory;
|
||||
inherit lib pkgs;
|
||||
}).fileType;
|
||||
|
||||
defaultCacheHome = "${config.home.homeDirectory}/.cache";
|
||||
defaultConfigHome = "${config.home.homeDirectory}/.config";
|
||||
defaultDataHome = "${config.home.homeDirectory}/.local/share";
|
||||
defaultStateHome = "${config.home.homeDirectory}/.local/state";
|
||||
|
||||
getEnvFallback = name: fallback:
|
||||
let value = builtins.getEnv name;
|
||||
in if value != "" then value else fallback;
|
||||
getEnvFallback =
|
||||
name: fallback:
|
||||
let
|
||||
value = builtins.getEnv name;
|
||||
in
|
||||
if value != "" then value else fallback;
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.xdg = {
|
||||
enable = lib.mkEnableOption "management of XDG base directories";
|
||||
|
||||
|
|
@ -64,8 +79,7 @@ in {
|
|||
};
|
||||
|
||||
dataFile = mkOption {
|
||||
type =
|
||||
fileType "xdg.dataFile" "<varname>xdg.dataHome</varname>" cfg.dataHome;
|
||||
type = fileType "xdg.dataFile" "<varname>xdg.dataHome</varname>" cfg.dataHome;
|
||||
default = { };
|
||||
description = ''
|
||||
Attribute set of files to link into the user's XDG
|
||||
|
|
@ -85,8 +99,7 @@ in {
|
|||
};
|
||||
|
||||
stateFile = mkOption {
|
||||
type = fileType "xdg.stateFile" "<varname>xdg.stateHome</varname>"
|
||||
cfg.stateHome;
|
||||
type = fileType "xdg.stateFile" "<varname>xdg.stateHome</varname>" cfg.stateHome;
|
||||
default = { };
|
||||
description = ''
|
||||
Attribute set of files to link into the user's XDG
|
||||
|
|
@ -107,34 +120,32 @@ in {
|
|||
};
|
||||
|
||||
config = lib.mkMerge [
|
||||
(let
|
||||
variables = {
|
||||
XDG_CACHE_HOME = cfg.cacheHome;
|
||||
XDG_CONFIG_HOME = cfg.configHome;
|
||||
XDG_DATA_HOME = cfg.dataHome;
|
||||
XDG_STATE_HOME = cfg.stateHome;
|
||||
};
|
||||
in mkIf cfg.enable {
|
||||
xdg.cacheHome = mkOptionDefault defaultCacheHome;
|
||||
xdg.configHome = mkOptionDefault defaultConfigHome;
|
||||
xdg.dataHome = mkOptionDefault defaultDataHome;
|
||||
xdg.stateHome = mkOptionDefault defaultStateHome;
|
||||
(
|
||||
let
|
||||
variables = {
|
||||
XDG_CACHE_HOME = cfg.cacheHome;
|
||||
XDG_CONFIG_HOME = cfg.configHome;
|
||||
XDG_DATA_HOME = cfg.dataHome;
|
||||
XDG_STATE_HOME = cfg.stateHome;
|
||||
};
|
||||
in
|
||||
mkIf cfg.enable {
|
||||
xdg.cacheHome = mkOptionDefault defaultCacheHome;
|
||||
xdg.configHome = mkOptionDefault defaultConfigHome;
|
||||
xdg.dataHome = mkOptionDefault defaultDataHome;
|
||||
xdg.stateHome = mkOptionDefault defaultStateHome;
|
||||
|
||||
home.sessionVariables = variables;
|
||||
systemd.user.sessionVariables =
|
||||
mkIf pkgs.stdenv.hostPlatform.isLinux variables;
|
||||
})
|
||||
home.sessionVariables = variables;
|
||||
systemd.user.sessionVariables = mkIf pkgs.stdenv.hostPlatform.isLinux variables;
|
||||
}
|
||||
)
|
||||
|
||||
# Legacy non-deterministic setup.
|
||||
(mkIf (!cfg.enable && lib.versionOlder config.home.stateVersion "20.09") {
|
||||
xdg.cacheHome =
|
||||
mkOptionDefault (getEnvFallback "XDG_CACHE_HOME" defaultCacheHome);
|
||||
xdg.configHome =
|
||||
mkOptionDefault (getEnvFallback "XDG_CONFIG_HOME" defaultConfigHome);
|
||||
xdg.dataHome =
|
||||
mkOptionDefault (getEnvFallback "XDG_DATA_HOME" defaultDataHome);
|
||||
xdg.stateHome =
|
||||
mkOptionDefault (getEnvFallback "XDG_STATE_HOME" defaultStateHome);
|
||||
xdg.cacheHome = mkOptionDefault (getEnvFallback "XDG_CACHE_HOME" defaultCacheHome);
|
||||
xdg.configHome = mkOptionDefault (getEnvFallback "XDG_CONFIG_HOME" defaultConfigHome);
|
||||
xdg.dataHome = mkOptionDefault (getEnvFallback "XDG_DATA_HOME" defaultDataHome);
|
||||
xdg.stateHome = mkOptionDefault (getEnvFallback "XDG_STATE_HOME" defaultStateHome);
|
||||
})
|
||||
|
||||
# "Modern" deterministic setup.
|
||||
|
|
@ -147,18 +158,10 @@ in {
|
|||
|
||||
{
|
||||
home.file = lib.mkMerge [
|
||||
(lib.mapAttrs'
|
||||
(name: file: lib.nameValuePair "${cfg.cacheHome}/${name}" file)
|
||||
cfg.cacheFile)
|
||||
(lib.mapAttrs'
|
||||
(name: file: lib.nameValuePair "${cfg.configHome}/${name}" file)
|
||||
cfg.configFile)
|
||||
(lib.mapAttrs'
|
||||
(name: file: lib.nameValuePair "${cfg.dataHome}/${name}" file)
|
||||
cfg.dataFile)
|
||||
(lib.mapAttrs'
|
||||
(name: file: lib.nameValuePair "${cfg.stateHome}/${name}" file)
|
||||
cfg.stateFile)
|
||||
(lib.mapAttrs' (name: file: lib.nameValuePair "${cfg.cacheHome}/${name}" file) cfg.cacheFile)
|
||||
(lib.mapAttrs' (name: file: lib.nameValuePair "${cfg.configHome}/${name}" file) cfg.configFile)
|
||||
(lib.mapAttrs' (name: file: lib.nameValuePair "${cfg.dataHome}/${name}" file) cfg.dataFile)
|
||||
(lib.mapAttrs' (name: file: lib.nameValuePair "${cfg.stateHome}/${name}" file) cfg.stateFile)
|
||||
{ "${cfg.cacheHome}/.keep".text = ""; }
|
||||
{ "${cfg.stateHome}/.keep".text = ""; }
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) mkOption types;
|
||||
|
|
@ -8,7 +13,11 @@ let
|
|||
xfIntVariant = types.submodule {
|
||||
options = {
|
||||
type = mkOption {
|
||||
type = types.enum [ "int" "uint" "uint64" ];
|
||||
type = types.enum [
|
||||
"int"
|
||||
"uint"
|
||||
"uint64"
|
||||
];
|
||||
description = ''
|
||||
To distinguish between int, uint and uint64 in xfconf,
|
||||
you can specify the type in xfconf with this submodule.
|
||||
|
|
@ -23,38 +32,50 @@ let
|
|||
};
|
||||
};
|
||||
|
||||
withType = v:
|
||||
if builtins.isAttrs v then [
|
||||
"-t"
|
||||
v.type
|
||||
"-s"
|
||||
(toString v.value)
|
||||
] else if builtins.isBool v then [
|
||||
"-t"
|
||||
"bool"
|
||||
"-s"
|
||||
(if v then "true" else "false")
|
||||
] else if builtins.isInt v then [
|
||||
"-t"
|
||||
"int"
|
||||
"-s"
|
||||
(toString v)
|
||||
] else if builtins.isFloat v then [
|
||||
"-t"
|
||||
"double"
|
||||
"-s"
|
||||
(toString v)
|
||||
] else if builtins.isString v then [
|
||||
"-t"
|
||||
"string"
|
||||
"-s"
|
||||
v
|
||||
] else if builtins.isList v then
|
||||
withType =
|
||||
v:
|
||||
if builtins.isAttrs v then
|
||||
[
|
||||
"-t"
|
||||
v.type
|
||||
"-s"
|
||||
(toString v.value)
|
||||
]
|
||||
else if builtins.isBool v then
|
||||
[
|
||||
"-t"
|
||||
"bool"
|
||||
"-s"
|
||||
(if v then "true" else "false")
|
||||
]
|
||||
else if builtins.isInt v then
|
||||
[
|
||||
"-t"
|
||||
"int"
|
||||
"-s"
|
||||
(toString v)
|
||||
]
|
||||
else if builtins.isFloat v then
|
||||
[
|
||||
"-t"
|
||||
"double"
|
||||
"-s"
|
||||
(toString v)
|
||||
]
|
||||
else if builtins.isString v then
|
||||
[
|
||||
"-t"
|
||||
"string"
|
||||
"-s"
|
||||
v
|
||||
]
|
||||
else if builtins.isList v then
|
||||
[ "-a" ] ++ lib.concatMap withType v
|
||||
else
|
||||
throw "unexpected xfconf type: ${builtins.typeOf v}";
|
||||
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.maintainers = [ lib.maintainers.chuangzhu ];
|
||||
|
||||
options.xfconf = {
|
||||
|
|
@ -73,10 +94,20 @@ in {
|
|||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = with types;
|
||||
# xfIntVariant must come AFTER str; otherwise strings are treated as submodule imports...
|
||||
let value = nullOr (oneOf [ bool int float str xfIntVariant ]);
|
||||
in attrsOf (attrsOf (either value (listOf value))) // {
|
||||
type =
|
||||
with types;
|
||||
# xfIntVariant must come AFTER str; otherwise strings are treated as submodule imports...
|
||||
let
|
||||
value = nullOr (oneOf [
|
||||
bool
|
||||
int
|
||||
float
|
||||
str
|
||||
xfIntVariant
|
||||
]);
|
||||
in
|
||||
attrsOf (attrsOf (either value (listOf value)))
|
||||
// {
|
||||
description = "xfconf settings";
|
||||
};
|
||||
default = { };
|
||||
|
|
@ -99,30 +130,33 @@ in {
|
|||
};
|
||||
|
||||
config = lib.mkIf (cfg.enable && cfg.settings != { }) {
|
||||
assertions =
|
||||
[ (lib.hm.assertions.assertPlatform "xfconf" pkgs lib.platforms.linux) ];
|
||||
assertions = [ (lib.hm.assertions.assertPlatform "xfconf" pkgs lib.platforms.linux) ];
|
||||
|
||||
home.activation.xfconfSettings = lib.hm.dag.entryAfter [ "installPackages" ]
|
||||
(let
|
||||
home.activation.xfconfSettings = lib.hm.dag.entryAfter [ "installPackages" ] (
|
||||
let
|
||||
mkCommand = channel: property: value: ''
|
||||
run ${pkgs.xfce.xfconf}/bin/xfconf-query \
|
||||
${
|
||||
lib.escapeShellArgs ([ "-c" channel "-p" "/${property}" ]
|
||||
++ (if value == null then
|
||||
[ "-r" ]
|
||||
else
|
||||
[ "-n" ] ++ withType value))
|
||||
}
|
||||
${lib.escapeShellArgs (
|
||||
[
|
||||
"-c"
|
||||
channel
|
||||
"-p"
|
||||
"/${property}"
|
||||
]
|
||||
++ (if value == null then [ "-r" ] else [ "-n" ] ++ withType value)
|
||||
)}
|
||||
'';
|
||||
|
||||
commands = lib.mapAttrsToList (channel: properties:
|
||||
lib.mapAttrsToList (mkCommand channel) properties) cfg.settings;
|
||||
commands = lib.mapAttrsToList (
|
||||
channel: properties: lib.mapAttrsToList (mkCommand channel) properties
|
||||
) cfg.settings;
|
||||
|
||||
load = pkgs.writeShellScript "load-xfconf" ''
|
||||
${config.lib.bash.initHomeManagerLib}
|
||||
${lib.concatMapStrings lib.concatStrings commands}
|
||||
'';
|
||||
in ''
|
||||
in
|
||||
''
|
||||
if [[ -v DBUS_SESSION_BUS_ADDRESS ]]; then
|
||||
export DBUS_RUN_SESSION_CMD=""
|
||||
else
|
||||
|
|
@ -132,6 +166,7 @@ in {
|
|||
run $DBUS_RUN_SESSION_CMD ${load}
|
||||
|
||||
unset DBUS_RUN_SESSION_CMD
|
||||
'');
|
||||
''
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue