about summary refs log tree commit diff
path: root/modules/user/aszlig
diff options
context:
space:
mode:
Diffstat (limited to 'modules/user/aszlig')
-rw-r--r--modules/user/aszlig/profiles/base.nix101
-rw-r--r--modules/user/aszlig/profiles/workstation/default.nix178
-rw-r--r--modules/user/aszlig/profiles/workstation/packages.nix92
-rw-r--r--modules/user/aszlig/programs/gajim/config.nix731
-rw-r--r--modules/user/aszlig/programs/gajim/config.patch80
-rw-r--r--modules/user/aszlig/programs/gajim/default.nix59
-rw-r--r--modules/user/aszlig/programs/git/default.nix74
-rw-r--r--modules/user/aszlig/programs/mpv/default.nix24
-rw-r--r--modules/user/aszlig/programs/taalo-build/default.nix65
-rw-r--r--modules/user/aszlig/programs/taskwarrior/config.patch48
-rw-r--r--modules/user/aszlig/programs/taskwarrior/default.nix36
-rw-r--r--modules/user/aszlig/programs/vim/default.nix384
-rw-r--r--modules/user/aszlig/programs/xpdf/default.nix20
-rw-r--r--modules/user/aszlig/programs/zsh/default.nix117
-rw-r--r--modules/user/aszlig/services/i3/conky.nix121
-rw-r--r--modules/user/aszlig/services/i3/default.nix136
-rw-r--r--modules/user/aszlig/services/i3/i3.conf131
-rw-r--r--modules/user/aszlig/services/i3/workspace.nix107
-rw-r--r--modules/user/aszlig/services/slim/default.nix45
-rw-r--r--modules/user/aszlig/services/vlock/default.nix57
-rw-r--r--modules/user/aszlig/services/vlock/message.cat18
-rw-r--r--modules/user/aszlig/services/vlock/message.colmap18
-rw-r--r--modules/user/aszlig/system/kernel.nix57
23 files changed, 2699 insertions, 0 deletions
diff --git a/modules/user/aszlig/profiles/base.nix b/modules/user/aszlig/profiles/base.nix
new file mode 100644
index 00000000..8f31467e
--- /dev/null
+++ b/modules/user/aszlig/profiles/base.nix
@@ -0,0 +1,101 @@
+{ config, pkgs, lib, ... }:
+
+let
+  cfg = config.vuizvui.user.aszlig.profiles.base;
+
+in {
+  options.vuizvui.user.aszlig.profiles.base = {
+    enable = lib.mkEnableOption "Base profile for aszlig";
+  };
+
+  config = lib.mkIf cfg.enable {
+    nix = {
+      useChroot = true;
+      readOnlyStore = true;
+      buildCores = 0;
+      extraOptions = ''
+        auto-optimise-store = true
+        log-servers = https://headcounter.org/hydra/log
+      '';
+    };
+
+    boot.loader.grub = {
+      enable = true;
+      version = 2;
+    };
+
+    hardware.cpu.intel.updateMicrocode = true;
+
+    users.defaultUserShell = "/var/run/current-system/sw/bin/zsh";
+
+    networking.wireless.enable = false;
+    networking.firewall.enable = false;
+    networking.useNetworkd = true;
+
+    i18n.consoleKeyMap = "dvorak";
+    i18n.consoleFont = "lat9w-16";
+
+    programs.ssh.startAgent = false;
+    programs.ssh.extraConfig = ''
+      ServerAliveInterval 60
+    '';
+
+    vuizvui.user.aszlig.programs.vim.enable = true;
+    vuizvui.user.aszlig.programs.zsh.enable = true;
+    vuizvui.enableGlobalNixpkgsConfig = true;
+
+    services.nixosManual.showManual = false;
+
+    services.journald.extraConfig = ''
+      MaxRetentionSec=3month
+    '';
+
+    environment.systemPackages = with pkgs; [
+      binutils
+      cacert
+      file
+      htop
+      iotop
+      psmisc
+      unrar
+      unzip
+      vlock
+      wget
+      xz
+    ];
+
+    nixpkgs.config = {
+      pulseaudio = true;
+      chromium.enablePepperFlash = true;
+      firefox.jre = true;
+
+      # Needed for CPU microcode
+      allowUnfree = true;
+
+      allowBroken = true;
+
+      packageOverrides = pkgs: {
+        beets = pkgs.beets.override {
+          enableAlternatives = true;
+        };
+        miro = pkgs.miro.override {
+          enableBonjour = true;
+        };
+        netrw = pkgs.netrw.override {
+          checksumType = "mhash";
+        };
+        nix = pkgs.nixUnstable;
+        uqm = pkgs.uqm.override {
+          use3DOVideos = true;
+          useRemixPacks = true;
+        };
+        w3m = pkgs.w3m.override {
+          graphicsSupport = true;
+        };
+      };
+    };
+
+    system.fsPackages = with pkgs; [ sshfsFuse ];
+    time.timeZone = "Europe/Berlin";
+  };
+}
diff --git a/modules/user/aszlig/profiles/workstation/default.nix b/modules/user/aszlig/profiles/workstation/default.nix
new file mode 100644
index 00000000..2e0d8a40
--- /dev/null
+++ b/modules/user/aszlig/profiles/workstation/default.nix
@@ -0,0 +1,178 @@
+{ pkgs, config, lib, ... }:
+
+let
+  cfg = config.vuizvui.user.aszlig.profiles.workstation;
+  randrHeads = config.services.xserver.xrandrHeads;
+
+in {
+  options.vuizvui.user.aszlig.profiles.workstation = {
+    enable = lib.mkEnableOption "Workstation profile for aszlig";
+  };
+
+  config = lib.mkIf cfg.enable {
+    vuizvui.user.aszlig.profiles.base.enable = true;
+
+    boot.kernelParams = [ "zswap.enabled=1" "panic=1800" ];
+    boot.cleanTmpDir = true;
+
+    environment.systemPackages = with lib; let
+      mkRandrConf = acc: name: acc ++ singleton {
+        inherit name;
+        value = "--output '${name}' --preferred"
+              + optionalString (acc != []) " --right-of '${(head acc).name}'";
+      };
+      randrConf = map (getAttr "value") (foldl mkRandrConf [] randrHeads);
+    in singleton (pkgs.writeScriptBin "xreset" ''
+      #!${pkgs.stdenv.shell}
+      ${pkgs.xorg.xrandr}/bin/xrandr ${concatStringsSep " " randrConf}
+    '') ++ import ./packages.nix pkgs;
+
+    hardware = {
+      pulseaudio.enable = true;
+      opengl = {
+        driSupport32Bit = true;
+        s3tcSupport = true;
+      };
+    };
+
+    fonts = {
+      enableCoreFonts = true;
+      enableFontDir = true;
+      enableGhostscriptFonts = true;
+      fonts = [
+        pkgs.dosemu_fonts
+        pkgs.liberation_ttf
+      ];
+    };
+
+    vuizvui.user.aszlig.services.i3.enable = true;
+    vuizvui.user.aszlig.services.slim.enable = true;
+    vuizvui.user.aszlig.services.vlock.enable = true;
+
+    vuizvui.user.aszlig.programs.gajim.enable = true;
+    vuizvui.user.aszlig.programs.mpv.enable = true;
+    vuizvui.user.aszlig.programs.taskwarrior.enable = true;
+    vuizvui.user.aszlig.programs.xpdf.enable = true;
+
+    vuizvui.user.aszlig.programs.git.enable = true;
+    vuizvui.user.aszlig.programs.git.config = {
+      color.ui = "auto";
+      merge.tool = "vimdiff3";
+      user.email = "aszlig@redmoonstudios.org";
+      user.name = "aszlig";
+      user.signkey = "8C2DC961";
+      gpg.program = "${pkgs.gnupg}/bin/gpg2";
+      push.default = "current";
+      tar."tar.xz".command = "${pkgs.xz}/bin/xz -c";
+      rebase.autosquash = true;
+      rerere.enabled = true;
+      rerere.autoupdate = true;
+      commit.gpgsign = true;
+
+      alias.backport = let
+        release = "14.04";
+        message = "Merge release ${release} into backports.";
+      in "!git fetch upstream release-${release} &&"
+       + " git merge -m \"${message}\" --log FETCH_HEAD";
+    };
+
+    vuizvui.hardware.gameController."03000000ff1100004133000010010000" = {
+      name = "PS2 Controller";
+      mapping = {
+        a = "b2";
+        b = "b1";
+        x = "b3";
+        y = "b0";
+        back = "b8";
+        start = "b9";
+        leftshoulder = "b6";
+        rightshoulder = "b7";
+        leftstick = "b10";
+        rightstick = "b11";
+        leftx = "a0";
+        lefty = "a1";
+        rightx = "a3";
+        righty = "a2";
+        lefttrigger = "b4";
+        righttrigger = "b5";
+        dpup = "h0.1";
+        dpleft = "h0.8";
+        dpdown = "h0.4";
+        dpright = "h0.2";
+      };
+    };
+
+    services = {
+      openssh = {
+        enable = true;
+        permitRootLogin = "without-password";
+      };
+
+      xfs.enable = false;
+
+      gpm = {
+        enable = true;
+        protocol = "exps2";
+      };
+
+      printing.enable = true;
+      printing.drivers = [ pkgs.gutenprint pkgs.hplip ];
+
+      udev.extraRules = ''
+        # aXbo S.P.A.C.
+        SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", \
+          ATTRS{serial}=="0001", OWNER="aszlig", SYMLINK+="axbo"
+        # Enttec DMX device
+        SUBSYSTEM=="usb*|tty", ACTION=="add|change", ATTRS{idVendor}=="0403", \
+          ATTRS{idProduct}=="6001", OWNER="aszlig"
+      '';
+
+      xserver = {
+        enable = true;
+        layout = "dvorak";
+
+        startGnuPGAgent = true;
+
+        displayManager.sessionCommands = ''
+          ${pkgs.redshift}/bin/redshift -l 48.428404:10.866007 &
+          ${pkgs.xorg.xrdb}/bin/xrdb "${pkgs.writeText "xrdb.config" ''
+            Rxvt*font:                 vga
+            Rxvt*background:           black
+            Rxvt*foreground:           grey
+            Rxvt*scrollBar:            false
+            Rxvt*saveLines:            2000
+
+            Rxvt*keysym.Home:          \033[1~
+            Rxvt*keysym.End:           \033[4~
+
+            Rxvt*urgentOnBell:         true
+
+            XTerm*font:                vga
+            XTerm*saveLines:           10000
+            XTerm*bellIsUrgent:        true
+            XTerm*background:          black
+            XTerm*foreground:          grey
+
+            XTerm*backarrowKeyIsErase: true
+            XTerm*ptyInitialErase:     true
+          ''}"
+        '';
+
+        desktopManager.default = "none";
+        desktopManager.xterm.enable = false;
+      };
+    };
+
+    virtualisation.virtualbox.host.enable = true;
+
+    users.extraUsers.aszlig = {
+      uid = 1000;
+      description = "aszlig";
+      group = "users";
+      extraGroups = [ "wheel" "video" ];
+      home = "/home/aszlig";
+      useDefaultShell = true;
+      createHome = true;
+    };
+  };
+}
diff --git a/modules/user/aszlig/profiles/workstation/packages.nix b/modules/user/aszlig/profiles/workstation/packages.nix
new file mode 100644
index 00000000..8ba1d309
--- /dev/null
+++ b/modules/user/aszlig/profiles/workstation/packages.nix
@@ -0,0 +1,92 @@
+pkgs: with pkgs; [
+  vuizvui.aacolorize
+  abook
+  acpi
+  apg
+  ascii
+  aspellDicts.de
+  aspellDicts.en
+  vuizvui.axbo
+  bc
+  beets
+  chromiumBeta
+  dash
+  dos2unix
+  erlang
+  fbida
+  ffmpeg
+  figlet
+  firefox
+  flac
+  gdb
+  ghostscript
+  gimp
+  glxinfo
+  gnumake
+  gnupg1compat
+  gpodder
+  graphviz
+  haskellPackages.cabal2nix
+  haskellPackages.cabal-install
+  haskellPackages.hlint
+  haskellPackages.yesod-bin
+  haxe
+  hexedit
+  i3
+  i3lock
+  imagemagick
+  jwhois
+  keychain
+  lastwatch
+  lftp
+  ltrace
+  manpages
+  mmv
+  mosh
+  mp3info
+  mpg321
+  mtr
+  mumble
+  mutt
+  ncdu
+  neko
+  netrw
+  nix-prefetch-scripts
+  nix-repl
+  vuizvui.nixops
+  nixpkgs-lint
+  nmap
+  openssh
+  openssl
+  p7zip
+  pavucontrol
+  picard
+  posix_man_pages
+  pulseaudioLight
+  vuizvui.pvolctrl
+  python
+  python3
+  pythonPackages.hetzner
+  pythonPackages.pep8
+  pythonPackages.polib
+  rlwrap
+  rtorrent
+  samplicator
+  screen
+  scrot
+  socat
+  sox
+  sqlite
+  strace
+  surfraw
+  telnet
+  vuizvui.tomahawk
+  unzip
+  uqm
+  valgrind
+  vbindiff
+  vorbisTools
+  w3m
+  wireshark
+  youtubeDL
+]
diff --git a/modules/user/aszlig/programs/gajim/config.nix b/modules/user/aszlig/programs/gajim/config.nix
new file mode 100644
index 00000000..86c4fef1
--- /dev/null
+++ b/modules/user/aszlig/programs/gajim/config.nix
@@ -0,0 +1,731 @@
+lib: with lib;
+
+let
+  mkConfig = let
+    traverse = path: attrs: let
+      mkVal = name: value: let
+        flatPath = concatStringsSep "." (path ++ [name]);
+      in if isAttrs value then traverse (path ++ [name]) value
+         else if value == true then "${flatPath} = True"
+         else if value == false then "${flatPath} = False"
+         else "${flatPath} = ${value}";
+    in concatStringsSep "\n" (mapAttrsToList mkVal attrs);
+
+    rootTraverse = attrs: (traverse [] attrs) + "\n";
+  in rootTraverse;
+
+in mkConfig {
+  activity_iconset = "default";
+  after_nickname = ">";
+  allow_hide_roster = true;
+  always_english_wikipedia = false;
+  always_english_wiktionary = true;
+  ascii_formatting = true;
+  ask_avatars_on_startup = true;
+  ask_offline_status = true;
+  ask_offline_status_on_connection = false;
+  ask_online_status = false;
+  attach_notifications_to_systray = false;
+  audio_input_device = "pulsesrc device=alsa_input."
+                     + "usb-046d_0804_DD519390-02-U0x46d0x804.analog-mono"
+                     + " ! volume name=gajim_vol";
+  audio_input_volume = "50";
+  audio_output_device = "pulsesink device=alsa_output."
+                      + "pci-0000_00_1b.0.analog-stereo sync=true";
+  audio_output_volume = "50";
+  autoaway = false;
+  autoaway_message = "$S (Away as a result of being idle more than $T min)";
+  autoawaytime = "5";
+  autodetect_browser_mailer = false;
+  autopopup = true;
+  autopopupaway = true;
+  autoxa = false;
+  autoxa_message = "$S (Not available as a result of being"
+                 + " idle more than $T min)";
+  autoxatime = "15";
+  avatar_position_in_roster = "left";
+  before_nickname = "<";
+  change_roster_title = true;
+  change_status_window_timeout = "15";
+  "chat-msgwin-height" = "440";
+  "chat-msgwin-width" = "480";
+  "chat-msgwin-x-position" = "-1";
+  "chat-msgwin-y-position" = "-1";
+  chat_avatar_height = "52";
+  chat_avatar_width = "52";
+  chat_merge_consecutive_nickname = false;
+  chat_merge_consecutive_nickname_indent = "  ";
+  check_idle_every_foo_seconds = "2";
+  check_if_gajim_is_default = true;
+  collapsed_rows = "";
+  compact_view = false;
+  confirm_block = "";
+  confirm_close_muc = true;
+  confirm_close_muc_rooms = "";
+  confirm_close_multiple_tabs = true;
+  confirm_custom_status = "no";
+  confirm_metacontacts = "no";
+  conversation_font = "Liberation Mono 10";
+  ctrl_tab_go_to_next_composing = true;
+  custom_file_manager = "";
+  custombrowser = "chromium";
+  custommailapp = "";
+  dictionary_url = "WIKTIONARY";
+  displayed_chat_state_notifications = "all";
+  emoticons_theme = "";
+  enable_negative_priority = false;
+  escape_key_closes = false;
+  esession_modp = "5,14";
+  file_transfers_port = "28011";
+  ft_add_hosts_to_send = "";
+  "gc-hpaned-position" = "979";
+  "gc-msgwin-height" = "440";
+  "gc-msgwin-width" = "600";
+  "gc-msgwin-x-position" = "-1";
+  "gc-msgwin-y-position" = "-1";
+  gc_nicknames_colors = "#4e9a06:#f57900:#ce5c00:#3465a4:#204a87:#75507b:"
+                      + "#5c3566:#c17d11:#8f5902:#ef2929:#cc0000:#a40000";
+  gc_proposed_nick_char = "_";
+  gc_refer_to_nick_char = ":";
+  global_proxy = "";
+  hide_avatar_of_transport = true;
+  hide_chat_banner = false;
+  hide_groupchat_banner = false;
+  hide_groupchat_occupants_list = false;
+  history_window_height = "1156";
+  history_window_width = "1596";
+  "history_window_x-position" = "0";
+  "history_window_y-position" = "20";
+  iconset = "dcraven";
+  ignore_incoming_xhtml = false;
+  inmsgcolor = "#ff7f50";
+  inmsgfont = "";
+  inmsgtxtcolor = "";
+  inmsgtxtfont = "";
+  just_connected_bg_color = "#adc3c6";
+  just_disconnected_bg_color = "#ab6161";
+  key_up_lines = "25";
+  last_emoticons_dir = "";
+  last_roster_visible = true;
+  last_save_dir = "";
+  last_send_dir = "";
+  last_sounds_dir = "";
+  latex_png_dpi = "108";
+  log_contact_status_changes = true;
+  log_xhtml_messages = false;
+  markedmsgcolor = "#ff8080";
+  max_conversation_lines = "500";
+  mergeaccounts = false;
+  mood_iconset = "default";
+  "msgwin-height" = "1156";
+  "msgwin-max-state" = true;
+  "msgwin-width" = "1336";
+  "msgwin-x-position" = "0";
+  "msgwin-y-position" = "20";
+  muc_autorejoin_on_kick = false;
+  muc_autorejoin_timeout = "1";
+  muc_highlight_words = "DOWN;PROBLEM;CRITICAL;UNREACHABLE";
+  muc_restore_lines = "20";
+  muc_restore_timeout = "60";
+  networkmanager_support = true;
+  noconfirm_close_muc_rooms = "";
+  notification_avatar_height = "48";
+  notification_avatar_width = "48";
+  notification_position_x = "-1";
+  notification_position_y = "-1";
+  notification_preview_message = true;
+  notification_timeout = "5";
+  notify_on_all_muc_messages = false;
+  notify_on_file_complete = true;
+  notify_on_new_gmail_email = true;
+  notify_on_new_gmail_email_command = "";
+  notify_on_new_gmail_email_extra = false;
+  notify_on_new_message = false;
+  notify_on_signin = false;
+  notify_on_signout = false;
+  one_message_window = "always_with_roster";
+  openwith = "xdg-open";
+  outgoing_chat_state_notifications = "composing_only";
+  outmsgcolor = "#add8e6";
+  outmsgfont = "";
+  outmsgtxtcolor = "";
+  outmsgtxtfont = "";
+  plugins.plugin_installer.active = false;
+  print_ichat_every_foo_minutes = "5";
+  print_status_in_chats = true;
+  print_status_in_muc = "in_and_out";
+  print_time = "always";
+  print_time_fuzzy = "0";
+  quit_on_roster_x_button = true;
+  recently_groupchat = "";
+  remote_control = true;
+  restore_lines = "10";
+  restore_timeout = "60";
+  restored_messages_color = "#555753";
+  restored_messages_small = false;
+  roster_avatar_height = "16";
+  roster_avatar_width = "16";
+  roster_height = "1156";
+  roster_theme = "blue";
+  roster_width = "206";
+  roster_window_skip_taskbar = false;
+  "roster_x-position" = "0";
+  "roster_y-position" = "20";
+  rst_formatting_outgoing_messages = false;
+  "save-roster-position" = true;
+  scroll_roster_to_last_message = true;
+  search_engine = "https://www.google.com/search?&q=%s&sourceid=gajim";
+  send_on_ctrl_enter = false;
+  send_sha_in_gc_presence = true;
+  shell_like_completion = true;
+  show_activity_in_roster = true;
+  show_affiliation_in_groupchat = true;
+  show_ascii_formatting_chars = true;
+  show_avatar_in_chat = true;
+  show_avatars_in_roster = true;
+  show_contacts_number = true;
+  show_location_in_roster = true;
+  show_mood_in_roster = true;
+  show_only_chat_and_online = false;
+  show_roster_on_startup = "always";
+  show_self_contact = "when_other_resource";
+  show_status_msgs_in_roster = true;
+  show_transports_group = true;
+  show_tunes_in_roster = true;
+  show_unread_tab_icon = true;
+  showoffline = false;
+  "single-msg-height" = "280";
+  "single-msg-width" = "400";
+  "single-msg-x-position" = "0";
+  "single-msg-y-position" = "0";
+  sort_by_show_in_muc = false;
+  sort_by_show_in_roster = true;
+  sounddnd = false;
+  soundplayer = "aplay -q";
+  sounds_on = false;
+  speller_language = "de.en";
+  statusmsgcolor = "#4e9a06";
+  statusmsgfont = "";
+  stun_server = "";
+  tabs_always_visible = true;
+  tabs_border = false;
+  tabs_close_button = true;
+  tabs_position = "right";
+  time_stamp = "[%H:%M:%S]";
+  tooltip_account_name_color = "#888A85";
+  tooltip_affiliation_administrator_color = "#F57900";
+  tooltip_affiliation_member_color = "#73D216";
+  tooltip_affiliation_none_color = "#555753";
+  tooltip_affiliation_owner_color = "#CC0000";
+  tooltip_avatar_height = "125";
+  tooltip_avatar_width = "125";
+  tooltip_idle_color = "#888A85";
+  tooltip_status_away_color = "#EDD400";
+  tooltip_status_busy_color = "#F57900";
+  tooltip_status_free_for_chat_color = "#3465A4";
+  tooltip_status_na_color = "#CC0000";
+  tooltip_status_offline_color = "#555753";
+  tooltip_status_online_color = "#73D216";
+  trayicon = "never";
+  trayicon_notification_on_events = true;
+  treat_incoming_messages = "";
+  uri_schemes = "aaa:// aaas:// acap:// cap:// cid: crid:// data: dav: "
+              + "dict:// dns: fax: file:/ ftp:// geo: go: gopher:// h323: "
+              + "http:// https:// iax: icap:// im: imap:// info: ipp:// iris: "
+              + "iris.beep: iris.xpc: iris.xpcs: iris.lwz: ldap:// mid: "
+              + "modem: msrp:// msrps:// mtqp:// mupdate:// news: nfs:// "
+              + "nntp:// opaquelocktoken: pop:// pres: prospero:// rtsp:// "
+              + "service: shttp:// sip: sips: sms: snmp:// soap.beep:// "
+              + "soap.beeps:// tag: tel: telnet:// tftp:// thismessage:/ "
+              + "tip:// tv: urn:// vemmi:// xmlrpc.beep:// xmlrpc.beeps:// "
+              + "z39.50r:// z39.50s:// about: apt: cvs:// daap:// ed2k:// "
+              + "feed: fish:// git:// iax2: irc:// ircs:// ldaps:// magnet: "
+              + "mms:// rsync:// ssh:// svn:// sftp:// smb:// webcal://";
+  urlmsgcolor = "#add8e6";
+  use_gnomekeyring = true;
+  use_gpg_agent = true;
+  use_kib_mib = false;
+  use_kwalletcli = true;
+  use_latex = false;
+  use_notif_daemon = true;
+  use_smooth_scrolling = true;
+  use_speller = true;
+  use_stun_server = false;
+  use_transports_iconsets = true;
+  use_urgency_hint = true;
+  vcard_avatar_height = "200";
+  vcard_avatar_width = "200";
+  verbose = false;
+  version = "0.15.4";
+  video_framerate = "";
+  video_input_device = "v4l2src device=/dev/video0";
+  video_output_device = "ximagesink";
+  video_size = "";
+
+  accounts = {
+    Local = {
+      action_when_plaintext_connection = "warn";
+      active = true;
+      adjust_priority_with_status = true;
+      allow_no_log_for = "";
+      anonymous_auth = false;
+      answer_receipts = true;
+      attached_gpg_keys = "";
+      autoauth = false;
+      autoconnect = true;
+      autoconnect_as = "online";
+      autonegotiate_esessions = true;
+      autopriority_away = "40";
+      autopriority_chat = "50";
+      autopriority_dnd = "20";
+      autopriority_invisible = "10";
+      autopriority_online = "50";
+      autopriority_xa = "30";
+      autoreconnect = true;
+      client_cert = "";
+      client_cert_encrypted = false;
+      connection_types = "tls ssl plain";
+      custom_host = "";
+      custom_port = "5298";
+      dont_ack_subscription = false;
+      enable_esessions = true;
+      enable_message_carbons = false;
+      file_transfer_proxies = "proxy.eu.jabber.org, proxy.jabber.ru, "
+                            + "proxy.jabbim.cz";
+      ft_send_local_ips = true;
+      gpg_sign_presence = true;
+      hostname = "mmrnmhrm";
+      http_auth = "ask";
+      ignore_ssl_errors = "";
+      ignore_unknown_contacts = false;
+      is_zeroconf = true;
+      keep_alive_every_foo_secs = "55";
+      keep_alives_enabled = true;
+      keyid = "";
+      keyname = "";
+      last_archiving_time = "1970-01-01T00:00:00Z";
+      last_status = "online";
+      last_status_msg = "";
+      listen_to_network_manager = true;
+      log_encrypted_sessions = true;
+      minimized_gc = "";
+      "msgwin-height" = "440";
+      "msgwin-width" = "480";
+      "msgwin-x-position" = "-1";
+      "msgwin-y-position" = "-1";
+      name = "aszlig";
+      no_log_for = "";
+      password = "zeroconf";
+      ping_alive_every_foo_secs = "120";
+      ping_alives_enabled = true;
+      priority = "5";
+      proxy = "";
+      publish_location = false;
+      publish_tune = false;
+      request_receipt = true;
+      resource = "gajim";
+      restore_last_status = false;
+      roster_version = "";
+      savepass = false;
+      send_idle_time = true;
+      send_os_info = true;
+      send_time_info = true;
+      ssl_fingerprint_sha1 = "";
+      subscribe_activity = true;
+      subscribe_location = true;
+      subscribe_mood = true;
+      subscribe_nick = true;
+      subscribe_tune = true;
+      subscription_request_msg = "";
+      sync_with_global_status = true;
+      test_ft_proxies_on_startup = true;
+      time_for_ping_alive_answer = "60";
+      try_connecting_for_foo_secs = "60";
+      use_custom_host = false;
+      use_env_http_proxy = false;
+      use_ft_proxies = false;
+      use_srv = true;
+      warn_when_insecure_password = true;
+      warn_when_insecure_ssl_connection = true;
+      zeroconf_email = "";
+      zeroconf_first_name = "";
+      zeroconf_jabber_id = "";
+      zeroconf_last_name = "";
+    };
+
+    "aszlig.net" = {
+      action_when_plaintext_connection = "disconnect";
+      active = true;
+      adjust_priority_with_status = true;
+      allow_no_log_for = "";
+      anonymous_auth = false;
+      answer_receipts = true;
+      autoauth = false;
+      autoconnect = false;
+      autoconnect_as = "online";
+      autonegotiate_esessions = true;
+      autopriority_away = "40";
+      autopriority_chat = "50";
+      autopriority_dnd = "20";
+      autopriority_invisible = "10";
+      autopriority_online = "50";
+      autopriority_xa = "30";
+      autoreconnect = true;
+      client_cert = "";
+      client_cert_encrypted = false;
+      connection_types = "tls ssl plain";
+      custom_host = "aszlig.net";
+      custom_port = "5222";
+      dont_ack_subscription = false;
+      enable_esessions = true;
+      enable_message_carbons = false;
+      file_transfer_proxies = "proxy.headcounter.org";
+      ft_send_local_ips = true;
+      gpg_sign_presence = true;
+      hostname = "aszlig.net";
+      http_auth = "ask";
+      ignore_ssl_errors = "";
+      ignore_unknown_contacts = false;
+      is_zeroconf = false;
+      keep_alive_every_foo_secs = "55";
+      keep_alives_enabled = true;
+      keyid = "8C2DC961";
+      keyname = ''aszlig <"^[0-9]+$"@regexmail.net>'';
+      last_archiving_time = "1970-01-01T00:00:00Z";
+      last_status_msg = "";
+      listen_to_network_manager = true;
+      log_encrypted_sessions = true;
+      minimized_gc = "";
+      "msgwin-height" = "440";
+      "msgwin-width" = "480";
+      "msgwin-x-position" = "-1";
+      "msgwin-y-position" = "-1";
+      name = "aszlig";
+      no_log_for = "";
+      ping_alive_every_foo_secs = "120";
+      ping_alives_enabled = true;
+      priority = "5";
+      proxy = "";
+      publish_location = false;
+      publish_tune = false;
+      request_receipt = true;
+      resource = "redmoon";
+      restore_last_status = false;
+      savepass = true;
+      send_idle_time = true;
+      send_os_info = true;
+      send_time_info = true;
+      ssl_fingerprint_sha1 = "8D:BC:E5:46:AB:B3:53:F7:36:B3:"
+                           + "66:0D:B4:B7:83:32:65:BA:A8:EF";
+      subscribe_activity = true;
+      subscribe_location = true;
+      subscribe_mood = true;
+      subscribe_nick = true;
+      subscribe_tune = true;
+      subscription_request_msg = "";
+      sync_with_global_status = true;
+      test_ft_proxies_on_startup = true;
+      time_for_ping_alive_answer = "60";
+      try_connecting_for_foo_secs = "60";
+      use_custom_host = false;
+      use_env_http_proxy = false;
+      use_ft_proxies = true;
+      use_srv = true;
+      warn_when_insecure_password = true;
+      warn_when_insecure_ssl_connection = true;
+      zeroconf_email = "";
+      zeroconf_first_name = "";
+      zeroconf_jabber_id = "";
+      zeroconf_last_name = "";
+    };
+  };
+
+  defaultstatusmsg = {
+    away = {
+      enabled = false;
+      message = "Be right back.";
+    };
+
+    chat = {
+      enabled = false;
+      message = "I'm free for chat.";
+    };
+
+    dnd = {
+      enabled = false;
+      message = "Do not disturb.";
+    };
+
+    invisible = {
+      enabled = false;
+      message = "Bye!";
+    };
+
+    offline = {
+      enabled = false;
+      message = "Bye!";
+    };
+
+    online = {
+      enabled = false;
+      message = "I'm available.";
+    };
+
+    xa = {
+      enabled = false;
+      message = "I'm not available.";
+    };
+  };
+
+  statusmsg = let
+    defaults = {
+      activity = "";
+      activity_text = "";
+      message = "";
+      mood = "";
+      mood_text = "";
+      subactivity = "";
+    };
+    applyDefaults = const (attrs: defaults // attrs);
+  in mapAttrs applyDefaults {
+    zone.activity = "working";
+    zone.subactivity = "coding";
+    zone.message = "In The Zone[TM]";
+
+    rofa.activity = "working";
+    rofa.activity_text = "Blinded by the lights...";
+    rofa.subactivity = "other";
+    rofa.message = "RoFa";
+
+    kernel.mood = "happy";
+    kernel.message = "Kerneling down for reboot NOW.";
+
+    sleep.activity = "inactive";
+    sleep.subactivity = "sleeping";
+    sleep.mood = "sleepy";
+    sleep.message = "Sleeping the hell out of here...";
+
+    _last_away = {};
+    _last_chat = {};
+    _last_dnd = {};
+    _last_invisible = {};
+    _last_offline = {};
+    _last_online = {};
+    _last_xa = {};
+  };
+
+  soundevents = {
+    contact_connected = {
+      enabled = false;
+      path = "connected.wav";
+    };
+
+    contact_disconnected = {
+      enabled = false;
+      path = "disconnected.wav";
+    };
+
+    first_message_received = {
+      enabled = true;
+      path = "message1.wav";
+    };
+
+    gmail_received = {
+      enabled = false;
+      path = "message1.wav";
+    };
+
+    message_sent = {
+      enabled = false;
+      path = "sent.wav";
+    };
+
+    muc_message_highlight = {
+      enabled = true;
+      path = "gc_message1.wav";
+    };
+
+    muc_message_received = {
+      enabled = false;
+      path = "gc_message2.wav";
+    };
+
+    next_message_received_focused = {
+      enabled = false;
+      path = "message2.wav";
+    };
+
+    next_message_received_unfocused = {
+      enabled = true;
+      path = "message2.wav";
+    };
+  };
+
+  proxies.Tor = {
+    bosh_content = "text/xml; charset=utf-8";
+    bosh_hold = "2";
+    bosh_http_pipelining = false;
+    bosh_uri = "";
+    bosh_useproxy = false;
+    bosh_wait = "30";
+    bosh_wait_for_restart_response = false;
+    host = "localhost";
+    pass = "";
+    port = "9050";
+    type = "socks5";
+    useauth = false;
+    user = "";
+  };
+
+  themes = {
+    blue = {
+      accountbgcolor = "#0c232e";
+      accountfont = "Liberation Mono 8";
+      accountfontattrs = "B";
+      accounttextcolor = "#ffffff";
+      bannerbgcolor = "#0f4864";
+      bannerfont = "Liberation Mono Bold 12";
+      bannerfontattrs = "B";
+      bannertextcolor = "#ffffff";
+      contactbgcolor = "#0c232b";
+      contactfont = "Liberation Mono Bold 8";
+      contactfontattrs = "";
+      contacttextcolor = "#ffffff";
+      groupbgcolor = "#18515f";
+      groupfont = "Liberation Mono Bold 8";
+      groupfontattrs = "I";
+      grouptextcolor = "#ffffff";
+      state_composing_color = "green4";
+      state_gone_color = "grey";
+      state_inactive_color = "grey62";
+      state_muc_directed_msg_color = "red2";
+      state_muc_msg_color = "mediumblue";
+      state_paused_color = "mediumblue";
+    };
+
+    default = {
+      accountbgcolor = "";
+      accountfont = "";
+      accountfontattrs = "B";
+      accounttextcolor = "";
+      bannerbgcolor = "";
+      bannerfont = "";
+      bannerfontattrs = "B";
+      bannertextcolor = "";
+      contactbgcolor = "";
+      contactfont = "";
+      contactfontattrs = "";
+      contacttextcolor = "";
+      groupbgcolor = "";
+      groupfont = "";
+      groupfontattrs = "I";
+      grouptextcolor = "";
+      state_composing_color = "green4";
+      state_gone_color = "grey";
+      state_inactive_color = "grey62";
+      state_muc_directed_msg_color = "red2";
+      state_muc_msg_color = "mediumblue";
+      state_paused_color = "mediumblue";
+    };
+
+    green = {
+      accountbgcolor = "#94aa8c";
+      accountfont = "";
+      accountfontattrs = "B";
+      accounttextcolor = "";
+      bannerbgcolor = "#94aa8c";
+      bannerfont = "";
+      bannerfontattrs = "B";
+      bannertextcolor = "";
+      contactbgcolor = "";
+      contactfont = "";
+      contactfontattrs = "";
+      contacttextcolor = "#000000";
+      groupbgcolor = "#eff3e7";
+      groupfont = "";
+      groupfontattrs = "I";
+      grouptextcolor = "#0000ff";
+      state_composing_color = "green4";
+      state_gone_color = "grey";
+      state_inactive_color = "grey62";
+      state_muc_directed_msg_color = "red2";
+      state_muc_msg_color = "mediumblue";
+      state_paused_color = "mediumblue";
+    };
+
+    grocery = {
+      accountbgcolor = "#6bbe18";
+      accountfont = "";
+      accountfontattrs = "B";
+      accounttextcolor = "";
+      bannerbgcolor = "#108abd";
+      bannerfont = "";
+      bannerfontattrs = "B";
+      bannertextcolor = "";
+      contactbgcolor = "#efb26b";
+      contactfont = "";
+      contactfontattrs = "";
+      contacttextcolor = "#000000";
+      groupbgcolor = "#ceefad";
+      groupfont = "";
+      groupfontattrs = "I";
+      grouptextcolor = "#12125a";
+      state_composing_color = "green4";
+      state_gone_color = "grey";
+      state_inactive_color = "grey62";
+      state_muc_directed_msg_color = "red2";
+      state_muc_msg_color = "mediumblue";
+      state_paused_color = "mediumblue";
+    };
+
+    human = {
+      accountbgcolor = "#996442";
+      accountfont = "";
+      accountfontattrs = "B";
+      accounttextcolor = "";
+      bannerbgcolor = "#996442";
+      bannerfont = "";
+      bannerfontattrs = "B";
+      bannertextcolor = "";
+      contactbgcolor = "";
+      contactfont = "";
+      contactfontattrs = "";
+      contacttextcolor = "#000000";
+      groupbgcolor = "#e3ca94";
+      groupfont = "";
+      groupfontattrs = "I";
+      grouptextcolor = "#ab5920";
+      state_composing_color = "green4";
+      state_gone_color = "grey";
+      state_inactive_color = "grey62";
+      state_muc_directed_msg_color = "red2";
+      state_muc_msg_color = "mediumblue";
+      state_paused_color = "mediumblue";
+    };
+
+    marine = {
+      accountbgcolor = "#918caa";
+      accountfont = "";
+      accountfontattrs = "B";
+      accounttextcolor = "";
+      bannerbgcolor = "#918caa";
+      bannerfont = "";
+      bannerfontattrs = "B";
+      bannertextcolor = "";
+      contactbgcolor = "";
+      contactfont = "";
+      contactfontattrs = "";
+      contacttextcolor = "#000000";
+      groupbgcolor = "#e9e7f3";
+      groupfont = "";
+      groupfontattrs = "I";
+      grouptextcolor = "";
+      state_composing_color = "green4";
+      state_gone_color = "grey";
+      state_inactive_color = "grey62";
+      state_muc_directed_msg_color = "red2";
+      state_muc_msg_color = "mediumblue";
+      state_paused_color = "mediumblue";
+    };
+  };
+}
diff --git a/modules/user/aszlig/programs/gajim/config.patch b/modules/user/aszlig/programs/gajim/config.patch
new file mode 100644
index 00000000..fcfcc371
--- /dev/null
+++ b/modules/user/aszlig/programs/gajim/config.patch
@@ -0,0 +1,80 @@
+diff --git a/src/common/optparser.py b/src/common/optparser.py
+index f84b18a..0078317 100644
+--- a/src/common/optparser.py
++++ b/src/common/optparser.py
+@@ -30,6 +30,7 @@ import os
+ import sys
+ import locale
+ import re
++from itertools import chain
+ from time import time
+ from common import gajim
+ from common import helpers
+@@ -46,19 +47,25 @@ class OptionsParser:
+ 
+     def read(self):
+         try:
+-            fd = open(self.__filename)
++            cfg = nixfd = open("@nix_config@", 'r')
+         except Exception:
+             if os.path.exists(self.__filename):
+                 #we talk about a file
+                 print _('Error: cannot open %s for reading') % self.__filename
+             return False
+ 
++        try:
++            fd = open(self.__filename)
++            cfg = chain(cfg, fd)
++        except Exception:
++            fd = None
++
+         new_version = gajim.config.get('version')
+         new_version = new_version.split('-', 1)[0]
+         seen = set()
+         regex = re.compile(r"(?P<optname>[^.=]+)(?:(?:\.(?P<key>.+))?\.(?P<subname>[^.=]+))?\s=\s(?P<value>.*)")
+ 
+-        for line in fd:
++        for line in cfg:
+             try:
+                 line = line.decode('utf-8')
+             except UnicodeDecodeError:
+@@ -79,10 +86,13 @@ class OptionsParser:
+         self.update_config(old_version, new_version)
+         self.old_values = {} # clean mem
+ 
+-        fd.close()
++        if fd is not None:
++            fd.close()
++
++        nixfd.close()
+         return True
+ 
+-    def write_line(self, fd, opt, parents, value):
++    def write_line(self, (fd, nixcfg), opt, parents, value):
+         if value is None:
+             return
+         value = value[1]
+@@ -102,17 +112,21 @@ class OptionsParser:
+                     p = p.encode('utf-8')
+                 s += p + '.'
+         s += opt
+-        fd.write(s + ' = ' + value + '\n')
++        line = s + ' = ' + value + '\n'
++        if not nixcfg.startswith(line) and not ('\n' + line) in nixcfg:
++            fd.write(line)
+ 
+     def write(self):
+         (base_dir, filename) = os.path.split(self.__filename)
+         self.__tempfile = os.path.join(base_dir, '.' + filename)
++
+         try:
++            nixcfg = open("@nix_config@", 'r').read()
+             f = open(self.__tempfile, 'w')
+         except IOError, e:
+             return str(e)
+         try:
+-            gajim.config.foreach(self.write_line, f)
++            gajim.config.foreach(self.write_line, (f, nixcfg))
+         except IOError, e:
+             return str(e)
+         f.flush()
diff --git a/modules/user/aszlig/programs/gajim/default.nix b/modules/user/aszlig/programs/gajim/default.nix
new file mode 100644
index 00000000..4c8a4304
--- /dev/null
+++ b/modules/user/aszlig/programs/gajim/default.nix
@@ -0,0 +1,59 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+  cfg = config.vuizvui.user.aszlig.programs.gajim;
+
+  gtkTheme = pkgs.writeText "gajim.gtkrc" ''
+    style "default" {
+      fg[NORMAL] = "#d5faff"
+      fg[ACTIVE] = "#fffeff"
+      fg[SELECTED] = "#fffeff"
+      fg[INSENSITIVE] = "#85aaaf"
+      fg[PRELIGHT] = "#d7f2ff"
+
+      text[NORMAL] = "#fffefe"
+      text[ACTIVE] = "#fffeff"
+      text[SELECTED] = "#fffeff"
+      text[INSENSITIVE] = "#85aaaf"
+      text[PRELIGHT] = "#d7f2ff"
+
+      bg[NORMAL] = "#0f4866"
+      bg[ACTIVE] = "#0c232e"
+      bg[SELECTED] = "#005a56"
+      bg[INSENSITIVE] = "#103040"
+      bg[PRELIGHT] = "#1d5875"
+
+      base[NORMAL] = "#0c232e"
+      base[ACTIVE] = "#0f4864"
+      base[SELECTED] = "#005a56"
+      base[INSENSITIVE] = "#103040"
+      base[PRELIGHT] = "#1d5875"
+    }
+
+    class "GtkWidget" style "default"
+
+    gtk-enable-animations = 0
+  '';
+
+  gajimPatched = overrideDerivation pkgs.gajim (o: {
+    patches = (o.patches or []) ++ singleton (pkgs.substituteAll {
+      src = ./config.patch;
+      nix_config = pkgs.writeText "gajim.config" (import ./config.nix lib);
+    });
+    postPatch = (o.postPatch or "") + ''
+      sed -i -e '/^export/i export GTK2_RC_FILES="${gtkTheme}"' \
+        scripts/gajim.in
+    '';
+  });
+
+in {
+  options.vuizvui.user.aszlig.programs.gajim = {
+    enable = mkEnableOption "aszlig's Gajim";
+  };
+
+  config = mkIf cfg.enable {
+    environment.systemPackages = [ gajimPatched ];
+  };
+}
diff --git a/modules/user/aszlig/programs/git/default.nix b/modules/user/aszlig/programs/git/default.nix
new file mode 100644
index 00000000..0090b617
--- /dev/null
+++ b/modules/user/aszlig/programs/git/default.nix
@@ -0,0 +1,74 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.vuizvui.user.aszlig.programs.git;
+
+  genConf = attrs: let
+    escStr = s: "\"${escape [ "\"" "\\" ] s}\"";
+    mkVal = v: if isBool v && v  then "true"
+          else if isBool v && !v then "false"
+          else escStr (toString v);
+    mkLine = key: val: "${key} = ${mkVal val}";
+
+    filterNull = filterAttrs (_: v: !(isNull v));
+
+    mkSection = sect: subsect: vals: ''
+      [${sect}${optionalString (subsect != null) " ${escStr subsect}"}]
+      ${concatStringsSep "\n" (mapAttrsToList mkLine (filterNull vals))}
+    '';
+
+    mkConf = sect: content: let
+      subs = filterAttrs (_: isAttrs) content;
+      nonSubs = filterAttrs (_: s: !isAttrs s) content;
+      hasPlain = (attrNames nonSubs) != [];
+      plainSects = singleton (mkSection sect null nonSubs);
+    in mapAttrsToList (mkSection sect) subs ++ optional hasPlain plainSects;
+
+    text = concatStringsSep "\n" (flatten (mapAttrsToList mkConf attrs));
+  in pkgs.writeText "gitconfig" text;
+
+  gitPatched = overrideDerivation pkgs.gitFull (git: {
+    makeFlags = let
+      oldFlags = git.makeFlags or [];
+      newVal = "ETC_GITCONFIG=${cfg.config}";
+    in if isList oldFlags
+       then oldFlags ++ [ newVal ]
+       else "${oldFlags} ${newVal}";
+  });
+in {
+  options.vuizvui.user.aszlig.programs.git = {
+    enable = mkEnableOption "Git";
+
+    config = mkOption {
+      description = "System-wide default config for Git";
+
+      type = let
+        superType = types.attrsOf types.unspecified;
+      in mkOptionType {
+        name = "attribute set of either plain values or "
+             + "attribute sets of values (if it is a subsection)";
+        inherit (superType) check merge;
+        inherit (superType) getSubOptions getSubModules substSubModules;
+      };
+
+      default = {};
+      example = {
+        color.ui = "auto";
+        merge.tool = "vimdiff";
+        guitool.foobar.noconsole = true;
+      };
+
+      apply = genConf;
+    };
+  };
+
+  config = mkIf cfg.enable {
+    environment.systemPackages = [
+      gitPatched
+      pkgs.gitAndTools.git-remote-hg
+      pkgs.gitAndTools.hub
+    ];
+  };
+}
diff --git a/modules/user/aszlig/programs/mpv/default.nix b/modules/user/aszlig/programs/mpv/default.nix
new file mode 100644
index 00000000..1e412c71
--- /dev/null
+++ b/modules/user/aszlig/programs/mpv/default.nix
@@ -0,0 +1,24 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+  cfg = config.vuizvui.user.aszlig.programs.mpv;
+
+  patchedMpv = overrideDerivation pkgs.mpv (o: {
+    installPhase = o.installPhase + ''
+      cat > "$out/etc/mpv/mpv.conf" <<CONFIG
+      ao=pulse
+      CONFIG
+    '';
+  });
+
+in {
+  options.vuizvui.user.aszlig.programs.mpv = {
+    enable = mkEnableOption "aszlig's MPV";
+  };
+
+  config = mkIf cfg.enable {
+    environment.systemPackages = [ patchedMpv ];
+  };
+}
diff --git a/modules/user/aszlig/programs/taalo-build/default.nix b/modules/user/aszlig/programs/taalo-build/default.nix
new file mode 100644
index 00000000..6b50df1d
--- /dev/null
+++ b/modules/user/aszlig/programs/taalo-build/default.nix
@@ -0,0 +1,65 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+{
+  options.vuizvui.user.aszlig.programs.taalo-build = {
+    enable = mkEnableOption "aszlig's build helper for remote builds";
+  };
+  config = mkIf config.vuizvui.user.aszlig.programs.taalo-build.enable {
+    environment.systemPackages = singleton (pkgs.writeScriptBin "taalo-build" ''
+      #!${pkgs.perl}/bin/perl -I${pkgs.nix}/lib/perl5/site_perl
+      use strict;
+      use Nix::CopyClosure;
+      use Nix::SSH;
+      use IPC::Open2;
+
+      binmode STDERR, ":encoding(utf8)";
+
+      open my $instantiate, "-|", "nix-instantiate", @ARGV
+        or die "Failed to run nix-instantiate";
+      my $to_realize = join "", <$instantiate>;
+      close $instantiate or exit $? >> 8;
+
+      chomp $to_realize;
+
+      my ($from, $to);
+      my $dest = 'nix-remote-build@taalo.headcounter.org';
+      my $cmd = "exec ssh $dest -C -- nix-store --serve --write";
+      my $pid = open2($from, $to, $cmd);
+
+      # Do the handshake.
+      my $magic;
+      eval {
+          my $SERVE_MAGIC_1 = 0x390c9deb; # FIXME
+          my $clientVersion = 0x200;
+          syswrite($to, pack("L<x4L<x4", $SERVE_MAGIC_1, $clientVersion))
+            or die;
+          $magic = readInt($from);
+      };
+
+      die "unable to connect to taalo\n" if $@;
+      die "did not get valid handshake from taalo\n" if $magic != 0x5452eecb;
+
+      my $serverVersion = readInt($from);
+      die "unsupported server version\n"
+        if $serverVersion < 0x200 || $serverVersion >= 0x300;
+
+      Nix::CopyClosure::copyToOpen(
+        $from, $to, "taalo", [$to_realize], 0, 0, 0, 1
+      );
+
+      writeInt(6, $to) or die;
+      writeStrings([$to_realize], $to);
+      writeInt(0, $to);
+      writeInt(0, $to);
+
+      my $res = readInt($from);
+
+      close $to;
+
+      waitpid($pid, 0);
+      exit $res;
+    '');
+  };
+}
diff --git a/modules/user/aszlig/programs/taskwarrior/config.patch b/modules/user/aszlig/programs/taskwarrior/config.patch
new file mode 100644
index 00000000..4ee4c4ce
--- /dev/null
+++ b/modules/user/aszlig/programs/taskwarrior/config.patch
@@ -0,0 +1,48 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 5558f6b..c8956f8 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -91,6 +91,9 @@ SET (TASK_DOCDIR  share/doc/task CACHE STRING "Installation directory for doc fi
+ SET (TASK_RCDIR "${TASK_DOCDIR}/rc" CACHE STRING "Installation directory for configuration files")
+ SET (TASK_BINDIR  bin            CACHE STRING "Installation directory for the binary")
+ 
++SET (SYSTEM_TASKRC "${CMAKE_INSTALL_PREFIX}/etc/taskrc"
++     CACHE STRING "System-wide taskrc")
++
+ message ("-- Looking for SHA1 references")
+ if (EXISTS ${CMAKE_SOURCE_DIR}/.git/index)
+   set (HAVE_COMMIT true)
+diff --git a/cmake.h.in b/cmake.h.in
+index 0041e6e..f8c1a0e 100644
+--- a/cmake.h.in
++++ b/cmake.h.in
+@@ -16,6 +16,7 @@
+ 
+ /* Installation details */
+ #define TASK_RCDIR "${CMAKE_INSTALL_PREFIX}/${TASK_RCDIR}"
++#define SYSTEM_TASKRC "${SYSTEM_TASKRC}"
+ 
+ /* Localization */
+ #define PACKAGE_LANGUAGE ${PACKAGE_LANGUAGE}
+diff --git a/src/Context.cpp b/src/Context.cpp
+index 8aae74e..ffa5557 100644
+--- a/src/Context.cpp
++++ b/src/Context.cpp
+@@ -121,7 +121,8 @@ int Context::initialize (int argc, const char** argv)
+     }
+ 
+     config.clear ();
+-    config.load (rc_file);
++    config.load (SYSTEM_TASKRC);
++    config.load (rc_file, 2);
+     CLI2::applyOverrides (argc, argv);
+ 
+     ////////////////////////////////////////////////////////////////////////////
+@@ -146,7 +147,6 @@ int Context::initialize (int argc, const char** argv)
+     }
+ 
+     tdb2.set_location (data_dir);
+-    createDefaultConfig ();
+ 
+     ////////////////////////////////////////////////////////////////////////////
+     //
diff --git a/modules/user/aszlig/programs/taskwarrior/default.nix b/modules/user/aszlig/programs/taskwarrior/default.nix
new file mode 100644
index 00000000..99d428de
--- /dev/null
+++ b/modules/user/aszlig/programs/taskwarrior/default.nix
@@ -0,0 +1,36 @@
+{ config, pkgs, lib, ... }:
+
+let
+  cfg = config.vuizvui.user.aszlig.programs.taskwarrior;
+
+  taskrc = pkgs.writeText "taskrc.in" ''
+    data.location=~/.task
+    include @out@/share/doc/task/rc/dark-yellow-green.theme
+
+    color=on
+    dateformat=Y-m-d
+    dateformat.annotation=Y-m-d
+    dateformat.edit=Y-m-d H:N:S
+    dateformat.holiday=YMD
+    dateformat.info=Y-m-d H:N:S
+    dateformat.report=Y-m-d
+    weekstart=Monday
+  '';
+
+  taskwarrior = pkgs.taskwarrior.overrideDerivation (t: {
+    patches = (t.patches or []) ++ [ ./config.patch ];
+    postInstall = (t.postInstall or "") + ''
+      mkdir -p "$out/etc"
+      substituteAll "${taskrc}" "$out/etc/taskrc"
+    '';
+  });
+
+in {
+  options.vuizvui.user.aszlig.programs.taskwarrior = {
+    enable = lib.mkEnableOption "aszlig's TaskWarrior";
+  };
+
+  config = lib.mkIf cfg.enable {
+    environment.systemPackages = lib.singleton taskwarrior;
+  };
+}
diff --git a/modules/user/aszlig/programs/vim/default.nix b/modules/user/aszlig/programs/vim/default.nix
new file mode 100644
index 00000000..cb6149fe
--- /dev/null
+++ b/modules/user/aszlig/programs/vim/default.nix
@@ -0,0 +1,384 @@
+{ config, pkgs, lib, ... }:
+
+let
+  cfg = config.vuizvui.user.aszlig.programs.vim;
+
+  fetchVimScript = { srcId, sha256, type, name }: let
+    baseUrl = "http://www.vim.org/scripts/download_script.php";
+    src = pkgs.fetchurl {
+      name = "script${toString srcId}.vim";
+      url = "${baseUrl}?src_id=${toString srcId}";
+      inherit sha256;
+    };
+  in pkgs.stdenv.mkDerivation {
+    name = "vim-${type}-${toString srcId}";
+    buildCommand = ''
+      install -vD -m 0644 "${src}" "$out/${type}/${name}.vim"
+    '';
+  };
+
+  extractSubdir = subdir: src: pkgs.stdenv.mkDerivation {
+    name = "${src.name}-subdir";
+    phases = [ "unpackPhase" "installPhase" ];
+    inherit src;
+    installPhase = ''
+      cp -Rd "${subdir}" "$out"
+    '';
+  };
+
+  mkVimPlugins = plugins: pkgs.buildEnv {
+    name = "vim-plugins";
+    paths = with lib; mapAttrsToList (const id) plugins;
+    ignoreCollisions = true;
+    postBuild = ''
+      find -L "$out" -mindepth 1 -maxdepth 1 -type f -delete
+    '';
+  };
+
+  pluginDeps = {
+    vimAddonMwUtils = pkgs.fetchFromGitHub {
+      owner = "MarcWeber";
+      repo = "vim-addon-mw-utils";
+      rev = "0c5612fa31ee434ba055e21c76f456244b3b5109";
+      sha256 = "147s1k4n45d3x281vj35l26sv4waxjlpqdn83z3k9n51556h1d45";
+    };
+
+    vimAddonCompletion = pkgs.fetchFromGitHub {
+      owner = "MarcWeber";
+      repo = "vim-addon-completion";
+      rev = "80f717d68df5b0d7b32228229ddfd29c3e86e435";
+      sha256 = "08acffzy847w8b5j8pdw6qsidm2859ki5q351n4r7fkr969p80mi";
+    };
+
+    vimAddonActions = pkgs.fetchFromGitHub {
+      owner = "MarcWeber";
+      repo = "vim-addon-actions";
+      rev = "a5d20500fb8812958540cf17862bd73e7af64936";
+      sha256 = "1wfkwr89sn2w97i94d0dqylcg9mr6pirjadi0a4l492nfnsh99bc";
+    };
+
+    vimAddonBackgroundCmd = pkgs.fetchFromGitHub {
+      owner = "MarcWeber";
+      repo = "vim-addon-background-cmd";
+      rev = "14df72660a95804a57c02b9ff0ae3198608e2491";
+      sha256 = "09lh6hqbx05gm7njhpqvhqdwig3pianq9rddxmjsr6b1vylgdgg4";
+    };
+
+    vimAddonErrorFormats = pkgs.fetchFromGitHub {
+      owner = "MarcWeber";
+      repo = "vim-addon-errorformats";
+      rev = "dcbb203ad5f56e47e75fdee35bc92e2ba69e1d28";
+      sha256 = "159zqm69fxbxcv3b2y99g57bf20qrzsijcvb5rzy2njxah3049m1";
+    };
+
+    vimAddonToggleBuffer = pkgs.fetchFromGitHub {
+      owner = "MarcWeber";
+      repo = "vim-addon-toggle-buffer";
+      rev = "a1b38b9c5709cba666ed2d84ef06548f675c6b0b";
+      sha256 = "1xq38kfdm36c34ln66znw841q797w5gm8bpq1x64bsf2h6n3ml03";
+    };
+
+    vimAddonGotoThingAtCursor = pkgs.fetchFromGitHub {
+      owner = "MarcWeber";
+      repo = "vim-addon-goto-thing-at-cursor";
+      rev = "f052e094bdb351829bf72ae3435af9042e09a6e4";
+      sha256 = "1ksm2b0j80zn8sz2y227bpcx4jsv76lwgr2gpgy2drlyqhn2vlv0";
+    };
+
+    vimAddonViews = pkgs.fetchFromGitHub {
+      owner = "MarcWeber";
+      repo = "vim-addon-views";
+      rev = "d1383ad56d0a07d7350880adbadf9de501729fa8";
+      sha256 = "09gqh7w5rk4lmra706schqaj8dnisf396lpsipm7xv6gy1qbslnv";
+    };
+
+    vimAddonSwfMill = pkgs.fetchFromGitHub {
+      owner = "MarcWeber";
+      repo = "vim-addon-swfmill";
+      rev = "726777e02cbe3ad8f82e37421fb37674f446a148";
+      sha256 = "0ablzl5clgfzhzwvzzbaj0cda0b4cyrj3pbv02f26hx7rfnssaqm";
+    };
+
+    vimHaxeSyntax = pkgs.fetchFromGitHub {
+      owner = "MarcWeber";
+      repo = "vim-haxe-syntax";
+      rev = "500acc2f2ab92d77ff6cd04fdc7868800c033dfa";
+      sha256 = "1ipm0igplplfmscm3bk95qpf9rw71h133l9shmw54mxr4h0ymnmj";
+    };
+
+    tlib = pkgs.fetchFromGitHub {
+      owner = "tomtom";
+      repo = "tlib_vim";
+      rev = "bc4097bd38c4bc040fe1e74df68dec6c9adfcb6a";
+      sha256 = "19v7bgmkk4k2g1z62bd0kky29xxfq96l7wfrl27wb2zijlhbrnpz";
+    };
+
+    vamStub = pkgs.writeTextFile {
+      name = "vam-stub";
+      destination = "/autoload/vam.vim";
+      text = ''
+        fun! vam#DefineAndBind(local, global, default)
+          return ' if !exists('.string(a:global).') |
+                 \ let '.a:global.' = '.a:default.' |
+                 \ endif | let '.a:local.' = '.a:global
+        endfun
+      '';
+    };
+  };
+
+  plugins = mkVimPlugins (pluginDeps // {
+    vimErl = pkgs.fetchFromGitHub {
+      owner = "jimenezrick";
+      repo = "vimerl";
+      rev = "823bf8cb515bb10396c705cdc017aa9121cc4d12";
+      sha256 = "0sybkx8iy8qhr6nlwn52j7zd5v99rn0b8wbg43d112z2px4yq5x3";
+    };
+
+    vimHaxe = pkgs.fetchFromGitHub {
+      owner = "MarcWeber";
+      repo = "vim-haxe";
+      rev = "8efc705db41a01713d67d437f29866a1ff831e8a";
+      sha256 = "15kv13gvpgf23p0566qrlw7gmpir2z7g5dnkfs1knmcwzw45am5d";
+    };
+
+    factor = extractSubdir "misc/vim" (pkgs.fetchFromGitHub {
+      owner = "slavapestov";
+      repo = "factor";
+      rev = "0d6f70cc7cf35cc627ee78886e2932091a651fe6";
+      sha256 = "0lmqzvrmwgmxpcpwgn59y033sf4jybmw3lffbjwww5d7ch90333q";
+    });
+
+    opaLang = extractSubdir "tools/editors/vim" (pkgs.fetchFromGitHub {
+      owner = "MLstate";
+      repo = "opalang";
+      rev = "94e4e6d9d8da9a72214f4f28dd1ffa1a987997eb";
+      sha256 = "0d6b67868cfqakkz63y5ynpz549lbpfzc3c3x7kx3ffsv10xy3bb";
+    });
+
+    lslvim = pkgs.fetchFromGitHub {
+      owner = "sukima";
+      repo = "LSLvim";
+      rev = "f269de39a1c713a43470e90d0ec78208c0f05e0b";
+      sha256 = "1plwx5id3jsj4y6yhshlf3rishxhf1b9k47g2cpzaczvqb5bl40w";
+    };
+
+    vimSyntaxShakespeare = pkgs.fetchFromGitHub {
+      owner = "pbrisbin";
+      repo = "vim-syntax-shakespeare";
+      rev = "29085ae94ee3dbd7f39f2a7705d86692ef5bc365";
+      sha256 = "0kvys81jiwqzwmpbk1lvbciw28yha4shd1xby5saiy4b68l6d8rk";
+    };
+
+    glsl = fetchVimScript {
+      name = "glsl";
+      srcId = 3194;
+      sha256 = "1vqfcpjmfyjc95wns3i84kgd1k5r2lwjjvjcprygi9g9vng7i5xc";
+      type = "syntax";
+    };
+
+    actionScript = fetchVimScript {
+      name = "actionscript";
+      srcId = 1205;
+      sha256 = "0pdzqg678lhn7lmqf3z9icpj6ff2nnghsxy983kxkn8sblnzlhfs";
+      type = "syntax";
+    };
+
+    indentPython = fetchVimScript {
+      name = "python";
+      srcId = 4316;
+      sha256 = "1pgdiaqd1hm0qpspy1asj7i103pq0846lnjrxvl6pk17ymww9pmk";
+      type = "indent";
+    };
+
+    nixAddon = pkgs.stdenv.mkDerivation {
+      name = "vim-nix-support";
+
+      lnl7 = pkgs.fetchFromGitHub {
+        owner = "LnL7";
+        repo = "vim-nix";
+        rev = "f0b7bd4bce5ed0f12fb4d26115c84fb3edcd1e12";
+        sha256 = "0x12a191xafn7918xa8r4sjiw79005lcr0yv5kjc4p1izwddfgdv";
+      };
+
+      src = pkgs.fetchFromGitHub {
+        owner = "MarcWeber";
+        repo = "vim-addon-nix";
+        rev = "2aed79ba5d8c5e6abd102de77e55e242f61b17f1";
+        sha256 = "0zx1q9994py6jmm0qbbx6fc1dy5la8zfskkbvqqxssxrl5dx7vvi";
+      };
+
+      phases = [ "unpackPhase" "patchPhase" "installPhase" ];
+      patchPhase = ''
+        for what in indent syntax; do
+          install -vD -m 0644 "$lnl7/$what/nix.vim" "$what/nix.vim"
+        done
+        sed -i -re '/^ *au(group)? /,/^ *au(group)? +end/ {
+          s/^ *au(tocmd)? +((BufRead|BufNewFile),?)+ +[^ ]+ +setl(ocal)?/${
+            "& sw=2 sts=2 et iskeyword+=-"
+          }/
+        }' plugin/vim-addon-nix.vim
+        grep '^setlocal' "$lnl7/ftplugin/nix.vim" >> ftplugin/nix.vim
+      '';
+
+      installPhase = ''
+        cp -Rd . "$out"
+      '';
+    };
+
+    urwebAddon = pkgs.fetchFromGitHub {
+      owner = "MarcWeber";
+      repo = "vim-addon-urweb";
+      rev = "49ea3960a9924a5dd7ff70956d1a7c0479a55773";
+      sha256 = "090ww8nxqsabrwf4r8g7a93kawnp6zwpsx65yxpacwwwlbc73m7s";
+    };
+
+    indentHaskell = fetchVimScript {
+      name = "haskell";
+      srcId = 7407;
+      sha256 = "1lj44jkyihmcnj2kcfckhqzr9gfipda9frbzicix2wrc5728kjsv";
+      type = "indent";
+    };
+
+    fishSyntax = fetchVimScript {
+      name = "fish";
+      srcId = 20242;
+      sha256 = "12gfmyxxf84f19bp8xfmkb9phbfkifn89sjgi8hnv6dn0a5y1zpj";
+      type = "syntax";
+    };
+
+    elmVim = pkgs.fetchFromGitHub {
+      owner = "lambdatoast";
+      repo = "elm.vim";
+      rev = "ad556c97e26072b065825852ceead0fe6a1f7d7c";
+      sha256 = "19k6b6m5ngm5qn2f3p13hzjyvha53fpdgq691z8n0lwfn8831b21";
+    };
+
+    flake8 = pkgs.fetchFromGitHub {
+      owner = "nvie";
+      repo = "vim-flake8";
+      rev = "293613dbe731a2875ce93739e7b64ee504d8bbab";
+      sha256 = "0xmqmbh66g44vhx9769mzs820k6ksbpfnsfvivmbhzlps2hjqpqg";
+    };
+
+    vader = pkgs.fetchFromGitHub {
+      owner = "junegunn";
+      repo = "vader.vim";
+      rev = "ad2c752435baba9e7544d0046f0277c3573439bd";
+      sha256 = "0yvnah4lxk5w5qidc3y5nvl6lpi8rcv26907b3w7vjskqc935b8f";
+    };
+  });
+
+  generic = ''
+    syntax on
+    colorscheme elflord
+
+    " boolean
+    set nocompatible
+    set showcmd
+    set showmatch
+    set ignorecase
+    set smartcase
+    set incsearch
+    set modeline
+    set smarttab
+    set expandtab
+    set smartindent
+    set ruler
+
+    " non-boolean
+    set tabstop=4
+    set softtabstop=4
+    set shiftwidth=4
+    set textwidth=80
+    set termencoding=ascii
+    set backspace=indent,eol,start
+    set background=dark
+  '';
+
+  plugin = ''
+    " erlang
+    let erlang_folding = 0
+    let erlang_highlight_bif = 1
+    let erlang_force_use_vimerl_indent = 1
+
+    " python
+    let python_highlight_numbers = 1
+    let python_highlight_builtins = 1
+    let python_highlight_exceptions = 1
+    let g:flake8_cmd = '${pkgs.pythonPackages.flake8}/bin/flake8'
+
+    " all plugins
+    set runtimepath^=${plugins}
+    set runtimepath+=${plugins}/after
+    runtime! ftdetect/*.vim
+  '';
+
+  autocmd = ''
+    " jump to last position
+    au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") |
+                   \ exe "normal! g'\"zz" | endif
+
+    " filetype defaults
+    filetype plugin indent on
+    au BufNewFile,BufRead *.as set filetype=actionscript
+    au BufNewFile,BufRead *.html set tabstop=4|set shiftwidth=4|set expandtab
+    au FileType python set textwidth=79
+    au FileType gitcommit set textwidth=72
+    au FileType docbk set tabstop=2 shiftwidth=2 expandtab
+
+    " highlight unnecessary whitespace
+    highlight ExtraWhitespace ctermbg=red guibg=red
+    match ExtraWhitespace /\s\+$/
+    au BufWinEnter,InsertLeave * match ExtraWhitespace /\s\+$/
+    au InsertEnter * match ExtraWhitespace /\s\+\%#\@<!$/
+    " prevent colorscheme from overriding these highlights
+    au ColorScheme * highlight ExtraWhitespace ctermbg=red guibg=red
+
+    " highlight everything exceeding 80 characters
+    au BufWinEnter * let w:m2=matchadd('ErrorMsg', '\%>80v.\+', -1)
+  '';
+
+  misc = ''
+    " ASCII art mode
+    fun! AAMode()
+      highlight clear ExtraWhitespace
+      for m in getmatches()
+        if m.group == 'ErrorMsg' && m.pattern == '\%>80v.\+'
+          call matchdelete(m.id)
+        endif
+      endfor
+    endfun
+
+    command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis
+      \ | wincmd p | diffthis
+
+    " flake everything that has been *detected* as python (not just by suffix).
+    autocmd BufWritePost * if &ft ==# 'python' | call Flake8() | endif
+  '';
+
+  vimrc = pkgs.writeText "vimrc" ''
+    ${generic}
+    ${plugin}
+
+    if has("autocmd")
+      ${autocmd}
+    endif
+
+    ${misc}
+  '';
+
+  patchedVim = lib.overrideDerivation pkgs.vim_configurable (o: {
+    postInstall = (o.postInstall or "") + ''
+      ln -sf "${vimrc}" "$out/share/vim/vimrc"
+    '';
+  });
+
+in {
+  options.vuizvui.user.aszlig.programs.vim = {
+    enable = lib.mkEnableOption "aszlig's Vim";
+  };
+
+  config = lib.mkIf cfg.enable {
+    environment.systemPackages = lib.singleton patchedVim;
+  };
+}
diff --git a/modules/user/aszlig/programs/xpdf/default.nix b/modules/user/aszlig/programs/xpdf/default.nix
new file mode 100644
index 00000000..e7edd806
--- /dev/null
+++ b/modules/user/aszlig/programs/xpdf/default.nix
@@ -0,0 +1,20 @@
+{ config, pkgs, lib, ... }:
+
+let
+  cfg = config.vuizvui.user.aszlig.programs.xpdf;
+
+  xpdf = pkgs.xpdf.overrideDerivation (drv: {
+    postInstall = (drv.postInstall or "") + ''
+      echo 'bind ctrl-o any toggleOutline' >> "$out/etc/xpdfrc"
+    '';
+  });
+
+in {
+  options.vuizvui.user.aszlig.programs.xpdf = {
+    enable = lib.mkEnableOption "aszlig's xpdf";
+  };
+
+  config = lib.mkIf cfg.enable {
+    environment.systemPackages = lib.singleton xpdf;
+  };
+}
diff --git a/modules/user/aszlig/programs/zsh/default.nix b/modules/user/aszlig/programs/zsh/default.nix
new file mode 100644
index 00000000..119b6aa9
--- /dev/null
+++ b/modules/user/aszlig/programs/zsh/default.nix
@@ -0,0 +1,117 @@
+{ config, lib, ... }:
+
+with lib;
+
+let
+  cfg = config.vuizvui.user.aszlig.programs.zsh;
+
+in {
+  options.vuizvui.user.aszlig.programs.zsh = {
+    enable = mkEnableOption "zsh";
+  };
+
+  config = mkIf cfg.enable {
+    environment.shellInit = ''
+      export EDITOR="vim"
+      export EMAIL="aszlig@redmoonstudios.org"
+    '';
+
+    nixpkgs.config.packageOverrides = pkgs: {
+      zsh = overrideDerivation pkgs.zsh (o: {
+        postConfigure = (o.postConfigure or "") + ''
+          sed -i -e '/^name=zsh\/newuser/d' config.modules
+        '';
+      });
+    };
+
+    programs.zsh.enable = true;
+
+    programs.zsh.shellAliases.t = "task";
+
+    programs.zsh.interactiveShellInit = mkAfter ''
+      export HISTFILE=~/.histfile
+      export HISTSIZE=100000
+      export SAVEHIST=100000
+
+      unsetopt SHARE_HISTORY
+
+      setopt extendedglob
+      setopt extendedhistory
+      setopt globcomplete
+      setopt histnostore
+      setopt histreduceblanks
+      setopt correct
+      setopt dvorak
+      setopt interactivecomments
+      setopt autopushd
+      setopt autocd
+      setopt beep
+
+      bindkey -v
+      if [[ "$TERM" = xterm ]]; then
+        bindkey -v '\e[H' vi-beginning-of-line
+        bindkey -v '\e[F' vi-end-of-line
+
+        function set-title() {
+          echo -en "\e]2;$2\a"
+        }
+
+        function reset-title() {
+          echo -en "\e]2;''${(%):-%~}\a\a"
+        }
+
+        autoload -Uz add-zsh-hook
+        add-zsh-hook preexec set-title
+        add-zsh-hook precmd reset-title
+      else
+        bindkey -v '\e[1~' vi-beginning-of-line
+        bindkey -v '\e[4~' vi-end-of-line
+      fi
+
+      bindkey -a '/' history-incremental-pattern-search-backward
+      bindkey -a '?' history-incremental-pattern-search-forward
+      bindkey '\e[A' up-line-or-history
+      bindkey '\e[B' down-line-or-history
+
+      zstyle ':completion:*' completer _expand _complete _ignored _approximate
+      zstyle ':completion:*' expand prefix suffix
+      zstyle ':completion:*' group-name '''
+      zstyle ':completion:*' insert-unambiguous true
+      zstyle ':completion:*' list-colors '''
+      zstyle ':completion:*' list-prompt \
+        %SAt %p: Hit TAB for more, or the character to insert%s
+      zstyle ':completion:*' list-suffixes true
+      zstyle ':completion:*' matcher-list ''' \
+        'm:{[:lower:]}={[:upper:]}' \
+        'm:{[:lower:][:upper:]}={[:upper:][:lower:]}' \
+        'l:|=* r:|=*' \
+        'r:|[._-]=** r:|=**'
+      zstyle ':completion:*' max-errors 2 numeric
+      zstyle ':completion:*' menu select=long
+      zstyle ':completion:*' original true
+      zstyle ':completion:*' preserve-prefix '//[^/]##/'
+      zstyle ':completion:*' prompt \
+        'Hm, did you mistype something? There are %e errors in the completion.'
+      zstyle ':completion:*' select-prompt \
+        %SScrolling active: current selection at %p%s
+      zstyle ':completion:*' use-compctl false
+      zstyle ':completion:*' verbose true
+
+      autoload -Uz compinit
+      compinit
+
+      autoload -Uz zmv
+    '';
+
+    programs.zsh.promptInit = ''
+      autoload -Uz prompt_special_chars
+
+      () {
+          local p_machine='%(!..%B%F{red}%n%b%F{blue}@)%b%F{red}%m'
+          local p_path='%B%F{blue}[%F{cyan}%~%B%F{blue}]'
+          local p_exitcode='%F{green}%?%(!.%F{cyan}>.%b%F{green}>)%b%f '
+          PROMPT="$p_machine$p_path$p_exitcode"
+      }
+    '';
+  };
+}
diff --git a/modules/user/aszlig/services/i3/conky.nix b/modules/user/aszlig/services/i3/conky.nix
new file mode 100644
index 00000000..76c61160
--- /dev/null
+++ b/modules/user/aszlig/services/i3/conky.nix
@@ -0,0 +1,121 @@
+{ pkgs ? import (import ../../../../../nixpkgs-path.nix) {}
+, lib ? import "${import ../../../../../nixpkgs-path.nix}/lib"
+, timeout ? 300
+}:
+
+with lib;
+
+let
+  baseConfig = pkgs.writeText "conkyrc" ''
+    conky.config = {
+      cpu_avg_samples = 2,
+      net_avg_samples = 2,
+      no_buffers = true,
+      out_to_console = true,
+      out_to_ncurses = false,
+      out_to_stderr = false,
+      out_to_x = false,
+      extra_newline = false,
+      update_interval = 1.0,
+      uppercase = false,
+      use_spacer = 'none',
+      pad_percents = 3,
+      use_spacer = 'left',
+    };
+
+    conky.text = ''';
+  '';
+
+  optexpr = name: expr: "\${${name}_disabled:-\\\${${name} ${expr}\\}}";
+  cexpr = name: args: "${optexpr name (concatStringsSep " " args)}";
+
+  mkNetInfo = iface: let
+    upspeed = cexpr "upspeed" [ iface ];
+    downspeed = cexpr "downspeed" [ iface ];
+  in "${upspeed} ${downspeed}";
+
+  mkDiskFree = path: let
+    used = cexpr "fs_used" [ path ];
+    size = cexpr "fs_size" [ path ];
+  in "${used}/${size}";
+
+  gpuTemp = "${cexpr "hwmon" [ "0" "temp" "1" ]}C";
+
+  weather = (cexpr "weather" [
+    "http://weather.noaa.gov/pub/data/observations/metar/stations/"
+    "EDMA"
+    "temperature"
+  ]) + "C";
+
+  mkConky = args: let
+    time = cexpr "time" [ "%a %b %d %T %Z %Y" ];
+    text = concatStringsSep " | " (args ++ singleton time);
+    conky = pkgs.conky.override {
+      weatherMetarSupport = true;
+    };
+  in pkgs.writeScript "conky-run.sh" ''
+    #!${pkgs.stdenv.shell}
+    PATH="${pkgs.coreutils}/bin"
+
+    cpuload() {
+      for i in $(seq 1 $(nproc))
+      do
+        [ $i -eq 1 ] || echo -n ' '
+        echo -n "\''${cpu cpu$i}%"
+      done
+    }
+
+    cputemp_collect() {
+      for i in /sys/bus/platform/devices/coretemp.?/hwmon/hwmon?/temp?_input
+      do
+        [ -e "$i" ] || continue
+        echo "$i" | ${pkgs.gnused}/bin/sed -re \
+          's/^.*hwmon([0-9]+)[^0-9]*([0-9]+).*$/''${hwmon \1 temp \2}/'
+      done
+    }
+
+    cputemp() {
+      echo $(cputemp_collect)
+    }
+
+    tries=0
+    while ! raw_netinfo="$(${
+      "${pkgs.iproute}/sbin/ip route get 8.8.8.8 2> /dev/null"
+    })"; do
+      if [ $tries -ge ${toString timeout} ]; then
+        upspeed_disabled=N/A
+        downspeed_disabled=N/A
+        break
+      fi
+      echo "Waiting for primary network interface to become available..."
+      tries=$(($tries + 1))
+      sleep 1
+    done
+
+    primary_netdev="$(echo "$raw_netinfo" | \
+      ${pkgs.gnused}/bin/sed -nre 's/^.*dev *([^ ]+).*$/\1/p')"
+
+    ${conky}/bin/conky -c "${baseConfig}" -t "${text}"
+  '';
+
+in {
+  left = mkConky [
+    "CPU: $(cpuload) - ${cexpr "cpu" [ "cpu0" ]}%"
+    "MEM: \\$mem/\\$memmax - \\$memperc%"
+    "SWAP: \\$swap/\\$swapmax \\$swapperc%"
+  ];
+
+  right = mkConky [
+    "NET: ${mkNetInfo "$primary_netdev"}"
+    "DF: ${mkDiskFree "/"}"
+    "LAVG: \\$loadavg"
+    "TEMP - CPU: $(cputemp) - GPU: ${gpuTemp} - OUTSIDE: ${weather}"
+  ];
+
+  single = mkConky [
+    "CPU: $(cpuload) - ${cexpr "cpu" [ "cpu0" ]}%"
+    "MEM: \\$mem/\\$memmax - \\$memperc%"
+    "NET: ${mkNetInfo "$primary_netdev"}"
+    "TEMP - CPU: $(cputemp) - OUTSIDE: ${weather}"
+  ];
+}
diff --git a/modules/user/aszlig/services/i3/default.nix b/modules/user/aszlig/services/i3/default.nix
new file mode 100644
index 00000000..0814ac1e
--- /dev/null
+++ b/modules/user/aszlig/services/i3/default.nix
@@ -0,0 +1,136 @@
+{ pkgs, lib, config, ... }:
+
+with lib;
+
+let
+  cfg = config.vuizvui.user.aszlig.services.i3;
+  inherit (config.services.xserver) xrandrHeads;
+
+  # The symbols if you press shift and a number key.
+  wsNumberSymbols = [
+    "exclam" "at" "numbersign" "dollar" "percent"
+    "asciicircum" "ampersand" "asterisk" "parenleft" "parenright"
+  ];
+
+  wsCount = length wsNumberSymbols;
+
+  headCount = length xrandrHeads;
+  wsPerHead = wsCount / headCount;
+  excessWs = wsCount - (headCount * wsPerHead);
+  headModifier = if cfg.reverseHeads then reverseList else id;
+  getHeadAt = elemAt (headModifier xrandrHeads);
+
+  mkSwitchTo = number: "$mod+${if number == 10 then "0" else toString number}";
+
+  mkDefaultWorkspace = number: numberSymbol: {
+    name = toString number;
+    value = {
+      label = mkDefault null;
+      labelPrefix = mkDefault "${toString number}: ";
+      keys.switchTo = mkDefault (mkSwitchTo number);
+      keys.moveTo = mkDefault "$mod+Shift+${numberSymbol}";
+      head = if headCount == 0 then mkDefault null
+             else mkDefault (getHeadAt ((number - (excessWs + 1)) / wsPerHead));
+    };
+  };
+
+  wsCfgList = mapAttrsToList (_: getAttr "config") cfg.workspaces;
+  wsConfig = concatStrings wsCfgList;
+  defaultWorkspaces = listToAttrs (imap mkDefaultWorkspace wsNumberSymbols);
+
+  conky = import ./conky.nix {
+    inherit pkgs lib;
+    timeout = cfg.networkTimeout;
+  };
+
+  mkBar = output: statusCmd: singleton ''
+    bar {
+      ${optionalString (output != null) "output ${output}"}
+      ${optionalString (statusCmd != null) "status_command ${statusCmd}"}
+      colors {
+        focused_workspace  #5c5cff #e5e5e5
+        active_workspace   #ffffff #0000ee
+        inactive_workspace #00cdcd #0000ee
+        urgent_workspace   #ffff00 #cd0000
+      }
+    }
+  '';
+
+  barConfig = let
+    barHeads = headModifier xrandrHeads;
+    bars = if headCount == 0 then mkBar null conky.single
+      else if headCount == 1 then mkBar (head barHeads) conky.single
+      else let inner = take (length barHeads - 2) (tail barHeads);
+           in mkBar (head barHeads) conky.left
+           ++ map (flip mkBar null) inner
+           ++ mkBar (last barHeads) conky.right;
+  in concatStrings (headModifier bars);
+
+in
+{
+  options.vuizvui.user.aszlig.services.i3 = {
+    enable = mkEnableOption "i3";
+
+    workspaces = mkOption {
+      type = types.attrsOf (types.submodule (import ./workspace.nix));
+      description = ''
+        Workspace to monitor assignment.
+
+        Workspaces are by default assigned starting from the leftmost monitor
+        being workspace 1 and the rightmost monitor being workspace 10. The
+        workspaces are divided by the number of available heads, so if you have
+        a dual head system, you'll end up having workspace 1 to 5 on the left
+        monitor and 6 to 10 on the right.
+      '';
+    };
+
+    reverseHeads = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Reverse the order of the heads, so if enabled and you have two heads,
+        you'll end up having workspaces 1 to 5 on the right head and 6 to 10 on
+        the left head.
+      '';
+    };
+
+    networkTimeout = mkOption {
+      type = types.int;
+      default = 300;
+      description = ''
+        Maximum number of seconds to wait for network device detection.
+      '';
+    };
+  };
+
+  config = mkIf cfg.enable {
+    vuizvui.user.aszlig.services.i3.workspaces = defaultWorkspaces;
+
+    vuizvui.requiresTests = [ ["vuizvui" "aszlig" "i3"] ];
+
+    services.xserver.windowManager = {
+      default = "i3";
+
+      i3.enable = true;
+      i3.configFile = pkgs.substituteAll {
+        name = "i3.conf";
+        src = ./i3.conf;
+
+        inherit (pkgs) dmenu xterm;
+        inherit (pkgs.vuizvui) pvolctrl;
+        inherit (pkgs.xorg) xsetroot;
+        inherit wsConfig barConfig;
+
+        lockall = pkgs.writeScript "lockvt.sh" ''
+          #!${pkgs.stdenv.shell}
+          "${pkgs.socat}/bin/socat" - UNIX-CONNECT:/run/console-lock.sock \
+            < /dev/null
+        '';
+
+        postInstall = ''
+          ${pkgs.i3}/bin/i3 -c "$target" -C
+        '';
+      };
+    };
+  };
+}
diff --git a/modules/user/aszlig/services/i3/i3.conf b/modules/user/aszlig/services/i3/i3.conf
new file mode 100644
index 00000000..cd14c425
--- /dev/null
+++ b/modules/user/aszlig/services/i3/i3.conf
@@ -0,0 +1,131 @@
+# default modifier key
+set $mod Mod4
+
+# we want to have a VT-style font :-)
+font -dosemu-vga-medium-r-normal--17-160-75-75-c-80-ibm-cp866
+
+# Use Mouse+$mod to drag floating windows to their wanted position
+floating_modifier $mod
+
+# reasonable defaults!
+default_orientation horizontal
+workspace_layout tabbed
+popup_during_fullscreen ignore
+
+# start a terminal
+bindsym $mod+Shift+Return exec --no-startup-id @xterm@/bin/xterm
+
+# kill focused window
+bindsym $mod+Shift+C kill
+
+# start dmenu (a program launcher)
+bindsym $mod+p exec --no-startup-id @dmenu@/bin/dmenu_run
+
+# start lock screen
+bindsym $mod+Shift+Escape exec --no-startup-id @lockall@
+
+# set background
+exec @xsetroot@/bin/xsetroot -solid black
+
+# audio controls
+bindsym XF86AudioLowerVolume exec @pvolctrl@/bin/pvolctrl -10
+bindsym XF86AudioRaiseVolume exec @pvolctrl@/bin/pvolctrl 10
+bindsym XF86AudioMute exec @pvolctrl@/bin/pvolctrl 0
+
+# change/move focus
+bindsym $mod+Shift+Left move left
+bindsym $mod+Shift+H move left
+bindsym $mod+Shift+Down move down
+bindsym $mod+Shift+T move down
+bindsym $mod+Shift+Up move up
+bindsym $mod+Shift+N move up
+bindsym $mod+Shift+Right move right
+bindsym $mod+Shift+S move right
+
+bindsym $mod+Left focus left
+bindsym $mod+h focus left
+bindsym $mod+Down focus down
+bindsym $mod+t focus down
+bindsym $mod+Up focus up
+bindsym $mod+n focus up
+bindsym $mod+Right focus right
+bindsym $mod+s focus right
+
+# split in horizontal orientation
+bindsym $mod+i split h
+
+# split in vertical orientation
+bindsym $mod+d split v
+
+# enter fullscreen mode for the focused container
+bindsym $mod+f fullscreen
+
+# change container layout (stacked, tabbed, default)
+bindsym $mod+apostrophe layout stacking
+bindsym $mod+comma layout tabbed
+bindsym $mod+period layout default
+
+# toggle tiling / floating
+bindsym $mod+Shift+space floating toggle
+
+# change focus between tiling / floating windows
+bindsym $mod+space focus mode_toggle
+
+# focus the parent container
+bindsym $mod+a focus parent
+
+# focus the child container
+bindsym $mod+semicolon focus child
+
+# reload the configuration file
+bindsym $mod+Shift+L reload
+# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
+bindsym $mod+Shift+R restart
+# exit i3 (logs you out of your X session)
+bindsym $mod+Shift+Q exit
+
+# resize window (you can also use the mouse for that)
+mode "resize" {
+    # These bindings trigger as soon as you enter the resize mode
+
+    # They resize the border in the direction you pressed, e.g.
+    # when pressing left, the window is resized so that it has
+    # more space on its left
+
+    bindsym Left resize shrink left 10 px or 10 ppt
+    bindsym h resize shrink left 10 px or 10 ppt
+    bindsym Down resize shrink down 10 px or 10 ppt
+    bindsym t resize shrink down 10 px or 10 ppt
+    bindsym Up resize shrink up 10 px or 10 ppt
+    bindsym n resize shrink up 10 px or 10 ppt
+    bindsym Right resize shrink right 10 px or 10 ppt
+    bindsym s resize shrink right 10 px or 10 ppt
+
+    bindsym Shift+Left resize grow left 10 px or 10 ppt
+    bindsym Shift+H resize grow left 10 px or 10 ppt
+    bindsym Shift+Down resize grow down 10 px or 10 ppt
+    bindsym Shift+T resize grow down 10 px or 10 ppt
+    bindsym Shift+Up resize grow up 10 px or 10 ppt
+    bindsym Shift+N resize grow up 10 px or 10 ppt
+    bindsym Shift+Right resize grow right 10 px or 10 ppt
+    bindsym Shift+S resize grow right 10 px or 10 ppt
+
+    # back to normal: Enter or Escape
+    bindsym Return mode "default"
+    bindsym Escape mode "default"
+}
+
+bindsym $mod+r mode "resize"
+
+# workspace configuration
+@wsConfig@
+
+# ratmenu should be as unintrusive as possible
+for_window [class="^ratmenu$"] floating enable
+for_window [class="^ratmenu$"] border none
+
+# various app cruft
+for_window [class="^Dia$"] floating enable
+
+# bar configuration
+@barConfig@
diff --git a/modules/user/aszlig/services/i3/workspace.nix b/modules/user/aszlig/services/i3/workspace.nix
new file mode 100644
index 00000000..403ba57d
--- /dev/null
+++ b/modules/user/aszlig/services/i3/workspace.nix
@@ -0,0 +1,107 @@
+{ name, lib, config, ... }:
+
+with lib;
+
+let
+  finalLabel =
+    if config.label == null then name
+    else config.labelPrefix + config.label;
+
+  mkDoc = anchor: "http://i3wm.org/docs/userguide.html#${anchor}";
+in
+{
+  options = {
+    labelPrefix = mkOption {
+      type = types.str;
+      default = "";
+      example = "666: ";
+      description = ''
+        The value that will be put in front of the <option>label</option>.
+        So if you have a label called <replaceable>bar</replaceable> and a
+        <option>labelPrefix</option> called <replaceable>foo</replaceable> the
+        label for the workspace will be <replaceable>foobar</replaceable>.
+      '';
+    };
+
+    label = mkOption {
+      type = types.nullOr types.str;
+      default = name;
+      description = ''
+        The label of this workspace, which is its name by default. If the value
+        is <replaceable>null</replaceable>, the resulting label of the workspace
+        is just its name and no <option>labelPrefix</option> is applied.
+      '';
+    };
+
+    assign = mkOption {
+      type = types.listOf types.attrs;
+      default = [];
+      example = [
+        { class = "^Chromium(?:-browser)?\$"; }
+        { instance = "^gajim\$"; }
+      ];
+      description = let
+        anchor = "_automatically_putting_clients_on_specific_workspaces";
+      in ''
+        Assign windows to this specific workspace using the attribute names
+        described by <link xlink:href="${mkDoc anchor}"/>.
+      '';
+    };
+
+    head = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      description = ''
+        The XRandR head this workspace will be assigned to.
+      '';
+    };
+
+    keys = let
+      commonDesc = ''
+        The <replaceable>$mod</replaceable> placeholder represents the default
+        modifier key. Details about the syntax of key combinations can be found
+        at <link xlink:href="${mkDoc "keybindings"}"/>.
+      '';
+    in {
+      switchTo = mkOption {
+        type = types.nullOr types.str;
+        default = null;
+        example = "$mod+1";
+        description = ''
+          Key combination to switch to this workspace.
+        '' + commonDesc;
+      };
+
+      moveTo = mkOption {
+        type = types.nullOr types.str;
+        default = null;
+        example = "$mod+Shift+exclam";
+        description = ''
+          Key combination to move a container to this workspace.
+        '' + commonDesc;
+      };
+    };
+
+    config = mkOption {
+      type = types.lines;
+      default = "";
+      description = ''
+        Raw configuration options for this workspace.
+      '';
+    };
+  };
+
+  config.config = let
+    mkAssign = mapAttrsToList (criteria: value: "${criteria}=\"${value}\"");
+    mkSym = sym: rest: optionalString (sym != null) "bindsym ${sym} ${rest}";
+  in ''
+    ${optionalString (config.head != null) ''
+    workspace "${finalLabel}" output ${config.head}
+    ''}
+    ${mkSym config.keys.switchTo "workspace \"${finalLabel}\""}
+    ${mkSym config.keys.moveTo "move workspace \"${finalLabel}\""}
+    ${concatMapStrings (assign: ''
+    assign [${concatStringsSep " " (mkAssign assign)}] ${finalLabel}
+    '') config.assign}
+  '';
+}
diff --git a/modules/user/aszlig/services/slim/default.nix b/modules/user/aszlig/services/slim/default.nix
new file mode 100644
index 00000000..e5dea220
--- /dev/null
+++ b/modules/user/aszlig/services/slim/default.nix
@@ -0,0 +1,45 @@
+{ pkgs, config, lib, ... }:
+
+with lib;
+
+let
+  cfg = config.vuizvui.user.aszlig.services.slim;
+  randrHeads = config.services.xserver.xrandrHeads;
+in {
+  options.vuizvui.user.aszlig.services.slim = {
+    enable = mkEnableOption "Vuizvui SLiM";
+  };
+
+  config.services.xserver.displayManager.slim = mkIf cfg.enable {
+    enable = true;
+    theme = pkgs.stdenv.mkDerivation {
+      name = "nixos-theme-vuizvui";
+      src = pkgs.slimThemes.nixosSlim;
+      phases = [ "unpackPhase" "patchPhase" "installPhase" ];
+      patchPhase = let
+        headFactor = if randrHeads == [] then 1 else lib.length randrHeads;
+        centerLeft = 100 / (headFactor * 2);
+      in ''
+        ${pkgs.imagemagick}/bin/mogrify \
+          -fill '#080010' -draw 'color 0,0 reset' \
+          share/slim/themes/nixos-slim-testing/background.png
+        ${pkgs.imagemagick}/bin/mogrify \
+          -negate -region 100x110+0+0 -negate -fill white -colorize 20% \
+          share/slim/themes/nixos-slim-testing/panel.png
+        sed -i \
+          -e 's/^\([a-z_]\+_x[^0-9]*\)[0-9]\+%/\1${toString centerLeft}%/' \
+          share/slim/themes/nixos-slim-testing/slim.theme
+        cat >> share/slim/themes/nixos-slim-testing/slim.theme <<EOF
+        session_x      ${toString centerLeft}%
+        msg_color      #ffffff
+        username_color #ffffff
+        password_color #ffffff
+        input_color    #ffffff
+        EOF
+      '';
+      installPhase = ''
+        cp -R share/slim/themes/nixos-slim-testing "$out"
+      '';
+    };
+  };
+}
diff --git a/modules/user/aszlig/services/vlock/default.nix b/modules/user/aszlig/services/vlock/default.nix
new file mode 100644
index 00000000..f750ccf7
--- /dev/null
+++ b/modules/user/aszlig/services/vlock/default.nix
@@ -0,0 +1,57 @@
+{ pkgs, config, lib, ... }:
+
+let
+  cfg = config.vuizvui.user.aszlig.services.vlock;
+
+  messageFile = pkgs.runCommand "message.cat" {} ''
+    echo -en '\e[H\e[2J\e[?25l' > "$out"
+    "${pkgs.vuizvui.aacolorize}/bin/aacolorize" \
+      "${./message.cat}" "${./message.colmap}" \
+      >> "$out"
+  '';
+
+  esc = "\\\\033";
+  unlockCSI = "${esc}[16;39H${esc}[?25h${esc}[K";
+
+  vlock = lib.overrideDerivation pkgs.vlock (o: {
+    postPatch = (o.postPatch or "") + ''
+      echo -n '"' > src/message.h
+      sed -e ':nl;N;$!bnl;s/[\\"]/\\&/g;s/\n/\\n/g' "${messageFile}" \
+        >> src/message.h
+      sed -i -e '$s/$/"/' src/message.h
+      sed -i -e 's!getenv("VLOCK_MESSAGE")!\n#include "message.h"\n!' \
+        src/vlock-main.c
+      sed -i -re 's/(fprintf[^"]*")(.*user)/\1${unlockCSI}\2/' \
+        src/auth-pam.c
+    '';
+  });
+in {
+  options.vuizvui.user.aszlig.services.vlock = {
+    enable = lib.mkEnableOption "console lock";
+  };
+
+  config = lib.mkIf cfg.enable {
+    systemd.sockets.vlock = {
+      description = "Console Lock Socket";
+      wantedBy = [ "sockets.target" ];
+      socketConfig.ListenStream = "/run/console-lock.sock";
+      socketConfig.Accept = true;
+    };
+
+    systemd.services."vlock@" = {
+      description = "Lock All Consoles";
+      serviceConfig.Type = "oneshot";
+
+      #environment.USER = "%i"; XXX
+      environment.USER = "aszlig";
+
+      script = ''
+        retval=0
+        oldvt="$("${pkgs.kbd}/bin/fgconsole")"
+        "${vlock}/bin/vlock" -asn || retval=$?
+        if [ $retval -ne 0 ]; then "${pkgs.kbd}/bin/chvt" "$oldvt"; fi
+        exit $retval
+      '';
+    };
+  };
+}
diff --git a/modules/user/aszlig/services/vlock/message.cat b/modules/user/aszlig/services/vlock/message.cat
new file mode 100644
index 00000000..f079e829
--- /dev/null
+++ b/modules/user/aszlig/services/vlock/message.cat
@@ -0,0 +1,18 @@
+
+                .
+                |
+          -_    |     .           .-.  .-. ..      ,.--., ,===.
+            `-_ |     |           '||\.||' `' ,  , ||  || ;___
+    -_         >:_    |    _-      ||`\||  || `\/' ||  ||     ;
+      `-_   _-'   `-_ | _-'       .'   `|  ;' /'`\ ``=='' ,==='
+         >:'         `:'
+      _-' |           |    _-   ..              ..             ..
+    -'    |           | _-'     ||              ||             ||
+         .|.         _:<        ||  ,---. .---. ||,-. .--.  .--||
+      _-' | `-_   _-'   `-_     ||  ||"|| ||''' |.,'' |"/'  |,";|
+    -'    |    `:<         `-   ||_ ||_|| ||__  |,\\. ||__  ||_,|
+          |     | `-_           `--'`---' `---' '' `' `---' `---'
+          '     |    `-
+                |                     press ENTER to unlock
+                `
+
diff --git a/modules/user/aszlig/services/vlock/message.colmap b/modules/user/aszlig/services/vlock/message.colmap
new file mode 100644
index 00000000..d7e42fb6
--- /dev/null
+++ b/modules/user/aszlig/services/vlock/message.colmap
@@ -0,0 +1,18 @@
+
+                c
+                c
+          cc    c     b           WWW  WWW WW      BccccB cBBBc
+            ccc c     b           WWWWWWWW WW W  W Bc  cB cccc
+    bb         ccc    b    bb      WWWWWW  WW WWWW Bc  cB     c
+      bbb   bbb   ccc b bbb       WW   WW  WW WWWW BcBBcB cBBBc
+         bbb         cbb
+      bbb c           b    cc   rr              rr             rr
+    bb    c           b ccc     rr              rr             rr
+         ccb         ccc        rr  rrrrr rrrrr rrrrr rrrr  rrrrr
+      ccc c bbb   ccc   ccc     rr  rrRrr rrRRR rrrrr rRrr  rrRrr
+    cc    c    bbb         cc   rrr rrrrr rrrr  rrrrr rrrr  rrrrr
+          c     b bbb           rrrrrrrrr rrrrr rr rr rrrrr rrrrr
+          c     b    bb
+                b                     ppppp PPPPP pp pppppp
+                b
+
diff --git a/modules/user/aszlig/system/kernel.nix b/modules/user/aszlig/system/kernel.nix
new file mode 100644
index 00000000..b1f666e4
--- /dev/null
+++ b/modules/user/aszlig/system/kernel.nix
@@ -0,0 +1,57 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+  cfg = config.vuizvui.user.aszlig.system.kernel;
+
+  generateKConf = exprs: let
+    isNumber = c: elem c ["0" "1" "2" "3" "4" "5" "6" "7" "8" "9"];
+    mkValue = val:
+      if val == "" then "\"\""
+      else if val == "y" || val == "m" || val == "n" then val
+      else if all isNumber (stringToCharacters val) then val
+      else if substring 0 2 val == "0x" then val
+      else "\"${val}\"";
+    mkConfigLine = key: val: "${key}=${mkValue val}";
+    mkConf = cfg: concatStringsSep "\n" (mapAttrsToList mkConfigLine cfg);
+  in pkgs.writeText "generated.kconf" (mkConf exprs + "\n");
+
+  mainlineKernel = {
+    version = "4.4.0-rc8";
+    src = pkgs.fetchgit {
+      url = git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git;
+      rev = "02006f7a7a715af10974a30b7ad8e6ee340f954c";
+      sha256 = "1m08bjbizh2w04l17rq0mkmrayfrhrrsbymaawlr5mi2gvv9rmca";
+    };
+  };
+
+in {
+  options.vuizvui.user.aszlig.system.kernel = {
+    enable = mkEnableOption "aszlig's custom kernel";
+
+    config = mkOption {
+      type = types.attrsOf types.unspecified;
+      default = {};
+      description = ''
+        An attribute set of configuration options to use
+        for building a custom kernel.
+      '';
+    };
+  };
+
+  config = mkIf cfg.enable {
+    boot = let
+      linuxVuizvui = pkgs.buildLinux {
+        inherit (mainlineKernel) version src;
+
+        kernelPatches = singleton pkgs.vuizvui.kernelPatches.bfqsched;
+        configfile = generateKConf cfg.config;
+        allowImportFromDerivation = true;
+      };
+    in rec {
+      kernelPackages = pkgs.recurseIntoAttrs
+        (pkgs.linuxPackagesFor linuxVuizvui kernelPackages);
+    };
+  };
+}