Home Manager
Posted on ·Table of Contents
I am going to start hacking nix code on my macbook first. Home Manager is a unobstrusive entry-point to the nix world. You need to first install nix with flakes. Use the determinate installer.
Once thats done, create a new directory in your development folder, lets
say nixhome
, and create a flake.nix
:
{
description = "Home Manager configuration";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = inputs@{ self, nixpkgs, home-manager, ... }:
let
system = "x86_64-darwin";
pkgs = nixpkgs.legacyPackages.${system};
in {
homeConfigurations."play" = home-manager.lib.homeManagerConfiguration {
inherit pkgs;
modules = [
./home.nix
];
};
};
}
and a home.nix
file:
{ config, pkgs, lib, ... }:
let
toLua = str: "\nlua << EOF\n${str}\nEOF";
toLuaFile = file: "\nlua << EOF\n${builtins.readFile file}\nEOF";
fromGitHub =
{
ref,
repo,
sha256 ? lib.fakeSha256,
}:
pkgs.vimUtils.buildVimPlugin {
pname = "${lib.strings.sanitizeDerivationName repo}";
version = ref;
src = pkgs.fetchFromGitHub {
owner = lib.strings.elemAt (lib.strings.splitString "/" repo) 0;
repo = lib.strings.elemAt (lib.strings.splitString "/" repo) 1;
rev = ref;
sha256 = sha256;
};
};
fakeVimPlugin = pkgs.runCommand "fakeVimPlugin" { } "mkdir $out";
in
{
nixpkgs = {
config = {
allowUnfree = true;
allowUnfreePredicate = (_: true);
};
};
home.username = "<username>";
home.homeDirectory = "/Users/<username>";
home.stateVersion = "24.11";
home.packages = [
pkgs.ripgrep
pkgs.neofetch
];
home.file = {
".p10k.zsh".source = ./zsh/p10k.zsh;
".config/git/message".source = ./git/message;
};
fonts.fontconfig.enable = true;
programs.home-manager.enable = true;
programs.zsh = {
enable = true;
syntaxHighlighting.enable = true;
autosuggestion.enable = true;
enableCompletion = true;
defaultKeymap = "viins";
completionInit = ''autoload -U compinit && compinit -u'';
history = {
append = true;
extended = true;
size = 10000;
save = 1000000;
};
initExtraFirst = builtins.readFile ./zsh/zshrc;
plugins = [
{
name = "zsh-powerlevel10k";
src = "${pkgs.zsh-powerlevel10k}/share/zsh-powerlevel10k/";
file = "powerlevel10k.zsh-theme";
}
];
};
programs.tmux = {
enable = true;
extraConfig = builtins.readFile ./tmux/tmux.conf;
};
programs.git = {
enable = true;
extraConfig = builtins.readFile ./git/config;
delta.enable = true;
};
programs.neovim = {
enable = true;
defaultEditor = true;
viAlias = true;
vimAlias = true;
vimdiffAlias = true;
plugins = with pkgs.vimPlugins; [
{
plugin = fakeVimPlugin;
config = toLuaFile ./nvim/base.lua;
}
plenary-nvim
which-key-nvim
copilot-vim
{
plugin = nvim-treesitter.withAllGrammars;
config = toLuaFile ./nvim/treesitter.lua;
}
{
plugin = (
fromGitHub {
ref = "HEAD";
repo = "bluz71/vim-moonfly-colors";
sha256 = "c5fxaT8Bc5MzOjJsuU95K9yzTpGqj/7QP4GuLfsY4VE=";
}
);
config = "colorscheme moonfly";
}
# Redacted list of plugins ...
];
extraPackages = with pkgs; [
gopls
pyright
];
};
}
Neovim
In the home.nix
file, you can see that we defined three functions which
are used to activate three types of vim plugins:
- Ones which do not need any further configuration, like plenary
- Ones which do need a lua config to function well, like treesitter
- Ones which do not exist on the nixpkg store currently
- Also I wanted to append these configs in the order of the plugins, and
programs.neovim.extraconfig
added the config at the end of the .vim config file. So i created a fakeVimPlugin and injected a base config in order.
Other things
Home manager has a rich set of options to explore. I am currently using also aerc and alacritty through it.
File tree
This is the final state of my flake folder:
├── flake.nix
├── flake.lock
├── git
│ ├── config
│ ├── message
├── home.nix
├── nvim
│ ├── base.lua
│ └── treesitter.lua
├── tmux
│ └── tmux.conf
└── zsh
├── p10k.zsh
└── zshrc
Commands
To apply this config, you can either just build it with the flake as an app or just use the binary in a nix-shell:
home-manager switch --flake .#play
Home manager maintains a list of generations and adds one whenever you switch to a new nix output. You can easily rollback on switches.
Future
Home manager is nice and unobtrusive piece of software which is fine for
setting up on foreign hosts. Let's move ahead and integrate home-manager
with nix-darwin
to also make system level changes.