capsule.adrianhesketh.com
Using Nix to set up my new Mac
I recently started working with a new client that uses Microsoft Teams. It's such a resource hog that I was unable to be on calls and do some programming at the same time on my 2015 13" Macbook Pro (16GB RAM), so I decided to upgrade to the latest 13" Macbook Pro which with 32GB of RAM, and 10th gen Intel processor. All-in-all, it's got around twice the single threaded performance, and twice as many CPU cores, so it's just about fast enough.
My work mostly involves using infrastructure as code to build repeatable processes, and I'm attracted to having that same capability on my desktop computer. I've been keeping my "dotfiles" configuration at [0] for a while, but I hadn't got a list of the various programs that I've added to the system using `brew` or added manually to my path, so I knew I'd lose a few programs during the move.
In my work, I move around a lot between programming languages and tools, and I'm always trying something out. This sometimes leaves me with a bunch of random programs around my disk, so a lot of the stuff that's lying around is stuff I can live without.
I saw some posts about NixOS [1] and found the idea of defining the operating system configuration in code very appealing, especially being able to roll back easily, and to create throwaway shells.
I sometimes use Docker for throwaway shells, but it's a hassle to mount volumes in and out of the container, and it can be quite tedious. I also resent the amount of RAM and CPU that Docker uses, and Brew was very slow on my old Mac, so I was looking for some extra speed there too.
When I first looked around Nix, I didn't quite get the ecosystem. The Nix package manager seems focussed on local environments, and there isn't much of a concept of an overall base system in the documentation. It turns out that I was looking for [2] to be able to configure my Mac in a similar way to NixOS.
I was able to find most of the packages I needed in Nix by using the command line search (`nix search <x>`) and to list some of the stuff I was going to migrate on my old Mac with `brew list`.
The first problem I came to was converting various examples of how to configure vim, fortunately, the community was very helpful. I nipped on to the chat at [3] and [4] gave me a few pointers that got me unstuck.
With a few more pointers from [5] and a browse of [6] I was able to get my own configuration up and running with no brew on my Mac at all.
The workflow is simple, search for missing packages with `nix search <name>`, then add it to the `darwin-configuration.nix` file, then run `darwin-rebuild switch` to update the system and use the new configuration.
The key things I needed help with were packaging vim plugins that weren't already in Nix's package list (coverage and easygrep), and installing some global python packages - answers can be found in the config below. I'm using it day-to-day now, the latest version will always be over at [7]
{ config, pkgs, ... }:
let
coverage = pkgs.vimUtils.buildVimPlugin {
name = "vim-coverage";
src = pkgs.fetchFromGitHub {
owner = "ruanyl";
repo = "coverage.vim";
rev = "1d4cd01e1e99d567b640004a8122be8105046921";
sha256 = "1vr6ylppwd61rj0l7m6xb0scrld91wgqm0bvnxs54b20vjbqcsap";
};
};
easygrep = pkgs.vimUtils.buildVimPlugin {
name = "vim-easygrep";
src = pkgs.fetchFromGitHub {
owner = "dkprice";
repo = "vim-easygrep";
rev = "d0c36a77cc63c22648e792796b1815b44164653a";
sha256 = "0y2p5mz0d5fhg6n68lhfhl8p4mlwkb82q337c22djs4w5zyzggbc";
};
};
python-with-global-packages = pkgs.python3.withPackages(ps: with ps; [
pip
botocore
]);
in
{
environment.variables = { EDITOR = "vim"; };
# List packages installed in system profile. To search by name, run:
# $ nix-env -qaP | grep wget
environment.systemPackages =
[
python-with-global-packages
pkgs.asciinema
pkgs.awscli
pkgs.docker
pkgs.fzf
pkgs.git
pkgs.gitAndTools.gh
pkgs.gnupg
pkgs.go
pkgs.gopass
pkgs.graphviz
pkgs.htop
pkgs.hugo
pkgs.jq
pkgs.lynx
pkgs.musescore
pkgs.nmap
pkgs.nodejs
pkgs.nodePackages.typescript
pkgs.nodePackages.serverless
pkgs.ripgrep
pkgs.terraform
pkgs.tmux
pkgs.tree
pkgs.unzip
pkgs.vscode
pkgs.wget
pkgs.yarn
pkgs.zip
(
pkgs.neovim.override {
vimAlias = true;
configure = {
packages.myPlugins = with pkgs.vimPlugins; {
start = [
vim-go
vim-lastplace
vim-nix
coc-nvim
coc-tsserver # neoclide/coc-tsserver
coc-yaml
coc-json
nerdcommenter #preservim/nerdcommenter
ctrlp #ctrlpvim/ctrlp.vim
vim-sleuth #tpope/vim-sleuth
vim-surround #tpope/vim-surround
vim-test #janko/vim-test
coverage #ruanyl/coverage.vim
ultisnips #SirVer/ultisnips
vim-snippets #honza/vim-snippets
easygrep #dkprice/vim-easygrep
];
opt = [];
};
customRC = builtins.readFile ./../dotfiles/.vimrc;
};
}
)
];
# Create /etc/bashrc that loads the nix-darwin environment.
programs.zsh.enable = true; # default shell on catalina
# Used for backwards compatibility, please read the changelog before changing.
system.stateVersion = 4;
nixpkgs.config.allowUnfree = true;
}