Merge remote-tracking branch 'cd/master'

This commit is contained in:
lassulus 2016-06-30 21:51:09 +02:00
commit b3fa9cbd7e
34 changed files with 267 additions and 2925 deletions

View File

@ -91,8 +91,6 @@ let
imp = lib.mkMerge [
{ krebs = import ./lass { inherit config lib; }; }
{ krebs = import ./makefu { inherit config lib; }; }
{ krebs = import ./miefda { inherit config lib; }; }
{ krebs = import ./mv { inherit config lib; }; }
{ krebs = import ./shared { inherit config lib; }; }
{ krebs = import ./tv { inherit config lib; }; }
{

View File

@ -1,39 +0,0 @@
{ config, lib, ... }:
with config.krebs.lib;
{
hosts = mapAttrs (_: setAttr "owner" config.krebs.users.miefda) {
bobby = {
cores = 4;
nets = {
retiolum = {
ip4.addr = "10.243.111.112";
ip6.addr = "42:0:0:0:0:0:111:112";
aliases = [
"bobby.retiolum"
"cgit.bobby.retiolum"
];
tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA+AScnIqFdzGl+iRZTNZ7r91n/r1H4GzDsrAupUvJ4mi7nDN4eP8s
uLvKtJp22RxfuF3Kf4KhHb8LHQ8bLLN/KDaNDXrCNBc69d7vvLsjoY+wfGLJNu4Y
Ad/8J4r3rdb83mTA3IHb47T/70MERPBr2gF84YiG6ZoQrPQuTk4lHxaI83SOhjny
0F0ucS/rBV6Vv9y5/756TKi1cFPSpY4X+qeWc8xWrBGJcJiiqYb8ZX2o/lkAJ5c+
jI/VdybGFVGY9+bp4Jw5xBIo5KGuFnm8+blRmSDDl3joRneKQSx9FAu7RUwoajBu
cEbi1529NReQzIFT6Vt22ymbHftxOiuh4QIDAQAB
-----END RSA PUBLIC KEY-----
'';
};
};
#ssh.privkey.path = <secrets/ssh.ed25519>;
#ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM+7Qa51l0NSkBiaK2s8vQEoeObV3UPZyEzMxfUK/ZAO root@stro";
};
};
users = {
miefda = {
mail = "miefda@miefda.de";
pubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCVdNCks6mrItKHYIwgW3s+NINFhHqZtLPj3l6TJUWd93ZSuuI6P+Z/0m0G9Z4tWWaXWsOCnzMA2WOKcitBbLcaQxVypJfvmfoA5CVlh4/nf8NfvbMFkVIYPehxR7YoejfKOxPOCNC3248RiD8kqa4/5IF8qdqE+mRQUIZJXvN0jZZ+rGnYo5Z544O9JqsV+VjjOgK0Fchpxf/lC8dnBucIce7gUwi5npwsGQZgSDmRobBRFVDZag1abLFNZN2faI8uqzSlU6KRRapYV266Of7j3kmDokMan4szjP1EexmTWm+arwRiz9p0M5oKs6zofez0mOyF5ux02NB3XIhbJc8CfMjeA7PmSg4ZhghjlSjIOR+1mMIDiDVi6PNLw5atzvpyfYtpf5sWpdIpXCS0lyzIgasqW4gbAiWoFPv5A0mw0QI6UqlxQ8Pdm6R7P6yQxyknrxnvFGMQPiqgl21ssSNA9A+YRd4j0nATntzOeD1bxTZkyU4FtW++0hg3Ph6HiHLfPd9w70wPr7b0RITVnBcN2ZqIO+5NIqQYU801FCNXsTuBh0ueTsVTGJYySUGkmkHyH5spLYdr1Z5w+4W+HgbxPk40pyZJ18S0umL49igxR9NsniucFy1/jqqi0TiDIsHx6vsawFT1F2rq9ZtGaRcJL6Yfz0p+uZC5rc/nI+mMlQ== miefda@nixos";
};
};
}

View File

@ -1,39 +0,0 @@
{ config, ... }:
with config.krebs.lib;
{
hosts = mapAttrs (_: setAttr "owner" config.krebs.users.mv) {
stro = {
cores = 4;
nets = {
retiolum = {
ip4.addr = "10.243.111.111";
ip6.addr = "42:0:0:0:0:0:111:111";
aliases = [
"stro.retiolum"
"cgit.stro.retiolum"
];
tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA0vIzLyoetOyi3R7qOh3gjSvUVjPEdqCvd0NEevDCIhhFy0nIbZ/b
vnuk3EUeTb6e384J8fKB4agig0JeR3JjtDvtjy5g9Cdy2nrU71w8wqU0etmv2PTb
FjbCFfeBXn0N3U7gXwjZGCvjAXa1a4jGb4R2iYBYGG3aY4reCN8B8Ah81h+S0oLg
ZJJfaBmWM5vNRFEI5X4CLaVnwtsoZuXIjYStgNn/9Mg/Y6NQS0H0H+HFeyhigAqG
oYGqNar/2QqPU176V/FwrD30F3qJV1uyzuPta7hmdfOxqYjZ/jqdPSRYtlunYYcq
XbH5oYmzO9NEeVWzjdac/DiV2OP8HufoYwIDAQAB
-----END RSA PUBLIC KEY-----
'';
};
};
ssh.privkey.path = <secrets/ssh.ed25519>;
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM+7Qa51l0NSkBiaK2s8vQEoeObV3UPZyEzMxfUK/ZAO root@stro";
};
};
users = {
mv-stro = {
mail = "mv@stro.retiolum";
pubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCxM34g1GUm5EtU00DAOlGSx8MsCWunhGTrozurj460QT7EdUbZvj0AcrQC0lP9kaZyhX+KueTjmLC+ICsnlHYeg4zoSEnSAUkccuyZxfgynVc4wrpfNAc1nHjDhDb/ulnC+8wNxvxUpI0XlBgu/Y7AbbChZj3ofv6uGGHJKfG3uSyCkt9VTCi1KwydHpe9P252N8NbopnbnkT0EMkRHruh7ICEKr4/ivmUL/IUrbFicEeCy4SeRAl8+00x4WqqvbBPzgdXn0AIjKLvus3dBoQubJNpUoXnyXJbElnit5a7QcgZJNLMbV0kf9zzCGduxkADzHkAFB9D4PuSMYt62iy12QlGbm80A9ncuwaSyJf7hPTvNbU8VyCblyfRz/SCaudUrfk5Xbxxu26FHi4hZqr3IUQt4T8pD8JWYGl4n2ZKnD8hHz/jrmNBK8h9d+VFafU9t1hRxlFsW1AhMEM+kfWClyhfTcKBKbml2a657lgUEVmlZt+18kwwsivM1QhHNTgxn5urRXRkh1VQ40UQroVuV1OUmvAngyAthF441VPGc5z7kEI+D4qjmUjSy6k4dvEy/RGfsAgJCf63zilRuUbL68f2OpxE8aeZZUXPvgdLml284pry7+C5sjlnCDoJfCj/yhdVx6mU9pWUd/Q97CLQewbsYhMzsqlBlIkXuipkDQ== mv@stro";
};
};
}

View File

@ -58,6 +58,10 @@ let out = rec {
genAttrs' = names: f: listToAttrs (map f names);
getAttrs = names: set:
listToAttrs (map (name: nameValuePair name set.${name})
(filter (flip hasAttr set) names));
setAttr = name: value: set: set // { ${name} = value; };
optionalTrace = c: msg: x: if c then trace msg x else x;

View File

@ -74,33 +74,59 @@ rec {
writeOut = name: specs0:
let
specs = mapAttrsToList (path0: spec0: rec {
path = guard {
type = types.pathname;
value = path0;
writers.link =
{ path
, link
}:
assert path == "" || types.absolute-pathname.check path;
assert types.package.check link;
{
install = /* sh */ ''
${optionalString (dirOf path != "/") /* sh */ ''
${pkgs.coreutils}/bin/mkdir -p $out${dirOf path}
''}
${pkgs.coreutils}/bin/ln -s ${link} $out${path}
'';
};
var = "file_${hashString "sha1" path}";
text = spec0.text;
executable = guard {
type = types.bool;
value = spec0.executable or false;
};
mode = guard {
type = types.file-mode;
value = spec0.mode or (if executable then "0755" else "0644");
};
}) specs0;
filevars = genAttrs' specs (spec: nameValuePair spec.var spec.text);
writers.text =
{ path
, executable ? false
, mode ? if executable then "0755" else "0644"
, text
}:
assert path == "" || types.absolute-pathname.check path;
assert types.bool.check executable;
assert types.file-mode.check mode;
rec {
var = "file_${hashString "sha1" path}";
val = text;
install = /* sh */ ''
${pkgs.coreutils}/bin/install -m ${mode} -D ''$${var}Path $out${path}
'';
};
write = spec: writers.${spec.type} (removeAttrs spec ["type"]);
specs =
mapAttrsToList
(path: spec: let
known-types = [ "link" "text" ];
found-types = attrNames (getAttrs known-types spec);
type = assert length found-types == 1; head found-types;
in spec // { inherit path type; })
specs0;
files = map write specs;
filevars = genAttrs' (filter (hasAttr "var") files)
(spec: nameValuePair spec.var spec.val);
env = filevars // { passAsFile = attrNames filevars; };
in
pkgs.runCommand name env /* sh */ ''
set -efu
PATH=${makeBinPath [pkgs.coreutils]}
${concatMapStrings (spec: /* sh */ ''
install -m ${spec.mode} -D ''$${spec.var}Path $out${spec.path}
'') specs}
${concatMapStringsSep "\n" (getAttr "install") files}
'';
writeHaskell =
@ -213,4 +239,6 @@ rec {
(name: path: pkgs.runCommand name {} /* sh */ ''
${pkgs.cabal2nix}/bin/cabal2nix ${path} > $out
'');
writeSed = makeScriptWriter "${pkgs.gnused}/bin/sed -f";
}

View File

@ -1,102 +0,0 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running nixos-help).
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
../.
../2configs/miefda.nix
../2configs/tlp.nix
../2configs/x220t.nix
../2configs/hardware-configuration.nix
../2configs/tinc-basic-retiolum.nix
../2configs/git.nix
];
# Use the GRUB 2 boot loader.
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
# Define on which hard drive you want to install Grub.
boot.loader.grub.device = "/dev/sda";
networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
# Select internationalisation properties.
i18n = {
# consoleFont = "Lat2-Terminus16";
consoleKeyMap = "us";
# defaultLocale = "en_US.UTF-8";
};
# Set your time zone.
time.timeZone = "Europe/Amsterdam";
# List packages installed in system profile. To search by name, run:
# $ nix-env -qaP | grep wget
environment.systemPackages = with pkgs; [
wget chromium
];
# List services that you want to enable:
# Enable the OpenSSH daemon.
services.openssh.enable = true;
# Enable CUPS to print documents.
services.printing.enable = true;
# Enable the X11 windowing system.
services.xserver.enable = true;
services.xserver.layout = "us";
# services.xserver.xkbOptions = "eurosign:e";
# Enable the KDE Desktop Environment.
#services.xserver.displayManager.kdm.enable = true;
services.xserver.desktopManager = {
xfce.enable = true;
xterm.enable= false;
};
# Define a user account. Don't forget to set a password with passwd.
users.extraUsers.miefda = {
isNormalUser = true;
initialPassword= "welcome";
uid = 1000;
extraGroups= [
"wheel"
];
};
# The NixOS release to be compatible with for stateful data such as databases.
system.stateVersion = "15.09";
networking.hostName = config.krebs.build.host.name;
krebs = {
enable = true;
search-domain = "retiolum";
build = {
host = config.krebs.hosts.bobby;
user = config.krebs.users.miefda;
source = {
git.nixpkgs = {
url = https://github.com/Lassulus/nixpkgs;
rev = "363c8430f1efad8b03d5feae6b3a4f2fe7b29251";
target-path = "/var/src/nixpkgs";
};
dir.secrets = {
host = config.krebs.hosts.bobby;
path = "/home/miefda/secrets/${config.krebs.build.host.name}";
};
dir.stockholm = {
host = config.krebs.hosts.bobby;
path = "/home/miefda/gits/stockholm";
};
};
};
};
}

View File

@ -1,91 +0,0 @@
{ config, lib, pkgs, ... }:
with config.krebs.lib;
let
out = {
krebs.git = {
enable = true;
cgit = {
settings = {
root-title = "public repositories at ${config.krebs.build.host.name}";
root-desc = "keep calm and engage";
};
};
repos = mapAttrs (_: s: removeAttrs s ["collaborators"]) repos;
rules = rules;
};
krebs.iptables.tables.filter.INPUT.rules = [
{ predicate = "-i retiolum -p tcp --dport 80"; target = "ACCEPT"; }
];
};
repos =
public-repos //
optionalAttrs config.krebs.build.host.secure restricted-repos;
rules = concatMap make-rules (attrValues repos);
public-repos = mapAttrs make-public-repo {
painload = {};
stockholm = {
cgit.desc = "take all the computers hostage, they'll love you!";
};
#wai-middleware-time = {};
#web-routes-wai-custom = {};
#go = {};
#newsbot-js = {};
#kimsufi-check = {};
#realwallpaper = {};
};
restricted-repos = mapAttrs make-restricted-repo (
{
brain = {
collaborators = with config.krebs.users; [ tv makefu ];
};
} //
import <secrets/repos.nix> { inherit config lib pkgs; }
);
make-public-repo = name: { cgit ? {}, ... }: {
inherit cgit name;
public = true;
hooks = {
post-receive = pkgs.git-hooks.irc-announce {
# TODO make nick = config.krebs.build.host.name the default
nick = config.krebs.build.host.name;
channel = "#retiolum";
server = "cd.retiolum";
verbose = config.krebs.build.host.name == "bobby";
};
};
};
make-restricted-repo = name: { collaborators ? [], ... }: {
inherit collaborators name;
public = false;
};
make-rules =
with git // config.krebs.users;
repo:
singleton {
user = miefda;
repo = [ repo ];
perm = push "refs/*" [ non-fast-forward create delete merge ];
} ++
optional repo.public {
user = [ lass tv makefu uriel ];
repo = [ repo ];
perm = fetch;
} ++
optional (length (repo.collaborators or []) > 0) {
user = repo.collaborators;
repo = [ repo ];
perm = fetch;
};
in out

View File

@ -1,23 +0,0 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, ... }:
{
imports =
[ <nixpkgs/nixos/modules/installer/scan/not-detected.nix>
];
boot.initrd.availableKernelModules = [ "ehci_pci" "ata_piix" "usb_storage" ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/4db70ae3-1ff9-43d7-8fcc-83264761a0bb";
fsType = "ext4";
};
swapDevices = [ ];
nix.maxJobs = 4;
}

View File

@ -1,8 +0,0 @@
{ config, lib, pkgs, ... }:
with config.krebs.lib;
{
#networking.wicd.enable = true;
}

View File

@ -1,14 +0,0 @@
{ config, lib, pkgs, ... }:
with config.krebs.lib;
{
krebs.retiolum = {
enable = true;
connectTo = [
"gum"
"pigstarter"
"prism"
"ire"
];
};
}

View File

@ -1,25 +0,0 @@
{ config, lib, pkgs, ... }:
with config.krebs.lib;
{
hardware.enableAllFirmware = true;
nixpkgs.config.allowUnfree = true;
hardware.cpu.intel.updateMicrocode = true;
zramSwap.enable = true;
zramSwap.numDevices = 2;
hardware.trackpoint = {
enable = true;
sensitivity = 220;
speed = 220;
emulateWheel = true;
};
services.tlp.enable = true;
services.tlp.extraConfig = ''
START_CHARGE_THRESH_BAT0=80
'';
}

View File

@ -1,27 +0,0 @@
{ config, lib, pkgs, ... }:
with config.krebs.lib;
{
services.xserver = {
xkbVariant = "altgr-intl";
videoDriver = "intel";
# vaapiDrivers = [ pkgs.vaapiIntel pkgs.vaapiVdpau ];
deviceSection = ''
Option "AccelMethod" "sna"
'';
};
services.xserver.displayManager.sessionCommands =''
xinput set-int-prop "TPPS/2 IBM TrackPoint" "Evdev Wheel Emulation" 8 1
xinput set-int-prop "TPPS/2 IBM TrackPoint" "Evdev Wheel Emulation Button" 8 2
xinput set-prop "TPPS/2 IBM TrackPoint" "Evdev Wheel Emulation Axes" 6 7 4 5
# xinput set-int-prop "TPPS/2 IBM TrackPoint" "Evdev Wheel Emulation Timeout" 8 200
'';
hardware.bluetooth.enable = true;
}

View File

@ -1,6 +0,0 @@
_:
{
imports = [
../krebs
];
}

View File

@ -1,245 +0,0 @@
{ config, lib, pkgs, ... }:
with config.krebs.lib;
{
krebs.build.host = config.krebs.hosts.stro;
krebs.build.source.git.nixpkgs.rev =
"7ae05edcdd14f6ace83ead9bf0d114e97c89a83a";
imports = [
../.
../2configs/hw/x220.nix
../2configs/git.nix
../2configs/mail-client.nix
../2configs/xserver
{
environment.systemPackages = with pkgs; [
# stockholm
genid
gnumake
hashPassword
lentil
parallel
(pkgs.writeScriptBin "im" ''
#! ${pkgs.bash}/bin/bash
export PATH=${makeSearchPath "bin" (with pkgs; [
tmux
gnugrep
weechat
])}
if tmux list-sessions -F\#S | grep -q '^im''$'; then
exec tmux attach -t im
else
exec tmux new -s im weechat
fi
'')
# root
cryptsetup
ntp # ntpate
# tv
bc
bind # dig
#cac
dic
file
gnupg21
haskellPackages.hledger
htop
jq
manpages
mkpasswd
netcat
nix-repl
nmap
p7zip
pass
posix_man_pages
qrencode
texLive
tmux
#ack
#apache-httpd
#ascii
#emacs
#es
#esniper
#gcc
#gptfdisk
#graphviz
#haskellPackages.cabal2nix
#haskellPackages.ghc
#haskellPackages.shake
#hdparm
#i7z
#iftop
#imagemagick
#inotifyTools
#iodine
#iotop
#lshw
#lsof
#minicom
#mtools
#ncmpc
#nethogs
#nix-prefetch-scripts #cvs bug
#openssl
#openswan
#parted
#perl
#powertop
#ppp
#proot
#pythonPackages.arandr
#pythonPackages.youtube-dl
#racket
#rxvt_unicode-with-plugins
#scrot
#sec
#silver-searcher
#sloccount
#smartmontools
#socat
#sshpass
#strongswan
#sysdig
#sysstat
#tcpdump
#tlsdate
#unetbootin
#utillinuxCurses
#wvdial
#xdotool
#xkill
#xl2tpd
#xsel
unison
];
}
{
tv.iptables = {
enable = true;
input-internet-accept-new-tcp = [
"ssh"
"http"
"tinc"
"smtp"
];
};
}
{
krebs.exim-retiolum.enable = true;
}
{
krebs.nginx = {
enable = true;
servers.default.locations = [
(nameValuePair "~ ^/~(.+?)(/.*)?\$" ''
alias /home/$1/public_html$2;
'')
];
};
}
{
krebs.retiolum = {
enable = true;
connectTo = [
"cd"
"gum"
"wry"
];
};
}
];
boot.initrd.luks = {
cryptoModules = [ "aes" "sha512" "xts" ];
devices = [
{ name = "xuca"; device = "/dev/sda2"; }
];
};
fileSystems = {
"/" = {
device = "/dev/mapper/xuvga-root";
fsType = "btrfs";
options = "defaults,noatime,ssd,compress=lzo";
};
"/home" = {
device = "/dev/mapper/xuvga-home";
fsType = "btrfs";
options = "defaults,noatime,ssd,compress=lzo";
};
"/boot" = {
device = "/dev/sda1";
};
"/tmp" = {
device = "tmpfs";
fsType = "tmpfs";
options = "nosuid,nodev,noatime";
};
};
nixpkgs.config.chromium.enablePepperFlash = true;
#nixpkgs.config.allowUnfreePredicate = pkg:
# pkgs.lib.hasPrefix "virtualbox" pkg.name;
#nixpkgs.config.allowUnfree = true;
#hardware.bumblebee.enable = true;
#hardware.bumblebee.group = "video";
hardware.enableAllFirmware = true;
#hardware.opengl.driSupport32Bit = true;
hardware.pulseaudio.enable = true;
environment.systemPackages = with pkgs; [
#xlibs.fontschumachermisc
#slock
ethtool
#firefoxWrapper # with plugins
#chromiumDevWrapper
tinc
iptables
#jack2
gptfdisk
];
security.setuidPrograms = [
"sendmail" # for cron
];
services.bitlbee.enable = true;
services.printing.enable = true;
services.journald.extraConfig = ''
SystemMaxUse=1G
RuntimeMaxUse=128M
'';
# see tmpfiles.d(5)
systemd.tmpfiles.rules = [
"d /tmp 1777 root root - -" # does this work with mounted /tmp?
];
#virtualisation.libvirtd.enable = true;
#services.bitlbee.enable = true;
#services.tor.client.enable = true;
#services.tor.enable = true;
#nixpkgs.config.virtualbox.enableExtensionPack = true;
# XXX Enable for maximum slowness:
virtualisation.virtualbox.host.enable = true;
# The NixOS release to be compatible with for stateful data such as databases.
system.stateVersion = "15.09";
}

View File

@ -1,779 +0,0 @@
# Expand variable starting with tilde (~)
# We want to expand ~foo/... to /home/foo/... to avoid problems when
# word-to-complete starting with a tilde is fed to commands and ending up
# quoted instead of expanded.
# Only the first portion of the variable from the tilde up to the first slash
# (~../) is expanded. The remainder of the variable, containing for example
# a dollar sign variable ($) or asterisk (*) is not expanded.
# Example usage:
#
# $ v="~"; __expand_tilde_by_ref v; echo "$v"
#
# Example output:
#
# v output
# -------- ----------------
# ~ /home/user
# ~foo/bar /home/foo/bar
# ~foo/$HOME /home/foo/$HOME
# ~foo/a b /home/foo/a b
# ~foo/* /home/foo/*
#
# @param $1 Name of variable (not the value of the variable) to expand
__expand_tilde_by_ref()
{
# Does $1 start with tilde (~)?
if [[ ${!1} == \~* ]]; then
# Does $1 contain slash (/)?
if [[ ${!1} == */* ]]; then
# Yes, $1 contains slash;
# 1: Remove * including and after first slash (/), i.e. "~a/b"
# becomes "~a". Double quotes allow eval.
# 2: Remove * before the first slash (/), i.e. "~a/b"
# becomes "b". Single quotes prevent eval.
# +-----1----+ +---2----+
eval $1="${!1/%\/*}"/'${!1#*/}'
else
# No, $1 doesn't contain slash
eval $1="${!1}"
fi
fi
} # __expand_tilde_by_ref()
# Get the word to complete.
# This is nicer than ${COMP_WORDS[$COMP_CWORD]}, since it handles cases
# where the user is completing in the middle of a word.
# (For example, if the line is "ls foobar",
# and the cursor is here --------> ^
# @param $1 string Characters out of $COMP_WORDBREAKS which should NOT be
# considered word breaks. This is useful for things like scp where
# we want to return host:path and not only path, so we would pass the
# colon (:) as $1 in this case.
# @param $2 integer Index number of word to return, negatively offset to the
# current word (default is 0, previous is 1), respecting the exclusions
# given at $1. For example, `_get_cword "=:" 1' returns the word left of
# the current word, respecting the exclusions "=:".
# @deprecated Use `_get_comp_words_by_ref cur' instead
# @see _get_comp_words_by_ref()
_get_cword()
{
local LC_CTYPE=C
local cword words
__reassemble_comp_words_by_ref "$1" words cword
# return previous word offset by $2
if [[ ${2//[^0-9]/} ]]; then
printf "%s" "${words[cword-$2]}"
elif [[ "${#words[cword]}" -eq 0 || "$COMP_POINT" == "${#COMP_LINE}" ]]; then
printf "%s" "${words[cword]}"
else
local i
local cur="$COMP_LINE"
local index="$COMP_POINT"
for (( i = 0; i <= cword; ++i )); do
while [[
# Current word fits in $cur?
"${#cur}" -ge ${#words[i]} &&
# $cur doesn't match cword?
"${cur:0:${#words[i]}}" != "${words[i]}"
]]; do
# Strip first character
cur="${cur:1}"
# Decrease cursor position
((index--))
done
# Does found word matches cword?
if [[ "$i" -lt "$cword" ]]; then
# No, cword lies further;
local old_size="${#cur}"
cur="${cur#${words[i]}}"
local new_size="${#cur}"
index=$(( index - old_size + new_size ))
fi
done
if [[ "${words[cword]:0:${#cur}}" != "$cur" ]]; then
# We messed up! At least return the whole word so things
# keep working
printf "%s" "${words[cword]}"
else
printf "%s" "${cur:0:$index}"
fi
fi
} # _get_cword()
# Get word previous to the current word.
# This is a good alternative to `prev=${COMP_WORDS[COMP_CWORD-1]}' because bash4
# will properly return the previous word with respect to any given exclusions to
# COMP_WORDBREAKS.
# @deprecated Use `_get_comp_words_by_ref cur prev' instead
# @see _get_comp_words_by_ref()
#
_get_pword()
{
if [[ $COMP_CWORD -ge 1 ]]; then
_get_cword "${@:-}" 1
fi
}
# Complete variables.
# @return True (0) if variables were completed,
# False (> 0) if not.
_variables()
{
if [[ $cur =~ ^(\$\{?)([A-Za-z0-9_]*)$ ]]; then
[[ $cur == *{* ]] && local suffix=} || local suffix=
COMPREPLY+=( $( compgen -P ${BASH_REMATCH[1]} -S "$suffix" -v -- \
"${BASH_REMATCH[2]}" ) )
return 0
fi
return 1
}
# Assign variable one scope above the caller
# Usage: local "$1" && _upvar $1 "value(s)"
# Param: $1 Variable name to assign value to
# Param: $* Value(s) to assign. If multiple values, an array is
# assigned, otherwise a single value is assigned.
# NOTE: For assigning multiple variables, use '_upvars'. Do NOT
# use multiple '_upvar' calls, since one '_upvar' call might
# reassign a variable to be used by another '_upvar' call.
# See: http://fvue.nl/wiki/Bash:_Passing_variables_by_reference
_upvar()
{
if unset -v "$1"; then # Unset & validate varname
if (( $# == 2 )); then
eval $1=\"\$2\" # Return single value
else
eval $1=\(\"\${@:2}\"\) # Return array
fi
fi
}
# Assign variables one scope above the caller
# Usage: local varname [varname ...] &&
# _upvars [-v varname value] | [-aN varname [value ...]] ...
# Available OPTIONS:
# -aN Assign next N values to varname as array
# -v Assign single value to varname
# Return: 1 if error occurs
# See: http://fvue.nl/wiki/Bash:_Passing_variables_by_reference
_upvars()
{
if ! (( $# )); then
echo "${FUNCNAME[0]}: usage: ${FUNCNAME[0]} [-v varname"\
"value] | [-aN varname [value ...]] ..." 1>&2
return 2
fi
while (( $# )); do
case $1 in
-a*)
# Error checking
[[ ${1#-a} ]] || { echo "bash: ${FUNCNAME[0]}: \`$1': missing"\
"number specifier" 1>&2; return 1; }
printf %d "${1#-a}" &> /dev/null || { echo "bash:"\
"${FUNCNAME[0]}: \`$1': invalid number specifier" 1>&2
return 1; }
# Assign array of -aN elements
[[ "$2" ]] && unset -v "$2" && eval $2=\(\"\${@:3:${1#-a}}\"\) &&
shift $((${1#-a} + 2)) || { echo "bash: ${FUNCNAME[0]}:"\
"\`$1${2+ }$2': missing argument(s)" 1>&2; return 1; }
;;
-v)
# Assign single value
[[ "$2" ]] && unset -v "$2" && eval $2=\"\$3\" &&
shift 3 || { echo "bash: ${FUNCNAME[0]}: $1: missing"\
"argument(s)" 1>&2; return 1; }
;;
*)
echo "bash: ${FUNCNAME[0]}: $1: invalid option" 1>&2
return 1 ;;
esac
done
}
# @param $1 exclude Characters out of $COMP_WORDBREAKS which should NOT be
# considered word breaks. This is useful for things like scp where
# we want to return host:path and not only path, so we would pass the
# colon (:) as $1 in this case.
# @param $2 words Name of variable to return words to
# @param $3 cword Name of variable to return cword to
# @param $4 cur Name of variable to return current word to complete to
# @see __reassemble_comp_words_by_ref()
__get_cword_at_cursor_by_ref()
{
local cword words=()
__reassemble_comp_words_by_ref "$1" words cword
local i cur index=$COMP_POINT lead=${COMP_LINE:0:$COMP_POINT}
# Cursor not at position 0 and not leaded by just space(s)?
if [[ $index -gt 0 && ( $lead && ${lead//[[:space:]]} ) ]]; then
cur=$COMP_LINE
for (( i = 0; i <= cword; ++i )); do
while [[
# Current word fits in $cur?
${#cur} -ge ${#words[i]} &&
# $cur doesn't match cword?
"${cur:0:${#words[i]}}" != "${words[i]}"
]]; do
# Strip first character
cur="${cur:1}"
# Decrease cursor position
((index--))
done
# Does found word match cword?
if [[ $i -lt $cword ]]; then
# No, cword lies further;
local old_size=${#cur}
cur="${cur#"${words[i]}"}"
local new_size=${#cur}
index=$(( index - old_size + new_size ))
fi
done
# Clear $cur if just space(s)
[[ $cur && ! ${cur//[[:space:]]} ]] && cur=
# Zero $index if negative
[[ $index -lt 0 ]] && index=0
fi
local "$2" "$3" "$4" && _upvars -a${#words[@]} $2 "${words[@]}" \
-v $3 "$cword" -v $4 "${cur:0:$index}"
}
# Reassemble command line words, excluding specified characters from the
# list of word completion separators (COMP_WORDBREAKS).
# @param $1 chars Characters out of $COMP_WORDBREAKS which should
# NOT be considered word breaks. This is useful for things like scp where
# we want to return host:path and not only path, so we would pass the
# colon (:) as $1 here.
# @param $2 words Name of variable to return words to
# @param $3 cword Name of variable to return cword to
#
__reassemble_comp_words_by_ref()
{
local exclude i j line ref
# Exclude word separator characters?
if [[ $1 ]]; then
# Yes, exclude word separator characters;
# Exclude only those characters, which were really included
exclude="${1//[^$COMP_WORDBREAKS]}"
fi
# Default to cword unchanged
eval $3=$COMP_CWORD
# Are characters excluded which were former included?
if [[ $exclude ]]; then
# Yes, list of word completion separators has shrunk;
line=$COMP_LINE
# Re-assemble words to complete
for (( i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do
# Is current word not word 0 (the command itself) and is word not
# empty and is word made up of just word separator characters to
# be excluded and is current word not preceded by whitespace in
# original line?
while [[ $i -gt 0 && ${COMP_WORDS[$i]} == +([$exclude]) ]]; do
# Is word separator not preceded by whitespace in original line
# and are we not going to append to word 0 (the command
# itself), then append to current word.
[[ $line != [$' \t']* ]] && (( j >= 2 )) && ((j--))
# Append word separator to current or new word
ref="$2[$j]"
eval $2[$j]=\${!ref}\${COMP_WORDS[i]}
# Indicate new cword
[[ $i == $COMP_CWORD ]] && eval $3=$j
# Remove optional whitespace + word separator from line copy
line=${line#*"${COMP_WORDS[$i]}"}
# Start new word if word separator in original line is
# followed by whitespace.
[[ $line == [$' \t']* ]] && ((j++))
# Indicate next word if available, else end *both* while and
# for loop
(( $i < ${#COMP_WORDS[@]} - 1)) && ((i++)) || break 2
done
# Append word to current word
ref="$2[$j]"
eval $2[$j]=\${!ref}\${COMP_WORDS[i]}
# Remove optional whitespace + word from line copy
line=${line#*"${COMP_WORDS[i]}"}
# Indicate new cword
[[ $i == $COMP_CWORD ]] && eval $3=$j
done
[[ $i == $COMP_CWORD ]] && eval $3=$j
else
# No, list of word completions separators hasn't changed;
eval $2=\( \"\${COMP_WORDS[@]}\" \)
fi
} # __reassemble_comp_words_by_ref()
# If the word-to-complete contains a colon (:), left-trim COMPREPLY items with
# word-to-complete.
# With a colon in COMP_WORDBREAKS, words containing
# colons are always completed as entire words if the word to complete contains
# a colon. This function fixes this, by removing the colon-containing-prefix
# from COMPREPLY items.
# The preferred solution is to remove the colon (:) from COMP_WORDBREAKS in
# your .bashrc:
#
# # Remove colon (:) from list of word completion separators
# COMP_WORDBREAKS=${COMP_WORDBREAKS//:}
#
# See also: Bash FAQ - E13) Why does filename completion misbehave if a colon
# appears in the filename? - http://tiswww.case.edu/php/chet/bash/FAQ
# @param $1 current word to complete (cur)
# @modifies global array $COMPREPLY
#
__ltrim_colon_completions()
{
if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then
# Remove colon-word prefix from COMPREPLY items
local colon_word=${1%"${1##*:}"}
local i=${#COMPREPLY[*]}
while [[ $((--i)) -ge 0 ]]; do
COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"}
done
fi
} # __ltrim_colon_completions()
# NOTE: Using this function as a helper function is deprecated. Use
# `_known_hosts_real' instead.
_known_hosts()
{
local cur prev words cword
_init_completion -n : || return
# NOTE: Using `_known_hosts' as a helper function and passing options
# to `_known_hosts' is deprecated: Use `_known_hosts_real' instead.
local options
[[ "$1" == -a || "$2" == -a ]] && options=-a
[[ "$1" == -c || "$2" == -c ]] && options+=" -c"
_known_hosts_real $options -- "$cur"
} # _known_hosts()
# Helper function for completing _known_hosts.
# This function performs host completion based on ssh's config and known_hosts
# files, as well as hostnames reported by avahi-browse if
# COMP_KNOWN_HOSTS_WITH_AVAHI is set to a non-empty value. Also hosts from
# HOSTFILE (compgen -A hostname) are added, unless
# COMP_KNOWN_HOSTS_WITH_HOSTFILE is set to an empty value.
# Usage: _known_hosts_real [OPTIONS] CWORD
# Options: -a Use aliases
# -c Use `:' suffix
# -F configfile Use `configfile' for configuration settings
# -p PREFIX Use PREFIX
# Return: Completions, starting with CWORD, are added to COMPREPLY[]
_known_hosts_real()
{
local configfile flag prefix
local cur curd awkcur user suffix aliases i host
local -a kh khd config
local OPTIND=1
while getopts "acF:p:" flag "$@"; do
case $flag in
a) aliases='yes' ;;
c) suffix=':' ;;
F) configfile=$OPTARG ;;
p) prefix=$OPTARG ;;
esac
done
[[ $# -lt $OPTIND ]] && echo "error: $FUNCNAME: missing mandatory argument CWORD"
cur=${!OPTIND}; let "OPTIND += 1"
[[ $# -ge $OPTIND ]] && echo "error: $FUNCNAME("$@"): unprocessed arguments:"\
$(while [[ $# -ge $OPTIND ]]; do printf '%s\n' ${!OPTIND}; shift; done)
[[ $cur == *@* ]] && user=${cur%@*}@ && cur=${cur#*@}
kh=()
# ssh config files
if [[ -n $configfile ]]; then
[[ -r $configfile ]] && config+=( "$configfile" )
else
for i in /etc/ssh/ssh_config ~/.ssh/config ~/.ssh2/config; do
[[ -r $i ]] && config+=( "$i" )
done
fi
# Known hosts files from configs
if [[ ${#config[@]} -gt 0 ]]; then
local OIFS=$IFS IFS=$'\n' j
local -a tmpkh
# expand paths (if present) to global and user known hosts files
# TODO(?): try to make known hosts files with more than one consecutive
# spaces in their name work (watch out for ~ expansion
# breakage! Alioth#311595)
tmpkh=( $( awk 'sub("^[ \t]*([Gg][Ll][Oo][Bb][Aa][Ll]|[Uu][Ss][Ee][Rr])[Kk][Nn][Oo][Ww][Nn][Hh][Oo][Ss][Tt][Ss][Ff][Ii][Ll][Ee][ \t]+", "") { print $0 }' "${config[@]}" | sort -u ) )
IFS=$OIFS
for i in "${tmpkh[@]}"; do
# First deal with quoted entries...
while [[ $i =~ ^([^\"]*)\"([^\"]*)\"(.*)$ ]]; do
i=${BASH_REMATCH[1]}${BASH_REMATCH[3]}
j=${BASH_REMATCH[2]}
__expand_tilde_by_ref j # Eval/expand possible `~' or `~user'
[[ -r $j ]] && kh+=( "$j" )
done
# ...and then the rest.
for j in $i; do
__expand_tilde_by_ref j # Eval/expand possible `~' or `~user'
[[ -r $j ]] && kh+=( "$j" )
done
done
fi
if [[ -z $configfile ]]; then
# Global and user known_hosts files
for i in /etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts2 \
/etc/known_hosts /etc/known_hosts2 ~/.ssh/known_hosts \
~/.ssh/known_hosts2; do
[[ -r $i ]] && kh+=( "$i" )
done
for i in /etc/ssh2/knownhosts ~/.ssh2/hostkeys; do
[[ -d $i ]] && khd+=( "$i"/*pub )
done
fi
# If we have known_hosts files to use
if [[ ${#kh[@]} -gt 0 || ${#khd[@]} -gt 0 ]]; then
# Escape slashes and dots in paths for awk
awkcur=${cur//\//\\\/}
awkcur=${awkcur//\./\\\.}
curd=$awkcur
if [[ "$awkcur" == [0-9]*[.:]* ]]; then
# Digits followed by a dot or a colon - just search for that
awkcur="^$awkcur[.:]*"
elif [[ "$awkcur" == [0-9]* ]]; then
# Digits followed by no dot or colon - search for digits followed
# by a dot or a colon
awkcur="^$awkcur.*[.:]"
elif [[ -z $awkcur ]]; then
# A blank - search for a dot, a colon, or an alpha character
awkcur="[a-z.:]"
else
awkcur="^$awkcur"
fi
if [[ ${#kh[@]} -gt 0 ]]; then
# FS needs to look for a comma separated list
COMPREPLY+=( $( awk 'BEGIN {FS=","}
/^\s*[^|\#]/ {
sub("^@[^ ]+ +", ""); \
sub(" .*$", ""); \
for (i=1; i<=NF; ++i) { \
sub("^\\[", "", $i); sub("\\](:[0-9]+)?$", "", $i); \
if ($i !~ /[*?]/ && $i ~ /'"$awkcur"'/) {print $i} \
}}' "${kh[@]}" 2>/dev/null ) )
fi
if [[ ${#khd[@]} -gt 0 ]]; then
# Needs to look for files called
# .../.ssh2/key_22_<hostname>.pub
# dont fork any processes, because in a cluster environment,
# there can be hundreds of hostkeys
for i in "${khd[@]}" ; do
if [[ "$i" == *key_22_$curd*.pub && -r "$i" ]]; then
host=${i/#*key_22_/}
host=${host/%.pub/}
COMPREPLY+=( $host )
fi
done
fi
# apply suffix and prefix
for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
COMPREPLY[i]=$prefix$user${COMPREPLY[i]}$suffix
done
fi
# append any available aliases from config files
if [[ ${#config[@]} -gt 0 && -n "$aliases" ]]; then
local hosts=$( sed -ne 's/^[ \t]*[Hh][Oo][Ss][Tt]\([Nn][Aa][Mm][Ee]\)\{0,1\}['"$'\t '"']\{1,\}\([^#*?]*\)\(#.*\)\{0,1\}$/\2/p' "${config[@]}" )
COMPREPLY+=( $( compgen -P "$prefix$user" \
-S "$suffix" -W "$hosts" -- "$cur" ) )
fi
# Add hosts reported by avahi-browse, if desired and it's available.
if [[ ${COMP_KNOWN_HOSTS_WITH_AVAHI:-} ]] && \
type avahi-browse &>/dev/null; then
# The original call to avahi-browse also had "-k", to avoid lookups
# into avahi's services DB. We don't need the name of the service, and
# if it contains ";", it may mistify the result. But on Gentoo (at
# least), -k wasn't available (even if mentioned in the manpage) some
# time ago, so...
COMPREPLY+=( $( compgen -P "$prefix$user" -S "$suffix" -W \
"$( avahi-browse -cpr _workstation._tcp 2>/dev/null | \
awk -F';' '/^=/ { print $7 }' | sort -u )" -- "$cur" ) )
fi
# Add hosts reported by ruptime.
COMPREPLY+=( $( compgen -W \
"$( ruptime 2>/dev/null | awk '!/^ruptime:/ { print $1 }' )" \
-- "$cur" ) )
# Add results of normal hostname completion, unless
# `COMP_KNOWN_HOSTS_WITH_HOSTFILE' is set to an empty value.
if [[ -n ${COMP_KNOWN_HOSTS_WITH_HOSTFILE-1} ]]; then
COMPREPLY+=(
$( compgen -A hostname -P "$prefix$user" -S "$suffix" -- "$cur" ) )
fi
__ltrim_colon_completions "$prefix$user$cur"
return 0
} # _known_hosts_real()
# Get the word to complete and optional previous words.
# This is nicer than ${COMP_WORDS[$COMP_CWORD]}, since it handles cases
# where the user is completing in the middle of a word.
# (For example, if the line is "ls foobar",
# and the cursor is here --------> ^
# Also one is able to cross over possible wordbreak characters.
# Usage: _get_comp_words_by_ref [OPTIONS] [VARNAMES]
# Available VARNAMES:
# cur Return cur via $cur
# prev Return prev via $prev
# words Return words via $words
# cword Return cword via $cword
#
# Available OPTIONS:
# -n EXCLUDE Characters out of $COMP_WORDBREAKS which should NOT be
# considered word breaks. This is useful for things like scp
# where we want to return host:path and not only path, so we
# would pass the colon (:) as -n option in this case.
# -c VARNAME Return cur via $VARNAME
# -p VARNAME Return prev via $VARNAME
# -w VARNAME Return words via $VARNAME
# -i VARNAME Return cword via $VARNAME
#
# Example usage:
#
# $ _get_comp_words_by_ref -n : cur prev
#
_get_comp_words_by_ref()
{
local exclude flag i OPTIND=1
local cur cword words=()
local upargs=() upvars=() vcur vcword vprev vwords
while getopts "c:i:n:p:w:" flag "$@"; do
case $flag in
c) vcur=$OPTARG ;;
i) vcword=$OPTARG ;;
n) exclude=$OPTARG ;;
p) vprev=$OPTARG ;;
w) vwords=$OPTARG ;;
esac
done
while [[ $# -ge $OPTIND ]]; do
case ${!OPTIND} in
cur) vcur=cur ;;
prev) vprev=prev ;;
cword) vcword=cword ;;
words) vwords=words ;;
*) echo "bash: $FUNCNAME(): \`${!OPTIND}': unknown argument" \
1>&2; return 1
esac
let "OPTIND += 1"
done
__get_cword_at_cursor_by_ref "$exclude" words cword cur
[[ $vcur ]] && { upvars+=("$vcur" ); upargs+=(-v $vcur "$cur" ); }
[[ $vcword ]] && { upvars+=("$vcword"); upargs+=(-v $vcword "$cword"); }
[[ $vprev && $cword -ge 1 ]] && { upvars+=("$vprev" ); upargs+=(-v $vprev
"${words[cword - 1]}"); }
[[ $vwords ]] && { upvars+=("$vwords"); upargs+=(-a${#words[@]} $vwords
"${words[@]}"); }
(( ${#upvars[@]} )) && local "${upvars[@]}" && _upvars "${upargs[@]}"
}
# Initialize completion and deal with various general things: do file
# and variable completion where appropriate, and adjust prev, words,
# and cword as if no redirections exist so that completions do not
# need to deal with them. Before calling this function, make sure
# cur, prev, words, and cword are local, ditto split if you use -s.
#
# Options:
# -n EXCLUDE Passed to _get_comp_words_by_ref -n with redirection chars
# -e XSPEC Passed to _filedir as first arg for stderr redirections
# -o XSPEC Passed to _filedir as first arg for other output redirections
# -i XSPEC Passed to _filedir as first arg for stdin redirections
# -s Split long options with _split_longopt, implies -n =
# @return True (0) if completion needs further processing,
# False (> 0) no further processing is necessary.
#
_init_completion()
{
local exclude= flag outx errx inx OPTIND=1
while getopts "n:e:o:i:s" flag "$@"; do
case $flag in
n) exclude+=$OPTARG ;;
e) errx=$OPTARG ;;
o) outx=$OPTARG ;;
i) inx=$OPTARG ;;
s) split=false ; exclude+== ;;
esac
done
# For some reason completion functions are not invoked at all by
# bash (at least as of 4.1.7) after the command line contains an
# ampersand so we don't get a chance to deal with redirections
# containing them, but if we did, hopefully the below would also
# do the right thing with them...
COMPREPLY=()
local redir="@(?([0-9])<|?([0-9&])>?(>)|>&)"
_get_comp_words_by_ref -n "$exclude<>&" cur prev words cword
# Complete variable names.
_variables && return 1
# Complete on files if current is a redirect possibly followed by a
# filename, e.g. ">foo", or previous is a "bare" redirect, e.g. ">".
if [[ $cur == $redir* || $prev == $redir ]]; then
local xspec
case $cur in
2'>'*) xspec=$errx ;;
*'>'*) xspec=$outx ;;
*'<'*) xspec=$inx ;;
*)
case $prev in
2'>'*) xspec=$errx ;;
*'>'*) xspec=$outx ;;
*'<'*) xspec=$inx ;;
esac
;;
esac
cur="${cur##$redir}"
_filedir $xspec
return 1
fi
# Remove all redirections so completions don't have to deal with them.
local i skip
for (( i=1; i < ${#words[@]}; )); do
if [[ ${words[i]} == $redir* ]]; then
# If "bare" redirect, remove also the next word (skip=2).
[[ ${words[i]} == $redir ]] && skip=2 || skip=1
words=( "${words[@]:0:i}" "${words[@]:i+skip}" )
[[ $i -le $cword ]] && cword=$(( cword - skip ))
else
i=$(( ++i ))
fi
done
[[ $cword -le 0 ]] && return 1
prev=${words[cword-1]}
[[ ${split-} ]] && _split_longopt && split=true
return 0
}
# Try to complete -o SubOptions=
#
# Returns 0 if the completion was handled or non-zero otherwise.
_ssh_suboption_check()
{
# Get prev and cur words without splitting on =
local cureq=`_get_cword :=` preveq=`_get_pword :=`
if [[ $cureq == *=* && $preveq == -o ]]; then
_ssh_suboption $cureq
return $?
fi
return 1
}
_complete_ssh()
{
local cur prev words cword
_init_completion -n : || return
local configfile
local -a config
_ssh_suboption_check && return 0
case $prev in
-F|-i|-S)
_filedir
return 0
;;
-c)
_ssh_ciphers
return 0
;;
-m)
_ssh_macs
return 0
;;
-l)
COMPREPLY=( $( compgen -u -- "$cur" ) )
return 0
;;
-O)
COMPREPLY=( $( compgen -W 'check forward exit stop' -- "$cur" ) )
return 0
;;
-o)
_ssh_options
return 0
;;
-w)
_available_interfaces
return 0
;;
-b)
_ip_addresses
return 0
;;
-D|-e|-I|-L|-p|-R|-W)
return 0
;;
esac
if [[ "$cur" == -F* ]]; then
cur=${cur#-F}
_filedir
# Prefix completions with '-F'
COMPREPLY=( "${COMPREPLY[@]/#/-F}" )
cur=-F$cur # Restore cur
elif [[ "$cur" == -* ]]; then
COMPREPLY=( $( compgen -W '$( _parse_usage "$1" )' -- "$cur" ) )
else
# Search COMP_WORDS for '-F configfile' or '-Fconfigfile' argument
set -- "${words[@]}"
while [[ $# -gt 0 ]]; do
if [[ $1 == -F* ]]; then
if [[ ${#1} -gt 2 ]]; then
configfile="$(dequote "${1:2}")"
else
shift
[[ $1 ]] && configfile="$(dequote "$1")"
fi
break
fi
shift
done
_known_hosts_real -a -F "$configfile" "$cur"
if [[ $cword -ne 1 ]]; then
compopt -o filenames
COMPREPLY+=( $( compgen -c -- "$cur" ) )
fi
fi
return 0
} &&
shopt -u hostcomplete && complete -F _complete_ssh ssh

View File

@ -1,197 +0,0 @@
{ config, lib, pkgs, ... }:
with config.krebs.lib;
let
HOME = getEnv "HOME";
in
{
krebs.enable = true;
krebs.build = {
user = config.krebs.users.mv;
target = mkDefault "root@${config.krebs.build.host.name}";
source = {
git.nixpkgs = {
url = mkDefault https://github.com/NixOS/nixpkgs;
rev = mkDefault "c44a593aa43bba6a0708f6f36065a514a5110613";
target-path = mkDefault "/var/src/nixpkgs";
};
dir.secrets = {
path = mkDefault "${HOME}/secrets/${config.krebs.build.host.name}";
};
dir.stockholm = {
path = mkDefault "${HOME}/stockholm";
target-path = mkDefault "/var/src/stockholm";
};
};
};
networking.hostName = config.krebs.build.host.name;
imports = [
<secrets>
./vim.nix
{
# stockholm dependencies
environment.systemPackages = with pkgs; [
git
];
}
{
users = {
defaultUserShell = "/run/current-system/sw/bin/bash";
mutableUsers = false;
users = {
mv = {
isNormalUser = true;
uid = 1338;
};
};
};
}
{
security.sudo.extraConfig = ''
Defaults mailto="${config.krebs.users.mv.mail}"
'';
time.timeZone = "Europe/Berlin";
}
{
# TODO check if both are required:
nix.chrootDirs = [ "/etc/protocols" pkgs.iana_etc.outPath ];
nix.trustedBinaryCaches = [
"https://cache.nixos.org"
"http://cache.nixos.org"
"http://hydra.nixos.org"
];
nix.useChroot = true;
}
{
environment.profileRelativeEnvVars.PATH = mkForce [ "/bin" ];
environment.systemPackages = with pkgs; [
rxvt_unicode.terminfo
];
environment.shellAliases = mkForce {
# alias cal='cal -m3'
gp = "${pkgs.pari}/bin/gp -q";
df = "df -h";
du = "du -h";
# alias grep='grep --color=auto'
# TODO alias cannot contain #\'
# "ps?" = "ps ax | head -n 1;ps ax | fgrep -v ' grep --color=auto ' | grep";
# alias la='ls -lA'
lAtr = "ls -lAtr";
# alias ll='ls -l'
ls = "ls -h --color=auto --group-directories-first";
dmesg = "dmesg -L --reltime";
view = "vim -R";
reload = "systemctl reload";
restart = "systemctl restart";
start = "systemctl start";
status = "systemctl status";
stop = "systemctl stop";
};
environment.variables = {
NIX_PATH =
with config.krebs.build.source; with dir; with git;
mkForce (concatStringsSep ":" [
"nixpkgs=${nixpkgs.target-path}"
"secrets=${stockholm.target-path}/null"
]);
};
programs.bash = {
interactiveShellInit = ''
HISTCONTROL='erasedups:ignorespace'
HISTSIZE=65536
HISTFILESIZE=$HISTSIZE
shopt -s checkhash
shopt -s histappend histreedit histverify
shopt -s no_empty_cmd_completion
complete -d cd
${readFile ./bash_completion.sh}
# TODO source bridge
'';
promptInit = ''
case $UID in
0)
PS1='\[\e[1;31m\]\w\[\e[0m\] '
;;
1337)
PS1='\[\e[1;32m\]\w\[\e[0m\] '
;;
*)
PS1='\[\e[1;35m\]\u \[\e[1;32m\]\w\[\e[0m\] '
;;
esac
if test -n "$SSH_CLIENT"; then
PS1='\[\e[35m\]\h'" $PS1"
fi
if test -n "$SSH_AGENT_PID"; then
PS1="ssh-agent[$SSH_AGENT_PID] $PS1"
fi
'';
};
programs.ssh.startAgent = false;
}
{
services.cron.enable = false;
services.nscd.enable = false;
services.ntp.enable = false;
}
{
boot.kernel.sysctl = {
# Enable IPv6 Privacy Extensions
"net.ipv6.conf.all.use_tempaddr" = 2;
"net.ipv6.conf.default.use_tempaddr" = 2;
};
}
{
services.openssh = {
enable = true;
hostKeys = [
{ type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; }
];
};
}
{
# TODO: exim
security.setuidPrograms = [
"sendmail" # for sudo
];
}
{
environment.systemPackages = [
pkgs.get
pkgs.krebszones
pkgs.nix-prefetch-scripts
pkgs.push
];
}
{
systemd.tmpfiles.rules = let
forUsers = flip map users;
isUser = { group, ... }: hasSuffix "users" group;
users = filter isUser (mapAttrsToList (_: id) config.users.users);
in forUsers (u: "d /run/xdg/${u.name} 0700 ${u.name} ${u.group} -");
environment.variables.XDG_RUNTIME_DIR = "/run/xdg/$LOGNAME";
}
];
}

View File

@ -1,62 +0,0 @@
{ config, lib, pkgs, ... }:
with config.krebs.lib;
let
out = {
krebs.git = {
enable = true;
cgit = {
settings = {
root-title = "public repositories at ${config.krebs.build.host.name}";
root-desc = "Hmhmh, im Moment nicht.";
};
};
repos = mapAttrs (_: s: removeAttrs s ["collaborators"]) repos;
rules = rules;
};
};
repos = public-repos;
rules = concatMap make-rules (attrValues repos);
public-repos = mapAttrs make-public-repo {
stockholm = {};
};
make-public-repo = name: { cgit ? {}, ... }: {
inherit cgit name;
public = true;
hooks = {
post-receive = pkgs.git-hooks.irc-announce {
# TODO make nick = config.krebs.build.host.name the default
nick = config.krebs.build.host.name;
channel = "#retiolum";
server = "cd.retiolum";
verbose = config.krebs.build.host.name == "stro";
};
};
};
make-rules =
with git // config.krebs.users;
repo:
singleton {
user = [ mv_stro ];
repo = [ repo ];
perm = push "refs/*" [ non-fast-forward create delete merge ];
} ++
optional repo.public {
user = [ lass makefu uriel tv tv-xu ];
repo = [ repo ];
perm = fetch;
} ++
optional (length (repo.collaborators or []) > 0) {
user = repo.collaborators;
repo = [ repo ];
perm = fetch;
};
in out

View File

@ -1,77 +0,0 @@
{ config, pkgs, ... }:
{
imports = [
../smartd.nix
];
boot.initrd.availableKernelModules = [
"aesni-intel"
"ahci"
"fbcon"
"i915"
];
boot.kernelModules = [
"kvm-intel"
"msr"
"tp-smapi"
];
boot.extraModulePackages = [
config.boot.kernelPackages.tp_smapi
];
# disabled for fbcon and i915 to kick in or to disable the kernelParams
# XXX: investigate
boot.vesa = false;
boot.loader.gummiboot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
networking.wireless.enable = true;
#hardware.enableAllFirmware = true;
#nixpkgs.config.allowUnfree = true;
#zramSwap.enable = true;
#zramSwap.numDevices = 2;
hardware.trackpoint = {
enable = true;
sensitivity = 220;
speed = 0;
emulateWheel = true;
};
services.tlp.enable = true;
services.tlp.extraConfig = ''
START_CHARGE_THRESH_BAT0=80
'';
nix = {
buildCores = 2;
maxJobs = 2;
daemonIONiceLevel = 1;
daemonNiceLevel = 1;
};
services.logind.extraConfig = ''
HandleHibernateKey=ignore
HandleLidSwitch=ignore
HandlePowerKey=ignore
HandleSuspendKey=ignore
'';
services.xserver = {
videoDriver = "intel";
#vaapiDrivers = [ pkgs.vaapiIntel pkgs.vaapiVdpau ];
#deviceSection = ''
# Option "AccelMethod" "sna"
#'';
};
#services.xserver.displayManager.sessionCommands =''
# xinput set-int-prop "TPPS/2 IBM TrackPoint" "Evdev Wheel Emulation" 8 1
# xinput set-int-prop "TPPS/2 IBM TrackPoint" "Evdev Wheel Emulation Button" 8 2
# xinput set-prop "TPPS/2 IBM TrackPoint" "Evdev Wheel Emulation Axes" 6 7 4 5
#'';
}

View File

@ -1,13 +0,0 @@
{ pkgs, ... }:
with pkgs;
{
environment.systemPackages = [
much
msmtp
notmuch
pythonPackages.alot
qprint
w3m
];
}

View File

@ -1,17 +0,0 @@
{ config, pkgs, ... }:
{
services.smartd = {
enable = true;
devices = [
{
device = "DEVICESCAN";
options = toString [
"-a"
"-m ${config.krebs.users.tv.mail}"
"-s (O/../.././09|S/../.././04|L/../../6/05)"
];
}
];
};
}

View File

@ -1,123 +0,0 @@
{ config, lib, pkgs, ... }:
with config.krebs.lib;
let
out = {
environment.systemPackages = [
pkgs.vim
];
# Nano really is just a stupid name for Vim.
nixpkgs.config.packageOverrides = pkgs: {
nano = pkgs.vim;
};
environment.etc.vimrc.source = vimrc;
environment.variables.EDITOR = mkForce "vim";
environment.variables.VIMINIT = ":so /etc/vimrc";
};
extra-runtimepath = concatStringsSep "," [
"${pkgs.vimPlugins.undotree}/share/vim-plugins/undotree"
];
vimrc = pkgs.writeText "vimrc" ''
set nocompatible
set autoindent
set backspace=indent,eol,start
set backup
set backupdir=$HOME/.vim/backup/
set directory=$HOME/.vim/cache//
set hlsearch
set incsearch
set mouse=a
set noruler
set pastetoggle=<INS>
set runtimepath=${extra-runtimepath},$VIMRUNTIME
set shortmess+=I
set showcmd
set showmatch
set ttimeoutlen=0
set undodir=$HOME/.vim/undo
set undofile
set undolevels=1000000
set undoreload=1000000
set viminfo='20,<1000,s100,h,n$HOME/.vim/cache/info
set visualbell
set wildignore+=*.o,*.class,*.hi,*.dyn_hi,*.dyn_o
set wildmenu
set wildmode=longest,full
set et ts=2 sts=2 sw=2
filetype plugin indent on
set t_Co=256
colorscheme industry
syntax on
au Syntax * syn match Tabstop containedin=ALL /\t\+/
\ | hi Tabstop ctermbg=16
\ | syn match TrailingSpace containedin=ALL /\s\+$/
\ | hi TrailingSpace ctermbg=88
\ | hi Normal ctermfg=White
au BufRead,BufNewFile *.hs so ${pkgs.writeText "hs.vim" ''
syn region String start=+\[[[:alnum:]]*|+ end=+|]+
''}
au BufRead,BufNewFile *.nix so ${pkgs.writeText "nix.vim" ''
setf nix
set isk=@,48-57,_,192-255,-,'
" Ref <nix/src/libexpr/lexer.l>
syn match INT /\<[0-9]\+\>/
syn match PATH /[a-zA-Z0-9\.\_\-\+]*\(\/[a-zA-Z0-9\.\_\-\+]\+\)\+/
syn match HPATH /\~\(\/[a-zA-Z0-9\.\_\-\+]\+\)\+/
syn match SPATH /<[a-zA-Z0-9\.\_\-\+]\+\(\/[a-zA-Z0-9\.\_\-\+]\+\)*>/
syn match URI /[a-zA-Z][a-zA-Z0-9\+\-\.]*:[a-zA-Z0-9\%\/\?\:\@\&\=\+\$\,\-\_\.\!\~\*\']\+/
hi link INT Constant
hi link PATH Constant
hi link HPATH Constant
hi link SPATH Constant
hi link URI Constant
syn match String /"\([^\\"]\|\\.\)*"/
syn match Comment /\(^\|\s\)#.*/
''}
au BufRead,BufNewFile /dev/shm/* set nobackup nowritebackup noswapfile
nmap <esc>q :buffer
nmap <M-q> :buffer
cnoremap <C-A> <Home>
noremap <C-c> :q<cr>
nnoremap <esc>[5^ :tabp<cr>
nnoremap <esc>[6^ :tabn<cr>
nnoremap <esc>[5@ :tabm -1<cr>
nnoremap <esc>[6@ :tabm +1<cr>
nnoremap <f1> :tabp<cr>
nnoremap <f2> :tabn<cr>
inoremap <f1> <esc>:tabp<cr>
inoremap <f2> <esc>:tabn<cr>
" <C-{Up,Down,Right,Left>
noremap <esc>Oa <nop> | noremap! <esc>Oa <nop>
noremap <esc>Ob <nop> | noremap! <esc>Ob <nop>
noremap <esc>Oc <nop> | noremap! <esc>Oc <nop>
noremap <esc>Od <nop> | noremap! <esc>Od <nop>
" <[C]S-{Up,Down,Right,Left>
noremap <esc>[a <nop> | noremap! <esc>[a <nop>
noremap <esc>[b <nop> | noremap! <esc>[b <nop>
noremap <esc>[c <nop> | noremap! <esc>[c <nop>
noremap <esc>[d <nop> | noremap! <esc>[d <nop>
vnoremap u <nop>
'';
in
out

View File

@ -1,215 +0,0 @@
{ config, lib, pkgs, ... }:
with config.krebs.lib;
pkgs.writeText "Xresources" ''
!URxvt*background: #050505
! 2013-02-25 \e was reas escape before
! *VT100.Translations: #override\
! :<Btn4Down>: string("\e[5~")\n\
! :<Btn5Down>: string("\e[6~")
! XTerm*VT100*Translations: #override \
! Shift<Key>Return: string(" &") string(0x0A) \n\
! Meta<Key>Return: string(" | less") string(0x0A) \n\
! ~Shift<Key>Prior: scroll-back(1,page) \n\
! ~Shift<Key>Next: scroll-forw(1,page) \n\
! Shift<Key>Prior: scroll-back(1) \n\
! Shift<Key>Next: scroll-forw(1) \n\
! <Key>Delete: string(0x1b) string("[2~")
! \n\
! <Key>BackSpace: string(0x7f)
! 2013-02-2013-02-25
! ! <M-c>: load bash-completion (if not already)
! URxvt*VT100*Translations: #override\
! Meta<KeyPress>c:\
! string("\eOH# \eOF\n+compl\n\eOA\eOA\eOH\e[3~\e[3~\eOF")\
! string(0x7)\n
! do not scroll automatically on output:
! XTerm*scrollTtyOutput: false
URxvt*cutchars: "\\`\"'&()*,;<=>?@[]^{|}"
! URxvt*secondaryScreen: false
! URxvt*loginShell: true
URxvt*eightBitInput: false
! *eightBitOutput: 1
! URxvt*decTerminalID: 220
! URxvt*utf8: 1
! URxvt*locale: UTF-8
! XTerm*customization: -color
URxvt*SaveLines: 4096
URxvt*font: -*-clean-*-*-*-*-*-*-*-*-*-*-iso10646-1
URxvt*boldFont: -*-clean-*-*-*-*-*-*-*-*-*-*-iso10646-1
! 2013-05-23 if this does not work try
! xset +fp /usr/share/fonts/local/
! xset fp rehash
! URxvt*font: -*-termsynu-edium-*-*-*-12-*-*-*-*-*-iso10646-1
! URxvt*boldFont: -*-termsynu-bold-*-*-*-12-*-*-*-*-*-iso10646-1
!
!-misc-termsynu-medium-r-normal--12-87-100-100-c-70-iso10646-1
! XTerm*font: -misc-fixed-medium-r-normal--13-120-75-75-c-80-iso10646-1
URxvt*scrollBar: false
! XTerm*font:-nil-profont-medium-r-normal--11-110-72-72-c-60-iso8859-1
! URxvt*boldFont:-nil-profont-medium-r-normal--11-110-72-72-c-60-iso8859-1
URxvt*background: #050505
! URxvt*background: #041204
!URxvt.depth: 32
!URxvt*background: rgba:0500/0500/0500/cccc
! URxvt*background: #080810
URxvt*foreground: #d0d7d0
! URxvt*background: black
! URxvt*foreground: white
! URxvt*background: rgb:00/00/40
! URxvt*foreground: rgb:a0/a0/d0
! XTerm*cursorColor: rgb:00/00/60
URxvt*cursorColor: #f042b0
URxvt*cursorColor2: #f0b000
URxvt*cursorBlink: off
! URxvt*cursorUnderline: true
! URxvt*highlightColor: #232323
! URxvt*highlightTextColor: #b0ffb0
URxvt*.pointerBlank: true
URxvt*.pointerBlankDelay: 987654321
URxvt*.pointerColor: #f042b0
URxvt*.pointerColor2: #050505
! URxvt*fading: 50
! URxvt*fadeColor: #0f0f0f
! XTerm*colorMode: on
! URxvt*dynamicColors: on
! URxvt*boldColors: off
URxvt*jumpScroll: true
! allow synthetic events for fvwm, so pass window specific keys
! XTerm*allowSendEvents: true
URxvt*allowSendEvents: false
! better double/tripple clicking in xterms
! Format: csv, [low-]high:value
!
! extend character class 48 due they are used in urls
! (see: man xterm; /CHARACTER CLASSES)
! ! % -./ @ & = ?
URxvt*charClass: 33:48,37:48,45-47:48,64:48,38:48,61:48,63:48
URxvt*cutNewline: False
URxvt*cutToBeginningOfLine: False
! BLACK for indigo background
URxvt*color0: #232342
! TODO: man xterm; /ACTIONS
! *VT100*colorULMode: on
! XTerm*underLine: on
!
! URxvt*color0: black
! URxvt*color1: red3
! URxvt*color2: green3
! URxvt*color3: yellow3
! URxvt*color4: blue2
! URxvt*color5: magenta3
! URxvt*color6: cyan3
! URxvt*color7: gray90
! URxvt*color8: burlywood1
! URxvt*color9: sienna1
! URxvt*color10: PaleVioletRed1
! URxvt*color11: LightSkyBlue
! URxvt*color12: white
! URxvt*color13: white
! URxvt*color14: white
! URxvt*color33: #f0b0f0
! URxvt*color0: #000000
! URxvt*color1: #c00000
! URxvt*color2: #80c070
URxvt*color3: #c07000
! URxvt*color4: #0000c0
URxvt*color4: #4040c0
! URxvt*color5: #c000c0
! URxvt*color6: #008080
URxvt*color7: #c0c0c0
URxvt*color8: #707070
URxvt*color9: #ff6060
URxvt*color10: #70ff70
URxvt*color11: #ffff70
URxvt*color12: #7070ff
URxvt*color13: #ff50ff
URxvt*color14: #70ffff
URxvt*color15: #ffffff
! XTerm*color91: #000070
! XTerm*color92: #000080
! XTerm*color93: #000090
! XTerm*color94: #0000a0
! XTerm*color95: #0000b0
! XTerm*color96: #0000c0
! XTerm*color97: #0000d0
! XTerm*color98: #0000e0
! XTerm*color99: #0000f0
! !! vim-create-colorscheme {{{
! !! Question cterm=none
! XTerm*color20: #f0b000
! !! }}}
!
!
! #include ".xrdb/look-zenburn.xrdb"
! #include ".xrdb/xterm.xrdb"
! URxvt.perl-ext: matcher
! URxvt.urlLauncher: cr
! URxvt.underlineColor: blue
! URxvt.matcher.button: 1
! URxvt.perl-ext: default,matcher
! URxvt.urlLauncher: cr
! URxvt.matcher.pattern.1: \\bwww\\.[\\w-]+\\.[\\w./?&@#-]*[\\w/-]
! URxvt.underlineColor: blue
! 2014-05-12 von lass
!URxvt.perl-ext-common: default,clipboard,url-select,keyboard-select
!URxvt.url-select.launcher: /home/tv/bin/ff -new-tab
!URxvt.url-select.underline: true
!URxvt.keysym.M-u: perl:url-select:select_next
!URxvt.keysym.M-Escape: perl:keyboard-select:activate
!URxvt.keysym.M-s: perl:keyboard-select:search
! 2013-02-25 I neve use this
URxvt*iso14755: False
URxvt*urgentOnBell: True
URxvt*visualBell: True
! ref https://github.com/muennich/urxvt-perls
URxvt*perl-ext: default,url-select
URxvt*keysym.M-u: perl:url-select:select_next
URxvt*url-select.launcher: ${pkgs.ff}/bin/ff -new-tab
URxvt*url-select.underline: true
URxvt*colorUL: #4682B4
URxvt.perl-lib: ${pkgs.urxvt_perls}/lib/urxvt/perl
root-urxvt*background: #230000
root-urxvt*foreground: #e0c0c0
root-urxvt*BorderColor: #400000
root-urxvt*color0: #800000
''

View File

@ -1,153 +0,0 @@
{ config, lib, pkgs, ... }@args:
with config.krebs.lib;
let
# TODO krebs.build.user
user = config.users.users.mv;
out = {
services.xserver.display = 11;
services.xserver.tty = 11;
services.xserver.synaptics = {
enable = true;
twoFingerScroll = true;
accelFactor = "0.035";
};
fonts.fonts = [
pkgs.xlibs.fontschumachermisc
];
systemd.services.urxvtd = {
wantedBy = [ "multi-user.target" ];
reloadIfChanged = true;
serviceConfig = {
ExecReload = need-reload "urxvtd.service";
ExecStart = "${pkgs.rxvt_unicode}/bin/urxvtd";
Restart = "always";
RestartSec = "2s";
StartLimitBurst = 0;
User = user.name;
};
};
environment.systemPackages = [
pkgs.ff
pkgs.gitAndTools.qgit
pkgs.mpv
pkgs.pavucontrol
pkgs.slock
pkgs.sxiv
pkgs.xsel
pkgs.zathura
];
security.setuidPrograms = [
"slock"
];
systemd.services.display-manager = mkForce {};
services.xserver.enable = true;
systemd.services.xmonad = {
wantedBy = [ "multi-user.target" ];
requires = [ "xserver.service" ];
environment = xmonad-environment;
serviceConfig = {
ExecStart = "${xmonad-start}/bin/xmonad";
ExecStop = "${xmonad-stop}/bin/xmonad-stop";
User = user.name;
WorkingDirectory = user.home;
};
};
systemd.services.xserver = {
after = [
"systemd-udev-settle.service"
"local-fs.target"
"acpid.service"
];
reloadIfChanged = true;
environment = xserver-environment;
serviceConfig = {
ExecReload = need-reload "xserver.service";
ExecStart = "${xserver}/bin/xserver";
};
};
};
xmonad-environment = {
DISPLAY = ":${toString config.services.xserver.display}";
XMONAD_STATE = "/tmp/xmonad.state";
# XXX JSON is close enough :)
XMONAD_WORKSPACES0_FILE = pkgs.writeText "xmonad.workspaces0" (toJSON [
"Dashboard" # we start here
"23"
"cr"
"ff"
"hack"
"im"
"mail"
"stockholm"
"za" "zh" "zj" "zs"
]);
};
xmonad-start = pkgs.writeScriptBin "xmonad" ''
#! ${pkgs.bash}/bin/bash
set -efu
export PATH; PATH=${makeSearchPath "bin" [
pkgs.rxvt_unicode
]}:/var/setuid-wrappers
settle() {(
# Use PATH for a clean journal
command=''${1##*/}
PATH=''${1%/*}; export PATH
shift
until "$command" "$@"; do
${pkgs.coreutils}/bin/sleep 1
done
)&}
settle ${pkgs.xorg.xhost}/bin/xhost +LOCAL:
settle ${pkgs.xorg.xrdb}/bin/xrdb -merge ${import ./Xresources.nix args}
settle ${pkgs.xorg.xsetroot}/bin/xsetroot -solid '#1c1c1c'
exec ${pkgs.xmonad-tv}/bin/xmonad
'';
xmonad-stop = pkgs.writeScriptBin "xmonad-stop" ''
#! /bin/sh
exec ${pkgs.xmonad-tv}/bin/xmonad --shutdown
'';
xserver-environment = {
XKB_BINDIR = "${pkgs.xorg.xkbcomp}/bin"; # Needed for the Xkb extension.
XORG_DRI_DRIVER_PATH = "/run/opengl-driver/lib/dri"; # !!! Depends on the driver selected at runtime.
LD_LIBRARY_PATH = concatStringsSep ":" (
[ "${pkgs.xorg.libX11}/lib" "${pkgs.xorg.libXext}/lib" ]
++ concatLists (catAttrs "libPath" config.services.xserver.drivers));
};
xserver = pkgs.writeScriptBin "xserver" ''
#! /bin/sh
set -efu
exec ${pkgs.xorg.xorgserver}/bin/X \
:${toString config.services.xserver.display} \
vt${toString config.services.xserver.tty} \
-config ${import ./xserver.conf.nix args} \
-logfile /var/log/X.${toString config.services.xserver.display}.log \
-nolisten tcp \
-xkbdir ${pkgs.xkeyboard_config}/etc/X11/xkb \
'';
need-reload = s: let
pkg = pkgs.writeScriptBin "need-reload" ''
#! /bin/sh
echo "$*"
'';
in "${pkg}/bin/need-reload ${s}";
in out

View File

@ -1,40 +0,0 @@
{ config, lib, pkgs, ... }:
with config.krebs.lib;
let
cfg = config.services.xserver;
in
pkgs.stdenv.mkDerivation {
name = "xserver.conf";
xfs = optionalString (cfg.useXFS != false)
''FontPath "${toString cfg.useXFS}"'';
inherit (cfg) config;
buildCommand =
''
echo 'Section "Files"' >> $out
echo $xfs >> $out
for i in ${toString config.fonts.fonts}; do
if test "''${i:0:''${#NIX_STORE}}" == "$NIX_STORE"; then
for j in $(find $i -name fonts.dir); do
echo " FontPath \"$(dirname $j)\"" >> $out
done
fi
done
for i in $(find ${toString cfg.modules} -type d); do
if test $(echo $i/*.so* | wc -w) -ne 0; then
echo " ModulePath \"$i\"" >> $out
fi
done
echo 'EndSection' >> $out
echo "$config" >> $out
'';
}

View File

@ -1,7 +0,0 @@
_:
{
imports = [
./iptables.nix
];
}

View File

@ -1,125 +0,0 @@
{ config, lib, pkgs, ... }:
with config.krebs.lib;
let
cfg = config.tv.iptables;
out = {
options.tv.iptables = api;
config = lib.mkIf cfg.enable imp;
};
api = {
enable = mkEnableOption "tv.iptables";
input-internet-accept-new-tcp = mkOption {
type = with types; listOf (either int str);
default = [];
};
input-retiolum-accept-new-tcp = mkOption {
type = with types; listOf (either int str);
default = [];
};
};
imp = {
networking.firewall.enable = false;
systemd.services.tv-iptables = {
description = "tv-iptables";
wantedBy = [ "network-pre.target" ];
before = [ "network-pre.target" ];
after = [ "systemd-modules-load.service" ];
path = with pkgs; [
iptables
];
restartIfChanged = true;
serviceConfig = {
Type = "simple";
RemainAfterExit = true;
Restart = "always";
ExecStart = "@${startScript} tv-iptables_start";
};
};
};
accept-new-tcp = port:
"-p tcp -m tcp --dport ${port} -m conntrack --ctstate NEW -j ACCEPT";
rules = iptables-version:
pkgs.writeText "tv-iptables-rules${toString iptables-version}" ''
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
${concatMapStringsSep "\n" (rule: "-A PREROUTING ${rule}") ([]
++ [
"! -i retiolum -p tcp -m tcp --dport 22 -j REDIRECT --to-ports 0"
"-p tcp -m tcp --dport 11423 -j REDIRECT --to-ports 22"
]
)}
COMMIT
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:Retiolum - [0:0]
${concatMapStringsSep "\n" (rule: "-A INPUT ${rule}") ([]
++ [
"-m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT"
"-i lo -j ACCEPT"
]
++ map accept-new-tcp (unique (map toString cfg.input-internet-accept-new-tcp))
++ ["-i retiolum -j Retiolum"]
)}
${concatMapStringsSep "\n" (rule: "-A Retiolum ${rule}") ([]
++ {
ip4tables = [
"-p icmp -m icmp --icmp-type echo-request -j ACCEPT"
];
ip6tables = [
"-p ipv6-icmp -m icmp6 --icmpv6-type echo-request -j ACCEPT"
];
}."ip${toString iptables-version}tables"
++ map accept-new-tcp (unique (map toString cfg.input-retiolum-accept-new-tcp))
++ {
ip4tables = [
"-p tcp -j REJECT --reject-with tcp-reset"
"-p udp -j REJECT --reject-with icmp-port-unreachable"
"-j REJECT --reject-with icmp-proto-unreachable"
];
ip6tables = [
"-p tcp -j REJECT --reject-with tcp-reset"
"-p udp -j REJECT --reject-with icmp6-port-unreachable"
"-j REJECT"
];
}."ip${toString iptables-version}tables"
)}
COMMIT
'';
startScript = pkgs.writeScript "tv-iptables_start" ''
#! /bin/sh
set -euf
iptables-restore < ${rules 4}
ip6tables-restore < ${rules 6}
'';
in
out
#let
# cfg = config.tv.iptables;
# arg' = arg // { inherit cfg; };
#in
#
#{
# options.tv.iptables = import ./options.nix arg';
# config = lib.mkIf cfg.enable (import ./config.nix arg');
#}

View File

@ -1,24 +0,0 @@
{ pkgs, ... }:
{
nixpkgs.config.packageOverrides = rec {
cr = pkgs.writeScriptBin "cr" ''
#! /bin/sh
set -efu
export LC_TIME=de_DE.utf8
exec ${pkgs.chromium}/bin/chromium \
--ssl-version-min=tls1 \
--disk-cache-dir=/tmp/chromium-disk-cache_"$LOGNAME" \
--disk-cache-size=50000000 \
"%@"
'';
ff = pkgs.writeScriptBin "ff" ''
#! /bin/sh
set -efu
exec ${pkgs.firefoxWrapper}/bin/firefox $(printf " %q" "$@")
'';
xmonad-tv =
let src = pkgs.writeNixFromCabal "xmonad-tv.nix" ./xmonad-tv; in
pkgs.haskellPackages.callPackage src {};
};
}

View File

@ -1 +0,0 @@
/shell.nix

View File

@ -1,277 +0,0 @@
{-# LANGUAGE DeriveDataTypeable #-} -- for XS
{-# LANGUAGE FlexibleContexts #-} -- for xmonad'
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import Control.Exception
import Text.Read (readEither)
import XMonad
import System.IO (hPutStrLn, stderr)
import System.Environment (getArgs, withArgs, getEnv, getEnvironment)
import System.Posix.Process (executeFile)
import XMonad.Prompt (defaultXPConfig)
import XMonad.Actions.DynamicWorkspaces ( addWorkspacePrompt, renameWorkspace
, removeEmptyWorkspace)
import XMonad.Actions.GridSelect
import XMonad.Actions.CycleWS (toggleWS)
--import XMonad.Actions.CopyWindow ( copy )
import XMonad.Layout.NoBorders ( smartBorders )
import qualified XMonad.StackSet as W
import Data.Map (Map)
import qualified Data.Map as Map
-- TODO import XMonad.Layout.WorkspaceDir
import XMonad.Hooks.UrgencyHook (SpawnUrgencyHook(..), withUrgencyHook)
-- import XMonad.Layout.Tabbed
--import XMonad.Layout.MouseResizableTile
import XMonad.Layout.Reflect (reflectVert)
import XMonad.Layout.FixedColumn (FixedColumn(..))
import XMonad.Hooks.Place (placeHook, smart)
import XMonad.Hooks.FloatNext (floatNextHook)
import XMonad.Actions.PerWorkspaceKeys (chooseAction)
import XMonad.Layout.PerWorkspace (onWorkspace)
--import XMonad.Layout.BinarySpacePartition
--import XMonad.Actions.Submap
import XMonad.Stockholm.Pager
import XMonad.Stockholm.Rhombus
import XMonad.Stockholm.Shutdown
myTerm :: String
myTerm = "urxvtc"
myRootTerm :: String
myRootTerm = "urxvtc -name root-urxvt -e su -"
myFont :: String
myFont = "-schumacher-*-*-*-*-*-*-*-*-*-*-*-iso10646-*"
main :: IO ()
main = getArgs >>= \case
["--shutdown"] -> sendShutdownEvent
_ -> mainNoArgs
mainNoArgs :: IO ()
mainNoArgs = do
workspaces0 <- getWorkspaces0
xmonad'
-- $ withUrgencyHookC dzenUrgencyHook { args = ["-bg", "magenta", "-fg", "magenta", "-h", "2"], duration = 500000 }
-- urgencyConfig { remindWhen = Every 1 }
-- $ withUrgencyHook borderUrgencyHook "magenta"
-- $ withUrgencyHookC BorderUrgencyHook { urgencyBorderColor = "magenta" } urgencyConfig { suppressWhen = Never }
$ withUrgencyHook (SpawnUrgencyHook "echo emit Urgency ")
$ defaultConfig
{ terminal = myTerm
, modMask = mod4Mask
, keys = myKeys
, workspaces = workspaces0
, layoutHook = smartBorders $ myLayout
-- , handleEventHook = myHandleEventHooks <+> handleTimerEvent
--, handleEventHook = handleTimerEvent
, manageHook = placeHook (smart (1,0)) <+> floatNextHook
, startupHook = spawn "echo emit XMonadStartup"
, normalBorderColor = "#1c1c1c"
, focusedBorderColor = "#f000b0"
, handleEventHook = handleShutdownEvent
}
where
myLayout =
(onWorkspace "im" $ reflectVert $ Mirror $ Tall 1 (3/100) (12/13))
(FixedColumn 1 20 80 10 ||| Full)
xmonad' :: (LayoutClass l Window, Read (l Window)) => XConfig l -> IO ()
xmonad' conf = do
path <- getEnv "XMONAD_STATE"
try (readFile path) >>= \case
Right content -> do
hPutStrLn stderr ("resuming from " ++ path)
withArgs ("--resume" : lines content) (xmonad conf)
Left e -> do
hPutStrLn stderr (displaySomeException e)
xmonad conf
getWorkspaces0 :: IO [String]
getWorkspaces0 =
try (getEnv "XMONAD_WORKSPACES0_FILE") >>= \case
Left e -> warn (displaySomeException e)
Right p -> try (readFile p) >>= \case
Left e -> warn (displaySomeException e)
Right x -> case readEither x of
Left e -> warn e
Right y -> return y
where
warn msg = hPutStrLn stderr ("getWorkspaces0: " ++ msg) >> return []
displaySomeException :: SomeException -> String
displaySomeException = displayException
spawnTermAt :: String -> X ()
--spawnTermAt _ = floatNext True >> spawn myTerm
--spawnTermAt "ff" = floatNext True >> spawn myTerm
--spawnTermAt _ = spawn myTerm
spawnTermAt ws = do
env <- liftIO getEnvironment
let env' = ("XMONAD_SPAWN_WORKSPACE", ws) : env
xfork (executeFile "urxvtc" True [] (Just env')) >> return ()
myKeys :: XConfig Layout -> Map (KeyMask, KeySym) (X ())
myKeys conf = Map.fromList $
[ ((_4 , xK_Escape ), spawn "/var/setuid-wrappers/slock")
, ((_4S , xK_c ), kill)
, ((_4 , xK_x ), chooseAction spawnTermAt)
, ((_4C , xK_x ), spawn myRootTerm)
--, ((_4M , xK_x ), spawn "xterm")
--, ((_4M , xK_x ), mySpawn "xterm")
--, ((_4 , xK_F1 ), withFocused jojo)
--, ((_4 , xK_F1 ), printAllGeometries)
, ((0 , xK_Menu ), gets windowset >>= allWorkspaceNames >>= pager pagerConfig (windows . W.view) )
, ((_S , xK_Menu ), gets windowset >>= allWorkspaceNames >>= pager pagerConfig (windows . W.shift) )
, ((_C , xK_Menu ), toggleWS)
, ((_4 , xK_Menu ), rhombus horseConfig (liftIO . hPutStrLn stderr) ["Correct", "Horse", "Battery", "Staple", "Stuhl", "Tisch"] )
-- %! Rotate through the available layout algorithms
, ((_4 , xK_space ), sendMessage NextLayout)
, ((_4S , xK_space ), setLayout $ XMonad.layoutHook conf) -- reset layout
---- BinarySpacePartition
--, ((_4 , xK_l), sendMessage $ ExpandTowards R)
--, ((_4 , xK_h), sendMessage $ ExpandTowards L)
--, ((_4 , xK_j), sendMessage $ ExpandTowards D)
--, ((_4 , xK_k), sendMessage $ ExpandTowards U)
--, ((_4S , xK_l), sendMessage $ ShrinkFrom R)
--, ((_4S , xK_h), sendMessage $ ShrinkFrom L)
--, ((_4S , xK_j), sendMessage $ ShrinkFrom D)
--, ((_4S , xK_k), sendMessage $ ShrinkFrom U)
--, ((_4 , xK_n), sendMessage Rotate)
--, ((_4S , xK_n), sendMessage Swap)
---- mouseResizableTile
--, ((_4 , xK_u), sendMessage ShrinkSlave)
--, ((_4 , xK_i), sendMessage ExpandSlave)
-- move focus up or down the window stack
--, ((_4 , xK_m ), windows W.focusMaster)
, ((_4 , xK_j ), windows W.focusDown)
, ((_4 , xK_k ), windows W.focusUp)
-- modifying the window order
, ((_4S , xK_m ), windows W.swapMaster)
, ((_4S , xK_j ), windows W.swapDown)
, ((_4S , xK_k ), windows W.swapUp)
-- resizing the master/slave ratio
, ((_4 , xK_h ), sendMessage Shrink) -- %! Shrink the master area
, ((_4 , xK_l ), sendMessage Expand) -- %! Expand the master area
-- floating layer support
, ((_4 , xK_t ), withFocused $ windows . W.sink) -- make tiling
-- increase or decrease number of windows in the master area
, ((_4 , xK_comma ), sendMessage $ IncMasterN 1)
, ((_4 , xK_period ), sendMessage $ IncMasterN (-1))
, ((_4 , xK_a ), addWorkspacePrompt defaultXPConfig)
, ((_4 , xK_r ), renameWorkspace defaultXPConfig)
, ((_4 , xK_Delete ), removeEmptyWorkspace)
, ((_4 , xK_Return ), toggleWS)
--, (0 , xK_Menu ) & \k -> (k, gridselectWorkspace wsGSConfig { gs_navigate = makeGSNav k } W.view)
--, (_4 , xK_v ) & \k -> (k, gridselectWorkspace wsGSConfig { gs_navigate = makeGSNav k } W.view)
--, (_4S , xK_v ) & \k -> (k, gridselectWorkspace wsGSConfig { gs_navigate = makeGSNav k } W.shift)
--, (_4 , xK_b ) & \k -> (k, goToSelected wGSConfig { gs_navigate = makeGSNav k })
]
where
_4 = mod4Mask
_C = controlMask
_S = shiftMask
_M = mod1Mask
_4C = _4 .|. _C
_4S = _4 .|. _S
_4M = _4 .|. _M
_4CM = _4 .|. _C .|. _M
_4SM = _4 .|. _S .|. _M
pagerConfig :: PagerConfig
pagerConfig = defaultPagerConfig
{ pc_font = myFont
, pc_cellwidth = 64
--, pc_cellheight = 36 -- TODO automatically keep screen aspect
--, pc_borderwidth = 1
--, pc_matchcolor = "#f0b000"
, pc_matchmethod = MatchPrefix
--, pc_colors = pagerWorkspaceColors
, pc_windowColors = windowColors
}
where
windowColors _ _ _ True _ = ("#ef4242","#ff2323")
windowColors wsf m c u wf = do
let def = defaultWindowColors wsf m c u wf
if m == False && wf == True
then ("#402020", snd def)
else def
horseConfig :: RhombusConfig
horseConfig = defaultRhombusConfig
{ rc_font = myFont
, rc_cellwidth = 64
--, rc_cellheight = 36 -- TODO automatically keep screen aspect
--, rc_borderwidth = 1
--, rc_matchcolor = "#f0b000"
, rc_matchmethod = MatchPrefix
--, rc_colors = pagerWorkspaceColors
--, rc_paint = myPaint
}
wGSConfig :: GSConfig Window
wGSConfig = defaultGSConfig
{ gs_cellheight = 20
, gs_cellwidth = 192
, gs_cellpadding = 5
, gs_font = myFont
, gs_navigate = navNSearch
}
-- wsGSConfig = defaultGSConfig
-- { gs_cellheight = 20
-- , gs_cellwidth = 64
-- , gs_cellpadding = 5
-- , gs_font = myFont
-- , gs_navigate = navNSearch
-- }
-- custom navNSearch
--makeGSNav :: (KeyMask, KeySym) -> TwoD a (Maybe a)
--makeGSNav esc = nav
-- where
-- nav = makeXEventhandler $ shadowWithKeymap keyMap navNSearchDefaultHandler
-- keyMap = Map.fromList
-- [ (esc , cancel)
-- , ((0,xK_Escape) , cancel)
-- , ((0,xK_Return) , select)
-- , ((0,xK_Left) , move (-1, 0) >> nav)
-- , ((0,xK_Right) , move ( 1, 0) >> nav)
-- , ((0,xK_Down) , move ( 0, 1) >> nav)
-- , ((0,xK_Up) , move ( 0,-1) >> nav)
-- , ((0,xK_BackSpace) , transformSearchString (\s -> if (s == "") then "" else init s) >> nav)
-- ]
-- -- The navigation handler ignores unknown key symbols, therefore we const
-- navNSearchDefaultHandler (_,s,_) = do
-- transformSearchString (++ s)
-- nav
(&) :: a -> (a -> c) -> c
(&) = flip ($)
allWorkspaceNames :: W.StackSet i l a sid sd -> X [i]
allWorkspaceNames ws =
return $ map W.tag (W.hidden ws) ++ [W.tag $ W.workspace $ W.current ws]

View File

@ -1,6 +0,0 @@
.PHONY: ghci
ghci: shell.nix
nix-shell --command 'exec ghci -Wall'
shell.nix: xmonad.cabal
cabal2nix --shell . > $@

View File

@ -1,17 +0,0 @@
Author: tv
Build-Type: Simple
Cabal-Version: >= 1.2
License: MIT
Name: xmonad-tv
Version: 0
Executable xmonad
Build-Depends:
base,
containers,
unix,
xmonad,
xmonad-contrib,
xmonad-stockholm
GHC-Options: -Wall -O3 -threaded -rtsopts
Main-Is: Main.hs

9
tv/2configs/audit.nix Normal file
View File

@ -0,0 +1,9 @@
{ ... }:
{
security.audit = {
rules = [
"-a task,never"
];
};
}

View File

@ -14,7 +14,7 @@ with config.krebs.lib;
stockholm = "/home/tv/stockholm";
nixpkgs = {
url = https://github.com/NixOS/nixpkgs;
rev = "87fe38fd0e19ca83fc3ea338f8e0e7b12971d204";
rev = "8bf31d7d27cae435d7c1e9e0ccb0a320b424066f";
};
} // optionalAttrs config.krebs.build.host.secure {
secrets-master = "/home/tv/secrets/master";
@ -25,6 +25,7 @@ with config.krebs.lib;
imports = [
<secrets>
./audit.nix
./backup.nix
./nginx
./vim.nix

View File

@ -14,6 +14,7 @@ let
};
extra-runtimepath = concatMapStringsSep "," (pkg: "${pkg.rtp}") [
pkgs.vimPlugins.ctrlp
pkgs.vimPlugins.undotree
(pkgs.vimUtils.buildVimPlugin {
name = "file-line-1.0";
@ -101,6 +102,170 @@ let
command! -n=0 -bar ShowSyntax :call ShowSyntax()
'';
})))
((rtp: rtp // { inherit rtp; }) (pkgs.writeOut "vim-tv" {
"/syntax/haskell.vim".text = /* vim */ ''
syn region String start=+\[[[:alnum:]]*|+ end=+|]+
hi link ConId Identifier
hi link VarId Identifier
hi link hsDelimiter Delimiter
'';
"/syntax/nix.vim".text = /* vim */ ''
"" Quit when a (custom) syntax file was already loaded
"if exists("b:current_syntax")
" finish
"endif
"setf nix
" Ref <nix/src/libexpr/lexer.l>
syn match NixID /[a-zA-Z\_][a-zA-Z0-9\_\'\-]*/
syn match NixINT /\<[0-9]\+\>/
syn match NixPATH /[a-zA-Z0-9\.\_\-\+]*\(\/[a-zA-Z0-9\.\_\-\+]\+\)\+/
syn match NixHPATH /\~\(\/[a-zA-Z0-9\.\_\-\+]\+\)\+/
syn match NixSPATH /<[a-zA-Z0-9\.\_\-\+]\+\(\/[a-zA-Z0-9\.\_\-\+]\+\)*>/
syn match NixURI /[a-zA-Z][a-zA-Z0-9\+\-\.]*:[a-zA-Z0-9\%\/\?\:\@\&\=\+\$\,\-\_\.\!\~\*\']\+/
syn region NixSTRING
\ matchgroup=NixSTRING
\ start='"'
\ skip='\\"'
\ end='"'
syn region NixIND_STRING
\ matchgroup=NixIND_STRING
\ start="'''"
\ skip="'''\('\|[$]\|\\[nrt]\)"
\ end="'''"
syn match NixOther /[-!+&<>|():/;=.,?\[\]*@]/
syn match NixCommentMatch /\(^\|\s\)#.*/
syn region NixCommentRegion start="/\*" end="\*/"
hi link NixCode Statement
hi link NixData Constant
hi link NixComment Comment
hi link NixCommentMatch NixComment
hi link NixCommentRegion NixComment
hi link NixID NixCode
hi link NixINT NixData
hi link NixPATH NixData
hi link NixHPATH NixData
hi link NixSPATH NixData
hi link NixURI NixData
hi link NixSTRING NixData
hi link NixIND_STRING NixData
hi link NixEnter NixCode
hi link NixOther NixCode
hi link NixQuote NixData
syn cluster nix_has_dollar_curly contains=@nix_ind_strings,@nix_strings
syn cluster nix_ind_strings contains=NixIND_STRING
syn cluster nix_strings contains=NixSTRING
${concatStringsSep "\n" (mapAttrsToList (lang: { extraStart ? null }: let
startAlts = filter isString [
''/\* ${lang} \*/''
extraStart
];
sigil = ''\(${concatStringsSep ''\|'' startAlts}\)[ \t\r\n]*'';
in /* vim */ ''
syn include @nix_${lang}_syntax syntax/${lang}.vim
unlet b:current_syntax
syn match nix_${lang}_sigil
\ X${replaceStrings ["X"] ["\\X"] sigil}\ze\('''\|"\)X
\ nextgroup=nix_${lang}_region_IND_STRING,nix_${lang}_region_STRING
\ transparent
syn region nix_${lang}_region_STRING
\ matchgroup=NixSTRING
\ start='"'
\ skip='\\"'
\ end='"'
\ contained
\ contains=@nix_${lang}_syntax
\ transparent
syn region nix_${lang}_region_IND_STRING
\ matchgroup=NixIND_STRING
\ start="'''"
\ skip="'''\('\|[$]\|\\[nrt]\)"
\ end="'''"
\ contained
\ contains=@nix_${lang}_syntax
\ transparent
syn cluster nix_ind_strings
\ add=nix_${lang}_region_IND_STRING
syn cluster nix_strings
\ add=nix_${lang}_region_STRING
" This is required because containedin isn't transitive.
syn cluster nix_has_dollar_curly
\ add=@nix_${lang}_syntax
'') {
c = {};
cabal = {};
diff = {};
haskell = {};
lua = {};
sed.extraStart = ''writeSed[^ \t\r\n]*[ \t\r\n]*"[^"]*"'';
sh.extraStart = concatStringsSep ''\|'' [
''write\(Ba\|Da\)sh[^ \t\r\n]*[ \t\r\n]*"[^"]*"''
''[a-z]*Phase[ \t\r\n]*=''
];
vim.extraStart =
''write[^ \t\r\n]*[ \t\r\n]*"\(\([^"]*\.\)\?vimrc\|[^"]*\.vim\)"'';
xdefaults = {};
})}
" Clear syntax that interferes with nixINSIDE_DOLLAR_CURLY.
syn clear shVarAssign
syn region nixINSIDE_DOLLAR_CURLY
\ matchgroup=NixEnter
\ start="[$]{"
\ end="}"
\ contains=TOP
\ containedin=@nix_has_dollar_curly
\ transparent
syn region nix_inside_curly
\ matchgroup=NixEnter
\ start="{"
\ end="}"
\ contains=TOP
\ containedin=nixINSIDE_DOLLAR_CURLY,nix_inside_curly
\ transparent
syn match NixQuote /'''\(''$\|\\.\)/he=s+2
\ containedin=@nix_ind_strings
\ contained
syn match NixQuote /'''\('\|\\.\)/he=s+1
\ containedin=@nix_ind_strings
\ contained
syn match NixQuote /\\./he=s+1
\ containedin=@nix_strings
\ contained
syn sync fromstart
let b:current_syntax = "nix"
set isk=@,48-57,_,192-255,-,'
'';
"/syntax/sed.vim".text = /* vim */ ''
syn region sedBranch
\ matchgroup=sedFunction start="T"
\ matchgroup=sedSemicolon end=";\|$"
\ contains=sedWhitespace
'';
}))
];
dirs = {
@ -121,6 +286,9 @@ let
vim = pkgs.writeDashBin "vim" ''
set -efu
(umask 0077; exec ${pkgs.coreutils}/bin/mkdir -p ${toString mkdirs})
if test $# = 0 && test -e "$PWD/.ctrlpignore"; then
set -- +CtrlP
fi
exec ${pkgs.vim}/bin/vim "$@"
'';
@ -137,7 +305,7 @@ let
set mouse=a
set noruler
set pastetoggle=<INS>
set runtimepath=${extra-runtimepath},$VIMRUNTIME
set runtimepath=$VIMRUNTIME,${extra-runtimepath}
set shortmess+=I
set showcmd
set showmatch
@ -164,15 +332,10 @@ let
\ | syn match TabStop containedin=ALL /\t\+/
\ | syn keyword Todo containedin=ALL TODO
au BufRead,BufNewFile *.hs so ${hs.vim}
au BufRead,BufNewFile *.nix so ${nix.vim}
au BufRead,BufNewFile *.nix set ft=nix
au BufRead,BufNewFile /dev/shm/* set nobackup nowritebackup noswapfile
nmap <esc>q :buffer
nmap <M-q> :buffer
cnoremap <C-A> <Home>
noremap <C-c> :q<cr>
@ -198,150 +361,41 @@ let
noremap <esc>[c <nop> | noremap! <esc>[c <nop>
noremap <esc>[d <nop> | noremap! <esc>[d <nop>
vnoremap u <nop>
'';
hs.vim = pkgs.writeText "hs.vim" ''
syn region String start=+\[[[:alnum:]]*|+ end=+|]+
hi link ConId Identifier
hi link VarId Identifier
hi link hsDelimiter Delimiter
'';
nix.vim = pkgs.writeText "nix.vim" ''
setf nix
" Ref <nix/src/libexpr/lexer.l>
syn match NixID /[a-zA-Z\_][a-zA-Z0-9\_\'\-]*/
syn match NixINT /\<[0-9]\+\>/
syn match NixPATH /[a-zA-Z0-9\.\_\-\+]*\(\/[a-zA-Z0-9\.\_\-\+]\+\)\+/
syn match NixHPATH /\~\(\/[a-zA-Z0-9\.\_\-\+]\+\)\+/
syn match NixSPATH /<[a-zA-Z0-9\.\_\-\+]\+\(\/[a-zA-Z0-9\.\_\-\+]\+\)*>/
syn match NixURI /[a-zA-Z][a-zA-Z0-9\+\-\.]*:[a-zA-Z0-9\%\/\?\:\@\&\=\+\$\,\-\_\.\!\~\*\']\+/
syn region NixSTRING
\ matchgroup=NixSTRING
\ start='"'
\ skip='\\"'
\ end='"'
syn region NixIND_STRING
\ matchgroup=NixIND_STRING
\ start="'''"
\ skip="'''\('\|[$]\|\\[nrt]\)"
\ end="'''"
syn match NixOther /[():/;=.,?\[\]]/
syn match NixCommentMatch /\(^\|\s\)#.*/
syn region NixCommentRegion start="/\*" end="\*/"
hi link NixCode Statement
hi link NixData Constant
hi link NixComment Comment
hi link NixCommentMatch NixComment
hi link NixCommentRegion NixComment
hi link NixID NixCode
hi link NixINT NixData
hi link NixPATH NixData
hi link NixHPATH NixData
hi link NixSPATH NixData
hi link NixURI NixData
hi link NixSTRING NixData
hi link NixIND_STRING NixData
hi link NixEnter NixCode
hi link NixOther NixCode
hi link NixQuote NixData
syn cluster nix_has_dollar_curly contains=@nix_ind_strings,@nix_strings
syn cluster nix_ind_strings contains=NixIND_STRING
syn cluster nix_strings contains=NixSTRING
${concatStringsSep "\n" (mapAttrsToList (lang: { extraStart ? null }: let
startAlts = filter isString [
''/\* ${lang} \*/''
extraStart
];
sigil = ''\(${concatStringsSep ''\|'' startAlts}\)[ \t\r\n]*'';
in /* vim */ ''
syn include @nix_${lang}_syntax syntax/${lang}.vim
unlet b:current_syntax
syn match nix_${lang}_sigil
\ X${replaceStrings ["X"] ["\\X"] sigil}\ze\('''\|"\)X
\ nextgroup=nix_${lang}_region_IND_STRING,nix_${lang}_region_STRING
\ transparent
syn region nix_${lang}_region_STRING
\ matchgroup=NixSTRING
\ start='"'
\ skip='\\"'
\ end='"'
\ contained
\ contains=@nix_${lang}_syntax
\ transparent
syn region nix_${lang}_region_IND_STRING
\ matchgroup=NixIND_STRING
\ start="'''"
\ skip="'''\('\|[$]\|\\[nrt]\)"
\ end="'''"
\ contained
\ contains=@nix_${lang}_syntax
\ transparent
syn cluster nix_ind_strings
\ add=nix_${lang}_region_IND_STRING
syn cluster nix_strings
\ add=nix_${lang}_region_STRING
syn cluster nix_has_dollar_curly
\ add=@nix_${lang}_syntax
'') {
c = {};
cabal = {};
haskell = {};
sh.extraStart = concatStringsSep ''\|'' [
''write\(Ba\|Da\)sh[^ \t\r\n]*[ \t\r\n]*"[^"]*"''
''[a-z]*Phase[ \t\r\n]*=''
];
vim.extraStart =
''write[^ \t\r\n]*[ \t\r\n]*"\(\([^"]*\.\)\?vimrc\|[^"]*\.vim\)"'';
})}
" Clear syntax that interferes with nixINSIDE_DOLLAR_CURLY.
syn clear shVarAssign
syn region nixINSIDE_DOLLAR_CURLY
\ matchgroup=NixEnter
\ start="[$]{"
\ end="}"
\ contains=TOP
\ containedin=@nix_has_dollar_curly
\ transparent
syn region nix_inside_curly
\ matchgroup=NixEnter
\ start="{"
\ end="}"
\ contains=TOP
\ containedin=nixINSIDE_DOLLAR_CURLY,nix_inside_curly
\ transparent
syn match NixQuote /'''\([''$']\|\\.\)/he=s+2
\ containedin=@nix_ind_strings
\ contained
syn match NixQuote /\\./he=s+1
\ containedin=@nix_strings
\ contained
syn sync fromstart
let b:current_syntax = "nix"
set isk=@,48-57,_,192-255,-,'
"
" CtrlP-related configuration
"
hi CtrlPPrtCursor ctermbg=199
hi CtrlPMatch ctermfg=226
set showtabline=0
let g:ctrlp_cmd = 'CtrlPMixed'
let g:ctrlp_map = '<esc>q'
let g:ctrlp_working_path_mode = 'a'
" Cannot use autoignore extension because it fails to initialize properly:
" when started the first time, e.g. using `vim +CtrlP`, then it won't use
" patterns from .ctrlpignore until CtrlP gets reopened and F5 pressed...
fu s:gen_ctrlp_custom_ignore()
let l:prefix = getcwd()
let l:pats = readfile(l:prefix . "/.ctrlpignore")
let l:pats = filter(l:pats, 's:ctrlpignore_filter(v:val)')
let l:pats = map(l:pats, 's:ctrlpignore_rewrite(v:val)')
return l:prefix . "\\(" . join(l:pats, "\\|") . "\\)"
endfu
fu s:ctrlpignore_filter(s)
" filter comments and blank lines
return match(a:s, '^\s*\(#.*\)''$') == -1
endfu
fu s:ctrlpignore_rewrite(s)
if a:s[0:0] == "^"
return "/" . a:s[1:]
else
return "/.*" . a:s
endif
endfu
try
let g:ctrlp_custom_ignore = s:gen_ctrlp_custom_ignore()
catch /^Vim\%((\a\+)\)\=:E484/
endtry
'';
in
out