[[ch-usage]]
== Using Home Manager

Your use of Home Manager is centered around the configuration file,
which is typically found at `~/.config/home-manager/home.nix` in the standard installation
or `~/.config/home-manager/flake.nix` in a Nix flake based installation.

[NOTE]
The default configuration used to be placed in `~/.config/nixpkgs`¸
so you may see references to that elsewhere.
The old directory still works but Home Manager will print a warning message when used.

This configuration file can be _built_ and _activated_.

Building a configuration produces a directory in the Nix store that contains all files and programs that should be available in your home directory and Nix user profile, respectively. The build step also checks that the configuration is valid and it will fail with an error if you, for example, assign a value to an option that does not exist or assign a value of the wrong type. Some modules also have custom assertions that perform more detailed, module specific, checks.

Concretely, if your configuration contains

[source,nix]
programs.emacs.enable = "yes";

then building it, for example using `home-manager build`, will result in an error message saying something like

[source,console]
----
$ home-manager build
error: A definition for option `programs.emacs.enable' is not of type `boolean'. Definition values:
- In `/home/jdoe/.config/home-manager/home.nix': "yes"
(use '--show-trace' to show detailed location information)
----

The message indicates that you must provide a Boolean value for this option, that is, either `true` or `false`. The documentation of each option will state the expected type, for <<opt-programs.emacs.enable>> you will see ``Type: boolean''. You there also find information about the default value and a description of the option. You can find the complete option documentation in <<ch-options>> or directly in the terminal by running

[source,console]
man home-configuration.nix

Once a configuration is successfully built, it can be activated. The activation performs the steps necessary to make the files, programs, and services available in your user environment. The `home-manager switch` command performs a combined build and activation.

[[sec-usage-configuration]]
=== Configuration Example

A fresh install of Home Manager will generate a minimal `~/.config/home-manager/home.nix` file containing something like

[source,nix]
----
{ config, pkgs, ... }:

{
  # Home Manager needs a bit of information about you and the
  # paths it should manage.
  home.username = "jdoe";
  home.homeDirectory = "/home/jdoe";

  # This value determines the Home Manager release that your
  # configuration is compatible with. This helps avoid breakage
  # when a new Home Manager release introduces backwards
  # incompatible changes.
  #
  # You can update Home Manager without changing this value. See
  # the Home Manager release notes for a list of state version
  # changes in each release.
  home.stateVersion = "22.11";

  # Let Home Manager install and manage itself.
  programs.home-manager.enable = true;
}
----

You can use this as a base for your further configurations.

[NOTE]
If you are not very familiar with the Nix language and NixOS modules then it is encouraged to start with small and simple changes. As you learn you can gradually grow the configuration with confidence.

As an example, let us expand the initial configuration file to also install the htop and fortune packages, install Emacs with a few extra packages available, and enable the user gpg-agent service.

To satisfy the above setup we should elaborate the `home.nix` file as follows:

[source,nix]
----
{ config, pkgs, ... }:

{
  # Home Manager needs a bit of information about you and the
  # paths it should manage.
  home.username = "jdoe";
  home.homeDirectory = "/home/jdoe";

  # Packages that should be installed to the user profile.
  home.packages = [                               <1>
    pkgs.htop
    pkgs.fortune
  ];

  # This value determines the Home Manager release that your
  # configuration is compatible with. This helps avoid breakage
  # when a new Home Manager release introduces backwards
  # incompatible changes.
  #
  # You can update Home Manager without changing this value. See
  # the Home Manager release notes for a list of state version
  # changes in each release.
  home.stateVersion = "22.11";

  # Let Home Manager install and manage itself.
  programs.home-manager.enable = true;

  programs.emacs = {                              <2>
    enable = true;
    extraPackages = epkgs: [
      epkgs.nix-mode
      epkgs.magit
    ];
  };

  services.gpg-agent = {                          <3>
    enable = true;
    defaultCacheTtl = 1800;
    enableSshSupport = true;
  };
}
----
<1> Nixpkgs packages can be installed to the user profile using <<opt-home.packages>>.
<2> The option names of a program module typically start with `programs.<package name>`.
<3> Similarly, for a service module, the names start with `services.<package name>`. Note in some cases a package has both programs _and_ service options – Emacs is such an example.

To activate this configuration you can run

[source,console]
home-manager switch

or if you are not feeling so lucky,

[source,console]
home-manager build

which will create a `result` link to a directory containing an
activation script and the generated home directory files.

[[sec-usage-rollbacks]]
=== Rollbacks

While the `home-manager` tool does not explicitly support rollbacks at the moment it is relatively easy to perform one manually. The steps to do so are

1.  Run `home-manager generations` to determine which generation you wish to rollback to:
+
[source,console]
----
$ home-manager generations
2018-01-04 11:56 : id 765 -> /nix/store/kahm1rxk77mnvd2l8pfvd4jkkffk5ijk-home-manager-generation
2018-01-03 10:29 : id 764 -> /nix/store/2wsmsliqr5yynqkdyjzb1y57pr5q2lsj-home-manager-generation
2018-01-01 12:21 : id 763 -> /nix/store/mv960kl9chn2lal5q8lnqdp1ygxngcd1-home-manager-generation
2017-12-29 21:03 : id 762 -> /nix/store/6c0k1r03fxckql4vgqcn9ccb616ynb94-home-manager-generation
2017-12-25 18:51 : id 761 -> /nix/store/czc5y6vi1rvnkfv83cs3rn84jarcgsgh-home-manager-generation
…
----

2.  Copy the Nix store path of the generation you chose, e.g.,
+
----
/nix/store/mv960kl9chn2lal5q8lnqdp1ygxngcd1-home-manager-generation
----
+
for generation 763.

3.  Run the `activate` script inside the copied store path:
+
[source,console]
----
$ /nix/store/mv960kl9chn2lal5q8lnqdp1ygxngcd1-home-manager-generation/activate
Starting home manager activation
…
----

[[sec-usage-dotfiles]]
=== Keeping your ~ safe from harm

To configure programs and services Home Manager must write various things to your home directory. To prevent overwriting any existing files when switching to a new generation, Home Manager will attempt to detect collisions between existing files and generated files. If any such collision is detected the activation will terminate before changing anything on your computer.

For example, suppose you have a wonderful, painstakingly created `~/.config/git/config` and add

[source,nix]
----
{
  # …

  programs.git = {
    enable = true;
    userName = "Jane Doe";
    userEmail = "jane.doe@example.org";
  };

  # …
}
----

to your configuration. Attempting to switch to the generation will then result in

[source,console]
----
$ home-manager switch
…
Activating checkLinkTargets
Existing file '/home/jdoe/.config/git/config' is in the way
Please move the above files and try again
----

[[sec-usage-graphical]]
=== Graphical services

Home Manager includes a number of services intended to run in a graphical session, for example `xscreensaver` and `dunst`. Unfortunately, such services will not be started automatically unless you let Home Manager start your X session. That is, you have something like

[source,nix]
----
{
  # …

  services.xserver.enable = true;

  # …
}
----

in your system configuration and

[source,nix]
----
{
  # …

  xsession.enable = true;
  xsession.windowManager.command = "…";

  # …
}
----

in your Home Manager configuration.

[[sec-updating]]
=== Updating

If you have installed Home Manager using the Nix channel method
then updating Home Manager is done by first updating the channel.
You can then switch to the updated Home Manager environment.

[source,console]
----
$ nix-channel --update
…
unpacking channels...
$ home-manager switch
----
