├── .gitignore ├── README.md ├── adho-configuration.nix ├── configuration.nix ├── desktop.nix ├── dotfiles.nix ├── dotfiles ├── alacritty.yml ├── config.fish ├── msmtprc ├── notmuch-config ├── offlineimaprc └── tmux.conf ├── emacs.nix ├── home.nix ├── mail.nix ├── packages.nix ├── pkgs ├── pulseaudio-ctl.nix └── wallpapers.nix └── stallo-configuration.nix /.gitignore: -------------------------------------------------------------------------------- 1 | hardware-configuration.nix 2 | local-configuration.nix 3 | result 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | NixOS configuration 2 | =================== 3 | 4 | My NixOS configuration! It configures most of the packages I require 5 | on my systems, sets up Emacs the way I need and does a bunch of other 6 | interesting things. 7 | 8 | In contrast with earlier versions of this configuration, the Nix 9 | channel versions are now pinned in Nix (see the beginning of 10 | [packages.nix][]). 11 | 12 | Machine-local configuration is kept in files with the naming scheme 13 | `$hostname-configuration.nix` and **must** be symlinked to 14 | `local-configuration.nix` before the first configuration run. 15 | 16 | I'm publishing this repository (and my [emacs configuration][]) as a 17 | convenience for myself, but also as a resource that people looking for 18 | example Nix or Emacs configurations can browse through. 19 | 20 | Feel free to ping me with any questions you might have. 21 | 22 | [packages.nix]: packages.nix 23 | [emacs configuration]: https://github.com/tazjin/emacs.d 24 | -------------------------------------------------------------------------------- /adho-configuration.nix: -------------------------------------------------------------------------------- 1 | # Local configuration for 'adho' (Thinkpad T470s) 2 | { config, pkgs, ...}: 3 | 4 | { 5 | boot.initrd.luks.devices.adho.device = "/dev/disk/by-uuid/722006b0-9654-4ea1-8703-e0cf9ac1905e"; 6 | boot.kernelModules = [ "kvm-intel" ]; 7 | 8 | services.xserver.libinput.enable = true; 9 | services.xserver.videoDrivers = [ "intel" ]; 10 | programs.light.enable = true; 11 | 12 | # Office printer configuration 13 | services.printing.enable = true; 14 | services.printing.drivers = [ pkgs.hplip ]; 15 | services.avahi.enable = true; 16 | services.avahi.nssmdns = true; 17 | 18 | # Enable VirtualBox to update Beatstep Pro firmware: 19 | virtualisation.virtualbox.host.enable = true; 20 | virtualisation.virtualbox.host.enableExtensionPack = true; 21 | 22 | # Enable LXC/LXD for Nixini work 23 | virtualisation.lxd.enable = true; 24 | 25 | # Give me more entropy: 26 | services.haveged.enable = true; 27 | 28 | # Disable sandbox to let work-builds function: 29 | nix.useSandbox = false; 30 | 31 | # Yubikey related: 32 | services.pcscd.enable = true; 33 | environment.systemPackages = with pkgs; [ 34 | cfssl 35 | libp11 36 | opensc 37 | yubico-piv-tool 38 | ]; 39 | 40 | networking = { 41 | hostName = "adho"; 42 | wireless.enable = true; 43 | wireless.userControlled.enable = true; 44 | 45 | wireless.networks = { 46 | # Welcome to roast club! 47 | "How do I computer?" = { 48 | psk = "washyourface"; 49 | }; 50 | 51 | # On the go! 52 | "Rumpetroll" = { 53 | psk = "fisk1234"; 54 | # If this network exists, chances are that I want it: 55 | priority = 10; 56 | }; 57 | 58 | # Public places in Oslo: 59 | "Abelone" = { 60 | psk = "speakeasy"; 61 | }; 62 | 63 | "Wurst" = { 64 | psk = "wurst2015"; 65 | }; 66 | 67 | "postkontoret" = { 68 | psk = "postkontoret"; 69 | }; 70 | 71 | # Eugene's apartment: 72 | "GET_5G_4FD250" = { 73 | psk = "62636342"; 74 | }; 75 | 76 | # FSCONS 2017 77 | "uioguest" = {}; 78 | 79 | # Hackeriet! 80 | "hackeriet.no" = { 81 | psk = "hackeriet.no"; 82 | }; 83 | 84 | # Cafe Sara 85 | "Sara Nett" = { 86 | psk = "sarabar1989"; 87 | }; 88 | 89 | # The Dubliner 90 | "DubGjest" = { 91 | # of course 92 | psk = "Guinness"; 93 | }; 94 | 95 | "MAGNAT Guest" = { 96 | psk = "elmolino021"; 97 | }; 98 | 99 | "BrewDog" = { 100 | psk = "welovebeer"; 101 | }; 102 | 103 | # Dima's 104 | "What's a Bad Idea?" = { 105 | psk = "DQDxzrzIvy0YtDwH"; 106 | }; 107 | 108 | # Loke's 109 | "VMC28F76E" = { 110 | psk = "d2ftQnr6xppw"; 111 | }; 112 | 113 | "SafetyWiFi - Teknologihuset" = { 114 | psk = "tech4ever"; 115 | }; 116 | 117 | "Selvaag Pluss" = { 118 | psk = "detlilleekstra"; 119 | }; 120 | 121 | "Langler" = { 122 | psk = "Oslo2018"; 123 | }; 124 | 125 | # Pils & Programmering 126 | "BEKKguest" = { 127 | psk = "guest7890"; 128 | }; 129 | 130 | "Homan-Gjest" = { 131 | psk = "haveaniceday"; 132 | }; 133 | 134 | # Røverstaden 135 | "Roverstaden" = { 136 | psk = "r0verstaden2018"; 137 | }; 138 | 139 | "The Brew Dock" = { 140 | psk = "realbeer"; 141 | }; 142 | 143 | "econ-guest" = { 144 | psk = "Finance2010"; 145 | }; 146 | 147 | "KabelBox-2FD0" = { 148 | psk = "92433048597489095671"; 149 | }; 150 | 151 | "TheKasbah" = { 152 | psk = "couscous"; 153 | }; 154 | 155 | # Kitty's misspelled network. 156 | "How do I Computer?" = { 157 | psk = "herpderpponies"; 158 | }; 159 | 160 | # NixCon 2018 161 | "Coin Street Community Builders " = { 162 | psk = "3vents2016"; 163 | }; 164 | 165 | "KH2 Gjest" = { 166 | psk = "haenfindag"; 167 | }; 168 | 169 | # Forest & Brown 170 | "Forest Guest" = { 171 | psk = "437B99AC5B"; 172 | }; 173 | 174 | "Gatwick FREE Wi-Fi" = {}; 175 | "mycloud" = {}; 176 | "Norwegian Internet Access" = {}; 177 | "NSB_INTERAKTIV" = {}; 178 | "The Thief" = {}; 179 | "espressohouse" = {}; 180 | "Gotanet Open" = {}; 181 | "wifi.flytoget.no" = {}; 182 | "AIRPORT" = {}; 183 | "ilcaffelovesyou" = {}; 184 | "WIFIonICE" = {}; 185 | "Lorry Gjest" = {}; 186 | "Amundsengjest" = {}; 187 | "Beer Palace Gjest" = {}; 188 | "ibis" = {}; 189 | "GoogleGuest" = {}; 190 | }; 191 | }; 192 | 193 | hardware.bluetooth.enable = true; 194 | 195 | # Configure POSIX queue limits (for work) 196 | systemd.tmpfiles.rules = let mqueue = "/proc/sys/fs/mqueue"; in [ 197 | "w ${mqueue}/msgsize_max - - - - ${toString (64 * 1024)}" 198 | "w ${mqueue}/msg_max - - - - 50" 199 | ]; 200 | } 201 | -------------------------------------------------------------------------------- /configuration.nix: -------------------------------------------------------------------------------- 1 | # Edit this configuration file to define what should be installed on 2 | # your system. Help is available in the configuration.nix(5) man page 3 | # and in the NixOS manual (accessible by running ‘nixos-help’). 4 | 5 | { config, lib, pkgs, ... }: 6 | 7 | { 8 | imports = 9 | [ 10 | ./desktop.nix 11 | ./dotfiles.nix 12 | ./hardware-configuration.nix 13 | ./local-configuration.nix 14 | ./mail.nix 15 | ./packages.nix 16 | ]; 17 | 18 | # Use the systemd-boot EFI boot loader. 19 | boot.loader.systemd-boot.enable = true; 20 | boot.loader.efi.canTouchEfiVariables = true; 21 | boot.cleanTmpDir = true; 22 | hardware.pulseaudio.enable = true; 23 | time.timeZone = "Europe/Oslo"; 24 | 25 | # Configure audio setup for JACK + Overtone 26 | boot.kernelModules = [ "snd-seq" "snd-rawmidi" ]; 27 | hardware.pulseaudio.package = pkgs.pulseaudioFull; 28 | 29 | # Update Intel microcode on boot (both machines have Intel CPUs): 30 | hardware.cpu.intel.updateMicrocode = true; 31 | 32 | networking = { 33 | # Don't use ISP's DNS servers: 34 | nameservers = [ 35 | "1.1.1.1" 36 | "1.0.0.1" 37 | ]; 38 | 39 | # Open Chromecast-related ports & servedir 40 | firewall.allowedTCPPorts = [ 3000 5556 5558 ]; 41 | }; 42 | 43 | # Generate an immutable /etc/resolv.conf from the nameserver settings 44 | # above (otherwise DHCP overwrites it): 45 | environment.etc."resolv.conf" = with lib; with pkgs; { 46 | source = writeText "resolv.conf" '' 47 | ${concatStringsSep "\n" (map (ns: "nameserver ${ns}") config.networking.nameservers)} 48 | options edns0 49 | ''; 50 | }; 51 | 52 | # Configure emacs: 53 | # (actually, that's a lie, this only installs emacs!) 54 | services.emacs = { 55 | install = true; 56 | defaultEditor = true; 57 | package = import ./emacs.nix { inherit pkgs; }; 58 | }; 59 | 60 | services.openssh.enable = true; 61 | 62 | # Enable GNOME keyring (required for Evolution) 63 | services.gnome3.gnome-keyring.enable = true; 64 | 65 | virtualisation = { 66 | # Configure Docker (with socket activation): 67 | # Side note: ... why is this in virtualisation? ... 68 | docker.enable = true; 69 | docker.autoPrune.enable = true; 70 | }; 71 | 72 | # Configure various other applications: 73 | programs = { 74 | java.enable = true; 75 | java.package = pkgs.openjdk; 76 | 77 | fish.enable = true; 78 | ssh.startAgent = true; 79 | }; 80 | 81 | services.postgresql.enable = true; 82 | 83 | # Configure user account 84 | users.defaultUserShell = pkgs.fish; 85 | users.extraUsers.vincent = { 86 | extraGroups = [ "wheel" "docker" "vboxusers" "lxd" ]; 87 | isNormalUser = true; 88 | uid = 1000; 89 | shell = pkgs.fish; 90 | }; 91 | 92 | security.sudo = { 93 | enable = true; 94 | extraConfig = "wheel ALL=(ALL:ALL) SETENV: ALL"; 95 | }; 96 | 97 | # This value determines the NixOS release with which your system is to be 98 | # compatible, in order to avoid breaking some software such as database 99 | # servers. You should change this only after NixOS release notes say you 100 | # should. 101 | system.stateVersion = "18.03"; # Did you read the comment? 102 | } 103 | -------------------------------------------------------------------------------- /desktop.nix: -------------------------------------------------------------------------------- 1 | # Configuration for the desktop environment 2 | 3 | { config, lib, pkgs, ... }: 4 | 5 | let emacs = import ./emacs.nix { inherit pkgs; }; 6 | screenLock = pkgs.writeShellScriptBin "screen-lock" '' 7 | find ${pkgs.wallpapers} -name "*.png" | shuf -n1 | xargs i3lock -f -t -i 8 | ''; 9 | in { 10 | # Configure basic X-server stuff: 11 | services.xserver = { 12 | enable = true; 13 | layout = "us,no"; 14 | xkbOptions = "caps:super, grp:shifts_toggle, parens:swap_brackets"; 15 | exportConfiguration = true; 16 | 17 | # Give EXWM permission to control the session. 18 | displayManager.sessionCommands = "${pkgs.xorg.xhost}/bin/xhost +SI:localuser:$USER"; 19 | 20 | # Use the pre 18.09 default display manager (slim) 21 | displayManager.slim.enable = true; 22 | }; 23 | 24 | # Add a shell script with random screen lock wallpaper selection 25 | environment.systemPackages = [ screenLock ]; 26 | 27 | # Apparently when you have house guests they complain about your screen tearing! 28 | services.compton.enable = true; 29 | services.compton.backend = "xrender"; 30 | 31 | # Configure desktop environment: 32 | services.xserver.windowManager.session = lib.singleton { 33 | name = "exwm"; 34 | start = '' 35 | ${emacs}/bin/emacs --eval '(progn (server-start) (exwm-enable))' 36 | ''; 37 | }; 38 | 39 | # Configure Redshift for Oslo 40 | services.redshift = { 41 | enable = true; 42 | latitude = "59.911491"; 43 | longitude = "10.757933"; 44 | }; 45 | 46 | # Configure fonts 47 | fonts = { 48 | fonts = with pkgs; [ 49 | corefonts 50 | font-awesome-ttf 51 | input-fonts 52 | noto-fonts-cjk 53 | noto-fonts-emoji 54 | powerline-fonts 55 | helvetica-neue-lt-std 56 | ]; 57 | }; 58 | 59 | # Configure random setting of wallpapers 60 | systemd.user.services.feh-wp = { 61 | description = "Randomly set wallpaper via feh"; 62 | serviceConfig = { 63 | Type = "oneshot"; 64 | WorkingDirectory = "${pkgs.wallpapers}/share/wallpapers"; 65 | 66 | # Manually shuffle because feh's --randomize option can't be restricted to 67 | # just certain file types. 68 | ExecStart = "${pkgs.bash}/bin/bash -c '${pkgs.fd}/bin/fd -atf | shuf | head -n1 | ${pkgs.findutils}/bin/xargs ${pkgs.feh}/bin/feh --bg-fill'"; 69 | }; 70 | }; 71 | 72 | systemd.user.timers.feh-wp = { 73 | description = "Set a random wallpaper every hour"; 74 | wantedBy = [ "graphical-session.target" ]; 75 | partOf = [ "graphical-session.target" ]; 76 | 77 | timerConfig = { 78 | OnActiveSec = "1second"; 79 | OnUnitActiveSec = "1hour"; 80 | }; 81 | }; 82 | } 83 | -------------------------------------------------------------------------------- /dotfiles.nix: -------------------------------------------------------------------------------- 1 | # Bundle configuration files into a derivation. 2 | # I call this derivation dotfiles despite that not technically being true 3 | # anymore ... 4 | 5 | { config, pkgs, ...}: 6 | 7 | let dotfiles = pkgs.stdenv.mkDerivation { 8 | name = "tazjins-dotfiles"; 9 | 10 | srcs = [ 11 | ./dotfiles 12 | ]; 13 | 14 | installPhase = '' 15 | mkdir -p $out 16 | cp ./* $out/ 17 | ''; 18 | }; 19 | in { 20 | # /etc/ is a special place in NixOS! 21 | # Symlinks that need to be created there must be specified explicitly. 22 | environment.etc = { 23 | "alacritty.yml".source = "${dotfiles}/alacritty.yml"; 24 | "fish/config.fish".source = "${dotfiles}/config.fish"; 25 | "tmux.conf".source = "${dotfiles}/tmux.conf"; 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /dotfiles/alacritty.yml: -------------------------------------------------------------------------------- 1 | # Configuration for Alacritty, the GPU enhanced terminal emulator 2 | 3 | # Any items in the `env` entry below will be added as 4 | # environment variables. Some entries may override variables 5 | # set by alacritty it self. 6 | env: 7 | TERM: xterm-256color 8 | 9 | window: 10 | # TODO 11 | decorations: full 12 | 13 | scrolling: 14 | history: 10000 15 | multiplier: 3 16 | faux_multiplier: 3 17 | auto_scroll: true # TODO 18 | 19 | # Display tabs using this many cells (changes require restart) 20 | tabspaces: 4 21 | 22 | # When true, bold text is drawn using the bright variant of colors. 23 | draw_bold_text_with_bright_colors: true 24 | 25 | # Font configuration (changes require restart) 26 | font: 27 | # The normal (roman) font face to use. 28 | normal: 29 | family: Input Mono 30 | bold: 31 | family: Input Mono 32 | italic: 33 | family: Input Mono 34 | 35 | # Point size of the font 36 | size: 12.0 37 | 38 | # Scale the font size based on the monitor's DPI. 39 | scale_with_dpi: false 40 | 41 | # Use custom cursor colors. If true, display the cursor in the cursor.foreground 42 | # and cursor.background colors, otherwise invert the colors of the cursor. 43 | custom_cursor_colors: false 44 | 45 | # Colors (Gruber Darker) 46 | colors: 47 | # Default colors 48 | primary: 49 | background: '0x181818' 50 | foreground: '0xe4e4ef' 51 | 52 | # Colors the cursor will use if `custom_cursor_colors` is true 53 | cursor: 54 | text: '0x000000' 55 | cursor: '0xf5f5f5' 56 | 57 | # Normal colors 58 | normal: 59 | black: '0x282828' 60 | red: '0xf43841' 61 | green: '0x73c936' 62 | yellow: '0xffdd33' 63 | blue: '0x96a6c8' 64 | magenta: '0x9e95c7' 65 | cyan: '0x1fad83' 66 | white: '0xf5f5f5' 67 | 68 | # Bright colors 69 | bright: 70 | black: '0x484848' 71 | red: '0xff4f58' 72 | green: '0x73c936' 73 | yellow: '0xffdd33' 74 | blue: '0x5f627f' 75 | magenta: '0x9e95c7' 76 | cyan: '0x1fad83' 77 | white: '0xffffff' 78 | 79 | # Background opacity 80 | # Key bindings 81 | # 82 | # Each binding is defined as an object with some properties. Most of the 83 | # properties are optional. All of the alphabetical keys should have a letter for 84 | # the `key` value such as `V`. Function keys are probably what you would expect 85 | # as well (F1, F2, ..). The number keys above the main keyboard are encoded as 86 | # `Key1`, `Key2`, etc. Keys on the number pad are encoded `Number1`, `Number2`, 87 | # etc. These all match the glutin::VirtualKeyCode variants. 88 | # 89 | # Possible values for `mods` 90 | # `Command`, `Super` refer to the super/command/windows key 91 | # `Control` for the control key 92 | # `Shift` for the Shift key 93 | # `Alt` and `Option` refer to alt/option 94 | # 95 | # mods may be combined with a `|`. For example, requiring control and shift 96 | # looks like: 97 | # 98 | # mods: Control|Shift 99 | # 100 | # The parser is currently quite sensitive to whitespace and capitalization - 101 | # capitalization must match exactly, and piped items must not have whitespace 102 | # around them. 103 | # 104 | # Either an `action`, `chars`, or `command` field must be present. 105 | # `action` must be one of `Paste`, `PasteSelection`, `Copy`, or `Quit`. 106 | # `chars` writes the specified string every time that binding is activated. 107 | # These should generally be escape sequences, but they can be configured to 108 | # send arbitrary strings of bytes. 109 | # `command` must be a map containing a `program` string, and `args` array of 110 | # strings. For example: 111 | # - { ... , command: { program: "alacritty", args: ["-e", "vttest"] } } 112 | # 113 | # Want to add a binding (e.g. "PageUp") but are unsure what the X sequence 114 | # (e.g. "\x1b[5~") is? Open another terminal (like xterm) without tmux, 115 | # then run `showkey -a` to get the sequence associated to a key combination. 116 | key_bindings: 117 | - { key: V, mods: Control|Shift, action: Paste } 118 | - { key: C, mods: Control|Shift, action: Copy } 119 | - { key: Q, mods: Command, action: Quit } 120 | - { key: W, mods: Command, action: Quit } 121 | - { key: Insert, mods: Shift, action: PasteSelection } 122 | - { key: Home, chars: "\x1bOH", mode: AppCursor } 123 | - { key: Home, chars: "\x1b[H", mode: ~AppCursor } 124 | - { key: End, chars: "\x1bOF", mode: AppCursor } 125 | - { key: End, chars: "\x1b[F", mode: ~AppCursor } 126 | - { key: PageUp, mods: Shift, chars: "\x1b[5;2~" } 127 | - { key: PageUp, mods: Control, chars: "\x1b[5;5~" } 128 | - { key: PageUp, chars: "\x1b[5~" } 129 | - { key: PageDown, mods: Shift, chars: "\x1b[6;2~" } 130 | - { key: PageDown, mods: Control, chars: "\x1b[6;5~" } 131 | - { key: PageDown, chars: "\x1b[6~" } 132 | - { key: Left, mods: Shift, chars: "\x1b[1;2D" } 133 | - { key: Left, mods: Control, chars: "\x1b[1;5D" } 134 | - { key: Left, mods: Alt, chars: "\x1b[1;3D" } 135 | - { key: Left, chars: "\x1b[D", mode: ~AppCursor } 136 | - { key: Left, chars: "\x1bOD", mode: AppCursor } 137 | - { key: Right, mods: Shift, chars: "\x1b[1;2C" } 138 | - { key: Right, mods: Control, chars: "\x1b[1;5C" } 139 | - { key: Right, mods: Alt, chars: "\x1b[1;3C" } 140 | - { key: Right, chars: "\x1b[C", mode: ~AppCursor } 141 | - { key: Right, chars: "\x1bOC", mode: AppCursor } 142 | - { key: Up, mods: Shift, chars: "\x1b[1;2A" } 143 | - { key: Up, mods: Control, chars: "\x1b[1;5A" } 144 | - { key: Up, mods: Alt, chars: "\x1b[1;3A" } 145 | - { key: Up, chars: "\x1b[A", mode: ~AppCursor } 146 | - { key: Up, chars: "\x1bOA", mode: AppCursor } 147 | - { key: Down, mods: Shift, chars: "\x1b[1;2B" } 148 | - { key: Down, mods: Control, chars: "\x1b[1;5B" } 149 | - { key: Down, mods: Alt, chars: "\x1b[1;3B" } 150 | - { key: Down, chars: "\x1b[B", mode: ~AppCursor } 151 | - { key: Down, chars: "\x1bOB", mode: AppCursor } 152 | - { key: Tab, mods: Shift, chars: "\x1b[Z" } 153 | - { key: F1, chars: "\x1bOP" } 154 | - { key: F2, chars: "\x1bOQ" } 155 | - { key: F3, chars: "\x1bOR" } 156 | - { key: F4, chars: "\x1bOS" } 157 | - { key: F5, chars: "\x1b[15~" } 158 | - { key: F6, chars: "\x1b[17~" } 159 | - { key: F7, chars: "\x1b[18~" } 160 | - { key: F8, chars: "\x1b[19~" } 161 | - { key: F9, chars: "\x1b[20~" } 162 | - { key: F10, chars: "\x1b[21~" } 163 | - { key: F11, chars: "\x1b[23~" } 164 | - { key: F12, chars: "\x1b[24~" } 165 | - { key: Back, chars: "\x7f" } 166 | - { key: Back, mods: Alt, chars: "\x1b\x7f" } 167 | - { key: Insert, chars: "\x1b[2~" } 168 | - { key: Delete, chars: "\x1b[3~" } 169 | 170 | # Mouse bindings 171 | # 172 | # Currently doesn't support modifiers. Both the `mouse` and `action` fields must 173 | # be specified. 174 | # 175 | # Values for `mouse`: 176 | # - Middle 177 | # - Left 178 | # - Right 179 | # - Numeric identifier such as `5` 180 | # 181 | # Values for `action`: 182 | # - Paste 183 | # - PasteSelection 184 | # - Copy (TODO) 185 | mouse_bindings: 186 | - { mouse: Middle, action: PasteSelection } 187 | 188 | mouse: 189 | double_click: { threshold: 300 } 190 | triple_click: { threshold: 300 } 191 | 192 | selection: 193 | semantic_escape_chars: ",│`|:\"' ()[]{}<>" 194 | background_opacity: 1.0 195 | 196 | hide_cursor_when_typing: false 197 | 198 | # Live config reload (changes require restart) 199 | live_config_reload: true 200 | 201 | # Disable visual bell 202 | visual_bell: 203 | duration: 0 204 | -------------------------------------------------------------------------------- /dotfiles/config.fish: -------------------------------------------------------------------------------- 1 | # Configure classic prompt 2 | set fish_color_user --bold blue 3 | set fish_color_cwd --bold white 4 | 5 | # Enable colour hints in VCS prompt: 6 | set __fish_git_prompt_showcolorhints yes 7 | set __fish_git_prompt_color_prefix purple 8 | set __fish_git_prompt_color_suffix purple 9 | 10 | # Fish configuration 11 | set fish_greeting "" 12 | set PATH $HOME/.local/bin $HOME/.cargo/bin $PATH 13 | 14 | # Editor configuration 15 | set -gx EDITOR "emacsclient" 16 | set -gx ALTERNATE_EDITOR "emacs -q -nw" 17 | set -gx VISUAL "emacsclient" 18 | 19 | # Miscellaneous 20 | eval (direnv hook fish) 21 | 22 | # Useful command aliases 23 | alias gpr 'git pull --rebase' 24 | alias gco 'git checkout' 25 | alias gf 'git fetch' 26 | alias gap 'git add -p' 27 | alias pbcopy 'xclip -selection clipboard' 28 | alias edit 'emacsclient -n' 29 | alias servedir 'nix-shell -p haskellPackages.wai-app-static --run warp' 30 | 31 | # Old habits die hard (also ls is just easier to type): 32 | alias ls 'exa' 33 | 34 | # Fix up nix-env & friends for Nix 2.0 35 | export NIX_REMOTE=daemon 36 | 37 | # Fix display of fish in emacs' term-mode: 38 | function fish_title 39 | true 40 | end 41 | -------------------------------------------------------------------------------- /dotfiles/msmtprc: -------------------------------------------------------------------------------- 1 | defaults 2 | 3 | port 587 4 | tls on 5 | tls_trust_file /etc/ssl/certs/ca-certificates.crt 6 | 7 | # Aprila mail 8 | account aprila 9 | from vincent@aprila.no 10 | host smtp.office365.com 11 | auth on 12 | user vincent@aprila.no 13 | passwordeval pass show aprila/office365-mail 14 | 15 | # Runbox mail 16 | account runbox 17 | from mail@tazj.in 18 | host mail.runbox.com 19 | auth on 20 | user mail@tazj.in 21 | passwordeval pass show general/runbox-tazjin 22 | 23 | # Use Runbox as default 24 | account default : runbox 25 | -------------------------------------------------------------------------------- /dotfiles/notmuch-config: -------------------------------------------------------------------------------- 1 | # .notmuch-config - Configuration file for the notmuch mail system 2 | # 3 | # For more information about notmuch, see https://notmuchmail.org 4 | 5 | [database] 6 | path=/home/vincent/mail 7 | 8 | [user] 9 | name=Vincent Ambo 10 | primary_email=vincent@aprila.no 11 | other_email=mail@tazj.in;tazjin@gmail.com; 12 | 13 | [new] 14 | tags=unread;inbox; 15 | ignore= 16 | 17 | [search] 18 | exclude_tags=deleted;spam;draft; 19 | 20 | [maildir] 21 | synchronize_flags=true 22 | -------------------------------------------------------------------------------- /dotfiles/offlineimaprc: -------------------------------------------------------------------------------- 1 | [general] 2 | accounts = aprila, tazjin, gmail 3 | 4 | [DEFAULT] 5 | ssl = yes 6 | sslcacertfile = /etc/ssl/certs/ca-certificates.crt 7 | 8 | # Main work account: 9 | [Account aprila] 10 | localrepository = aprila-local 11 | remoterepository = aprila-remote 12 | 13 | [Repository aprila-local] 14 | type = Maildir 15 | localfolders = ~/mail/aprila 16 | 17 | [Repository aprila-remote] 18 | type = IMAP 19 | remotehost = outlook.office365.com 20 | remoteuser = vincent@aprila.no 21 | remotepassfile = ~/.config/mail/aprila-pass 22 | # Office365 is a naughty boy when it comes to IMAP. Even worse, they 23 | # also seem to have decided that they should change IMAP folder names 24 | # based on the UI language. 25 | # 26 | # I can't be bothered to implement the entire (relatively long) 27 | # blacklist, so I'll instead whitelist relevant folders: 28 | folderfilter = lambda folder: folder in ['INBOX', 'Arkiv', 'Sende element'] 29 | 30 | # Private GMail account (old): 31 | [Account gmail] 32 | maxage = 90 33 | localrepository = gmail-local 34 | remoterepository = gmail-remote 35 | synclabels = yes 36 | 37 | [Repository gmail-local] 38 | type = GmailMaildir 39 | localfolders = ~/mail/gmail 40 | 41 | [Repository gmail-remote] 42 | type = Gmail 43 | remoteuser = tazjin@gmail.com 44 | remotepassfile = ~/.config/mail/gmail-pass 45 | folderfilter = lambda folder: folder == 'INBOX' 46 | 47 | # Main private account: 48 | [Account tazjin] 49 | localrepository = tazjin-local 50 | remoterepository = tazjin-remote 51 | 52 | [Repository tazjin-local] 53 | type = Maildir 54 | localfolders = ~/mail/tazjin 55 | 56 | [Repository tazjin-remote] 57 | type = IMAP 58 | remotehost = mail.runbox.com 59 | remoteuser = mail@tazj.in 60 | remotepassfile = ~/.config/mail/tazjin-pass 61 | auth_mechanisms = LOGIN 62 | -------------------------------------------------------------------------------- /dotfiles/tmux.conf: -------------------------------------------------------------------------------- 1 | set -g status off 2 | set -gw mode-keys emacs 3 | setw -g mouse on 4 | 5 | # Correctly set window titles 6 | set -g set-titles on 7 | set -g set-titles-string "#W (#T)" 8 | 9 | # List of plugins 10 | set -g @plugin 'tmux-plugins/tpm' 11 | set -g @plugin 'tmux-plugins/tmux-yank' 12 | 13 | # Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf) 14 | run '~/.tmux/plugins/tpm/tpm' 15 | -------------------------------------------------------------------------------- /emacs.nix: -------------------------------------------------------------------------------- 1 | # Derivation for Emacs pre-configured with packages that I need. 2 | # 3 | # TODO: Fix sly (again) 4 | 5 | { pkgs }: 6 | 7 | with pkgs; with emacsPackagesNg; 8 | let emacsWithPackages = (emacsPackagesNgGen emacs).emacsWithPackages; 9 | 10 | # As the EXWM-README points out, XELB should be built from source if 11 | # EXWM is. 12 | xelb = melpaBuild { 13 | pname = "xelb"; 14 | ename = "xelb"; 15 | version = "0.15"; 16 | recipe = builtins.toFile "recipe" '' 17 | (xelb :fetcher github 18 | :repo "ch11ng/xelb") 19 | ''; 20 | 21 | packageRequires = [ cl-generic emacs ]; 22 | 23 | src = fetchFromGitHub { 24 | owner = "ch11ng"; 25 | repo = "xelb"; 26 | rev = "b8f168b401977098fe2b30f4ca32629c0ab6eb83"; 27 | sha256 = "1ack1h68x8ia0ji6wbhmayrakq35p5sgrrl6qvha3ns3pswc0pl9"; 28 | }; 29 | }; 30 | 31 | # EXWM pinned to a newer version than what is released due to a 32 | # potential fix for ch11ng/exwm#425. 33 | exwm = melpaBuild { 34 | pname = "exwm"; 35 | ename = "exwm"; 36 | version = "0.19"; 37 | recipe = builtins.toFile "recipe" '' 38 | (exwm :fetcher github 39 | :repo "ch11ng/exwm") 40 | ''; 41 | 42 | packageRequires = [ xelb ]; 43 | 44 | src = fetchFromGitHub { 45 | owner = "ch11ng"; 46 | repo = "exwm"; 47 | rev = "472f7cb82b67b98843f10c12e6bda9b8ae7262bc"; 48 | sha256 = "19gflsrb19aijf2xcw7j2m658qad21nbwziw38s1h2jw66vhk8dj"; 49 | }; 50 | }; 51 | 52 | slyFixed = sly.overrideAttrs(_: { 53 | recipe = builtins.toFile "recipe" '' 54 | (sly :repo "joaotavora/sly" 55 | :fetcher github 56 | :files ("*.el" 57 | ("lib" "lib/*") 58 | ("contrib" "contrib/*") 59 | "doc/*.texi" 60 | "doc/*.info" 61 | "doc/dir")) 62 | ''; 63 | }); 64 | 65 | in emacsWithPackages(epkgs: 66 | # Actual ELPA packages (the enlightened!) 67 | (with epkgs.elpaPackages; [ 68 | ace-window 69 | avy 70 | company 71 | pinentry 72 | rainbow-mode 73 | undo-tree 74 | which-key 75 | ]) ++ 76 | 77 | # MELPA packages: 78 | (with epkgs.melpaPackages; [ 79 | browse-kill-ring 80 | cargo 81 | counsel 82 | counsel-notmuch 83 | dash 84 | dash-functional 85 | dockerfile-mode 86 | edit-server 87 | eglot 88 | elixir-mode 89 | erlang 90 | elm-mode 91 | exwm 92 | go-mode 93 | gruber-darker-theme 94 | haskell-mode 95 | ht 96 | hydra 97 | idle-highlight-mode 98 | intero 99 | ivy 100 | ivy-pass 101 | ivy-prescient 102 | jq-mode 103 | kotlin-mode 104 | magit 105 | markdown-mode 106 | markdown-toc 107 | meghanada 108 | multi-term 109 | multiple-cursors 110 | nginx-mode 111 | nix-mode 112 | omnisharp 113 | paredit 114 | password-store 115 | pg 116 | pkgs.notmuch 117 | prescient 118 | rainbow-delimiters 119 | restclient 120 | rust-mode 121 | s 122 | slyFixed 123 | smartparens 124 | string-edit 125 | swiper 126 | telephone-line 127 | terraform-mode 128 | toml-mode 129 | use-package 130 | uuidgen 131 | web-mode 132 | websocket 133 | yaml-mode 134 | ]) ++ 135 | 136 | # Custom packaged Emacs packages: 137 | [ xelb exwm ] 138 | ) 139 | -------------------------------------------------------------------------------- /home.nix: -------------------------------------------------------------------------------- 1 | # home-manager configuration used on ChromeOS systems 2 | 3 | { config, pkgs, ... }: 4 | 5 | { 6 | # Allow non-free software (fonts, IDEA, etc.): 7 | nixpkgs.config.allowUnfree = true; 8 | 9 | # Install various useful packages: 10 | home.packages = with pkgs; [ 11 | bat 12 | exa 13 | gnupg 14 | google-cloud-sdk 15 | htop 16 | pass 17 | ripgrep 18 | tdesktop 19 | transmission 20 | tree 21 | 22 | # Fonts to make available in X11 applications: 23 | input-fonts 24 | 25 | # Emacs configuration stays in the normal ~/.emacs.d location (for 26 | # now), hence this package is not installed via `programs.emacs`. 27 | (import ./emacs.nix { inherit pkgs; }) 28 | ]; 29 | 30 | programs.git = { 31 | enable = true; 32 | userEmail = "mail@tazj.in"; 33 | userName = "Vincent Ambo"; 34 | }; 35 | 36 | services.gpg-agent = { 37 | enable = true; 38 | extraConfig = '' 39 | pinentry-program ${pkgs.pinentry}/bin/pinentry-gtk-2 40 | allow-emacs-pinentry 41 | ''; 42 | }; 43 | 44 | # Let Home Manager install and manage itself. 45 | programs.home-manager.enable = true; 46 | manual.html.enable = true; 47 | 48 | # Shell configuration 49 | # 50 | # There are some differences between the ChromeOS / NixOS 51 | # configurations, so instead of fixing up the dotfile to support 52 | # both I opted for keeping the configuration here. 53 | programs.fish = { 54 | enable = true; 55 | interactiveShellInit = '' 56 | # Configure classic prompt 57 | set fish_color_user --bold blue 58 | set fish_color_cwd --bold white 59 | 60 | # Enable colour hints in VCS prompt: 61 | set __fish_git_prompt_showcolorhints yes 62 | set __fish_git_prompt_color_prefix purple 63 | set __fish_git_prompt_color_suffix purple 64 | 65 | # Fish configuration 66 | set fish_greeting "" 67 | 68 | # Fix up nix-env & friends for Nix 2.0 69 | export NIX_REMOTE=daemon 70 | ''; 71 | }; 72 | 73 | # Ensure fonts installed via Nix are picked up. 74 | fonts.fontconfig.enableProfileFonts = true; 75 | } 76 | -------------------------------------------------------------------------------- /mail.nix: -------------------------------------------------------------------------------- 1 | # This file configures offlineimap, notmuch and MSMTP. 2 | # 3 | # Some manual configuration is required the first time this is 4 | # applied: 5 | # 6 | # 1. Credential setup. 7 | # 2. Linking of MSMTP config (ln -s /etc/msmtprc ~/.msmtprc) 8 | # 3. Linking of notmuch config (ln -s /etc/notmuch-config ~/.notmuch-config) 9 | 10 | { config, lib, pkgs, ... }: 11 | 12 | let offlineImapConfig = pkgs.writeText "offlineimaprc" 13 | (builtins.readFile ./dotfiles/offlineimaprc); 14 | 15 | msmtpConfig = pkgs.writeText "msmtprc" 16 | (builtins.readFile ./dotfiles/msmtprc); 17 | 18 | notmuchConfig = pkgs.writeText "notmuch-config" 19 | (builtins.readFile ./dotfiles/notmuch-config); 20 | 21 | tagConfig = pkgs.writeText "notmuch-tags" '' 22 | # Tag emacs-devel mailing list: 23 | -inbox +emacs-devel -- to:emacs-devel@gnu.org OR cc:emacs-devel@gnu.org 24 | 25 | # Tag nix-devel mailing list & discourse: 26 | -inbox +nix-devel -- to:nix-devel@googlegroups.com OR from:nixos1@discoursemail.com 27 | 28 | # Filter out Gitlab mails: 29 | -inbox +gitlab -- from:gitlab@aprila.no 30 | 31 | # Tag my own mail (from other devices) as sent: 32 | -inbox +sent -- folder:"aprila/Sende element" OR from:vincent@aprila.no OR from:mail@tazj.in 33 | 34 | # Drafts are always read, duh. 35 | -unread -- tag:draft 36 | 37 | # Tag development list 38 | -inbox +aprila-dev -- to:dev@aprila.no OR cc:dev@aprila.no 39 | ''; 40 | 41 | notmuchIndex = pkgs.writeShellScriptBin "notmuch-index" '' 42 | echo "Indexing new mails in notmuch" 43 | 44 | # Index new mail 45 | ${pkgs.notmuch}/bin/notmuch new 46 | 47 | # Apply tags 48 | cat ${tagConfig} | ${pkgs.notmuch}/bin/notmuch tag --batch 49 | 50 | echo "Done indexing new mails" 51 | ''; 52 | in { 53 | # Enable OfflineIMAP timer & service: 54 | systemd.user.timers.offlineimap = { 55 | description = "OfflineIMAP timer"; 56 | wantedBy = [ "timers.target" ]; 57 | 58 | timerConfig = { 59 | Unit = "offlineimap.service"; 60 | OnCalendar = "*:0/2"; # every 2 minutes 61 | Persistent = "true"; # persist timer state after reboots 62 | }; 63 | }; 64 | 65 | systemd.user.services.offlineimap = { 66 | description = "OfflineIMAP service"; 67 | path = with pkgs; [ pass notmuch ]; 68 | 69 | serviceConfig = { 70 | Type = "oneshot"; 71 | ExecStart = "${pkgs.offlineimap}/bin/offlineimap -u syslog -o -c ${offlineImapConfig}"; 72 | ExecStartPost = "${notmuchIndex}/bin/notmuch-index"; 73 | TimeoutStartSec = "2min"; 74 | }; 75 | }; 76 | 77 | # Link configuration files to /etc/ (from where they will be linked 78 | # further): 79 | environment.etc = { 80 | "msmtprc".source = msmtpConfig; 81 | "notmuch-config".source = notmuchConfig; 82 | }; 83 | } 84 | -------------------------------------------------------------------------------- /packages.nix: -------------------------------------------------------------------------------- 1 | # This file contains configuration for packages to install. 2 | # It does not contain configuration for software that is already covered 3 | # by other NixOS options (e.g. emacs) 4 | 5 | { config, pkgs, ... }: 6 | 7 | let 8 | fetchChannel = { rev, sha256 }: import (fetchTarball { 9 | inherit sha256; 10 | url = "https://github.com/NixOS/nixpkgs-channels/archive/${rev}.tar.gz"; 11 | }) { config.allowUnfree = true; }; 12 | 13 | # Channels last updated: 2018-10-10 14 | # 15 | # Instead of relying on Nix channels and ending up with out-of-sync 16 | # situations between machines, the commit for the stable Nix channel 17 | # is pinned here. 18 | stable = fetchChannel { 19 | rev = "d96c7a356383302db4426a0d5a8383af921d964f"; 20 | sha256 = "0hlhczh3m077rwrhp4smf3zd2sfj38h2c126bycv66m0aff0gycn"; 21 | }; 22 | 23 | # Certain packages from unstable are hand-picked into the package 24 | # set. 25 | unstable = fetchChannel { 26 | rev = "32bcd72bf28a971c9063a9cdcc32effe49f49331"; 27 | sha256 = "1f74m18r6xl9s55jbkj9bjhdxg2489kwjam4d96pf9rzq0i1f8li"; 28 | }; 29 | in { 30 | # Configure the Nix package manager 31 | nixpkgs = { 32 | config.allowUnfree = true; 33 | # To use the pinned channel, the original package set is thrown 34 | # away in the overrides: 35 | config.packageOverrides = oldPkgs: stable // { 36 | # Store whole unstable channel in case that other modules need 37 | # it (see emacs.nix for example): 38 | inherit unstable; 39 | 40 | # Backport Exa from unstable until a fix for the Rust builder is 41 | # backported. 42 | # 43 | # https://github.com/NixOS/nixpkgs/pull/48020 44 | exa = unstable.exa; 45 | 46 | wallpapers = import ./pkgs/wallpapers.nix; 47 | pulseaudio-ctl = import pkgs/pulseaudio-ctl.nix; 48 | }; 49 | }; 50 | 51 | # ... and declare packages to be installed. 52 | environment.systemPackages = with pkgs; [ 53 | # Default nixos.* packages: 54 | alacritty 55 | binutils-unwrapped 56 | chromium 57 | curl 58 | direnv 59 | dnsutils 60 | dotnet-sdk 61 | evince 62 | exa 63 | extremetuxracer 64 | fd 65 | file 66 | firefox-unwrapped 67 | fish 68 | gcc 69 | git 70 | gnumake 71 | gnupg 72 | google-cloud-sdk 73 | gopass 74 | hicolor-icon-theme 75 | htop 76 | i3lock 77 | iftop 78 | jq 79 | kontemplate 80 | kubernetes 81 | lispPackages.quicklisp 82 | lxappearance-gtk3 83 | manpages 84 | maven 85 | mono 86 | mq-cli 87 | msmtp 88 | ngrok 89 | notmuch 90 | numix-cursor-theme 91 | numix-gtk-theme 92 | numix-icon-theme 93 | offlineimap 94 | openjdk 95 | openssl 96 | openssl.dev 97 | pass 98 | pavucontrol 99 | pkgconfig 100 | pulseaudio-ctl 101 | pwgen 102 | ripgrep 103 | rustup 104 | sbcl 105 | screen 106 | siege 107 | spotify 108 | stdmanpages 109 | systemd.dev 110 | tdesktop 111 | terraform 112 | tig 113 | tmux 114 | tokei 115 | transmission 116 | tree 117 | units 118 | unzip 119 | vlc 120 | xclip 121 | xfce.xfce4-screenshooter 122 | 123 | # Haskell packages: 124 | cabal-install 125 | ghc 126 | hlint 127 | stack 128 | stack2nix 129 | haskellPackages.stylish-haskell 130 | haskellPackages.yesod-bin 131 | ]; 132 | } 133 | -------------------------------------------------------------------------------- /pkgs/pulseaudio-ctl.nix: -------------------------------------------------------------------------------- 1 | with import {}; 2 | 3 | stdenv.mkDerivation rec { 4 | name = "pulseaudio-ctl-${version}"; 5 | version = "v1.66"; 6 | 7 | src = fetchzip { 8 | url = "https://github.com/graysky2/pulseaudio-ctl/archive/${version}.tar.gz"; 9 | sha256 = "19a24w7y19551ar41q848w7r1imqkl9cpff4dpb7yry7qp1yjg0y"; 10 | }; 11 | 12 | buildFlags = ''PREFIX=$(out)''; 13 | 14 | # Force Nix to detect the runtime dependency on 'bc' 15 | preInstall = '' 16 | sed -i 's|bc)|${bc}/bin/bc)|g' common/pulseaudio-ctl 17 | ''; 18 | 19 | installFlags = ''PREFIX=$(out)''; 20 | 21 | meta = with stdenv.lib; { 22 | description = "Control pulseaudio volume from the shell or mapped to keyboard shortcuts"; 23 | homepage = "https://github.com/graysky2/pulseaudio-ctl"; 24 | license = licenses.mit; 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /pkgs/wallpapers.nix: -------------------------------------------------------------------------------- 1 | # Fetch my wallpapers from git 2 | with import {}; 3 | 4 | stdenv.mkDerivation { 5 | name = "tazjins-wallpapers-1"; 6 | 7 | src = fetchgit { 8 | url = "https://git.tazj.in/tazjin/wallpapers.git"; 9 | rev = "3bce73b605ba5f848cb4e7cc33058a2be3952c68"; 10 | sha256 = "1gjlazag7x005sf2bd6a7dw5p9ry5vjgzmvycsyiw3pv9b1gzc0j"; 11 | }; 12 | 13 | installPhase = '' 14 | mkdir -p $out/share/wallpapers 15 | cp -r $src/* $out/share/wallpapers 16 | ''; 17 | 18 | meta = with stdenv.lib; { 19 | description = "tazjin's wallpaper collection"; 20 | platforms = platforms.all; 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /stallo-configuration.nix: -------------------------------------------------------------------------------- 1 | # Local configuration for 'stallo' (Home desktop PC) 2 | { config, pkgs, ...}: 3 | 4 | { 5 | boot.initrd.luks.devices.stallo-luks.device = "/dev/disk/by-uuid/b484cf1e-a27b-4785-8bd6-fa85a004b073"; 6 | 7 | # Use proprietary nvidia driver 8 | services.xserver.videoDrivers = [ "nvidia" ]; 9 | 10 | # Enable 32-bit compatibility for Steam: 11 | hardware.opengl.driSupport32Bit = true; 12 | hardware.pulseaudio.support32Bit = true; 13 | 14 | # Wine for Blizzard stuff 15 | environment.systemPackages = with pkgs.unstable; [ wineWowPackages.staging winetricks ]; 16 | 17 | networking = { 18 | hostName = "stallo"; 19 | wireless.enable = true; 20 | wireless.networks = { 21 | # Welcome to roast club! 22 | 23 | "How do I computer fast?" = { 24 | psk = "washyourface"; 25 | # Prefer 5Ghz unless the card is acting up. 26 | priority = 10; 27 | }; 28 | 29 | "How do I computer?" = { 30 | psk = "washyourface"; 31 | }; 32 | }; 33 | # IPv6 at home, of course: 34 | nameservers = [ 35 | "2606:4700:4700::1111" 36 | "2606:4700:4700::1001" 37 | ]; 38 | }; 39 | } 40 | --------------------------------------------------------------------------------