dustinlacewell's dotfiles

Table of Contents

This repository contains the sources for deploying my personal workstation environment on OSX.

The repository is deployed with home-manager which is built on Nix.

Quickstart

Install Nix

Install the Nix package manager to your workstation:

curl https://nixos.org/nix/install | sh

This will create /nix as well as some system-wide profile scripts which will integrate your shell with Nix.

Clone this repository

Clone this repo to $HOME/.config/nixpkgs/:

git clone https://github.com/dustinlacewell/dotfiles.git ~/.config/nixpkgs

Symlink hm script

Symlink the bin/hm script somewhere on your $PATH:

ln -s ~/.config/nixpkgs/bin/hm ~/bin/hm

(make sure $HOME/bin is on your $PATH!)

Protect your Secrets

So that you don't need to keep secrets in your configuration hm will source $HOME/.secrets. This file should export any environment variables that you utilize while building your configuration.

This file should probably not directly contain your secrets. We recommend instead, utilizing a a tool to manage your secrets. The tool can be used to interpolate secret values when the file is sourced. Some options might be:

Using hm

A wrapper-script $HOME/.config/nixpkgs/bin/hm is provided which you should symlink somewhere on your path:

usage: hm <command> <env>

Commands:
build  - build env to ./result/
switch - build env to ~/

Environments:
Loads ~/.config/nixpkgs/envs/<env>.nix

Building

To perform a dry-run use the build command. It creates a ./result/ directory with the files that would be symlinked into your home directory:

#> hm build osx

...
#> tree ./result/

./result/
├── activate
├── home-files -> /nix/store/5x3dxzivrnh0lks5sc3fgfkcg4884xb1-home-manager-files
└── home-path -> /nix/store/2scx60dwvx9fvi55cwcjmg39gd2ymvvl-home-manager-path

2 directories, 1 file

Switching

Once you're satisfied with the dry-run output, use the switch command to actually install symlinks into your home directory.

#> hm switch osx

...
#> find ~/ -type l -ls | grep "nix/store"

lrwxr-xr-x ~/.config/zsh/.zshenv -> /nix/store/5x3dxzivrnh0lks5sc3fgfkcg4884xb1-home-manager-files/.config/zsh/.zshenv
lrwxr-xr-x ~/.config/zsh/.zshrc -> /nix/store/5x3dxzivrnh0lks5sc3fgfkcg4884xb1-home-manager-files/.config/zsh/.zshrc
lrwxr-xr-x ~/.emacs.d/init.el -> /nix/store/5x3dxzivrnh0lks5sc3fgfkcg4884xb1-home-manager-files/.emacs.d/init.el
lrwxr-xr-x ~/.emacs.d/init.html -> /nix/store/5x3dxzivrnh0lks5sc3fgfkcg4884xb1-home-manager-files/.emacs.d/init.html
lrwxr-xr-x ~/.ssh/config -> /nix/store/5x3dxzivrnh0lks5sc3fgfkcg4884xb1-home-manager-files/.ssh/config
lrwxr-xr-x ~/.zshenv -> /nix/store/5x3dxzivrnh0lks5sc3fgfkcg4884xb1-home-manager-files/.zshenv

Plugins

Plugins are defined in $HOME/.config/nixpkgs/plugins.nix.

This expression contains a simple attrset. Each attribute is the name of a plugin. Its value should be a NixOS package. The package can be fetched dynamically using any of the following helpers:

pkgs.fetchFromBitbucket  pkgs.fetchFromGitHub
pkgs.fetchFromGitLab     pkgs.fetchFromRepoOrCz
pkgs.fetchFromSavannah   pkgs.fetchHex
pkgs.fetchMavenArtifact  pkgs.fetchNuGet
pkgs.fetchRepoProject    pkgs.fetchadc
pkgs.fetchbower          pkgs.fetchbzr
pkgs.fetchcvs            pkgs.fetchdarcs
pkgs.fetchegg            pkgs.fetchfossil
pkgs.fetchgit            pkgs.fetchgitLocal
pkgs.fetchgitPrivate     pkgs.fetchgitrevision
pkgs.fetchgx             pkgs.fetchhg
pkgs.fetchmail           pkgs.fetchmtn
pkgs.fetchpatch          pkgs.fetchs3
pkgs.fetchsvn            pkgs.fetchsvnrevision
pkgs.fetchsvnssh         pkgs.fetchurl
pkgs.fetchurlBoot        pkgs.fetchzip

Envfiles

Envfiles are a top-level Nix expressions that live in $HOME/.config/nixpkgs/envs/.

Their job is to import the other expressions which make up the environment. You can have multiple envfiles, one for each unique environment. Take look at envs/osx.nix to see how I write mine:

{
  imports = [
    ../src/ssh
    ../src/emacs
    ../src/zsh
    ../src/httpie
    ../src/aws
    ../src/fasd
  ];
}

The expression is an attrset. The only attribute is imports set to a list of paths of other expressions to load.

Expression Sources

Expression Sources are Nix expressions that actually make up your configuration. I organize these underneath $HOME/.config/nixpkgs/src/. For each tool I typically create a folder with a default.nix and any data files.

This is src/emacs/default.nix at the time of this writing:

{ pkgs, ... }: ①

let
  plugins = import <plugins>; ②

in {
  imports = [ ③
    plugins.org-build
    plugins.org-export
  ];

  programs.emacs = { enable = true; }; ④

  home.file.".emacs.d/init.el".source = pkgs.org-build { ⑤
    source = ./init.org;
  };

  home.file.".emacs.d/init.html".source = pkgs.org-export { ⑥
    source = ./init.org;
    user = "dustinlacewell";
    repo = "emacs.d";
  };
}

① Module function

The module is expressed as a function that accepts pkgs and returns an attrset.

② Import plugins.nix

The expression at $HOME/.config/nixpkgs/plugins.nix is imported so that we can refer to the plugin packages.

③ Add plugins to imports

One of the attributes of our module's returned attrset is imports. This takes a list of modules that should be merged by the module system. This has the effect of making available any Options declared or defined by the plugins. It also makes any package overrides provided by the plugins available under pkgs.

④ Install Emacs

This line declares the programs.emacs.enable option to be true. This will ensure Emacs gets installed the Nix profile.

⑤ Build init.org

Emacs configuration is done with Emacs-Lisp. But I choose to write my configuration as an Orgmode document. This section calls pkgs.org-build function which builds an Orgmode document into Emacs-Lisp. This returns the path of the built .el file in the store. We assign that to home.file.".emacs.d/init.el".source which will cause the file to be symlinked into our home directory.

⑥ Export init.org

Similar to ⑤ this calls a plugin function. This time it is pkgs.org-export which builds init.org as HTML. This line writes out the HTML file to .emacs.d/init.html but org-export will also publish the HTML file to http://dustinlacewell.github.com/emacs.d/

Author: Dustin Lacewell

Created: 2017-10-24 Tue 18:06

Emacs 25.3.1 (Org mode 8.2.10)

Validate