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 README.org --batch -f org-babel-tangle
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 (yet) covered in this document are:
- emacs configuration at
.emacs.d/
; - vim configuration at
.vimrc
and.vim/
; - awesome wm configuration at
.config/awesome/
; - scripts at
bin/
; - irssi config at
.irssi
;
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, lib, ... }:
let
meta = import ./meta.nix;
machine-config = lib.getAttr meta.name {
Larry = [
<<machine-larry>>
];
ashmalko = [
<<machine-ashmalko>>
];
omicron = [
<<machine-omicron>>
];
};
in
{
imports = [
{
nixpkgs.config.allowUnfree = true;
# The NixOS release to be compatible with for stateful data such as databases.
system.stateVersion = "15.09";
}
<<nixos-section>>
] ++ machine-config;
}
This <<nixos-section>>
is replaced by other parts of this doc.
This moves nixos configuration from the default location to the dotfiles/nixos/configuration.nix
.
This also disables channel mechanism and makes nixos use Nixpkgs in the dotfiles/channels
directory. I usually follow nixpkgs-unstable, but that gives me more control.
{
nix.nixPath =
let dotfiles = "/home/rasen/dotfiles";
in [
"nixos-config=${dotfiles}/nixos/configuration.nix"
"dotfiles=${dotfiles}"
"${dotfiles}/channels"
];
}
If you want to override default configuration location, use -I
flag:
sudo nixos-rebuild switch -I nixos-config=/etc/nixos/configuration.nix
Save nixos-config in the Nix store, so I can retrieve it later. The config for the current ly running system is located at /var/run/current-system/configuration.nix
.
{
system.copySystemConfiguration = true;
}
This setting copies only the configuration.nix
file, which works pretty nice as I have only one configuration file and don’t split it.
I’m the only user of the system:
{
users.extraUsers.rasen = {
isNormalUser = true;
uid = 1000;
extraGroups = [ "users" "wheel" "input" ];
initialPassword = "HelloWorld";
};
}
initialPassword
is used only first time when user is created. It must be changed as soon as possible with passwd
.
I have three machines running NixOS.
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).
{
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";
};
};
}
There are also two swap partitions, but one of them is from my slow hdd, so I probably shouldn’t use it.
{
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 a laptop).
{
nix.maxJobs = 8;
nix.buildCores = 8;
networking = {
hostName = "Larry";
useDHCP = false;
wicd.enable = true;
wireless.enable = false;
};
services.xserver.synaptics = {
enable = true;
twoFingerScroll = true;
vertEdgeScroll = true;
};
}
I have nvidia video card and integrated intel-one. I don’t use nvidia one, so next the line disables it:
{
hardware.nvidiaOptimus.disable = true;
}
ELK stack to gather information about my computer activity.
{
services.logstash = {
enable = true;
inputConfig = ''
file {
path => "/home/rasen/log.txt.processed"
sincedb_path => "/home/rasen/.log.txt.sincedb"
codec => "json"
start_position => "beginning"
tags => [ "awesomewm" ]
type => "awesomewm"
}
file {
path => "/home/rasen/log.txt.ashmalko"
sincedb_path => "/home/rasen/.log.txt.ashmalko.sincedb"
codec => "json"
start_position => "beginning"
tags => [ "awesomewm" ]
type => "awesomewm"
}
'';
filterConfig = ''
if [path] == "/home/rasen/log.txt.ashmalko" {
mutate {
replace => [ "host", "ashmalko" ]
}
}
'';
outputConfig = ''
elasticsearch {
index => "quantified-self"
document_type => "awesomewm"
}
'';
};
services.elasticsearch = {
enable = true;
cluster_name = "ashmalko";
extraConf = ''
node.name: "${meta.name}"
'';
};
services.kibana = {
enable = true;
};
}
This is my desktop corporate computer.
{
networking.hostName = "ashmalko";
nix.maxJobs = 4;
nix.buildCores = 4;
}
{
imports = [
<nixpkgs/nixos/modules/installer/scan/not-detected.nix>
];
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
boot.kernelParams = [ "intel_pstate=no_hwp" ];
boot.loader.grub = {
enable = true;
version = 2;
device = "/dev/sda";
efiSupport = true;
};
boot.loader.efi.canTouchEfiVariables = true;
}
This is encrypted LVM on LUKS setup.
{
boot.initrd.luks.devices = [
{
name = "root";
device = "/dev/disk/by-uuid/a3eb801b-7771-4112-bb8d-42a9676e65de";
preLVM = true;
allowDiscards = true;
}
];
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/4184-7556";
fsType = "vfat";
};
fileSystems."/" = {
device = "/dev/disk/by-uuid/84d89f4b-7707-4580-8dbc-ec7e15e43b52";
fsType = "ext4";
options = [ "noatime" "nodiratime" "discard" ];
};
swapDevices = [
{ device = "/dev/disk/by-uuid/5a8086b0-627e-4775-ac07-b827ced6998b"; }
];
}
Use pulseaudio (multiple sound sinks, skype calls). pavucontrol
is PulseAudio Volume Control—a nice package for controlling pulseaudio settings.
{
hardware.pulseaudio = {
enable = true;
support32Bit = true;
};
environment.systemPackages = [ pkgs.pavucontrol ];
}
I host some git repos on my machine:
{
services.gitolite = {
enable = true;
user = "git";
adminPubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDJhMhxIwZJgIY6CNSNEH+BetF/WCUtDFY2KTIl8LcvXNHZTh4ZMc5shTOS/ROT4aH8Awbm0NjMdW33J5tFMN8T7q89YZS8hbBjLEh8J04Y+kndjnllDXU6NnIr/AenMPIZxJZtSvWYx+f3oO6thvkZYcyzxvA5Vi6V1cGx6ni0Kizq/WV/mE/P1nNbwuN3C4lCtiBC9duvoNhp65PctQNohnKQs0vpQcqVlfqBsjQ7hhj2Fjg+Ofmt5NkL+NhKQNqfkYN5QyIAulucjmFAieKR4qQBABopl2F6f8D9IjY8yH46OCrgss4WTf+wxW4EBw/QEfNoKWkgVoZtxXP5pqAz rasen@Larry";
};
}
I expose some repos for the folks here, so relax avahi rules for they to discover my machine by ashmalko.local
rather than remember my IP address.
{
services.avahi.interfaces = [ "enp0s31f6" ];
}
I’m running an MQTT implementation in there.
{
networking.firewall.allowedTCPPorts = [
1883 8883 # Zink
3000 # Grafana
];
systemd.services.zink = {
description = "Zink service";
wantedBy = [ "multi-user.target" ];
after = [ "grafana.service" ];
serviceConfig =
let zink =
pkgs.rustPlatform.buildRustPackage {
name = "zink-0.0.1";
src = pkgs.fetchFromGitHub {
owner = "rasendubi";
repo = "zink";
rev = "influxdb-0.0.1";
sha256 = "1sw07p2a83s34mp69snz1znwqp8xlba8dqc5y6iqfhyc3zwwbd3w";
};
depsSha256 = "1dvk5l32nrpxy7h5pfiqssx06xd72pszd8kr2f2y3ba288ck97rr";
};
in {
ExecStart = "${zink}/bin/zink timestamp,tagId,batteryLevel,temperature";
Restart = "on-failure";
};
};
services.influxdb.enable = true;
services.grafana = {
enable = true;
addr = "0.0.0.0";
port = 3000;
domain = "ashmalko.local";
auth.anonymous.enable = true;
};
}
This is my small Dell XPS 13.
{
imports = [
<nixpkgs/nixos/modules/installer/scan/not-detected.nix>
];
boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
nix.maxJobs = lib.mkDefault 4;
powerManagement.cpuFreqGovernor = "powersave";
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
Same LVM on LUKS setup as ashmalko
uses.
boot.initrd.luks.devices = [
{
name = "root";
device = "/dev/disk/by-uuid/8b591c68-48cb-49f0-b4b5-2cdf14d583dc";
preLVM = true;
}
];
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/BA72-5382";
fsType = "vfat";
};
fileSystems."/" = {
device = "/dev/disk/by-uuid/434a4977-ea2c-44c0-b363-e7cf6e947f00";
fsType = "ext4";
options = [ "noatime" "nodiratime" "discard" ];
};
fileSystems."/home" = {
device = "/dev/disk/by-uuid/8bfa73e5-c2f1-424e-9f5c-efb97090caf9";
fsType = "ext4";
options = [ "noatime" "nodiratime" "discard" ];
};
swapDevices = [
{ device = "/dev/disk/by-uuid/26a19f99-4f3a-4bd5-b2ed-359bed344b1e"; }
];
Wireless networking.
networking = {
hostName = "omicron";
useDHCP = false;
wicd.enable = true;
wireless.enable = false;
};
services.xserver.synaptics = {
enable = true;
twoFingerScroll = true;
vertEdgeScroll = true;
};
}
I want to access my corporate network from my home laptop when I need to. I have a VPN up between my laptop and corporate desktop, so the solution is to use my corporate desktop as a router.
On Larry, route all corporate network traffic via ashmalko:
{
networking.localCommands = ''
ip route del 10.2.0.0/22 via 10.7.0.52 2> /dev/null || true
ip route add 10.2.0.0/22 via 10.7.0.52
'';
}
On ashmalko, rewrite packages from Larry into internal network. (Which is called “external” in the routing sense.)
{
networking.nat = {
enable = true;
internalInterfaces = [ "tap0" ];
externalInterface = "enp0s31f6";
};
}
As a responsible NixOS user, I refuse to install software blindly with sudo make install
. That’s why I must write my own nix-expressions. I keep them in my local overlay until they’re merged upstream.
The entry point is just a set of all my packages in nixpkgs-local/default.nix
:
{ pkgs ? import <nixpkgs> { } }:
let
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/default.nix -i
To make package results testing better, I build them in isolated environment (for more info, see nixos manual):
{
nix.useSandbox = "relaxed";
}
Note that this is "relaxed"
instead of true
, because I have some packages that require a network to build and thus are __noChroot
.
Update locate database daily.
{
services.locate = {
enable = true;
localuser = "rasen";
};
}
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;
browseDomains = [ ];
interfaces = [ "tap0" ];
nssmdns = true;
publish = {
enable = true;
addresses = true;
};
};
}
The following lines are needed to start avahi-daemon automatically. The default service is wantedBy “if-up.target” which doesn’t seem to be activated (maybe because of wicd).
{
systemd.services.avahi-daemon.wantedBy = [ "multi-user.target" ];
systemd.services.avahi-daemon.after = [ "openvpn-kaa.target" ];
}
{
services.openssh = {
enable = true;
passwordAuthentication = false;
# Disable default firewall rules
ports = [];
listenAddresses = [
{ addr = "0.0.0.0"; port = 22; }
];
};
# allow ssh from VPN network only
networking.firewall = {
extraCommands = ''
ip46tables -D INPUT -i tap0 -p tcp -m tcp --dport 22 -j ACCEPT 2> /dev/null || true
ip46tables -A INPUT -i tap0 -p tcp -m tcp --dport 22 -j ACCEPT
'';
};
}
Mosh (mobile shell) is a cool addition to ssh.
{
programs.mosh.enable = true;
}
Use dnsmasq as a DNS cache.
{
services.dnsmasq = {
enable = true;
# These are used in addition to resolv.conf
servers = [
"/cybervisiontech.com/10.2.2.45"
"/kaaiot.io/10.2.2.45"
"8.8.8.8"
"8.8.4.4"
];
extraConfig = ''
listen-address=127.0.0.1
cache-size=1000
no-negcache
'';
};
# Put the text in /etc/resolv.conf.head
#
# That will prepend dnsmasq server to /etc/resolv.conf (dhcpcd-specific)
environment.etc."resolv.conf.head".text = ''
nameserver 127.0.0.1
'';
# dhclient-specific.
#
# This prepends local dnsmasq to the list of domain name servers.
#
# The supersede host-name line resolves the issue when DHCP overrides my machine name.
# For more info, see https://support.cumulusnetworks.com/hc/en-us/articles/218289767-Hostname-Configured-in-etc-hostname-Is-Superseded-by-the-DHCP-hostname-Option-
systemd.services.wicd.preStart = let
dhclient_conf_template = pkgs.writeText "dhclient.conf.template" ''
prepend domain-name-servers 127.0.0.1;
supersede host-name "$_HOSTNAME";
'';
in ''
mkdir -p /var/lib/wicd/
cp ${dhclient_conf_template} /var/lib/wicd/dhclient.conf.template
'';
}
Enable firewall. This disables all ports and pings.
{
networking.firewall = {
enable = true;
allowPing = false;
connectionTrackingModules = [];
autoLoadConntrackHelpers = false;
};
}
{
virtualisation.virtualbox.host.enable = true;
users.extraUsers.rasen.extraGroups = [ "vboxusers" ];
}
I use mbsync to sync my accounts and make them available offline.
{
environment.systemPackages = [
pkgs.isyncUnstable
];
}
Config file is .mbsyncrc
.
MaildirStore local
Path ~/Mail/
Inbox ~/Mail/INBOX
SubFolders Verbatim
IMAPAccount gmail
Host imap.gmail.com
User [email protected]
PassCmd "pass imap.gmail.com/[email protected]"
SSLType IMAPS
CertificateFile /etc/ssl/certs/ca-certificates.crt
IMAPStore gmail-remote
Account gmail
Channel sync-gmail-all
Master :gmail-remote:"[Gmail]/All Mail"
Slave :local:Personal/all
Create Both
SyncState *
Channel sync-gmail-sent
Master :gmail-remote:"[Gmail]/Sent Mail"
Slave :local:Personal/sent
Create Both
SyncState *
Group sync-gmail
Channel sync-gmail-all
Channel sync-gmail-sent
IMAPAccount kaaiot
Host imap.gmail.com
User [email protected]
PassCmd "pass imap.gmail.com/[email protected]"
SSLType IMAPS
AuthMechs *
CertificateFile /etc/ssl/certs/ca-certificates.crt
IMAPStore kaaiot-remote
Account kaaiot
Channel sync-kaaiot-all
Master :kaaiot-remote:"[Gmail]/All Mail"
Slave :local:KaaIoT/all
Create Both
SyncState *
Channel sync-kaaiot-sent
Master :kaaiot-remote:"[Gmail]/Sent Mail"
Slave :local:KaaIoT/sent
Create Both
SyncState *
Group sync-kaaiot
Channel sync-kaaiot-all
Channel sync-kaaiot-sent
IMAPAccount cv
Host mail.cybervisiontech.com
User ashmalko
PassCmd "pass mail.cybervisiontech.com/[email protected]"
SSLType IMAPS
CertificateFile /etc/ssl/certs/ca-certificates.crt
IMAPStore cv-remote
Account cv
Channel sync-cv
Master :cv-remote:
Slave :local:Work/
Patterns * !Chats !Contacts !"Emailed Contacts"
Create Both
SyncState *
Dovecot serves fetched mail to gnus.
{
services.dovecot2 = {
enable = true;
enablePop3 = false;
enableImap = true;
mailLocation = "maildir:~/Mail:LAYOUT=fs";
};
# dovecot has some helpers in libexec (namely, imap).
environment.pathsToLink = [ "/libexec/dovecot" ];
}
Msmtp is used to send mail.
{
environment.systemPackages = [
pkgs.msmtp
];
}
Config file is .msmtprc
.
defaults
auth on
tls on
tls_starttls off
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile ~/.msmtp.log
# Gmail
account gmail
host smtp.gmail.com
port 465
from [email protected]
user [email protected]
passwordeval "pass imap.gmail.com/[email protected]"
# KaaIoT
account kaaiot
host smtp.gmail.com
port 465
from [email protected]
user [email protected]
passwordeval "pass imap.gmail.com/[email protected]"
# CyberVision
account cv
host mail.cybervisiontech.com
port 465
from [email protected]
user ashmalko
passwordeval "pass mail.cybervisiontech.com/[email protected]"
# default
account default : gmail
Notmuch is used for tagging.
{
environment.systemPackages = [
pkgs.notmuch
];
}
Config file is .notmuch-config
.
[user]
name=Alexey Shmalko
[email protected]
[email protected],[email protected]
[database]
path=/home/rasen/Mail
[new]
tags=new;
ignore=.mbsyncstate;.mbsyncstate.lock;.mbsyncstate.new;.mbsyncstate.journal;.uidvalidity;dovecot-uidlist;dovecot.index;dovecot.index.log;dovecot.index.log.2;dovecot.index.cache
[search]
exclude_tags=deleted;spam
[crypto]
gpg_path=gpg2
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";
}
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;
}
I use awesome wm:
{
services.xserver.windowManager.awesome = {
enable = true;
luaModules = [ pkgs.luaPackages.luafilesystem pkgs.luaPackages.cjson ];
};
}
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:
{
environment.systemPackages = [
pkgs.wmname
pkgs.xclip
pkgs.scrot
];
}
I use English and Ukrainian layouts. I also use Russian symbols, but they are on the third level.
{
services.xserver.layout = "us,ua";
services.xserver.xkbVariant = "workman,";
# Use same config for linux console
i18n.consoleUseXkbConfig = true;
}
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";
}
I use built-in awesome layout indicator. See .config/awesome/rc.lua for more details.
xkb_keymap {
xkb_keycodes { include "evdev+aliases(qwerty)"};
xkb_types { include "complete"};
xkb_compat { include "complete+ledcaps(group_lock)"};
xkb_geometry { include "pc(pc105)"};
xkb_symbols "my" {
include "pc+us+ru:2+inet(evdev)+group(menu_toggle)"
};
};
(Not sure I actually use it.)
Use left ctrl as escape when pressed on its own.
XCAPE can do that with the next command.
xcape -e 'Control_L=Escape'
(Of course, I need xcape in my system packages.)
{
environment.systemPackages = [ pkgs.xcape ];
}
Redshift adjusts the color temperature of the screen according to the position of the sun.
Blue light blocks melatonin (sleep harmone) secretion, so you feel less sleepy when you stare at computer screen. Redshift blocks some blue light (making screen more red), which should improve melatonin secretion and restore sleepiness (which is a good thing).
{
services.redshift = {
enable = true;
latitude = "50.4500";
longitude = "30.5233";
};
}
This makes apps look like in KDE:
{
environment.systemPackages = [
pkgs.oxygen-icons5
];
}
The next is a back-port of oxygen-gtk
theme, which was removed with remove of KDE4 from nixpkgs.
(let
oldpkgs = import (pkgs.fetchFromGitHub {
owner = "NixOS";
repo = "nixpkgs-channels";
rev = "1aa77d0519ae23a0dbef6cab6f15393cfadcc454";
sha256 = "1gcd8938n3z0a095b0203fhxp6lddaw1ic1rl33q441m1w0i19jv";
}) { config = config.nixpkgs.config; };
in {
environment.systemPackages = [ oldpkgs.oxygen-gtk2 oldpkgs.oxygen-gtk3 ];
environment.shellInit = ''
export GTK_PATH=$GTK_PATH:${oldpkgs.oxygen_gtk}/lib/gtk-2.0
export GTK2_RC_FILES=$GTK2_RC_FILES:${oldpkgs.oxygen_gtk}/share/themes/oxygen-gtk/gtk-2.0/gtkrc
'';
})
The theme has some issues with deadbeef, so I install adwaita icons to make deadbeef usable.
{
environment.systemPackages = [
pkgs.gnome3.adwaita-icon-theme
];
}
I’m not a font guru, so I just stuffed a bunch of random fonts in here.
{
fonts = {
enableCoreFonts = true;
enableFontDir = true;
enableGhostscriptFonts = false;
fonts = with pkgs; [
inconsolata
corefonts
dejavu_fonts
source-code-pro
ubuntu_font_family
unifont
];
};
}
Here go applications (almost) every normal user needs.
I don’t use full KDE but some apps are definitely nice.
{
environment.systemPackages = [
pkgs.gwenview
pkgs.dolphin
pkgs.kde4.kfilemetadata
pkgs.filelight
pkgs.shared_mime_info
];
}
KDE apps might have issues with mime types without this:
{
environment.pathsToLink = [ "/share" ];
}
Though my default browser is google-chrome, it has issues with Java plugin, so I use firefox for that. I also use Extended Support Release, which still supports Java.
{
nixpkgs.config.firefox = {
icedtea = true;
};
environment.systemPackages = [ pkgs.firefox-esr ];
}
Zathura is a cool document viewer with Vim-like bindings.
{
environment.systemPackages = [
pkgs.zathura
];
}
Enable incremental search (Zathura’s config goes to ~/.config/zathura/zathurarc
).
set incremental-search true
Slock is a simple X display locker and should probably not crash as xscreensaver does.
Slock tries to disable OOM killer (so the locker is not killed when memory is low) and this requires a suid flag for executable. Otherwise, you get the following message:
slock: unable to disable OOM killer. Make sure to suid or sgid slock.
{
security.wrappers = {
slock = {
source = "${pkgs.slock}/bin/slock";
};
};
}
Don’t require additional setup.
{
environment.systemPackages = [
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
pkgs.thunderbird
pkgs.xss-lock
pkgs.alarm-clock-applet
pkgs.pass
# Used by naga setup
pkgs.xdotool
];
}
I’m a seasoned Vim user, but I’ve switched to emacs now.
{
environment.systemPackages = [
(pkgs.vim_configurable.override { python3 = true; })
pkgs.emacs
];
}
The following packages are needed for emacs plugins:
{
environment.systemPackages = [
pkgs.ycmd
pkgs.rustracer
pkgs.ditaa
pkgs.jre
];
}
I use urxvt as my terminal emulator:
{
environment.systemPackages = [
pkgs.rxvt_unicode
];
}
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 reading this document in emacs now):
xrdb ~/.Xresources
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:
From urxvt-perls:
Since version 9.20 rxvt-unicode natively supports copying to and pasting from the CLIPBOARD buffer with the Ctrl-Meta-c and Ctrl-Meta-v key bindings. The clipboard.autocopy setting is provided by the selection_to_clipboard extension shipped with rxvt-unicode.
That means, I don’t need perl extensions at all.
I use Terminus font.
{
fonts = {
fonts = [
pkgs.powerline-fonts
pkgs.terminus_font
];
};
}
URxvt.font: xft:Terminus:normal:size=12
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
fish is a cool shell, I use it as my default for day-to-day work.
{
programs.fish.enable = true;
users.defaultUserShell = pkgs.fish;
}
The next section goes to .config/fish/functions/showqr.fish
. That’s a function I use for displaying arbitrary text (mainly passwords stored with pass
) as a QR code without any temporary files. (tr
is used to drop trailing newline.)
function showqr
tr -d '\n' | qrencode -t png -o - | feh -
end
It uses qrencode
and feh
packages:
{
environment.systemPackages = [
pkgs.qrencode
pkgs.feh
];
}
Zsh is my secondary shell. I use it when I need sh compatibility. (fish is not sh compliant.)
{
programs.zsh.enable = true;
}
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
Nothing special, but g=git
is a real timesaver.
alias ls='ls --color=auto'
alias grep='grep --color=auto'
alias g="git"
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}"
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
{
environment.systemPackages = [
pkgs.gitFull
pkgs.gitg
];
}
Basic info: my name, email, ui, editor, rerere.
[user]
name = Alexey Shmalko
email = [email protected]
[sendemail]
smtpencryption = ssl
smtpserver = smtp.gmail.com
smtpuser = [email protected]
smtpserverport = 465
[color]
ui = true
[core]
editor = vim
[push]
default = simple
[pull]
rebase = true
[rebase]
autostash = true
[rerere]
enabled = true
Configure signing with gpg.
[user]
signingkey = EB3066C3
[gpg]
program = gpg2
[push]
gpgSign = if-asked
I have LOTS of aliases:
[alias]
cl = clone
gh-cl = gh-clone
cr = cr-fix
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 --show-signature
l1 = log -1
lp = log -p
c = commit
ca = commit --amend
co = checkout
cb = checkout -b
cm = checkout origin/master
de = checkout --detach
fco = fetch-checkout
br = branch
s = status
re = reset --hard
r = rebase
rc = rebase --continue
ri = rebase -i
m = merge
t = tag
su = submodule update --init --recursive
bi = bisect
Always push to github with ssh keys instead of login/password.
[url "[email protected]:"]
pushInsteadOf = https://github.com/
{
environment.systemPackages = [
pkgs.tmux
];
}
Use 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
The following packages provide a termiinal emulator, Open On-Chip Debugger, telnet, and logic analyzer.
{
environment.systemPackages = [
pkgs.minicom
pkgs.openocd
pkgs.telnet
pkgs.saleae-logic
];
}
To allow user use openocd without sudo, we should add him to plugdev
group and install openocd udev rules:
{
users.extraGroups.plugdev = { };
users.extraUsers.rasen.extraGroups = [ "plugdev" "dialout" ];
services.udev.packages = [ pkgs.openocd ];
}
{
environment.systemPackages = [
pkgs.wget
pkgs.htop
pkgs.psmisc
pkgs.zip
pkgs.unzip
pkgs.unrar
pkgs.p7zip
pkgs.irssi
pkgs.bind
pkgs.file
pkgs.which
pkgs.whois
pkgs.gnupg
pkgs.utillinuxCurses
pkgs.patchelf
pkgs.nix-repl
pkgs.nox
pkgs.python
pkgs.python3
];
}
This install a number of default man pages for the linux/posix system.
{
environment.systemPackages = [
pkgs.man-pages
pkgs.stdman
pkgs.posix_man_pages
pkgs.stdmanpages
];
}
We need the following package:
{
environment.systemPackages = [
pkgs.steam
];
}
It’s also required to enable 32-bit support for opengl and pulseaudio:
{
hardware.opengl.driSupport32Bit = true;
hardware.pulseaudio.support32Bit = true;
}
I play nethack rarely, but still nice to have my setting in sync.
{
environment.systemPackages = [
pkgs.nethack
];
}
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=role:monk, gender:male
OPTIONS=statushilites
OPTIONS=pettype:dog, dogname:Fido
OPTIONS=!autopickup
OPTIONS=lit_corridor, DECgraphics, showscore, showexp, time, color, hilite_pet
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 .Xresources .config/awesome .config/nvim .nethackrc .emacs.d .ssh bin .config/zathura .irssi .config/xkb .config/fish .msmtprc .notmuch-config .mbsyncrc"
DEST=$1
if [ -z "$DEST" ]; then
DEST="$HOME"
fi
BASE=$(cd "$(dirname "$0")" && pwd)
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
Fisherman is a plugin for fish.
if [ ! -e "$DEST/.config/fish/functions/fisher.fish" ]; then
read -r -p "Install fisherman and all plugins? [y/N] " response
case $response in
[yY][eE][sS]|[yY])
curl -Lo "$DEST/.config/fish/functions/fisher.fish" --create-dirs \
https://raw.githubusercontent.com/fisherman/fisherman/master/fisher.fish
fish -c fisher
;;
esac
fi