All of the messiness with configuring email with Emacs reminded me that there might be a better way using Nix. Let's give it a try with some other packages.

Follow the quick install instructions to get a nix command.

Home Manager "provides a basic system for managing a user environment using the Nix package manager." I'm not sure what exactly that means over using just nix-shell, but it seems to be related to managing configuration dotfiles for the software installed using home-manager. The Home Manager manual say you can install with:

nix-shell '<home-manager>' -A install


There's also a note that we're supposed to source the

$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh  file in my shell configuration, but that this only supports Bash or ZSH, not fish. ### Fishing digression Luckily, we can use the foreign-env plugin in fish (installed using Oh My Fish), which provides an fenv function for sourcing variables using bash syntax. Now we can add a ~/.config/fish/nix.fish: if test -e '/home/shaun/.nix-profile/etc/profile.d/nix.sh' fenv source '/home/shaun/.nix-profile/etc/profile.d/nix.sh' end if test -e '/home/shaun/.nix-profile/etc/profile.d/hm-session-vars.sh' fenv source '/home/shaun/.nix-profile/etc/profile.d/hm-session-vars.sh' end  and call this from ~/.config/fish/config.fish . ~/.config/fish/nix.fish  and after restarting the fish session, the variables are set: ❯ export |grep HM_SESS __HM_SESS_VARS_SOURCED 1  Great. (There's also a ~/.nix-profile/etc/profile.d/nix-daemon.sh file too. Do I need that? Not sourcing it hasn't seemed to cause an issue yet.) ### Configuring packages with home-manager Installing home-manager created a ~/.config/nixpkgs/home.nix file. { config, pkgs, ... }: { # Let Home Manager install and manage itself. programs.home-manager.enable = true; # Home Manager needs a bit of information about you and the # paths it should manage. home.username = "shaun"; home.homeDirectory = "/home/shaun"; # 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 = "21.05"; }  Let's start with something (hopefully) simple and install Emacs, since I had been building from source to get Emacs 27. Is Emacs 27 available? ❯ nix search emacs27 * nixpkgs.emacs27 (emacs-27.1) The extensible, customizable GNU text editor * nixpkgs.emacs27-nox (emacs-nox-27.1) The extensible, customizable GNU text editor  Ok, so let's try to install it by adding the appropriate incantations to ~/.config/nixpkgs/home.nix. These "options" are documented at https://rycee.gitlab.io/home-manager/options.html. I don't know why most other tutorials don't link to this, and I only found this in a Reddit thread. The Home Manager documentation links to it in the Table of Contents, but I skipped right over it the first time. Some of the tutorials list packages in a home.packages expression, which defines " The set of packages to appear in the user environment." home.packages = with pkgs; [ emacs27 ];  This sounds reasonable. On the other hand, there's also a programs.emacs group, so I could do: programs.emacs = { enable = true; };  I tried both. That caused a conflict: ❯ home-manager switch these derivations will be built: /nix/store/1q13zc9ybdbvm918viav0v1jrlynk8q2-home-manager-path.drv /nix/store/pfcddd9ghlj7ixmcvbpkqcxysq9nl9pk-activation-script.drv /nix/store/cc09h27dkycp1jy8sprn1ng1s8y4vmx7-home-manager-generation.drv building '/nix/store/1q13zc9ybdbvm918viav0v1jrlynk8q2-home-manager-path.drv'... collision between /nix/store/m1mgx2y1drqmx90m2x6aql00biigzi89-emacs-27.1/bin/ctags' and /nix/store/26zz4k67p8rpiqsgg82dvssky3k0d49r-emacs-with-packages-27.1/bin/ctags' builder for '/nix/store/1q13zc9ybdbvm918viav0v1jrlynk8q2-home-manager-path.drv' failed with exit code 25 cannot build derivation '/nix/store/cc09h27dkycp1jy8sprn1ng1s8y4vmx7-home-manager-generation.drv': 1 dependencies couldn't be built error: build of '/nix/store/cc09h27dkycp1jy8sprn1ng1s8y4vmx7-home-manager-generation.drv' failed  For more details: ❯ home-manager switch these derivations will be built: /nix/store/1q13zc9ybdbvm918viav0v1jrlynk8q2-home-manager-path.drv /nix/store/pfcddd9ghlj7ixmcvbpkqcxysq9nl9pk-activation-script.drv /nix/store/cc09h27dkycp1jy8sprn1ng1s8y4vmx7-home-manager-generation.drv building '/nix/store/1q13zc9ybdbvm918viav0v1jrlynk8q2-home-manager-path.drv'... collision between /nix/store/m1mgx2y1drqmx90m2x6aql00biigzi89-emacs-27.1/bin/ctags' and /nix/store/26zz4k67p8rpiqsgg82dvssky3k0d49r-emacs-with-packages-27.1/bin/ctags' builder for '/nix/store/1q13zc9ybdbvm918viav0v1jrlynk8q2-home-manager-path.drv' failed with exit code 25 cannot build derivation '/nix/store/cc09h27dkycp1jy8sprn1ng1s8y4vmx7-home-manager-generation.drv': 1 dependencies couldn't be built error: build of '/nix/store/cc09h27dkycp1jy8sprn1ng1s8y4vmx7-home-manager-generation.drv' failed  Ok, so some clash between emacs-27.1 and emacs-with-packages-27.1. Let's get rid of the entry from home.packages: ❯ home-manager switch /nix/store/lidm821d00nn86im15gic2gjdh984i3w-home-manager-generation Starting home manager activation Activating checkFilesChanged Activating checkLinkTargets Activating writeBoundary Activating installPackages replacing old 'home-manager-path' installing 'home-manager-path' Activating linkGeneration Cleaning up orphan links from /home/shaun No change so reusing latest profile generation 9 Creating home file links in /home/shaun Activating onFilesChange Activating reloadSystemd  Looks promising. Let's try it: ❯ which emacs /home/shaun/.nix-profile/bin/emacs  Running emacs at the prompt starts GUI Emacs, as desired. Wonderful. Unfortunately, this new Emacs installation doesn't appear when I search for "emacs" using the Gnome Activities overlay by pressing Super. Digging around led me to some instructions on using Emacs as Default Editor, which indicated that I need an ~/.local/share/applications/emacs.desktop file. Adapting the example from that page (which was configured for EmacsClient): [Desktop Entry] Name=Emacs GenericName=Text Editor Comment=Edit text MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++; Exec=emacs Icon=emacs Type=Application Terminal=false Categories=Development;TextEditor; StartupWMClass=Emacs  And now I can launch emacs from the Activity overview, complete with an Emacs icon. It would have been nice if there was a home-manager option that would create this file, but I couldn't find one. So let's just cram it into a generic config file option: home.file:  home.file.emacsDesktop = { target = "./.local/share/applications/emacs.desktop"; text = "[Desktop Entry] Name=Emacs GenericName=Text Editor Comment=Edit text MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++; Exec=emacs Icon=emacs Type=Application Terminal=false Categories=Development;TextEditor; StartupWMClass=Emacs"; };  And it still works! This configuration process wasn't so bad. Next up, mail configuration using home-manager. ## Edit It turns out home-manager did create an emacs.desktop file, which is in ~/.nix-profile/share/applications. The problem is that my desktop environment wasn't looking for these XDG files there. I tried adding ~/.nix-profile/share/applications to XDG_DATA_DIRS using home.sessionVariables, but according to this Github thread, that's too late in the process. On the other hand, this post on the thread seemed to do what I wanted. so now home.nix includes these lines (xdg.mime.enable is true by default so unnecessary to add): xdg.enable = true; targets.genericLinux.enable = true;  And then I edited .profile to include: if [ -e /home/shaun/.nix-profile/share ] ; then XDG_DATA_DIRS="/home/shaun/.nix-profile/share:$XDG_DATA_DIRS"
fi


Log out, log in, and it works perfectly. So now I can delete the expression that manually generates the emacs.desktop file.