2017-01-07 19:16:26 +01:00
|
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
|
|
let
|
|
|
|
|
|
2021-07-29 02:52:25 +02:00
|
|
|
|
inherit (config.home) stateVersion;
|
|
|
|
|
|
2017-01-07 19:16:26 +01:00
|
|
|
|
cfg = config.home;
|
|
|
|
|
|
|
|
|
|
languageSubModule = types.submodule {
|
|
|
|
|
options = {
|
|
|
|
|
base = mkOption {
|
2017-02-12 01:18:37 +01:00
|
|
|
|
default = null;
|
|
|
|
|
type = types.nullOr types.str;
|
2017-01-07 19:16:26 +01:00
|
|
|
|
description = ''
|
|
|
|
|
The language to use unless overridden by a more specific option.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2020-05-27 14:33:55 +02:00
|
|
|
|
ctype = mkOption {
|
2017-01-07 19:16:26 +01:00
|
|
|
|
default = null;
|
|
|
|
|
type = types.nullOr types.str;
|
|
|
|
|
description = ''
|
2020-05-27 14:33:55 +02:00
|
|
|
|
Character classification category.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
numeric = mkOption {
|
|
|
|
|
default = null;
|
|
|
|
|
type = types.nullOr types.str;
|
|
|
|
|
description = ''
|
|
|
|
|
The language to use for numerical values.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
time = mkOption {
|
|
|
|
|
default = null;
|
|
|
|
|
type = types.nullOr types.str;
|
|
|
|
|
description = ''
|
|
|
|
|
The language to use for formatting times.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
collate = mkOption {
|
|
|
|
|
default = null;
|
|
|
|
|
type = types.nullOr types.str;
|
|
|
|
|
description = ''
|
|
|
|
|
The language to use for collation (alphabetical ordering).
|
2017-01-07 19:16:26 +01:00
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
monetary = mkOption {
|
|
|
|
|
default = null;
|
|
|
|
|
type = types.nullOr types.str;
|
|
|
|
|
description = ''
|
|
|
|
|
The language to use for formatting currencies and money amounts.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2020-05-27 14:33:55 +02:00
|
|
|
|
messages = mkOption {
|
|
|
|
|
default = null;
|
|
|
|
|
type = types.nullOr types.str;
|
|
|
|
|
description = ''
|
|
|
|
|
The language to use for messages, application UI languages, etc.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2017-01-07 19:16:26 +01:00
|
|
|
|
paper = mkOption {
|
|
|
|
|
default = null;
|
|
|
|
|
type = types.nullOr types.str;
|
|
|
|
|
description = ''
|
|
|
|
|
The language to use for paper sizes.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2020-05-27 14:33:55 +02:00
|
|
|
|
name = mkOption {
|
2017-01-07 19:16:26 +01:00
|
|
|
|
default = null;
|
|
|
|
|
type = types.nullOr types.str;
|
|
|
|
|
description = ''
|
2020-05-27 14:33:55 +02:00
|
|
|
|
The language to use for personal names.
|
2017-01-07 19:16:26 +01:00
|
|
|
|
'';
|
|
|
|
|
};
|
2020-05-27 14:33:55 +02:00
|
|
|
|
|
|
|
|
|
address = mkOption {
|
|
|
|
|
default = null;
|
|
|
|
|
type = types.nullOr types.str;
|
|
|
|
|
description = ''
|
|
|
|
|
The language to use for addresses.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
telephone = mkOption {
|
|
|
|
|
default = null;
|
|
|
|
|
type = types.nullOr types.str;
|
|
|
|
|
description = ''
|
|
|
|
|
The language to use for telephone numbers.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
measurement = mkOption {
|
|
|
|
|
default = null;
|
|
|
|
|
type = types.nullOr types.str;
|
|
|
|
|
description = ''
|
|
|
|
|
The language to use for measurement values.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2017-01-07 19:16:26 +01:00
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
keyboardSubModule = types.submodule {
|
|
|
|
|
options = {
|
|
|
|
|
layout = mkOption {
|
2019-09-05 01:37:45 +02:00
|
|
|
|
type = with types; nullOr str;
|
|
|
|
|
default =
|
|
|
|
|
if versionAtLeast config.home.stateVersion "19.09"
|
|
|
|
|
then null
|
|
|
|
|
else "us";
|
2021-10-09 11:14:08 +02:00
|
|
|
|
defaultText = literalExpression "null";
|
2017-01-07 19:16:26 +01:00
|
|
|
|
description = ''
|
2019-09-05 01:37:45 +02:00
|
|
|
|
Keyboard layout. If <literal>null</literal>, then the system
|
|
|
|
|
configuration will be used.
|
|
|
|
|
</para><para>
|
|
|
|
|
This defaults to <literal>null</literal> for state
|
|
|
|
|
version ≥ 19.09 and <literal>"us"</literal> otherwise.
|
2017-01-07 19:16:26 +01:00
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
model = mkOption {
|
2019-09-05 01:56:14 +02:00
|
|
|
|
type = with types; nullOr str;
|
|
|
|
|
default = null;
|
2017-01-07 19:16:26 +01:00
|
|
|
|
example = "presario";
|
|
|
|
|
description = ''
|
|
|
|
|
Keyboard model.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
options = mkOption {
|
|
|
|
|
type = types.listOf types.str;
|
|
|
|
|
default = [];
|
|
|
|
|
example = ["grp:caps_toggle" "grp_led:scroll"];
|
|
|
|
|
description = ''
|
|
|
|
|
X keyboard options; layout switching goes here.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
variant = mkOption {
|
2019-09-05 01:37:45 +02:00
|
|
|
|
type = with types; nullOr str;
|
|
|
|
|
default =
|
|
|
|
|
if versionAtLeast config.home.stateVersion "19.09"
|
|
|
|
|
then null
|
|
|
|
|
else "";
|
2021-10-09 11:14:08 +02:00
|
|
|
|
defaultText = literalExpression "null";
|
2017-01-07 19:16:26 +01:00
|
|
|
|
example = "colemak";
|
|
|
|
|
description = ''
|
2019-09-05 01:37:45 +02:00
|
|
|
|
X keyboard variant. If <literal>null</literal>, then the
|
|
|
|
|
system configuration will be used.
|
|
|
|
|
</para><para>
|
|
|
|
|
This defaults to <literal>null</literal> for state
|
|
|
|
|
version ≥ 19.09 and <literal>""</literal> otherwise.
|
2017-01-07 19:16:26 +01:00
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
|
|
{
|
2017-09-26 23:40:31 +02:00
|
|
|
|
meta.maintainers = [ maintainers.rycee ];
|
|
|
|
|
|
2018-02-08 22:54:29 +01:00
|
|
|
|
imports = [
|
|
|
|
|
(mkRemovedOptionModule [ "home" "sessionVariableSetter" ] ''
|
|
|
|
|
Session variables are now always set through the shell. This is
|
|
|
|
|
done automatically if the shell configuration is managed by Home
|
|
|
|
|
Manager. If not, then you must source the
|
|
|
|
|
|
|
|
|
|
~/.nix-profile/etc/profile.d/hm-session-vars.sh
|
|
|
|
|
|
|
|
|
|
file yourself.
|
|
|
|
|
'')
|
|
|
|
|
];
|
|
|
|
|
|
2017-01-07 19:16:26 +01:00
|
|
|
|
options = {
|
2017-10-06 00:15:22 +02:00
|
|
|
|
home.username = mkOption {
|
|
|
|
|
type = types.str;
|
2021-10-09 11:14:08 +02:00
|
|
|
|
defaultText = literalExpression ''
|
2020-05-24 18:08:49 +02:00
|
|
|
|
"$USER" for state version < 20.09,
|
|
|
|
|
undefined for state version ≥ 20.09
|
|
|
|
|
'';
|
|
|
|
|
example = "jane.doe";
|
2017-12-13 16:31:35 +01:00
|
|
|
|
description = "The user's username.";
|
2017-10-06 00:15:22 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
home.homeDirectory = mkOption {
|
|
|
|
|
type = types.path;
|
2021-10-09 11:14:08 +02:00
|
|
|
|
defaultText = literalExpression ''
|
2020-05-24 18:08:49 +02:00
|
|
|
|
"$HOME" for state version < 20.09,
|
|
|
|
|
undefined for state version ≥ 20.09
|
|
|
|
|
'';
|
2020-09-02 22:37:21 +02:00
|
|
|
|
apply = toString;
|
2020-05-24 18:08:49 +02:00
|
|
|
|
example = "/home/jane.doe";
|
|
|
|
|
description = "The user's home directory. Must be an absolute path.";
|
2017-10-06 00:15:22 +02:00
|
|
|
|
};
|
|
|
|
|
|
2018-07-29 18:15:50 +02:00
|
|
|
|
home.profileDirectory = mkOption {
|
|
|
|
|
type = types.path;
|
2021-11-19 22:53:48 +01:00
|
|
|
|
defaultText = literalExpression ''
|
|
|
|
|
"''${home.homeDirectory}/.nix-profile" or
|
|
|
|
|
"/etc/profiles/per-user/''${home.username}"
|
|
|
|
|
'';
|
2018-07-29 18:15:50 +02:00
|
|
|
|
readOnly = true;
|
|
|
|
|
description = ''
|
2021-11-19 22:53:48 +01:00
|
|
|
|
The profile directory where Home Manager generations are installed.
|
2018-07-29 18:15:50 +02:00
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2017-01-07 19:16:26 +01:00
|
|
|
|
home.language = mkOption {
|
|
|
|
|
type = languageSubModule;
|
|
|
|
|
default = {};
|
|
|
|
|
description = "Language configuration.";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
home.keyboard = mkOption {
|
2019-04-11 01:09:27 +02:00
|
|
|
|
type = types.nullOr keyboardSubModule;
|
2021-07-29 02:52:25 +02:00
|
|
|
|
default = if versionAtLeast stateVersion "21.11" then null else { };
|
|
|
|
|
defaultText = literalExpression ''
|
|
|
|
|
"{ }" for state version < 21.11,
|
|
|
|
|
"null" for state version ≥ 21.11
|
|
|
|
|
'';
|
2019-04-11 01:09:27 +02:00
|
|
|
|
description = ''
|
|
|
|
|
Keyboard configuration. Set to <literal>null</literal> to
|
|
|
|
|
disable Home Manager keyboard management.
|
|
|
|
|
'';
|
2017-01-07 19:16:26 +01:00
|
|
|
|
};
|
|
|
|
|
|
2021-11-06 17:10:15 +01:00
|
|
|
|
home.shellAliases = mkOption {
|
|
|
|
|
type = with types; attrsOf str;
|
|
|
|
|
default = { };
|
2021-11-07 09:10:57 +01:00
|
|
|
|
example = literalExpression ''
|
2021-11-06 17:10:15 +01:00
|
|
|
|
{
|
|
|
|
|
g = "git";
|
|
|
|
|
"..." = "cd ../..";
|
|
|
|
|
}
|
|
|
|
|
'';
|
|
|
|
|
description = ''
|
|
|
|
|
An attribute set that maps aliases (the top level attribute names
|
|
|
|
|
in this option) to command strings or directly to build outputs.
|
|
|
|
|
</para><para>
|
|
|
|
|
This option should only be used to manage simple aliases that are
|
|
|
|
|
compatible across all shells. If you need to use a shell specific
|
|
|
|
|
feature then make sure to use a shell specific option, for example
|
|
|
|
|
<xref linkend="opt-programs.bash.shellAliases"/> for Bash.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2017-01-07 19:16:26 +01:00
|
|
|
|
home.sessionVariables = mkOption {
|
|
|
|
|
default = {};
|
2022-12-29 22:33:15 +01:00
|
|
|
|
type = with types; lazyAttrsOf (oneOf [ str path int float ]);
|
2017-01-15 20:03:55 +01:00
|
|
|
|
example = { EDITOR = "emacs"; GS_OPTIONS = "-sPAPERSIZE=a4"; };
|
2017-01-16 23:54:45 +01:00
|
|
|
|
description = ''
|
|
|
|
|
Environment variables to always set at login.
|
2018-01-04 11:59:58 +01:00
|
|
|
|
</para><para>
|
2018-01-04 12:19:34 +01:00
|
|
|
|
The values may refer to other environment variables using
|
|
|
|
|
POSIX.2 style variable references. For example, a variable
|
|
|
|
|
<varname>parameter</varname> may be referenced as
|
|
|
|
|
<code>$parameter</code> or <code>''${parameter}</code>. A
|
|
|
|
|
default value <literal>foo</literal> may be given as per
|
|
|
|
|
<code>''${parameter:-foo}</code> and, similarly, an alternate
|
|
|
|
|
value <literal>bar</literal> can be given as per
|
|
|
|
|
<code>''${parameter:+bar}</code>.
|
|
|
|
|
</para><para>
|
2018-01-04 11:59:58 +01:00
|
|
|
|
Note, these variables may be set in any order so no session
|
|
|
|
|
variable may have a runtime dependency on another session
|
|
|
|
|
variable. In particular code like
|
2019-02-24 20:40:45 +01:00
|
|
|
|
<programlisting language="nix">
|
2019-04-27 00:21:18 +02:00
|
|
|
|
home.sessionVariables = {
|
|
|
|
|
FOO = "Hello";
|
|
|
|
|
BAR = "$FOO World!";
|
|
|
|
|
};
|
2018-01-04 11:59:58 +01:00
|
|
|
|
</programlisting>
|
|
|
|
|
may not work as expected. If you need to reference another
|
|
|
|
|
session variable, then do so inside Nix instead. The above
|
|
|
|
|
example then becomes
|
2019-02-24 20:40:45 +01:00
|
|
|
|
<programlisting language="nix">
|
2019-04-27 00:21:18 +02:00
|
|
|
|
home.sessionVariables = {
|
|
|
|
|
FOO = "Hello";
|
|
|
|
|
BAR = "''${config.home.sessionVariables.FOO} World!";
|
|
|
|
|
};
|
2018-01-04 11:59:58 +01:00
|
|
|
|
</programlisting>
|
2017-01-16 23:54:45 +01:00
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2020-05-30 23:16:54 +02:00
|
|
|
|
home.sessionPath = mkOption {
|
|
|
|
|
type = with types; listOf str;
|
|
|
|
|
default = [ ];
|
|
|
|
|
example = [
|
2021-10-31 11:18:28 +01:00
|
|
|
|
"$HOME/.local/bin"
|
2020-05-30 23:16:54 +02:00
|
|
|
|
"\${xdg.configHome}/emacs/bin"
|
2021-10-31 11:18:28 +01:00
|
|
|
|
".git/safe/../../bin"
|
2020-05-30 23:16:54 +02:00
|
|
|
|
];
|
2021-10-31 11:18:28 +01:00
|
|
|
|
description = ''
|
|
|
|
|
Extra directories to add to <envar>PATH</envar>.
|
|
|
|
|
|
|
|
|
|
</para><para>
|
|
|
|
|
|
|
|
|
|
These directories are added to the <envar>PATH</envar> variable in a
|
|
|
|
|
double-quoted context, so expressions like <code>$HOME</code> are
|
|
|
|
|
expanded by the shell. However, since expressions like <code>~</code> or
|
|
|
|
|
<code>*</code> are escaped, they will end up in the <envar>PATH</envar>
|
|
|
|
|
verbatim.
|
|
|
|
|
'';
|
2020-05-30 23:16:54 +02:00
|
|
|
|
};
|
|
|
|
|
|
2020-04-08 13:18:28 +02:00
|
|
|
|
home.sessionVariablesExtra = mkOption {
|
|
|
|
|
type = types.lines;
|
|
|
|
|
default = "";
|
|
|
|
|
internal = true;
|
|
|
|
|
description = ''
|
|
|
|
|
Extra configuration to add to the
|
|
|
|
|
<filename>hm-session-vars.sh</filename> file.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2017-01-07 19:16:26 +01:00
|
|
|
|
home.packages = mkOption {
|
|
|
|
|
type = types.listOf types.package;
|
|
|
|
|
default = [];
|
|
|
|
|
description = "The set of packages to appear in the user environment.";
|
|
|
|
|
};
|
|
|
|
|
|
2017-10-15 15:58:34 +02:00
|
|
|
|
home.extraOutputsToInstall = mkOption {
|
|
|
|
|
type = types.listOf types.str;
|
|
|
|
|
default = [];
|
|
|
|
|
example = [ "doc" "info" "devdoc" ];
|
|
|
|
|
description = ''
|
|
|
|
|
List of additional package outputs of the packages
|
|
|
|
|
<varname>home.packages</varname> that should be installed into
|
|
|
|
|
the user environment.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2017-01-07 19:16:26 +01:00
|
|
|
|
home.path = mkOption {
|
|
|
|
|
internal = true;
|
|
|
|
|
description = "The derivation installing the user packages.";
|
|
|
|
|
};
|
|
|
|
|
|
2017-12-11 17:03:34 +01:00
|
|
|
|
home.emptyActivationPath = mkOption {
|
|
|
|
|
internal = true;
|
|
|
|
|
type = types.bool;
|
2022-11-03 15:00:29 +01:00
|
|
|
|
default = versionAtLeast stateVersion "22.11";
|
|
|
|
|
defaultText = literalExpression ''
|
|
|
|
|
false for state version < 22.11,
|
|
|
|
|
true for state version ≥ 22.11
|
|
|
|
|
'';
|
2017-12-11 17:03:34 +01:00
|
|
|
|
description = ''
|
|
|
|
|
Whether the activation script should start with an empty
|
2022-11-03 15:00:29 +01:00
|
|
|
|
<envar>PATH</envar> variable. When <literal>false</literal> then the
|
|
|
|
|
user's <envar>PATH</envar> will be accessible in the script. It is
|
|
|
|
|
recommended to keep this at <literal>true</literal> to avoid
|
|
|
|
|
uncontrolled use of tools found in PATH.
|
2017-12-11 17:03:34 +01:00
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2017-01-07 19:16:26 +01:00
|
|
|
|
home.activation = mkOption {
|
2020-01-16 23:41:14 +01:00
|
|
|
|
type = hm.types.dagOf types.str;
|
2017-01-07 19:16:26 +01:00
|
|
|
|
default = {};
|
2021-10-09 11:14:08 +02:00
|
|
|
|
example = literalExpression ''
|
2020-01-15 20:57:06 +01:00
|
|
|
|
{
|
2020-01-16 23:41:14 +01:00
|
|
|
|
myActivationAction = lib.hm.dag.entryAfter ["writeBoundary"] '''
|
2020-01-15 20:57:06 +01:00
|
|
|
|
$DRY_RUN_CMD ln -s $VERBOSE_ARG \
|
|
|
|
|
''${builtins.toPath ./link-me-directly} $HOME
|
|
|
|
|
''';
|
|
|
|
|
}
|
|
|
|
|
'';
|
2017-01-16 00:06:27 +01:00
|
|
|
|
description = ''
|
2020-01-15 20:57:06 +01:00
|
|
|
|
The activation scripts blocks to run when activating a Home
|
|
|
|
|
Manager generation. Any entry here should be idempotent,
|
|
|
|
|
meaning running twice or more times produces the same result
|
|
|
|
|
as running it once.
|
|
|
|
|
|
|
|
|
|
</para><para>
|
|
|
|
|
|
|
|
|
|
If the script block produces any observable side effect, such
|
|
|
|
|
as writing or deleting files, then it
|
|
|
|
|
<emphasis>must</emphasis> be placed after the special
|
|
|
|
|
<literal>writeBoundary</literal> script block. Prior to the
|
|
|
|
|
write boundary one can place script blocks that verifies, but
|
|
|
|
|
does not modify, the state of the system and exits if an
|
|
|
|
|
unexpected state is found. For example, the
|
|
|
|
|
<literal>checkLinkTargets</literal> script block checks for
|
|
|
|
|
collisions between non-managed files and files defined in
|
2022-08-26 00:07:08 +02:00
|
|
|
|
<xref linkend="opt-home.file"/>.
|
2020-01-15 20:57:06 +01:00
|
|
|
|
|
2017-01-16 00:06:27 +01:00
|
|
|
|
</para><para>
|
2020-01-15 20:57:06 +01:00
|
|
|
|
|
|
|
|
|
A script block should respect the <varname>DRY_RUN</varname>
|
|
|
|
|
variable, if it is set then the actions taken by the script
|
|
|
|
|
should be logged to standard out and not actually performed.
|
2017-01-16 00:06:27 +01:00
|
|
|
|
The variable <varname>DRY_RUN_CMD</varname> is set to
|
2020-01-15 20:57:06 +01:00
|
|
|
|
<command>echo</command> if dry run is enabled.
|
|
|
|
|
|
|
|
|
|
</para><para>
|
|
|
|
|
|
|
|
|
|
A script block should also respect the
|
|
|
|
|
<varname>VERBOSE</varname> variable, and if set print
|
|
|
|
|
information on standard out that may be useful for debugging
|
|
|
|
|
any issue that may arise. The variable
|
|
|
|
|
<varname>VERBOSE_ARG</varname> is set to
|
|
|
|
|
<option>--verbose</option> if verbose output is enabled.
|
2017-01-16 00:06:27 +01:00
|
|
|
|
'';
|
2017-01-07 19:16:26 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
home.activationPackage = mkOption {
|
|
|
|
|
internal = true;
|
|
|
|
|
type = types.package;
|
|
|
|
|
description = "The package containing the complete activation script.";
|
|
|
|
|
};
|
2017-10-20 21:10:44 +02:00
|
|
|
|
|
2021-07-19 23:07:02 +02:00
|
|
|
|
home.extraActivationPath = mkOption {
|
|
|
|
|
internal = true;
|
|
|
|
|
type = types.listOf types.package;
|
|
|
|
|
default = [ ];
|
|
|
|
|
description = ''
|
|
|
|
|
Extra packages to add to <envar>PATH</envar> within the activation
|
|
|
|
|
script.
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2017-10-20 21:10:44 +02:00
|
|
|
|
home.extraBuilderCommands = mkOption {
|
|
|
|
|
type = types.lines;
|
|
|
|
|
default = "";
|
|
|
|
|
internal = true;
|
|
|
|
|
description = ''
|
|
|
|
|
Extra commands to run in the Home Manager generation builder.
|
|
|
|
|
'';
|
|
|
|
|
};
|
2018-09-14 21:08:51 +02:00
|
|
|
|
|
|
|
|
|
home.extraProfileCommands = mkOption {
|
|
|
|
|
type = types.lines;
|
|
|
|
|
default = "";
|
|
|
|
|
internal = true;
|
|
|
|
|
description = ''
|
|
|
|
|
Extra commands to run in the Home Manager profile builder.
|
|
|
|
|
'';
|
|
|
|
|
};
|
2021-07-03 00:36:30 +02:00
|
|
|
|
|
|
|
|
|
home.enableNixpkgsReleaseCheck = mkOption {
|
|
|
|
|
type = types.bool;
|
2021-11-25 17:18:08 +01:00
|
|
|
|
default = false; # Temporarily disabled until release stabilizes.
|
2021-07-03 00:36:30 +02:00
|
|
|
|
description = ''
|
|
|
|
|
Determines whether to check for release version mismatch between Home
|
|
|
|
|
Manager and Nixpkgs. Using mismatched versions is likely to cause errors
|
|
|
|
|
and unexpected behavior. It is therefore highly recommended to use a
|
|
|
|
|
release of Home Manager than corresponds with your chosen release of
|
|
|
|
|
Nixpkgs.
|
|
|
|
|
</para><para>
|
|
|
|
|
When this option is enabled and a mismatch is detected then a warning
|
|
|
|
|
will be printed when the user configuration is being built.
|
|
|
|
|
'';
|
|
|
|
|
};
|
2017-01-07 19:16:26 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
config = {
|
2017-10-06 00:15:22 +02:00
|
|
|
|
assertions = [
|
|
|
|
|
{
|
|
|
|
|
assertion = config.home.username != "";
|
|
|
|
|
message = "Username could not be determined";
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
assertion = config.home.homeDirectory != "";
|
|
|
|
|
message = "Home directory could not be determined";
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
|
2021-07-03 00:36:30 +02:00
|
|
|
|
warnings =
|
|
|
|
|
let
|
|
|
|
|
hmRelease = fileContents ../.release;
|
|
|
|
|
nixpkgsRelease = pkgs.lib.trivial.release;
|
|
|
|
|
releaseMismatch =
|
|
|
|
|
config.home.enableNixpkgsReleaseCheck
|
|
|
|
|
&& hmRelease != nixpkgsRelease;
|
|
|
|
|
in
|
|
|
|
|
optional releaseMismatch ''
|
|
|
|
|
You are using
|
|
|
|
|
|
|
|
|
|
Home Manager version ${hmRelease} and
|
|
|
|
|
Nixpkgs version ${nixpkgsRelease}.
|
|
|
|
|
|
|
|
|
|
Using mismatched versions is likely to cause errors and unexpected
|
|
|
|
|
behavior. It is therefore highly recommended to use a release of Home
|
|
|
|
|
Manager than corresponds with your chosen release of Nixpkgs.
|
|
|
|
|
|
|
|
|
|
If you insist then you can disable this warning by adding
|
|
|
|
|
|
|
|
|
|
home.enableNixpkgsReleaseCheck = false;
|
|
|
|
|
|
|
|
|
|
to your configuration.
|
|
|
|
|
'';
|
|
|
|
|
|
2020-05-24 18:08:49 +02:00
|
|
|
|
home.username =
|
|
|
|
|
mkIf (versionOlder config.home.stateVersion "20.09")
|
|
|
|
|
(mkDefault (builtins.getEnv "USER"));
|
|
|
|
|
home.homeDirectory =
|
|
|
|
|
mkIf (versionOlder config.home.stateVersion "20.09")
|
|
|
|
|
(mkDefault (builtins.getEnv "HOME"));
|
2017-10-06 00:15:22 +02:00
|
|
|
|
|
2017-12-19 15:43:40 +01:00
|
|
|
|
home.profileDirectory =
|
|
|
|
|
if config.submoduleSupport.enable
|
|
|
|
|
&& config.submoduleSupport.externalPackageInstall
|
2020-06-17 23:33:13 +02:00
|
|
|
|
then "/etc/profiles/per-user/${cfg.username}"
|
2023-04-14 22:50:39 +02:00
|
|
|
|
else if config.nix.enable && (config.nix.settings.use-xdg-base-directories or false)
|
|
|
|
|
then "${config.xdg.stateHome}/nix/profile"
|
2017-12-19 15:43:40 +01:00
|
|
|
|
else cfg.homeDirectory + "/.nix-profile";
|
2021-11-19 22:53:48 +01:00
|
|
|
|
|
2021-11-06 17:10:15 +01:00
|
|
|
|
programs.bash.shellAliases = cfg.shellAliases;
|
|
|
|
|
programs.zsh.shellAliases = cfg.shellAliases;
|
|
|
|
|
programs.fish.shellAliases = cfg.shellAliases;
|
2018-07-29 18:15:50 +02:00
|
|
|
|
|
2017-01-07 19:16:26 +01:00
|
|
|
|
home.sessionVariables =
|
|
|
|
|
let
|
2018-01-05 08:05:14 +01:00
|
|
|
|
maybeSet = n: v: optionalAttrs (v != null) { ${n} = v; };
|
2017-01-07 19:16:26 +01:00
|
|
|
|
in
|
|
|
|
|
(maybeSet "LANG" cfg.language.base)
|
|
|
|
|
//
|
2020-05-27 14:33:55 +02:00
|
|
|
|
(maybeSet "LC_CTYPE" cfg.language.ctype)
|
|
|
|
|
//
|
|
|
|
|
(maybeSet "LC_NUMERIC" cfg.language.numeric)
|
|
|
|
|
//
|
|
|
|
|
(maybeSet "LC_TIME" cfg.language.time)
|
|
|
|
|
//
|
|
|
|
|
(maybeSet "LC_COLLATE" cfg.language.collate)
|
2017-01-07 19:16:26 +01:00
|
|
|
|
//
|
|
|
|
|
(maybeSet "LC_MONETARY" cfg.language.monetary)
|
|
|
|
|
//
|
2020-05-27 14:33:55 +02:00
|
|
|
|
(maybeSet "LC_MESSAGES" cfg.language.messages)
|
|
|
|
|
//
|
2017-01-07 19:16:26 +01:00
|
|
|
|
(maybeSet "LC_PAPER" cfg.language.paper)
|
|
|
|
|
//
|
2020-05-27 14:33:55 +02:00
|
|
|
|
(maybeSet "LC_NAME" cfg.language.name)
|
|
|
|
|
//
|
|
|
|
|
(maybeSet "LC_ADDRESS" cfg.language.address)
|
|
|
|
|
//
|
|
|
|
|
(maybeSet "LC_TELEPHONE" cfg.language.telephone)
|
|
|
|
|
//
|
|
|
|
|
(maybeSet "LC_MEASUREMENT" cfg.language.measurement);
|
2017-01-07 19:16:26 +01:00
|
|
|
|
|
2018-01-04 13:15:22 +01:00
|
|
|
|
home.packages = [
|
|
|
|
|
# Provide a file holding all session variables.
|
|
|
|
|
(
|
|
|
|
|
pkgs.writeTextFile {
|
|
|
|
|
name = "hm-session-vars.sh";
|
|
|
|
|
destination = "/etc/profile.d/hm-session-vars.sh";
|
|
|
|
|
text = ''
|
|
|
|
|
# Only source this once.
|
|
|
|
|
if [ -n "$__HM_SESS_VARS_SOURCED" ]; then return; fi
|
|
|
|
|
export __HM_SESS_VARS_SOURCED=1
|
|
|
|
|
|
|
|
|
|
${config.lib.shell.exportAll cfg.sessionVariables}
|
2020-05-30 23:16:54 +02:00
|
|
|
|
'' + lib.optionalString (cfg.sessionPath != [ ]) ''
|
|
|
|
|
export PATH="$PATH''${PATH:+:}${concatStringsSep ":" cfg.sessionPath}"
|
2020-04-08 13:18:28 +02:00
|
|
|
|
'' + cfg.sessionVariablesExtra;
|
2018-01-04 13:15:22 +01:00
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
];
|
|
|
|
|
|
2017-05-04 00:36:39 +02:00
|
|
|
|
# A dummy entry acting as a boundary between the activation
|
|
|
|
|
# script's "check" and the "write" phases.
|
2020-01-16 23:41:14 +01:00
|
|
|
|
home.activation.writeBoundary = hm.dag.entryAnywhere "";
|
2017-05-04 00:36:39 +02:00
|
|
|
|
|
2017-10-14 20:56:02 +02:00
|
|
|
|
# Install packages to the user environment.
|
2017-12-19 15:43:40 +01:00
|
|
|
|
#
|
|
|
|
|
# Note, sometimes our target may not allow modification of the Nix
|
|
|
|
|
# store and then we cannot rely on `nix-env -i`. This is the case,
|
|
|
|
|
# for example, if we are running as a NixOS module and building a
|
|
|
|
|
# virtual machine. Then we must instead rely on an external
|
|
|
|
|
# mechanism for installing packages, which in NixOS is provided by
|
|
|
|
|
# the `users.users.<name?>.packages` option. The activation
|
|
|
|
|
# command is still needed since some modules need to run their
|
|
|
|
|
# activation commands after the packages are guaranteed to be
|
|
|
|
|
# installed.
|
|
|
|
|
#
|
|
|
|
|
# In case the user has moved from a user-install of Home Manager
|
|
|
|
|
# to a submodule managed one we attempt to uninstall the
|
|
|
|
|
# `home-manager-path` package if it is installed.
|
2020-01-16 23:41:14 +01:00
|
|
|
|
home.activation.installPackages = hm.dag.entryAfter ["writeBoundary"] (
|
2017-12-19 15:43:40 +01:00
|
|
|
|
if config.submoduleSupport.externalPackageInstall
|
|
|
|
|
then
|
|
|
|
|
''
|
2023-03-04 10:39:02 +01:00
|
|
|
|
if [[ -e $HOME/.nix-profile/manifest.json ]] ; then
|
2021-11-10 19:23:33 +01:00
|
|
|
|
nix profile list \
|
|
|
|
|
| { grep 'home-manager-path$' || test $? = 1; } \
|
|
|
|
|
| cut -d ' ' -f 4 \
|
|
|
|
|
| xargs -t $DRY_RUN_CMD nix profile remove $VERBOSE_ARG
|
|
|
|
|
else
|
|
|
|
|
if nix-env -q | grep '^home-manager-path$'; then
|
|
|
|
|
$DRY_RUN_CMD nix-env -e home-manager-path
|
|
|
|
|
fi
|
2017-12-19 15:43:40 +01:00
|
|
|
|
fi
|
|
|
|
|
''
|
|
|
|
|
else
|
|
|
|
|
''
|
2023-08-08 12:19:01 +02:00
|
|
|
|
function nixProfileList() {
|
|
|
|
|
# We attempt to use `--json` first (added in Nix 2.17). Otherwise attempt to
|
|
|
|
|
# parse the legacy output format.
|
|
|
|
|
{
|
|
|
|
|
nix profile list --json 2>/dev/null \
|
|
|
|
|
| jq -r --arg name "$1" '.elements[].storePaths[] | select(endswith($name))'
|
|
|
|
|
} || {
|
|
|
|
|
nix profile list \
|
|
|
|
|
| { grep "$1\$" || test $? = 1; } \
|
|
|
|
|
| cut -d ' ' -f 4
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function nixRemoveProfileByName() {
|
|
|
|
|
nixProfileList "$1" | xargs -t $DRY_RUN_CMD nix profile remove $VERBOSE_ARG
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-08 13:08:57 +02:00
|
|
|
|
function nixReplaceProfile() {
|
2022-11-01 15:51:58 +01:00
|
|
|
|
local oldNix="$(command -v nix)"
|
2022-09-08 13:08:57 +02:00
|
|
|
|
|
2023-08-08 12:19:01 +02:00
|
|
|
|
nixRemoveProfileByName 'home-manager-path'
|
2022-09-08 13:08:57 +02:00
|
|
|
|
|
|
|
|
|
$DRY_RUN_CMD $oldNix profile install $1
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-04 10:39:02 +01:00
|
|
|
|
if [[ -e $HOME/.nix-profile/manifest.json ]] ; then
|
2021-11-10 19:23:33 +01:00
|
|
|
|
INSTALL_CMD="nix profile install"
|
2022-09-08 13:08:57 +02:00
|
|
|
|
INSTALL_CMD_ACTUAL="nixReplaceProfile"
|
2021-11-10 19:23:33 +01:00
|
|
|
|
LIST_CMD="nix profile list"
|
|
|
|
|
REMOVE_CMD_SYNTAX='nix profile remove {number | store path}'
|
|
|
|
|
else
|
|
|
|
|
INSTALL_CMD="nix-env -i"
|
2022-09-08 13:08:57 +02:00
|
|
|
|
INSTALL_CMD_ACTUAL="$DRY_RUN_CMD nix-env -i"
|
2021-11-10 19:23:33 +01:00
|
|
|
|
LIST_CMD="nix-env -q"
|
|
|
|
|
REMOVE_CMD_SYNTAX='nix-env -e {package name}'
|
|
|
|
|
fi
|
|
|
|
|
|
2022-09-08 13:08:57 +02:00
|
|
|
|
if ! $INSTALL_CMD_ACTUAL ${cfg.path} ; then
|
2022-01-02 11:44:53 +01:00
|
|
|
|
echo
|
2021-11-10 19:23:33 +01:00
|
|
|
|
_iError $'Oops, Nix failed to install your new Home Manager profile!\n\nPerhaps there is a conflict with a package that was installed using\n"%s"? Try running\n\n %s\n\nand if there is a conflicting package you can remove it with\n\n %s\n\nThen try activating your Home Manager configuration again.' "$INSTALL_CMD" "$LIST_CMD" "$REMOVE_CMD_SYNTAX"
|
2021-04-29 17:53:56 +02:00
|
|
|
|
exit 1
|
|
|
|
|
fi
|
2023-08-08 12:19:01 +02:00
|
|
|
|
unset -f nixProfileList nixRemoveProfileByName nixReplaceProfile
|
2022-09-08 13:08:57 +02:00
|
|
|
|
unset INSTALL_CMD INSTALL_CMD_ACTUAL LIST_CMD REMOVE_CMD_SYNTAX
|
2017-12-19 15:43:40 +01:00
|
|
|
|
''
|
|
|
|
|
);
|
2017-01-07 19:16:26 +01:00
|
|
|
|
|
2021-04-30 01:29:39 +02:00
|
|
|
|
# Text containing Bash commands that will initialize the Home Manager Bash
|
|
|
|
|
# library. Most importantly, this will prepare for using translated strings
|
|
|
|
|
# in the `hm-modules` text domain.
|
|
|
|
|
lib.bash.initHomeManagerLib =
|
|
|
|
|
let
|
|
|
|
|
domainDir = pkgs.runCommand "hm-modules-messages" {
|
2022-04-15 02:58:15 +02:00
|
|
|
|
nativeBuildInputs = [ pkgs.buildPackages.gettext ];
|
2021-04-30 01:29:39 +02:00
|
|
|
|
} ''
|
|
|
|
|
for path in ${./po}/*.po; do
|
|
|
|
|
lang="''${path##*/}"
|
|
|
|
|
lang="''${lang%%.*}"
|
|
|
|
|
mkdir -p "$out/$lang/LC_MESSAGES"
|
|
|
|
|
msgfmt -o "$out/$lang/LC_MESSAGES/hm-modules.mo" "$path"
|
|
|
|
|
done
|
|
|
|
|
'';
|
|
|
|
|
in
|
|
|
|
|
''
|
|
|
|
|
export TEXTDOMAIN=hm-modules
|
|
|
|
|
export TEXTDOMAINDIR=${domainDir}
|
|
|
|
|
source ${../lib/bash/home-manager.sh}
|
|
|
|
|
'';
|
|
|
|
|
|
2017-01-07 19:16:26 +01:00
|
|
|
|
home.activationPackage =
|
|
|
|
|
let
|
2017-05-04 00:36:39 +02:00
|
|
|
|
mkCmd = res: ''
|
2021-04-30 01:29:39 +02:00
|
|
|
|
_iNote "Activating %s" "${res.name}"
|
2017-05-04 00:36:39 +02:00
|
|
|
|
${res.data}
|
|
|
|
|
'';
|
2020-01-16 23:41:14 +01:00
|
|
|
|
sortedCommands = hm.dag.topoSort cfg.activation;
|
2017-01-07 19:16:26 +01:00
|
|
|
|
activationCmds =
|
2017-05-04 00:36:39 +02:00
|
|
|
|
if sortedCommands ? result then
|
|
|
|
|
concatStringsSep "\n" (map mkCmd sortedCommands.result)
|
|
|
|
|
else
|
|
|
|
|
abort ("Dependency cycle in activation script: "
|
|
|
|
|
+ builtins.toJSON sortedCommands);
|
2017-01-07 19:16:26 +01:00
|
|
|
|
|
2017-10-19 22:42:35 +02:00
|
|
|
|
# Programs that always should be available on the activation
|
|
|
|
|
# script's PATH.
|
2021-07-19 23:07:02 +02:00
|
|
|
|
activationBinPaths = lib.makeBinPath (
|
2021-04-30 01:29:39 +02:00
|
|
|
|
with pkgs; [
|
|
|
|
|
bash
|
|
|
|
|
coreutils
|
|
|
|
|
diffutils # For `cmp` and `diff`.
|
|
|
|
|
findutils
|
|
|
|
|
gettext
|
|
|
|
|
gnugrep
|
|
|
|
|
gnused
|
2023-08-08 12:19:01 +02:00
|
|
|
|
jq
|
2021-04-30 01:29:39 +02:00
|
|
|
|
ncurses # For `tput`.
|
2022-11-03 15:00:29 +01:00
|
|
|
|
]
|
|
|
|
|
++ config.home.extraActivationPath
|
|
|
|
|
)
|
|
|
|
|
+ (
|
|
|
|
|
# Add path of the Nix binaries, if a Nix package is configured, then
|
|
|
|
|
# use that one, otherwise grab the path of the nix-env tool.
|
|
|
|
|
if config.nix.enable && config.nix.package != null then
|
|
|
|
|
":${config.nix.package}/bin"
|
|
|
|
|
else
|
2022-12-23 22:40:33 +01:00
|
|
|
|
":$(${pkgs.coreutils}/bin/dirname $(${pkgs.coreutils}/bin/readlink -m $(type -p nix-env)))"
|
2021-07-19 23:07:02 +02:00
|
|
|
|
)
|
2017-12-11 17:03:34 +01:00
|
|
|
|
+ optionalString (!cfg.emptyActivationPath) "\${PATH:+:}$PATH";
|
2017-10-19 22:42:35 +02:00
|
|
|
|
|
2021-05-18 00:18:57 +02:00
|
|
|
|
activationScript = pkgs.writeShellScript "activation-script" ''
|
2017-03-25 21:48:17 +01:00
|
|
|
|
set -eu
|
|
|
|
|
set -o pipefail
|
2017-01-16 20:26:42 +01:00
|
|
|
|
|
2017-10-25 18:01:23 +02:00
|
|
|
|
cd $HOME
|
|
|
|
|
|
2017-12-11 17:03:34 +01:00
|
|
|
|
export PATH="${activationBinPaths}"
|
2021-04-30 01:29:39 +02:00
|
|
|
|
${config.lib.bash.initHomeManagerLib}
|
2017-05-14 16:17:38 +02:00
|
|
|
|
|
|
|
|
|
${builtins.readFile ./lib-bash/activation-init.sh}
|
2017-01-16 00:06:27 +01:00
|
|
|
|
|
2023-05-26 15:11:22 +02:00
|
|
|
|
checkUsername ${escapeShellArg config.home.username}
|
|
|
|
|
checkHomeDirectory ${escapeShellArg config.home.homeDirectory}
|
|
|
|
|
|
2017-01-07 19:16:26 +01:00
|
|
|
|
${activationCmds}
|
|
|
|
|
'';
|
|
|
|
|
in
|
2019-03-18 01:25:14 +01:00
|
|
|
|
pkgs.runCommand
|
|
|
|
|
"home-manager-generation"
|
|
|
|
|
{
|
|
|
|
|
preferLocalBuild = true;
|
|
|
|
|
}
|
|
|
|
|
''
|
2017-11-06 10:28:48 +01:00
|
|
|
|
mkdir -p $out
|
|
|
|
|
|
2022-10-28 22:51:35 +02:00
|
|
|
|
echo "${config.home.version.full}" > $out/hm-version
|
2022-10-27 14:47:50 +02:00
|
|
|
|
|
2017-11-06 10:28:48 +01:00
|
|
|
|
cp ${activationScript} $out/activate
|
2017-01-08 22:06:53 +01:00
|
|
|
|
|
2021-04-07 19:17:39 +02:00
|
|
|
|
mkdir $out/bin
|
|
|
|
|
ln -s $out/activate $out/bin/home-manager-generation
|
|
|
|
|
|
2017-01-08 22:06:53 +01:00
|
|
|
|
substituteInPlace $out/activate \
|
|
|
|
|
--subst-var-by GENERATION_DIR $out
|
|
|
|
|
|
2017-10-05 21:38:46 +02:00
|
|
|
|
ln -s ${config.home-files} $out/home-files
|
2017-08-27 00:13:26 +02:00
|
|
|
|
ln -s ${cfg.path} $out/home-path
|
2017-10-20 21:10:44 +02:00
|
|
|
|
|
|
|
|
|
${cfg.extraBuilderCommands}
|
2017-01-07 19:16:26 +01:00
|
|
|
|
'';
|
|
|
|
|
|
|
|
|
|
home.path = pkgs.buildEnv {
|
|
|
|
|
name = "home-manager-path";
|
|
|
|
|
|
|
|
|
|
paths = cfg.packages;
|
2017-10-15 15:58:34 +02:00
|
|
|
|
inherit (cfg) extraOutputsToInstall;
|
2017-01-07 19:16:26 +01:00
|
|
|
|
|
2018-09-14 21:08:51 +02:00
|
|
|
|
postBuild = cfg.extraProfileCommands;
|
|
|
|
|
|
2017-01-07 19:16:26 +01:00
|
|
|
|
meta = {
|
|
|
|
|
description = "Environment of packages installed through home-manager";
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
}
|