summary refs log tree commit diff stats
path: root/user/settings
diff options
context:
space:
mode:
Diffstat (limited to 'user/settings')
-rw-r--r--user/settings/autorandr.nix8
-rw-r--r--user/settings/base.nix31
-rw-r--r--user/settings/darwin.nix49
-rw-r--r--user/settings/development/base.nix29
-rw-r--r--user/settings/development/lisp.nix13
-rw-r--r--user/settings/dunst.nix57
-rw-r--r--user/settings/emacs.nix169
-rw-r--r--user/settings/gaming.nix45
-rw-r--r--user/settings/git.nix77
-rw-r--r--user/settings/gnupg.nix8
-rw-r--r--user/settings/i3.nix149
-rw-r--r--user/settings/isync.nix5
-rw-r--r--user/settings/javascript.nix59
-rw-r--r--user/settings/ledger.nix8
-rw-r--r--user/settings/msmtp.nix5
-rw-r--r--user/settings/nix.nix5
-rw-r--r--user/settings/nixos.nix21
-rw-r--r--user/settings/nixpkgs.nix12
-rw-r--r--user/settings/passwords.nix10
-rw-r--r--user/settings/rofi.nix25
-rw-r--r--user/settings/satoshipay.nix55
-rw-r--r--user/settings/sxhkd.nix29
-rw-r--r--user/settings/tabnine.nix57
-rw-r--r--user/settings/trezor.nix9
-rw-r--r--user/settings/user-interface.nix17
-rw-r--r--user/settings/xresources.nix8
-rw-r--r--user/settings/zsh.nix181
27 files changed, 1141 insertions, 0 deletions
diff --git a/user/settings/autorandr.nix b/user/settings/autorandr.nix
new file mode 100644
index 00000000..f63095a4
--- /dev/null
+++ b/user/settings/autorandr.nix
@@ -0,0 +1,8 @@
+{ config, pkgs, ... }:
+
+{
+  xdg.configFile.autorandr = {
+    recursive = true;
+    source = ../autorandr/.config/autorandr;
+  };
+}
diff --git a/user/settings/base.nix b/user/settings/base.nix
new file mode 100644
index 00000000..cc83cb47
--- /dev/null
+++ b/user/settings/base.nix
@@ -0,0 +1,31 @@
+{ config, pkgs, ... }:
+
+{
+  # Let Home Manager install and manage itself.
+  programs.home-manager.enable = true;
+  manual = {
+    html.enable = true;
+  };
+  home.packages = with pkgs; [
+    pv
+    fd
+    unstable.sd
+    entr
+    file
+    htop
+    lsof
+    iftop
+    nmap
+    moreutils
+    mtr
+    tree
+    zip
+    telnet
+  ] ++ (
+  if !stdenv.isDarwin
+  then [
+    vim
+    unar
+  ] else [
+  ]);
+}
diff --git a/user/settings/darwin.nix b/user/settings/darwin.nix
new file mode 100644
index 00000000..b3c4d7d7
--- /dev/null
+++ b/user/settings/darwin.nix
@@ -0,0 +1,49 @@
+{ config, pkgs, ... }:
+
+{
+  nixpkgs.overlays = [
+    (self: super: {
+      darwin-zsh-completions = super.runCommandNoCC "darwin-zsh-completions-0.0.0"
+        { preferLocalBuild = true; }
+        ''
+          mkdir -p $out/share/zsh/site-functions
+          cat <<-'EOF' > $out/share/zsh/site-functions/_darwin-rebuild
+          #compdef darwin-rebuild
+          #autoload
+          _nix-common-options
+          local -a _1st_arguments
+          _1st_arguments=(
+            'switch:Build, activate, and update the current generation'\
+            'build:Build without activating or updating the current generation'\
+            'check:Build and run the activation sanity checks'\
+            'changelog:Show most recent entries in the changelog'\
+          )
+          _arguments \
+            '--list-generations[Print a list of all generations in the active profile]'\
+            '--rollback[Roll back to the previous configuration]'\
+            {--switch-generation,-G}'[Activate specified generation]'\
+            '(--profile-name -p)'{--profile-name,-p}'[Profile to use to track current and previous system configurations]:Profile:_nix_profiles'\
+            '1:: :->subcmds' && return 0
+          case $state in
+            subcmds)
+              _describe -t commands 'darwin-rebuild subcommands' _1st_arguments
+            ;;
+          esac
+          EOF
+        '';
+      })
+  ];
+  home.packages = with pkgs; [
+      aspell
+      aspellDicts.en
+      darwin-zsh-completions
+  ];
+
+  programs.zsh.shellAliases = {
+    da = "darwin-rebuild";
+    das = "darwin-rebuild switch";
+  };
+
+  # Use GPG from  GPGTools
+  programs.git.signing.gpgPath = "/usr/local/bin/gpg";
+}
diff --git a/user/settings/development/base.nix b/user/settings/development/base.nix
new file mode 100644
index 00000000..3ea20fc1
--- /dev/null
+++ b/user/settings/development/base.nix
@@ -0,0 +1,29 @@
+{ config, pkgs, ... }:
+
+{ home.packages = with pkgs; [
+    checkbashisms
+    editorconfig-core-c
+    go
+
+    mosh
+
+    wrk
+
+    ag
+    (ripgrep.override { withPCRE2 = true; })
+
+    httpie
+    jq
+
+    discount
+  ] ++ (
+    if !stdenv.isDarwin
+    then [
+      ldns
+      httping
+      http-prompt
+      firefox-devedition-bin
+    ] else [
+    ]
+  );
+}
diff --git a/user/settings/development/lisp.nix b/user/settings/development/lisp.nix
new file mode 100644
index 00000000..b8d465ee
--- /dev/null
+++ b/user/settings/development/lisp.nix
@@ -0,0 +1,13 @@
+{ config, pkgs, ... }:
+
+{ home.packages = with pkgs; [
+    ccl
+    sbcl
+    lispPackages.quicklisp
+    asdf
+    cl-launch
+
+    dust
+    pixie
+  ];
+}
diff --git a/user/settings/dunst.nix b/user/settings/dunst.nix
new file mode 100644
index 00000000..6d74b51b
--- /dev/null
+++ b/user/settings/dunst.nix
@@ -0,0 +1,57 @@
+{ config, pkgs, ... }:
+
+{
+  services.dunst = {
+    enable = true;
+    settings = {
+      global = {
+        font = "Monospace 13";
+        geometry = "300x10-10+30";
+        follow = "none";
+        sticky_history = "yes";
+        history_length = 20;
+        show_indicators = "yes";
+        separator_height = 2;
+        padding = 8;
+        horizontal_padding = 8;
+        idle_threshold = 30;
+
+        indicate_hidden = "no";
+
+        allow_markup = "yes";
+        format = "<b>%s</b>\n%b";
+        word_wrap = "yes";
+        ignore_newline = "no";
+
+        separator_color = "frame";
+      };
+      frame = {
+        width = 1;
+        color = "#383838";
+      };
+      shortcuts = {
+        close = "mod4+apostrophe";
+        close_all = "mod4+shift+apostrophe";
+        history = "mod4+grave";
+        context = "mod4+shift+period";
+      };
+      urgency_low = {
+        background = "#b8b8b8";
+        foreground = "#f8f8f8";
+        timeout = 10;
+      };
+
+      urgency_normal = {
+        background = "#7cafc2";
+        foreground = "#f8f8f8";
+        timeout = 10;
+      };
+
+      urgency_critical = {
+        background = "#ab4642";
+        foreground = "#f8f8f8";
+        timeout = 0;
+      };
+    };
+  };
+}
diff --git a/user/settings/emacs.nix b/user/settings/emacs.nix
new file mode 100644
index 00000000..9f542391
--- /dev/null
+++ b/user/settings/emacs.nix
@@ -0,0 +1,169 @@
+{ config, pkgs, lib, ... }:
+
+let
+  inherit (pkgs) stdenv;
+
+  pkgsUnstable = if stdenv.isDarwin then import <nixpkgs> {} else import <nixos-unstable> {};
+
+  editorScript = pkgs.writeScriptBin "edit" ''
+    #!${pkgs.runtimeShell}
+    if [ -z "$1" ]; then
+      exec ${config.programs.emacs.finalPackage}/bin/emacsclient --create-frame --alternate-editor ${config.programs.emacs.finalPackage}/bin/emacs
+    else
+      exec ${config.programs.emacs.finalPackage}/bin/emacsclient --alternate-editor ${config.programs.emacs.finalPackage}/bin/emacs "$@"
+    fi
+  '';
+  desktopApplicationFile = pkgs.writeTextFile {
+    name = "emacsclient.desktop";
+    destination = "/share/applications/emacsclient.desktop";
+    text = ''
+      [Desktop Entry]
+      Name=Emacsclient
+      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=${editorScript}/bin/edit %F
+      Icon=emacs
+      Type=Application
+      Terminal=false
+      Categories=Development;TextEditor;
+      StartupWMClass=Emacs
+      Keywords=Text;Editor;
+    '';
+  };
+in
+{
+  programs.emacs = {
+    enable = true;
+    extraPackages = epkgs: (with epkgs; [
+      ace-link
+      all-the-icons
+      almost-mono-themes
+      add-node-modules-path
+      ag
+      all-the-icons
+      amx
+      auto-async-byte-compile
+      avy
+      basic-theme
+      bash-completion
+      caddyfile-mode
+      company
+      company-web
+      company-tabnine
+      counsel
+      counsel-projectile
+      crux
+      docker-compose-mode
+      dockerfile-mode
+      dired-git-info
+      editorconfig
+      eink-theme
+      eldoc-box
+      emmet-mode
+      esh-autosuggest
+      esh-buf-stack
+      esh-help
+      eshell-fringe-status
+      eshell-toggle
+      eshell-up
+      evil
+      evil-collection
+      evil-commentary
+      evil-magit
+      evil-mu4e
+      evil-org
+      evil-quickscope
+      evil-space
+      evil-surround
+      eyebrowse
+      feature-mode
+      fish-completion
+      flycheck
+      flymake-diagnostic-at-point
+      general
+      git-gutter-fringe
+      git-messenger
+      git-timemachine
+      gitattributes-mode
+      gitconfig-mode
+      gitignore-mode
+      gitlab-ci-mode
+      gitlab-ci-mode-flycheck
+      goto-chg
+      haskell-mode
+      helpful
+      ivy-hydra
+      jinja2-mode
+      js2-mode
+      json-mode
+      k8s-mode
+      # kubernetes
+      # kubernetes-evil
+      ledger-mode
+      lsp-mode
+      lsp-ui
+      lsp-haskell
+      lsp-treemacs
+      magit
+      markdown-mode
+      minions
+      monotropic-theme
+      moody
+      nginx-mode
+      nix-mode
+      nix-update
+      org-journal
+      paredit
+      php-mode
+      posframe
+      prettier-js
+      projectile
+      projectile-ripgrep
+      quickrun
+      rainbow-mode
+      relative-buffers
+      restclient
+      ripgrep
+      rjsx-mode
+      scss-mode
+      spacemacs-theme
+      swiper
+      toml-mode
+      typescript-mode
+      undo-tree
+      use-package
+      web-mode
+      wgrep-ag
+      ws-butler
+      which-key
+      yaml-mode
+    ] ++ lib.optionals (!stdenv.isDarwin) [
+      pkgs.mu
+    ]);
+  };
+  home.packages = [
+    editorScript
+  ];
+  nixpkgs.overlays = [
+    (self: super: {
+      emacsPackagesNgGen = pkgsUnstable.emacsPackagesNgGen;
+      emacs = pkgsUnstable.emacs;
+    })
+  ];
+  home.sessionVariables = {
+    EDITOR = "${editorScript}/bin/edit";
+  };
+  home.file.".emacs.d/init.el" = {
+    source = ../emacs/.emacs.d/init.el;
+    onChange = ''
+      ${config.programs.emacs.finalPackage}/bin/emacs -batch -f batch-byte-compile .emacs.d/init.el
+    '';
+  };
+  home.file.".emacs.d/eshell/" = {
+    recursive = true;
+    source = ../emacs/.emacs.d/eshell;
+  };
+
+  home.file.".local/share/applications/emacsclient.desktop".source = desktopApplicationFile;
+}
diff --git a/user/settings/gaming.nix b/user/settings/gaming.nix
new file mode 100644
index 00000000..022846ca
--- /dev/null
+++ b/user/settings/gaming.nix
@@ -0,0 +1,45 @@
+{ config, pkgs, ... }:
+
+{
+  home.packages = with pkgs; [
+    unstable.steam
+    (
+      unstable.winePackages.unstable.override {
+        pngSupport = true;
+        jpegSupport = true;
+        tiffSupport = true;
+        gettextSupport = true;
+        fontconfigSupport = true;
+        alsaSupport = true;
+        gtkSupport = true;
+        openglSupport = true;
+        tlsSupport = true;
+        gstreamerSupport = true;
+        cupsSupport = true;
+        colorManagementSupport = true;
+        dbusSupport = true;
+        mpg123Support = true;
+        openalSupport = true;
+        openclSupport = true;
+        cairoSupport = true;
+        odbcSupport = true;
+        netapiSupport = true;
+        cursesSupport = true;
+        vaSupport = true;
+        pcapSupport = true;
+        v4lSupport = true;
+        saneSupport = true;
+        gsmSupport = true;
+        gphoto2Support = true;
+        ldapSupport = true;
+        pulseaudioSupport = true;
+        udevSupport = true;
+        xineramaSupport = true;
+        xmlSupport = true;
+        vulkanSupport = true;
+        sdlSupport = true;
+      }
+    )
+    unstable.lutris
+  ];
+}
diff --git a/user/settings/git.nix b/user/settings/git.nix
new file mode 100644
index 00000000..503b9e3f
--- /dev/null
+++ b/user/settings/git.nix
@@ -0,0 +1,77 @@
+{ config, pkgs, ... }:
+
+{
+  home.packages = with pkgs; [
+    gitAndTools.git-extras
+  ];
+  programs.git = {
+    enable = true;
+    userName = "Alan Pearce";
+    userEmail = "alan@alanpearce.eu";
+    extraConfig = {
+      pull = {
+        rebase = true;
+      };
+      push = {
+        default = "current";
+        followTags = true;
+      };
+      rebase = {
+        autosquash = true;
+      };
+      rerere = {
+        enable = true;
+      };
+      diff = {
+        algorithm = "patience";
+        tool = "icdiff";
+      };
+      difftool = {
+        prompt = false;
+      };
+      "difftool.icdiff" = {
+        cmd = "${pkgs.icdiff}/bin/icdiff --line-numbers $LOCAL $REMOTE";
+      };
+      "difftool.sopsdiffer" = {
+        textconf = "${pkgs.sops}/bin/sops -d";
+      };
+      "merge.npm-merge-driver" = {
+        name = "automatically merge npm lockfiles";
+        driver = "npx npm-merge-driver merge %A %O %B %P";
+      };
+      remote = {
+        autoSetupMerge = true;
+      };
+      "branch.master" = {
+        rebase = false;
+      };
+    };
+    signing = {
+      key = "0xCD4BEB92A8D46583";
+    };
+    lfs = {
+      enable = true;
+    };
+    aliases = {
+      authors = "shortlog -s -n";
+      mup = "merge FETCH_HEAD";
+      rup = "rebase FETCH_HEAD";
+      st = "status -sb";
+      ci = "commit";
+      br = "branch";
+      co = "checkout";
+      lasttag = "!sh -c 'git tag --sort=version:refname | grep \"^v\\\\?[0-9]\" | tail -n1'";
+      pending = "!sh -c 'git log --oneline --grep=\"#\" ...$(git lasttag)'";
+      lg = "log --pretty=format:'%Cred%h%Creset -%Creset %s %Cgreen(%cr) %C(bold blue)<%an> %Cred%d%Creset'";
+      prl = "log --pretty=format:'%Cred%h%Creset -%Creset %s %Cgreen(%cr) %C(bold blue)<%an> %Cred%d%Creset'  --grep='#'";
+      ignored = "ls-files --others -i --exclude-standard";
+    };
+    ignores = [
+      ".DS_Store"
+      "*_flymake.*"
+      "*~"
+      "\#*\#"
+      ".\#*"
+    ];
+  };
+}
diff --git a/user/settings/gnupg.nix b/user/settings/gnupg.nix
new file mode 100644
index 00000000..6dcb31f2
--- /dev/null
+++ b/user/settings/gnupg.nix
@@ -0,0 +1,8 @@
+{ config, pkgs, ... }:
+
+{
+  home.file.".gnupg" = {
+    recursive = true;
+    source = ../gnupg/.gnupg;
+  };
+}
diff --git a/user/settings/i3.nix b/user/settings/i3.nix
new file mode 100644
index 00000000..d83ee2e7
--- /dev/null
+++ b/user/settings/i3.nix
@@ -0,0 +1,149 @@
+{ config, pkgs, lib, ... }:
+
+{
+  xdg.configFile.i3status = {
+    recursive = true;
+    source = ../i3/.config/i3status;
+  };
+  xsession.windowManager.i3 = let
+    mod = "Mod4";
+    mode_system = "System (l) lock, (e) logout, (s) suspend, (h) hibernate, (r) reboot, (Shift+s) shutdown";
+    locker = "${pkgs.xautolock}/bin/xautolock -locknow";
+  in
+  {
+    enable = true;
+    config = {
+      modifier = mod;
+      fonts = [ "Terminus 12px" ];
+      floating = {
+        criteria = [
+          { class = "Pinentry$"; }
+        ];
+      };
+      window = {
+        titlebar = false;
+      };
+      keybindings = {
+        "${mod}+Return" = "exec --no-startup-id xst";
+        # kill focused window
+        "${mod}+w" = "kill";
+        "${mod}+Shift+w" = "kill";
+
+        "--release ${mod}+Mod1+r" = "exec rofi -show run";
+        "--release ${mod}+Shift+semicolon" = "exec rofi-pass";
+        "--release ${mod}+space" = "exec \"rofi -show combi -combi-modi drun,window\"";
+
+        # change focus
+        "${mod}+h" = "focus left";
+        "${mod}+j" = "focus down";
+        "${mod}+k" = "focus up";
+        "${mod}+l" = "focus right";
+
+        "${mod}+1" = "workspace 1";
+        "${mod}+2" = "workspace 2";
+        "${mod}+3" = "workspace 3";
+        "${mod}+4" = "workspace 4";
+        "${mod}+5" = "workspace 5";
+        "${mod}+6" = "workspace 6";
+        "${mod}+7" = "workspace 7";
+        "${mod}+8" = "workspace 8";
+        "${mod}+9" = "workspace 9";
+        "${mod}+0" = "workspace 10";
+
+        # move focused window
+        "${mod}+Shift+h" = "move left";
+        "${mod}+Shift+j" = "move down";
+        "${mod}+Shift+k" = "move up";
+        "${mod}+Shift+l" = "move right";
+
+        "${mod}+Shift+1" = "move container to workspace 1";
+        "${mod}+Shift+2" = "move container to workspace 2";
+        "${mod}+Shift+3" = "move container to workspace 3";
+        "${mod}+Shift+4" = "move container to workspace 4";
+        "${mod}+Shift+5" = "move container to workspace 5";
+        "${mod}+Shift+6" = "move container to workspace 6";
+        "${mod}+Shift+7" = "move container to workspace 7";
+        "${mod}+Shift+8" = "move container to workspace 8";
+        "${mod}+Shift+9" = "move container to workspace 9";
+
+
+        # move workspace
+        "${mod}+Mod1+h" = "move workspace to output left";
+        "${mod}+Mod1+j" = "move workspace to output down";
+        "${mod}+Mod1+k" = "move workspace to output up";
+        "${mod}+Mod1+l" = "move workspace to output right";
+
+        # split in horizontal orientation
+        "${mod}+b" = "split h";
+
+        # split in vertical orientation
+        "${mod}+v" = "split v";
+
+        "${mod}+F11" = "fullscreen toggle";
+        "${mod}+f" = "fullscreen toggle";
+
+        # change container layout (stacked, tabbed, toggle split)
+        "${mod}+Shift+s" = "layout stacking";
+        "${mod}+Shift+t" = "layout tabbed";
+        "${mod}+Shift+v" = "layout toggle split";
+
+        # toggle tiling / floating
+        "${mod}+Shift+f" = "floating toggle";
+
+        # change focus between tiling / floating windows
+        "${mod}+Tab" = "focus mode_toggle";
+
+        # focus the parent container
+        "${mod}+a" = "focus parent";
+
+        # focus the child container
+        "${mod}+d" = "focus child";
+
+        "${mod}+Shift+c" = "reload";
+        "${mod}+Shift+p" = "restart";
+
+        "${mod}+Shift+r" = "mode resize";
+        "${mod}+Shift+o" = "exec ${locker}";
+        "${mod}+Pause" = "mode \"${mode_system}\"";
+        "${mod}+Escape" = "mode \"${mode_system}\"";
+        "${mod}+Shift+q" = "mode \"${mode_system}\"";
+      };
+
+      modes = {
+        resize = {
+          "h" = "resize shrink width 10 px or 10 ppt";
+          "j" = "resize grow height 10 px or 10 ppt";
+          "k" = "resize shrink height 10 px or 10 ppt";
+          "l" = "resize grow width 10 px or 10 ppt";
+
+          "Left" = "resize shrink width 10 px or 10 ppt";
+          "Down" = "resize grow height 10 px or 10 ppt";
+          "Up" = "resize shrink height 10 px or 10 ppt";
+          "Right" = "resize grow width 10 px or 10 ppt";
+
+          "Return" = "mode default";
+          "Escape" = "mode default";
+        };
+        "${mode_system}" = {
+          "l" = "exec --no-startup-id ${locker}, mode default";
+          "e" = "exec --no-startup-id i3-msg exit, mode default";
+          "s" = "exec --no-startup-id systemctl suspend, mode default";
+          "h" = "exec --no-startup-id systemctl hibernate, mode default";
+          "r" = "exec --no-startup-id systemctl reboot, mode default";
+          "Shift+s" = "exec --no-startup-id systemctl poweroff -i, mode default";
+          "Return" = "mode default";
+          "Escape" = "mode default";
+        };
+      };
+
+      bars = [
+        {
+          fonts = [ "Terminus 12px" ];
+          position = "top";
+          hiddenState = "show";
+          statusCommand = "${pkgs.i3status}/bin/i3status -c ~/.config/i3status/config";
+        }
+      ];
+    };
+  };
+}
diff --git a/user/settings/isync.nix b/user/settings/isync.nix
new file mode 100644
index 00000000..b96db87d
--- /dev/null
+++ b/user/settings/isync.nix
@@ -0,0 +1,5 @@
+{ config, pkgs, ... }:
+
+{
+  home.file.".mbsyncrc".source = ../isync/.mbsyncrc;
+}
diff --git a/user/settings/javascript.nix b/user/settings/javascript.nix
new file mode 100644
index 00000000..4c75ea10
--- /dev/null
+++ b/user/settings/javascript.nix
@@ -0,0 +1,59 @@
+{ config, pkgs, ... }:
+
+let
+  node = pkgs.unstable.nodejs-10_x;
+  npmPackages = pkgs.unstable.nodePackages_10_x;
+  node2nixPackages = import ../packages/node2nix/default.nix {
+    pkgs = pkgs.unstable;
+    nodejs = node;
+  };
+in
+{ home.packages = (with pkgs.unstable; [
+    node
+  ] ++ (
+    if stdenv.isDarwin
+    then
+    [
+    ]
+    else
+    [
+    # npm install may use any of these
+    binutils
+    gcc
+    gnumake
+    python2
+    ]
+  )) ++ (with npmPackages; [
+    node-gyp
+    node-gyp-build
+    node-pre-gyp
+
+    tern
+    node2nix
+    nodemon
+    javascript-typescript-langserver
+    typescript-language-server
+    vscode-css-languageserver-bin
+    vscode-html-languageserver-bin
+    csslint
+    eslint_d
+    prettier
+    typescript
+
+    node2nixPackages.bunyan
+    node2nixPackages.pino-pretty
+    node2nixPackages."pnpm-3.6.2"
+    node2nixPackages.prettier_d
+    node2nixPackages.dockerfile-language-server-nodejs
+    node2nixPackages.yaml-language-server
+  ]);
+  home.file.".npmrc".text = ''
+    prefix=''${HOME}/.local
+    //registry.npmjs.org/:_authToken=''${NPM_AUTH_TOKEN}
+    always-auth=true
+    sign-git-tag=true
+    rebuild-bundle=false
+    update-notifier=false
+    registry=https://registry.npmjs.org/
+  '';
+}
diff --git a/user/settings/ledger.nix b/user/settings/ledger.nix
new file mode 100644
index 00000000..61d3df7e
--- /dev/null
+++ b/user/settings/ledger.nix
@@ -0,0 +1,8 @@
+{ config, pkgs, ... }:
+
+{
+  home.file.".ledgerrc".text = ''
+    --date-format %F
+    --start-of-week 1
+  '';
+}
diff --git a/user/settings/msmtp.nix b/user/settings/msmtp.nix
new file mode 100644
index 00000000..45c2f460
--- /dev/null
+++ b/user/settings/msmtp.nix
@@ -0,0 +1,5 @@
+{ config, pkgs, ... }:
+
+{
+  home.file.".msmtprc".source = ../msmtp/.msmtprc;
+}
diff --git a/user/settings/nix.nix b/user/settings/nix.nix
new file mode 100644
index 00000000..d0de3cab
--- /dev/null
+++ b/user/settings/nix.nix
@@ -0,0 +1,5 @@
+{ config, pkgs, ... }:
+
+{
+  nixpkgs.config = import ../config.nix;
+}
diff --git a/user/settings/nixos.nix b/user/settings/nixos.nix
new file mode 100644
index 00000000..64b523b8
--- /dev/null
+++ b/user/settings/nixos.nix
@@ -0,0 +1,21 @@
+{ config, pkgs, ... }:
+
+{
+  imports = [
+    ./nix.nix
+  ];
+  nixpkgs.overlays = [
+    (self: super: {
+      unstable = import <nixos-unstable> {
+        config = config.nixpkgs.config;
+      };
+    })
+  ];
+
+  programs.zsh.shellAliases = {
+    nor = "nixos-rebuild";
+    nors = "nixos-rebuild switch";
+    norb = "nixos-rebuild boot";
+    norr = "nixos-rebuild switch --rollback";
+  };
+}
diff --git a/user/settings/nixpkgs.nix b/user/settings/nixpkgs.nix
new file mode 100644
index 00000000..b89579e1
--- /dev/null
+++ b/user/settings/nixpkgs.nix
@@ -0,0 +1,12 @@
+{ config, pkgs, ... }:
+
+{
+  imports = [
+    ./nix.nix
+  ];
+  nixpkgs.overlays = [
+    (self: super: {
+      unstable = self;
+    })
+  ];
+}
diff --git a/user/settings/passwords.nix b/user/settings/passwords.nix
new file mode 100644
index 00000000..72493cef
--- /dev/null
+++ b/user/settings/passwords.nix
@@ -0,0 +1,10 @@
+{ config, pkgs, ... }:
+
+{
+  home.packages = with pkgs.unstable; [
+    keepassx-community
+    rofi-pass
+    pass-otp
+    pwgen
+  ];
+}
diff --git a/user/settings/rofi.nix b/user/settings/rofi.nix
new file mode 100644
index 00000000..b34af881
--- /dev/null
+++ b/user/settings/rofi.nix
@@ -0,0 +1,25 @@
+{ config, pkgs, ... }:
+
+{
+  xdg.configFile."networkmanager-dmenu/config.ini".text = ''
+    [dmenu]
+    dmenu_command = /run/current-system/sw/bin/rofi
+
+    [editor]
+    terminal = xst
+    gui_if_available = false
+  '';
+  programs.rofi = {
+    enable = true;
+    extraConfig = ''
+      rofi.matching:            glob
+      rofi.separator-style:     none
+
+      rofi.line-padding:        2
+
+      rofi.display-run:         cmd
+      rofi.display-drun:        run
+      rofi.display-window:      win
+    '';
+  };
+}
diff --git a/user/settings/satoshipay.nix b/user/settings/satoshipay.nix
new file mode 100644
index 00000000..6516bd59
--- /dev/null
+++ b/user/settings/satoshipay.nix
@@ -0,0 +1,55 @@
+{ config, pkgs, ... }:
+
+let
+  inherit (pkgs) stdenv;
+  spGitConfig = {
+    user.email = "alan@satoshipay.io";
+  };
+in
+{
+  imports = [
+    ./javascript.nix
+  ];
+
+  home.sessionVariables = {
+    KUBECTX_IGNORE_FZF = "1";
+  };
+  home.packages = with pkgs; ([
+    caddy
+    openssl
+    mongodb-tools
+    pgcli
+    s3cmd
+    sops
+
+    unstable.mkcert
+    unstable.google-cloud-sdk
+    unstable.docker_compose
+    unstable.kubernetes
+    unstable.kubectx
+    unstable.kubernetes-helm
+    unstable.helmfile
+  ] ++ (lib.optionals (!stdenv.isDarwin)
+  [
+    pgadmin
+
+    unstable.redis-desktop-manager
+    unstable.robo3t
+    unstable.slack
+  ]));
+
+  programs.git.includes = [
+    {
+      condition = "gitdir:~/projects/github.com/satoshipay/";
+      contents = spGitConfig;
+    }
+    {
+      condition = "gitdir:~/projects/gitlab.satoshipay.tech";
+      contents = spGitConfig;
+    }
+  ];
+
+  home.file.".npmrc".text = ''
+    @satoshipay:registry=https://registry.npmjs.org/
+  '';
+}
diff --git a/user/settings/sxhkd.nix b/user/settings/sxhkd.nix
new file mode 100644
index 00000000..7160ec08
--- /dev/null
+++ b/user/settings/sxhkd.nix
@@ -0,0 +1,29 @@
+{ config, pkgs, ... }:
+
+{
+  xdg.configFile."sxhkd/sxhkdrc".text = ''
+    XF86AudioMute
+      pamixer --toggle-mute
+
+    XF86Audio{Lower,Raise}Volume
+      pamixer --{decrease,increase} 1
+
+    @XF86AudioMicMute
+      pamixer --source 2 --toggle-mute
+
+    XF86MonBrightness{Down,Up}
+      light -{U,A} 2%
+
+    XF86Display
+      disper -C
+
+    XF86AudioPlay
+      cmus-remote --pause
+
+    XF86Audio{Prev,Next}
+      cmus-remote --{prev,next}
+
+    XF86Tools
+      networkmanager_dmenu
+  '';
+}
diff --git a/user/settings/tabnine.nix b/user/settings/tabnine.nix
new file mode 100644
index 00000000..8018bcca
--- /dev/null
+++ b/user/settings/tabnine.nix
@@ -0,0 +1,57 @@
+{ config, pkgs, ... }:
+
+let
+  cfg = {
+    config = {
+      "language.typescript" = {
+        command = "typescript-language-server";
+        args = ["--stdio"];
+      };
+      "language.javascript" = {
+        command = "javascript-typescript-stdio";
+        args = ["--stdio"];
+      };
+      "language.css" = {
+        command = "css-languageserver";
+        args = ["--stdio"];
+      };
+      "language.scss" = {
+        command = "css-languageserver";
+        args = ["--stdio"];
+      };
+      "language.html" = {
+        command = "html-languageserver";
+        args = ["--stdio"];
+      };
+      "language.dockerfile" = {
+        command = "docker-langserver";
+        args = ["--stdio"];
+      };
+      "language.yaml" = {
+        command = "yaml-language-server";
+        args = ["--stdio"];
+      };
+      "language.haskell" = {
+        command = "hie";
+        args = ["--stdio"];
+      };
+    };
+  };
+  configFile = config:
+    pkgs.runCommand "TabNine.toml"
+      {
+         buildInputs = [ pkgs.remarshal ];
+         preferLocalBuild = true;
+         allowSubstitutes = false;
+      }
+      ''
+        remarshal -if json -of toml \
+          < ${pkgs.writeText "config.json" (builtins.toJSON cfg.config)} \
+          > $out
+      '';
+in
+{
+  xdg.configFile."TabNine/TabNine.toml" = {
+    source = configFile cfg.config;
+  };
+}
diff --git a/user/settings/trezor.nix b/user/settings/trezor.nix
new file mode 100644
index 00000000..a4f3ba75
--- /dev/null
+++ b/user/settings/trezor.nix
@@ -0,0 +1,9 @@
+{ config, pkgs, ... }:
+
+{
+  home.file.".ssh/agent.config" = {
+    text = ''
+      ecdsa-curve-name = ed25519
+    '';
+  };
+}
diff --git a/user/settings/user-interface.nix b/user/settings/user-interface.nix
new file mode 100644
index 00000000..31ba349d
--- /dev/null
+++ b/user/settings/user-interface.nix
@@ -0,0 +1,17 @@
+{ config, pkgs, ... }:
+
+let
+  inherit (pkgs) stdenv;
+in
+{
+  home.sessionVariables = {
+    TERMINAL = "${pkgs.unstable.xst}/bin/xst";
+  };
+
+  home.packages = with pkgs; [
+    unstable.xst # st, but with support for XResources
+  ] ++ lib.optionals (!stdenv.isDarwin) [
+    pkgs.sshfs
+    pkgs.unstable.mu
+  ];
+}
diff --git a/user/settings/xresources.nix b/user/settings/xresources.nix
new file mode 100644
index 00000000..475113de
--- /dev/null
+++ b/user/settings/xresources.nix
@@ -0,0 +1,8 @@
+{ config, pkgs, ... }:
+
+{
+  home.file.".xresources" = {
+    recursive = true;
+    source = ../xresources/.xresources;
+  };
+}
diff --git a/user/settings/zsh.nix b/user/settings/zsh.nix
new file mode 100644
index 00000000..467c426b
--- /dev/null
+++ b/user/settings/zsh.nix
@@ -0,0 +1,181 @@
+{ config, pkgs, ... }:
+
+let
+  inherit (pkgs) stdenv;
+  lsOptions = if stdenv.isDarwin then "-p" else "-v --group-directories-first";
+  lsIsoDate = if stdenv.isDarwin then "" else "--time-style=long-iso";
+in
+{
+  home.file = {
+    ".rm_recycle_home".text = ""; # use trash automatically in home directory
+  };
+  home.packages = with pkgs; [
+    fzf
+    ghq
+  ] ++ (if stdenv.isDarwin
+  then []
+  else [
+    pkgs.git
+  ]);
+  xdg.configFile.zsh = {
+    recursive = true;
+    source = ../zsh/.config/zsh;
+  };
+
+  home.file.".zplugin/bin" = {
+    source = pkgs.fetchFromGitHub {
+      owner = "zdharma";
+      repo = "zplugin";
+      rev = "028b1e1d6d3eae204b499c7f815f4eeeb5051517";
+      sha256 = "1ynh323905iia3gwi9qghbywp94x306nna1yqk37frj5g7kg90fa";
+    };
+  };
+
+  programs.zsh = {
+    enable = true;
+
+    enableAutosuggestions = true;
+    enableCompletion = true;
+    defaultKeymap = "emacs";
+
+    dotDir = ".config/zsh";
+
+    history = {
+      expireDuplicatesFirst = true;
+      extended = true;
+      path = ".cache/zsh/history";
+      save = 20000;
+      size = 10000;
+    };
+
+    localVariables = {
+      ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE = "fg=7";
+    };
+
+    shellAliases = {
+      l = "ls ${lsOptions} -Bp";
+      l1="ls -1";
+      ls="ls ${lsOptions} -hF";
+      la="ls ${lsOptions} -hA";
+      ll="ls ${lsOptions} ${lsIsoDate} -hl";
+      lal="ll -A";
+      lla="lal";
+      llr="ll -t";
+
+      https = "http --default-scheme https";
+      kns = "kubens";
+      kx = "kubectx";
+      ava = "pnpx ava";
+      avt = "pnpx ava --tap";
+      avat = "pnpx ava --tap";
+      pino = "pino-pretty";
+      mocha = "pnpx mocha";
+      prettier = "pnpx prettier";
+      standard = "pnpx standard";
+      tsc = "pnpx tsc";
+      tslint = "pnpx tslint";
+      tsnode = "pnpx ts-node";
+
+      history = "fc -l $(( $LINES - 2 ))";
+      hist-freq-lines = "fc -l -2000 | cut -d' ' -f4- | sort | uniq -c | sort -g | tail -n100 | less";
+      hist-freq-commands = "fc -l -2000 | cut -d' ' -f4 | sort | uniq -c | sort -g | tail -n10 | less";
+      wprop = "xprop | egrep '^WM_(CLASS|NAME|WINDOW_ROLE|TYPE)'";
+
+      # Enable the following commands to support aliases.
+      sudo = "sudo ";
+      watch = "watch ";
+
+      g = "rg";
+
+      ga = "git add";
+      gi = "git";
+      gs = "git st";
+      gd = "git diff";
+      gf = "git fetch";
+      gk = "git push";
+      gj = "git pull";
+      gl = "git lg";
+      gr = "git remote";
+      gz = "git stash";
+      gzl = "git stash list";
+      gzp = "git stash pop";
+      gdt = "git difftool";
+      grl = "git reflog";
+      gri = "git rebase --interactive";
+      grs = "git reset";
+      grsh = "git reset --hard";
+      gsh = "git show";
+      gsm = "git submodule";
+      gci = "git commit";
+      gco = "git checkout";
+      gbr = "git br";
+      gbrc = "git checkout -b";
+      gbrd = "git branch --delete";
+      gbrm = "git branch --move";
+      gmup = "git mup";
+      grup = "git rup";
+
+      hos = "home-manager switch";
+      hon = "home-manager news";
+      hoh = "home-manager-help";
+
+      n = "nix-env";
+      ni = "nix-env -iA";
+      nq = "nix-env -q";
+      ne = "nix-env -e";
+      nup = "nix-env -u";
+      ngc = "nix-collect-garbage --delete-older-than 14d";
+    };
+
+    # move to envExtra after 19.09
+    initExtra = ''
+      case $OSTYPE in
+        darwin*)
+          os=darwin
+          ;;
+        linux-gnu)
+          os=linux
+          ;;
+        freebsd*)
+          os=freebsd
+          ;;
+        *)
+          os=unknown
+          ;;
+      esac
+
+      case $MACHTYPE in
+        *64)
+          arch=amd64
+          ;;
+        *)
+          arch=386
+          ;;
+      esac
+      if [[ ''${path[(I)$HOME/.local/bin ]} ]]
+      then
+        path+=($HOME/.local/bin)
+      fi
+
+      if [[ ''${path[(I)$HOME/go/bin ]} ]]
+      then
+        path+=($HOME/go/bin)
+      fi
+
+      if [[ $HOST =~ satoshi ]]
+      then
+        EMAIL=alan@satoshipay.io
+      else
+        EMAIL=alan@alanpearce.eu
+      fi
+
+      typeset -T GHQ_ROOT ghq_root
+      export GHQ_ROOT="$HOME/projects:$HOME/go/src:$HOME/quicklisp/local-projects"
+
+      function hist-freq-subcommands () {
+        fc -l -m "$1*" -2000 | cut -d' ' -f4- | sort | uniq -c | sort -g | tail -n100 | less
+      }
+
+    '' + builtins.readFile ../zsh/.config/zsh/.zshrc;
+  };
+}