Hi there! That’s my dotfiles. Most of config files are now generated by org-babel from this file (yes, from README.org). That’s literate programming applied to dotfiles. To generate all files you can open this file in emacs and press M-x org-babel-tangle. Or from command line with:
emacs -f org-babel-tangle --batch README.org
I keep this document in sync with generated config files just in case I won’t have access to my emacs. However, I recommend against looking at them—they’re just a generated mess; you’ll have much better time reading this doc instead—trust me.
Pieces not covered in this document (yet) are:
- emacs configuration at
.emacs.d/; - vim configuration at
.vimrcand.vim/; - awesome wm configuration at
.config/awesome/; - scripts at
bin/;
NixOS
I’m a NixOS user. What’s cool about it is that I can describe all my system configuration in one file (/etc/nixos/configuration.nix), so I can just copy it to other machine, call nixos-rebuild and have system with the same software, system settings, etc.
It looks like this:
{ config, pkgs, ... }: { nixpkgs.config.allowUnfree = true; <<nixos-machine>> <<nixos-general>> environment.systemPackages = [ <<nixos-system-packages>> ]; # The NixOS release to be compatible with for stateful data such as databases. system.stateVersion = "15.09"; }
These <<nixos-machine>>, <<nixos-general>>, and <<nixos-system-packages>> are replaced by other parts of this doc. <<nixos-machine>> is described in Machines section; <<nixos-general>> and <<nixos-system-packages>> are scatered around the doc. <<nixos-system-packages>> can only consist of packages, and they usually start with pkgs. so you can quickly distinguish these sections.
Users
I’m the only user of system:
users.extraUsers.rasen = { isNormalUser = true; uid = 1000; extraGroups = [ "users" "wheel" "networkmanager" "dialout" "plugdev" ]; initialPassword = "HelloWorld"; };
initialPassword is used only first time when user is created. It must be changed as soon as possible with passwd.
Machines
I have two machines. Currently, only one is running NixOS, but I’ll setup the second soon.
Larry
This one is a laptop that needs the proprietary driver for Wi-Fi card (this "wl" and broadcom_sta).
imports = [ <nixpkgs/nixos/modules/installer/scan/not-detected.nix> ]; boot.initrd.availableKernelModules = [ "ahci" "xhci_hcd" ]; boot.initrd.kernelModules = [ "wl" ]; boot.kernelModules = [ "kvm-intel" "wl" ]; boot.extraModulePackages = [ config.boot.kernelPackages.broadcom_sta ];
I have two partitions (usual “separate home” setup). There are also two swap partitions, but the one is from my slow hdd, so I probably shouldn’t use it.
fileSystems = { "/" = { device = "/dev/disk/by-uuid/ba82dd25-a9e5-436f-ae76-4ee44d53b2c6"; fsType = "ext4"; }; "/home" = { device = "/dev/disk/by-uuid/b27c07d0-aaf7-44a1-87e1-5a2cb30954ec"; fsType = "ext4"; }; }; swapDevices = [ # TODO: set priority # { device = "/dev/disk/by-uuid/f0bd0438-3324-4295-9981-07015fa0af5e"; } { device = "/dev/disk/by-uuid/75822d9d-c5f0-495f-b089-f57d0de5246d"; } ];
There is also Gentoo on the second drive—it’s good to keep it bootable.
boot.loader.grub = { enable = true; version = 2; device = "/dev/sda"; extraEntries = '' menuentry 'Gentoo' { configfile (hd1,1)/grub2/grub.cfg } ''; };
Boring stuff: 8 hyper-threads, networking (wicd), synaptics (Larry is laptop).
nix.maxJobs = 8; nix.buildCores = 8; networking = { hostName = "Larry"; wicd.enable = true; wireless.enable = false; extraHosts = '' 127.0.0.1 Larry Larry.local ''; }; services.xserver.synaptics = { enable = true; twoFingerScroll = true; vertEdgeScroll = true; };
Local overlay
As a responsible NixOS user, I refuse to install software blindly with sudo make install. That’s why I should write my own nix-expressions. I keep them in my local overlay until they’re merged upstream.
The entry is just a set of all my packages in nixpkgs-local/local-packages.nix:
{ system ? builtins.currentSystem }: let pkgs = import <nixpkgs> { inherit system; }; callPackage = pkgs.lib.callPackageWith (pkgs // pkgs.xlibs // self); pythonPackages = pkgs.pythonPackages // rec { <<nixpkgs-local-python-packages>> }; self = rec { <<nixpkgs-local-packages>> }; in self
You can install all packages to current user with:
nix-env -f nixpkgs-local/local-packages.nix -i
rust-nightly
Won’t submit. As nighties are unstable, it’s unlikely it will be at nixpkgs.
Rust wiki recommends using Ericson2314’s rustc-nightly package. However, it doesn’t pack libstd.
You can get hash with the following command: #+name rust-nightly-hash
nix-prefetch-url --type sha256 https://static.rust-lang.org/dist/$date/rust-nightly-x86_64-unknown-linux-gnu.tar.gzrust-nightly = callPackage ./pkgs/rust-nightly { date = "2016-03-11"; hash = "0s450rm51z9gywb4vnaradvy23cqyd19yk8j4swrr3v520f4dx6b"; };
{ date, hash , stdenv, fetchurl, zlib }: let target = if stdenv.system == "i686-linux" then "i686-unknown-linux-gnu" else if stdenv.system == "x86_64-linux" then "x86_64-unknown-linux-gnu" else if stdenv.system == "i686-darwin" then "i868-apple-darwin" else if stdenv.system == "x86_64-darwin" then "x86_64-apple-darwin" else abort "no snapshot to bootstrap for this platfrom (missing target triple)"; in stdenv.mkDerivation rec { name = "rust-nightly-${date}"; src = fetchurl { url = "https://static.rust-lang.org/dist/${date}/rust-nightly-${target}.tar.gz"; sha256 = hash; }; installPhase = '' ./install.sh --prefix=$out --disable-ldconfig ''; dontStrip = true; preFixup = if stdenv.isLinux then let rpath = stdenv.lib.concatStringsSep ":" [ "$out/lib" (stdenv.lib.makeLibraryPath [ zlib ]) ''${stdenv.cc.cc}/lib${stdenv.lib.optionalString stdenv.is64bit "64"}'' ]; in '' for executable in ${stdenv.lib.concatMapStringsSep " " (s: "$out/bin/" + s) [ "cargo" "rustc" "rustdoc" ]}; do patchelf --interpreter "${stdenv.glibc}/lib/${stdenv.cc.dynamicLinker}" \ --set-rpath "${rpath}" \ "$executable" done for library in $out/lib/*.so; do patchelf --set-rpath "${rpath}" "$library" done '' else ""; }
Services
OpenVPN
All my computers are members of the VPN:
services.openvpn.servers = { kaa.config = '' client dev tap port 22 proto tcp tls-client persist-key persist-tun ns-cert-type server remote vpn.kaa.org.ua ca /root/.vpn/ca.crt key /root/.vpn/alexey.shmalko.key cert /root/.vpn/alexey.shmalko.crt ''; };
Avahi is needed to allow resolution of .local names. For example, you can access this computer by larry.local if we meet at the same local network.
services.avahi = { enable = true; nssmdns = true; publish = { enable = true; userServices = true; workstation = true; }; };
SSH
services.openssh = { enable = true; passwordAuthentication = false; };
Gitolite
I host some git repos on my machines:
services.gitolite = { enable = true; adminPubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDJhMhxIwZJgIY6CNSNEH+BetF/WCUtDFY2KTIl8LcvXNHZTh4ZMc5shTOS/ROT4aH8Awbm0NjMdW33J5tFMN8T7q89YZS8hbBjLEh8J04Y+kndjnllDXU6NnIr/AenMPIZxJZtSvWYx+f3oO6thvkZYcyzxvA5Vi6V1cGx6ni0Kizq/WV/mE/P1nNbwuN3C4lCtiBC9duvoNhp65PctQNohnKQs0vpQcqVlfqBsjQ7hhj2Fjg+Ofmt5NkL+NhKQNqfkYN5QyIAulucjmFAieKR4qQBABopl2F6f8D9IjY8yH46OCrgss4WTf+wxW4EBw/QEfNoKWkgVoZtxXP5pqAz rasen@Larry"; };
Environment
General
I definitely use X server:
services.xserver.enable = true;
Use English as my only supported locale:
i18n.supportedLocales = [ "en_US.UTF-8/UTF-8" ];
Setup timezone:
time.timeZone = "Europe/Kiev";
Login manager
I use SLiM. It stands for Simple Login Manager. It’s fast and has little dependencies. The projects is dead since 2014, but still works fine, so I keep using it.
services.xserver.displayManager.slim.enable = true;
Window manager
I use awesome wm:
services.xserver.windowManager.awesome = { enable = true; luaModules = [ pkgs.luaPackages.luafilesystem ]; };
Disabling xterm makes awesome wm a default choice in slim:
services.xserver.desktopManager.xterm.enable = false;
These packages are used by my awesome wm setup:
pkgs.wmname pkgs.kbdd pkgs.xclip pkgs.scrot
Keyboard
Layouts
I use English, Russian, and Ukrainian layouts:
services.xserver.layout = "us,ru,ua";
I toggle between them with either Caps Lock, or Menu key—I have two different keyboards, and one doesn’t have Menu when Caps Lock is too far on the second. I never use Caps Lock–the feature, so it’s nice to have Caps LED indicate alternate layouts.
services.xserver.xkbOptions = "grp:caps_toggle,grp:menu_toggle,grp_led:caps";
Layout indicator
I use xxkb as a keyboard indicator.
Its settings are saved in .xxkbrc file. Xxkb just sits in the tray and displays layout image.
XXkb.image.path: /home/rasen/.config/xxkb
XXkb.mainwindow.enable: yes
XXkb.mainwindow.type: tray
XXkb.mainwindow.geometry: 17x14+0+0
XXkb.mainwindow.image.1: en.svg
XXkb.mainwindow.image.2: ru.svg
XXkb.mainwindow.image.3: ua.svg
XXkb.mainwindow.image.4:
XXkb.*.label.enable: no
XXkb.button.enable: no
XXkb.controls.add_when_start: yes
XXkb.controls.add_when_create: yes
XXkb.controls.add_when_change: no
XXkb.controls.focusout: no
XXkb.controls.button_delete: no
XXkb.controls.button_delete_and_forget: yes
XXkb.controls.mainwindow_delete: no
XXkb.mousebutton.1.reverse: no
XXkb.mousebutton.3.reverse: no
XXkb.bell.enable: no
XXkb.ignore.reverse: no
TODO make path relative
The following enables two-state mode—in that mode xxkb switches between one base (English) and one alternative layout (Russian or Ukrainian). Switching of alternate layouts is implemented in awesome wm config.
XXkb.controls.two_state: yes
XXkb.group.base: 1
XXkb.group.alt: 2
Redshift
Redshift adjusts the color temperature of the screen according to the position of the sun. That should improve my sleep.
services.redshift = { enable = true; latitude = "50.4500"; longitude = "30.5233"; };
Look and Feel
Qt theme
This makes apps look like in KDE:
pkgs.kde4.oxygen_icons pkgs.kde4.kwin_styles
Gtk theme
I like consistency, so oxygen-gtk is a nice choice:
pkgs.oxygen-gtk2 pkgs.oxygen-gtk3
Set it as a default theme:
environment.shellInit = '' export GTK_PATH=$GTK_PATH:${pkgs.oxygen_gtk}/lib/gtk-2.0 export GTK2_RC_FILES=$GTK2_RC_FILES:${pkgs.oxygen_gtk}/share/themes/oxygen-gtk/gtk-2.0/gtkrc '';
Fonts
fonts = { enableCoreFonts = true; enableFontDir = true; enableGhostscriptFonts = false; fonts = with pkgs; [ powerline-fonts inconsolata corefonts terminus_font dejavu_fonts source-code-pro ubuntu_font_family unifont ]; };
Applications
Here go applications every normal user needs.
KDE apps
I don’t use full KDE but some apps are definitely nice.
pkgs.kde4.okular pkgs.kde4.gwenview pkgs.kde4.kde_baseapps # <-- dolphin pkgs.kde4.kde_runtime pkgs.kde4.kfilemetadata pkgs.kde4.filelight pkgs.shared_mime_info
Okular can’t show anything without this:
environment.pathsToLink = [ "/share" ];
Firefox
Though my default browser is google-chrome, it has issues with Java plugin, so I use firefox for that:
The following enables jre support as well as uses newer version:
nixpkgs.config.firefox.jre = true; nixpkgs.config.packageOverrides = pkgs: rec { jrePlugin = pkgs.oraclejre8; };
Other applications
Don’t require additional setup.
pkgs.google-chrome pkgs.skype pkgs.libreoffice pkgs.qbittorrent pkgs.calibre pkgs.mnemosyne pkgs.deadbeef pkgs.wine pkgs.vlc pkgs.mplayer pkgs.smplayer pkgs.gparted pkgs.unetbootin pkgs.kvm
Development
Editors
I’m a seasoned Vim user, but I’m switching to emacs now.
(pkgs.vim_configurable.override { python3 = true; }) pkgs.emacs
The following packages are needed for emacs plugins:
pkgs.ycmd pkgs.racerRust pkgs.ditaa pkgs.oraclejre8 pkgs.texLive # pkgs.texLiveExtra
Leiningen is needed for clojure, but I don’t really use it now.
rxvt-unicode
I use urxvt as my terminal emulator:
pkgs.rxvt_unicode-with-plugins pkgs.urxvt_perl
Urxvt gets its setting from .Xresources file. If you ever want to reload it on-the-fly, type the following (or press C-c C-c if you’re in emacs):
General setup
See rxvt-unicode documentation for the full reference.
urxvt.loginShell: true
urxvt.saveLines: 65535
urxvt.urgentOnBell: true
urxvt.scrollBar: false
urxvt.scrollTtyOutput: false
urxvt.scrollTtyKeypress: true
urxvt.secondaryScroll: true
The next piece disables annoying message when pressing Ctrl+Shift:
urxvt.iso14755: False
Copy-paste with Ctrl+Shift+C, Ctrl+Shift+V:
urxvt.perl-ext-common: default,clipboard
urxvt.keysym.S-C-C: perl:clipboard:copy
urxvt.keysym.S-C-V: perl:clipboard:paste
urxvt.keysym.C-M-V: perl:clipboard:paste_escaped
urxvt.clipboard.copycmd: xclip -i -selection clipboard
urxvt.clipboard.pastecmd: xclip -o -selection clipboard
Font
I use Terminus font patched for use with Powerline.
URxvt.font: xft:Terminess Powerline:normal:size=12
Color theme
I like Molokai color theme.
URxvt*background: #101010
URxvt*foreground: #d0d0d0
URxvt*color0: #101010
URxvt*color1: #960050
URxvt*color2: #66aa11
URxvt*color3: #c47f2c
URxvt*color4: #30309b
URxvt*color5: #7e40a5
URxvt*color6: #3579a8
URxvt*color7: #9999aa
URxvt*color8: #303030
URxvt*color9: #ff0090
URxvt*color10: #80ff00
URxvt*color11: #ffba68
URxvt*color12: #5f5fee
URxvt*color13: #bb88dd
URxvt*color14: #4eb4fa
URxvt*color15: #d0d0d0
Zsh
Zsh is my default shell:
programs.zsh.enable = true; users.defaultUserShell = "/run/current-system/sw/bin/zsh";
Prompt
My prompt looks like this (though, the font is different; colors are also wrong at GitHub):
rasen@Larry directory(master|+8…) % command [0] 1:25
source $HOME/.zsh/git-prompt/zshrc.sh PROMPT='%B%F{green}%n@%m%k %B%F{blue}%1~%b$(git_super_status) %B%F{blue}%# %b%f%k' RPROMPT="[%?] %T"
The ~/.zsh/git-prompt/ is a submodule, so don’t forget to initialize it!
git submodule update --init --recursive
Aliases
Nothing special, but g=git is a real timesaver.
alias ls='ls --color=auto' alias grep='grep --color=auto' alias g="git"
PATH
Install stuff in ~/.local/; ~/bin/ is for my helper scripts (linked to bin directory in dotfiles repo).
export PATH="${HOME}/bin:${PATH}" export PATH="${HOME}/.local/bin:${PATH}" export LD_LIBRARY_PATH="${HOME}/.local/lib:${LD_LIBRARY_PATH}"
Other
This part was written long time ago; I’m not sure I understand and use all of it:
autoload -U compinit promptinit autoload -U colors compinit promptinit colors # Lines configured by zsh-newuser-install HISTFILE=~/.histfile HISTSIZE=1000 SAVEHIST=1000 setopt appendhistory autocd unsetopt beep bindkey -e # End of lines configured by zsh-newuser-install # The following lines were added by compinstall zstyle :compinstall filename '/home/rasen/.zshrc' zstyle ':completion:*:descriptions' format '%U%B%d%b%u' zstyle ':completion:*:warnings' format '%BSorry, no matches for: %d%b' setopt correct setopt hist_ignore_space setopt hist_ignore_all_dups setopt extendedglob setopt listpacked zstyle ':completion:*' use-cache on zstyle ':completion:*' cache-path ~/.zsh/cache zstyle ':completion:*' completer _complete _match _approximate zstyle ':completion:*:match:*' original only zstyle ':completion:*:approximate:*' max-errors 1 numeric zstyle ':completion:*:functions' ignored-patters '_*' xdvi() { command xdvi ${*:-*.dvi(om[1])} } zstyle ':completion:*:*:xdvi:*' menu yes select zstyle ':completion:*:*:xdvi:*' file-sort time zstyle ':completion:*' squeeze-slashes true # End of lines added by compinstall # create a zkbd compatible hash; # to add other keys to this hash, see: man 5 terminfo typeset -A key key[Home]=${terminfo[khome]} key[End]=${terminfo[kend]} key[Insert]=${terminfo[kich1]} key[Delete]=${terminfo[kdch1]} key[Up]=${terminfo[kcuu1]} key[Down]=${terminfo[kcud1]} key[Left]=${terminfo[kcub1]} key[Right]=${terminfo[kcuf1]} key[PageUp]=${terminfo[kpp]} key[PageDown]=${terminfo[knp]} # setup key accordingly [[ -n "${key[Home]}" ]] && bindkey "${key[Home]}" beginning-of-line [[ -n "${key[End]}" ]] && bindkey "${key[End]}" end-of-line [[ -n "${key[Insert]}" ]] && bindkey "${key[Insert]}" overwrite-mode [[ -n "${key[Delete]}" ]] && bindkey "${key[Delete]}" delete-char [[ -n "${key[Up]}" ]] && bindkey "${key[Up]}" up-line-or-history [[ -n "${key[Down]}" ]] && bindkey "${key[Down]}" down-line-or-history [[ -n "${key[Left]}" ]] && bindkey "${key[Left]}" backward-char [[ -n "${key[Right]}" ]] && bindkey "${key[Right]}" forward-char # Finally, make sure the terminal is in application mode, when zle is # active. Only then are the values from $terminfo valid. if (( ${+terminfo[smkx]} )) && (( ${+terminfo[rmkx]} )); then function zle-line-init () { printf '%s' "${terminfo[smkx]}" } function zle-line-finish () { printf '%s' "${terminfo[rmkx]}" } zle -N zle-line-init zle -N zle-line-finish fi
TODO review this
git
Basic info: my name, email, ui, editor, rerere.
[user] name = Alexey Shmalko email = rasen.dubi@gmail.com [sendemail] smtpencryption = ssl smtpserver = smtp.gmail.com smtpuser = rasen.dubi@gmail.com smtpserverport = 465 [color] ui = true [core] editor = vim [push] default = simple [rerere] enabled = true
I have LOTS of aliases:
[alias] cl = clone p = push pl = pull f = fetch fa = fetch --all a = add ap = add -p d = diff dl = diff HEAD~ HEAD ds = diff --staged l = log l1 = log -1 lp = log -p c = commit ca = commit --amend co = checkout cb = checkout -b cm = checkout origin/master de = checkout --detach br = branch s = status re = reset --hard dp = push origin HEAD:refs/drafts/master pp = push origin HEAD:refs/publish/master r = rebase rc = rebase --continue ri = rebase -i m = merge t = tag su = submodule update --init --recursive bi = bisect bg = bisect good bb = bisect bad bis = bisect start bir = bisect reset
The next is needed for proper resolving of GHC submodules:
[url "git://github.com/ghc/packages-"] insteadOf = git://github.com/ghc/packages/
tmux
I like C-a as a prefix.
set -g prefix C-a
unbind-key C-b
bind-key C-a send-prefix
TODO describe other settings
# To make vim work properly
set -g default-terminal "screen-256color"
set -g status-keys vi
setw -g mode-keys vi
set -g history-limit 10000
# Start numbering from 1
set -g base-index 1
# Allows for faster key repetition
set -s escape-time 0
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
bind-key s split-window
bind-key v split-window -h
bind r source-file ~/.tmux.conf \; display-message "Config reloaded..."
set-window-option -g automatic-rename
Haskell
Needed to work with Haskell:
pkgs.ghc pkgs.haskellPackages.ghc-mod pkgs.stack pkgs.cabal-install pkgs.cabal2nix
Embedded
The following packages provide compiler, ARM cross-compiler, debugger, and terminal.
pkgs.gnumake pkgs.cmake pkgs.binutils pkgs.gcc pkgs.gcc-arm-embedded (pkgs.gdb.override { multitarget = true; }) pkgs.minicom pkgs.openocd pkgs.expect pkgs.telnet
To allow user use openocd without sudo, we should add him to plugdev group and install openocd udev rules:
users.extraGroups.plugdev = { }; services.udev.packages = [ pkgs.openocd ];
Other terminal goodies
pkgs.wget pkgs.htop pkgs.psmisc pkgs.mosh pkgs.zip pkgs.unzip pkgs.unrar pkgs.p7zip pkgs.irssi pkgs.man-pages pkgs.bind pkgs.file pkgs.which pkgs.whois pkgs.gnupg pkgs.utillinuxCurses pkgs.patchelf pkgs.nix-repl pkgs.nox pkgs.python pkgs.python3
Games
Steam
We need the following package:
It’s also required to enable 32-bit support for opengl and pulseaudio:
hardware.opengl.driSupport32Bit = true; hardware.pulseaudio.support32Bit = true;
Nethack
I play nethack rarely, but still nice to have my setting in sync.
The following sets my default name, selects a dog, and disables auto-pickup; the last line makes interface a bit friendlier.
OPTIONS=name:rasen
OPTIONS=pettype:dog, dogname:Fido
OPTIONS=!autopickup
OPTIONS=lit_corridor, DECgraphics, showscore, showexp, time, color, hilite_pet
Meta
Setup
There is a setup.sh script in this directory. It just links all files to $HOME:
FILES=".vimrc .vim .nvimrc .nvim .gitconfig .zshrc .zsh .tmux.conf .xxkbrc .Xresources .config/awesome .config/nvim .config/xxkb .nethackrc .emacs.d .ssh" DEST=$1 if [ -z "$DEST" ]; then DEST="$HOME" fi BASE=$(dirname $(readlink -f $0)) ask_install() { FILENAME=$1 LINK="$DEST/$FILENAME" TARGET="$BASE/$FILENAME" if [ -e $LINK ]; then echo "$LINK exists. Skipping..." else read -r -p "Link $LINK to $TARGET? [y/N] " response case $response in [yY][eE][sS]|[yY]) ln -v -s "$TARGET" "$LINK" ;; esac fi } for FILE in $FILES; do ask_install $FILE done
Decrypt keys.
if [ ! -f "$BASE/.ssh/id_rsa" ]; then read -r -p "$BASE/.ssh/id_rsa doesn't exist. Decrypt file? [y/N] " response case "$response" in [yY][eE][sS]|[yY]) install -m 600 /dev/null "$BASE/.ssh/id_rsa" gpg2 --output "$BASE/.ssh/id_rsa" --yes --decrypt "$BASE/.ssh/id_rsa.gpg" ;; esac else echo "$BASE/.ssh/id_rsa exists. Skipping..." fi
Then copies nixos/* files to /etc/nixos/.
read -r -p "Copy NixOS config? [y/N] " response case "$response" in [yY][eE][sS]|[yY]) sudo mkdir -v -p /etc/nixos sudo cp -v "$BASE/nixos"/* "/etc/nixos/" ;; esac