summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--krebs/3modules/lass/default.nix2
-rw-r--r--krebs/3modules/makefu/default.nix2
-rw-r--r--krebs/3modules/mv/default.nix1
-rw-r--r--krebs/5pkgs/cacpanel/default.nix18
-rw-r--r--krebs/5pkgs/drivedroid-gen-repo/default.nix4
-rw-r--r--krebs/5pkgs/get/default.nix2
-rw-r--r--krebs/5pkgs/haskell-overrides/blessings.nix2
-rw-r--r--krebs/5pkgs/haskell-overrides/scanner.nix2
-rw-r--r--krebs/5pkgs/haskell-overrides/xmonad-stockholm.nix2
-rw-r--r--krebs/5pkgs/much/default.nix2
-rw-r--r--krebs/5pkgs/push/default.nix2
-rw-r--r--krebs/Zhosts/stro10
-rw-r--r--lass/3modules/bitlbee.nix153
-rw-r--r--lass/3modules/default.nix1
-rw-r--r--lass/3modules/dnsmasq.nix7
-rw-r--r--makefu/1systems/gum.nix9
-rw-r--r--makefu/2configs/base-gui.nix11
-rw-r--r--makefu/2configs/default.nix1
-rw-r--r--makefu/2configs/git/cgit-retiolum.nix4
-rw-r--r--makefu/2configs/mattermost-docker.nix47
-rw-r--r--mv/1systems/stro.nix4
-rw-r--r--mv/2configs/bash_completion.sh779
-rw-r--r--mv/2configs/default.nix15
-rw-r--r--mv/2configs/git.nix58
-rw-r--r--mv/2configs/xserver/default.nix2
-rw-r--r--mv/5pkgs/default.nix23
-rw-r--r--mv/5pkgs/xmonad-tv/.gitignore1
-rw-r--r--mv/5pkgs/xmonad-tv/Main.hs277
-rw-r--r--mv/5pkgs/xmonad-tv/Makefile6
-rw-r--r--mv/5pkgs/xmonad-tv/xmonad.cabal17
-rw-r--r--tv/1systems/wu.nix2
-rw-r--r--tv/1systems/xu.nix2
-rw-r--r--tv/2configs/pulse.nix83
-rw-r--r--tv/2configs/xserver/default.nix2
-rw-r--r--tv/5pkgs/xmonad-tv/Main.hs4
-rw-r--r--tv/5pkgs/xmonad-tv/xmonad.cabal1
36 files changed, 1376 insertions, 182 deletions
diff --git a/krebs/3modules/lass/default.nix b/krebs/3modules/lass/default.nix
index c99263fe8..26b0947bb 100644
--- a/krebs/3modules/lass/default.nix
+++ b/krebs/3modules/lass/default.nix
@@ -9,7 +9,7 @@ with lib;
dc = "lass"; #dc = "cac";
nets = rec {
internet = {
- addrs4 = ["167.88.34.158"];
+ addrs4 = ["162.252.241.33"];
aliases = [
"echelon.internet"
];
diff --git a/krebs/3modules/makefu/default.nix b/krebs/3modules/makefu/default.nix
index 652527da2..037abbdfd 100644
--- a/krebs/3modules/makefu/default.nix
+++ b/krebs/3modules/makefu/default.nix
@@ -245,6 +245,8 @@ with lib;
extraZones = {
"krebsco.de" = ''
share.euer IN A ${head nets.internet.addrs4}
+ mattermost.euer IN A ${head nets.internet.addrs4}
+ git.euer IN A ${head nets.internet.addrs4}
gum IN A ${head nets.internet.addrs4}
'';
};
diff --git a/krebs/3modules/mv/default.nix b/krebs/3modules/mv/default.nix
index 446caf454..6da2abc85 100644
--- a/krebs/3modules/mv/default.nix
+++ b/krebs/3modules/mv/default.nix
@@ -13,6 +13,7 @@ with lib;
addrs6 = ["42:0:0:0:0:0:111:111"];
aliases = [
"stro.retiolum"
+ "cgit.stro.retiolum"
];
tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY-----
diff --git a/krebs/5pkgs/cacpanel/default.nix b/krebs/5pkgs/cacpanel/default.nix
new file mode 100644
index 000000000..3e3e2e1fc
--- /dev/null
+++ b/krebs/5pkgs/cacpanel/default.nix
@@ -0,0 +1,18 @@
+{pkgs, python3Packages, ...}:
+
+python3Packages.buildPythonPackage rec {
+ name = "cacpanel-${version}";
+ version = "0.2.1";
+
+ src = pkgs.fetchurl {
+ url = "https://pypi.python.org/packages/source/c/cacpanel/cacpanel-${version}.tar.gz";
+ sha256 = "1zaazg5r10kgva32zh4fhpw6l6h51ijkwpa322na0kh4x6f6aqj3";
+ };
+
+ propagatedBuildInputs = with python3Packages; [
+ docopt
+ requests2
+ beautifulsoup4
+ ];
+}
+
diff --git a/krebs/5pkgs/drivedroid-gen-repo/default.nix b/krebs/5pkgs/drivedroid-gen-repo/default.nix
index 087f97c9a..de8046c4a 100644
--- a/krebs/5pkgs/drivedroid-gen-repo/default.nix
+++ b/krebs/5pkgs/drivedroid-gen-repo/default.nix
@@ -2,7 +2,7 @@
python3Packages.buildPythonPackage rec {
name = "drivedroid-gen-repo-${version}";
- version = "0.4.2";
+ version = "0.4.4";
propagatedBuildInputs = with pkgs;[
python3Packages.docopt
@@ -10,7 +10,7 @@ python3Packages.buildPythonPackage rec {
src = fetchurl {
url = "https://pypi.python.org/packages/source/d/drivedroid-gen-repo/drivedroid-gen-repo-${version}.tar.gz";
- sha256 = "1w4dqc9ndyiv5kjh2y8n4p4c280vhqyj8s7y6al2klchcp2ab7q7";
+ sha256 = "09p58hzp61r5fp025lak9z52y0aakmaqpi59p9w5xq42dvy2hnvl";
};
meta = {
diff --git a/krebs/5pkgs/get/default.nix b/krebs/5pkgs/get/default.nix
index d4f5f6b46..9a0192aab 100644
--- a/krebs/5pkgs/get/default.nix
+++ b/krebs/5pkgs/get/default.nix
@@ -4,7 +4,7 @@ stdenv.mkDerivation {
name = "get-1.3.1";
src = fetchgit {
- url = http://cgit.cd.retiolum/get;
+ url = http://cgit.cd.krebsco.de/get;
rev = "64c97edd3f9952cd5e703208c46748a035a515bf";
sha256 = "32ca83f4fd86fd3285bef9dcfd0917308086d239189858daceca175de49ff97c";
};
diff --git a/krebs/5pkgs/haskell-overrides/blessings.nix b/krebs/5pkgs/haskell-overrides/blessings.nix
index 311458211..741fb5c36 100644
--- a/krebs/5pkgs/haskell-overrides/blessings.nix
+++ b/krebs/5pkgs/haskell-overrides/blessings.nix
@@ -3,7 +3,7 @@ mkDerivation {
pname = "blessings";
version = "1.0.0";
src = fetchgit {
- url = http://cgit.cd.retiolum/blessings;
+ url = http://cgit.cd.krebsco.de/blessings;
rev = "25a510dcb38ea9158e9969d56eb66cb1b860ab5f";
sha256 = "b962153e80e51519b52220199d8350b54154833e4bc25a792ecc58898fef3fb2";
};
diff --git a/krebs/5pkgs/haskell-overrides/scanner.nix b/krebs/5pkgs/haskell-overrides/scanner.nix
index ebc5cd620..b88b9dbe3 100644
--- a/krebs/5pkgs/haskell-overrides/scanner.nix
+++ b/krebs/5pkgs/haskell-overrides/scanner.nix
@@ -3,7 +3,7 @@ mkDerivation {
pname = "scanner";
version = "1.0.0";
src = fetchgit {
- url = http://cgit.cd.retiolum/scanner;
+ url = http://cgit.cd.krebsco.de/scanner;
rev = "7f091a3bc152ad3974a1873b460fa1759bf8dcad";
sha256 = "7d123c227777932039d26fc832b8d32a90f04c0bd6b7e8bcff0a6f49a54e0054";
};
diff --git a/krebs/5pkgs/haskell-overrides/xmonad-stockholm.nix b/krebs/5pkgs/haskell-overrides/xmonad-stockholm.nix
index 5c6f068e7..096597808 100644
--- a/krebs/5pkgs/haskell-overrides/xmonad-stockholm.nix
+++ b/krebs/5pkgs/haskell-overrides/xmonad-stockholm.nix
@@ -5,7 +5,7 @@ mkDerivation {
pname = "xmonad-stockholm";
version = "1.0.0";
src = fetchgit {
- url = "http://cgit.cd/xmonad-stockholm";
+ url = "http://cgit.cd.krebsco.de/xmonad-stockholm";
sha256 = "35dda5d16acc90af94ae2fae10ab5cc2d5b450c3f1ff2e7f515ac53877269abf";
rev = "2dbefe42fc5cfe9093465bf3e22ba8f82feeef6e";
};
diff --git a/krebs/5pkgs/much/default.nix b/krebs/5pkgs/much/default.nix
index ba5ab2327..2a9376139 100644
--- a/krebs/5pkgs/much/default.nix
+++ b/krebs/5pkgs/much/default.nix
@@ -12,7 +12,7 @@ mkDerivation {
pname = "much";
version = "1.0.0";
src = fetchgit {
- url = "http://cgit.cd.retiolum/much";
+ url = "http://cgit.cd.krebsco.de/much";
rev = "045dc986b4de225a927175f81c8ccfdab450202c";
sha256 = "cec175e3dc32ef93029ee5285f6c4042ce11d637945bc8cec02cb6699d06cc13";
};
diff --git a/krebs/5pkgs/push/default.nix b/krebs/5pkgs/push/default.nix
index bc5c030a0..13769c747 100644
--- a/krebs/5pkgs/push/default.nix
+++ b/krebs/5pkgs/push/default.nix
@@ -12,7 +12,7 @@ stdenv.mkDerivation {
name = "push-1.1.1";
src = fetchgit {
- url = http://cgit.cd.retiolum/push;
+ url = http://cgit.cd.krebsco.de/push;
rev = "ea8b76569c6b226fe148e559477669b095408472";
sha256 = "c305a1515d30603f6ed825d44487e863fdc7d90400620ceaf2c335a3b5d1e221";
};
diff --git a/krebs/Zhosts/stro b/krebs/Zhosts/stro
new file mode 100644
index 000000000..cddab5421
--- /dev/null
+++ b/krebs/Zhosts/stro
@@ -0,0 +1,10 @@
+Subnet = 10.243.111.111/32
+Subnet = 42:0:0:0:0:0:111:111/128
+-----BEGIN RSA PUBLIC KEY-----
+MIIBCgKCAQEA0vIzLyoetOyi3R7qOh3gjSvUVjPEdqCvd0NEevDCIhhFy0nIbZ/b
+vnuk3EUeTb6e384J8fKB4agig0JeR3JjtDvtjy5g9Cdy2nrU71w8wqU0etmv2PTb
+FjbCFfeBXn0N3U7gXwjZGCvjAXa1a4jGb4R2iYBYGG3aY4reCN8B8Ah81h+S0oLg
+ZJJfaBmWM5vNRFEI5X4CLaVnwtsoZuXIjYStgNn/9Mg/Y6NQS0H0H+HFeyhigAqG
+oYGqNar/2QqPU176V/FwrD30F3qJV1uyzuPta7hmdfOxqYjZ/jqdPSRYtlunYYcq
+XbH5oYmzO9NEeVWzjdac/DiV2OP8HufoYwIDAQAB
+-----END RSA PUBLIC KEY-----
diff --git a/lass/3modules/bitlbee.nix b/lass/3modules/bitlbee.nix
deleted file mode 100644
index 8ce560146..000000000
--- a/lass/3modules/bitlbee.nix
+++ /dev/null
@@ -1,153 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-
-let
-
- inherit (lib)
- mkIf
- mkOption
- types
- singleton
- ;
-
- authModeCheck = v:
- v == "Open" ||
- v == "Closed" ||
- v == "Registered"
- ;
-
- bitlbeeConfig = pkgs.writeText "bitlbee.conf" ''
- [settings]
- RunMode = Daemon
- User = bitlbee
- ConfigDir = ${cfg.configDir}
- DaemonInterface = ${cfg.interface}
- DaemonPort = ${toString cfg.portNumber}
- AuthMode = ${cfg.authMode}
- ${lib.optionalString (cfg.hostName != "") "HostName = ${cfg.hostName}"}
- ${lib.optionalString (cfg.protocols != "") "Protocols = ${cfg.protocols}"}
- ${cfg.extraSettings}
-
- [defaults]
- ${cfg.extraDefaults}
- '';
-
- cfg = config.lass.bitlbee;
-
- out = {
- options.lass.bitlbee = api;
- config = mkIf cfg.enable imp;
- };
-
- api = {
- enable = mkOption {
- default = false;
- description = ''
- Whether to run the BitlBee IRC to other chat network gateway.
- Running it allows you to access the MSN, Jabber, Yahoo! and ICQ chat
- networks via an IRC client.
- '';
- };
-
- interface = mkOption {
- default = "127.0.0.1";
- description = ''
- The interface the BitlBee deamon will be listening to. If `127.0.0.1',
- only clients on the local host can connect to it; if `0.0.0.0', clients
- can access it from any network interface.
- '';
- };
-
- portNumber = mkOption {
- default = 6667;
- description = ''
- Number of the port BitlBee will be listening to.
- '';
- };
-
- authMode = mkOption {
- default = "Open";
- type = types.addCheck types.str authModeCheck;
- description = ''
- The following authentication modes are available:
- Open -- Accept connections from anyone, use NickServ for user authentication.
- Closed -- Require authorization (using the PASS command during login) before allowing the user to connect at all.
- Registered -- Only allow registered users to use this server; this disables the register- and the account command until the user identifies himself.
- '';
- };
-
- hostName = mkOption {
- default = "";
- type = types.str;
- description = ''
- Normally, BitlBee gets a hostname using getsockname(). If you have a nicer
- alias for your BitlBee daemon, you can set it here and BitlBee will identify
- itself with that name instead.
- '';
- };
-
- configDir = mkOption {
- default = "/var/lib/bitlbee";
- type = types.path;
- description = ''
- Specify an alternative directory to store all the per-user configuration
- files.
- '';
- };
-
- protocols = mkOption {
- default = "";
- type = types.str;
- description = ''
- This option allows to remove the support of protocol, even if compiled
- in. If nothing is given, there are no restrictions.
- '';
- };
-
- extraSettings = mkOption {
- default = "";
- description = ''
- Will be inserted in the Settings section of the config file.
- '';
- };
-
- extraDefaults = mkOption {
- default = "";
- description = ''
- Will be inserted in the Default section of the config file.
- '';
- };
-
- bitlbeePkg = mkOption {
- default = pkgs.bitlbee;
- description = ''
- the bitlbee pkg to use.
- '';
- };
- };
-
- imp = {
- users.extraUsers = singleton {
- name = "bitlbee";
- uid = config.ids.uids.bitlbee;
- description = "BitlBee user";
- home = "/var/lib/bitlbee";
- createHome = true;
- };
-
- users.extraGroups = singleton {
- name = "bitlbee";
- gid = config.ids.gids.bitlbee;
- };
-
- systemd.services.bitlbee = {
- description = "BitlBee IRC to other chat networks gateway";
- after = [ "network.target" ];
- wantedBy = [ "multi-user.target" ];
- serviceConfig.User = "bitlbee";
- serviceConfig.ExecStart = "${cfg.bitlbeePkg}/sbin/bitlbee -F -n -c ${bitlbeeConfig}";
- };
- };
-
-in
-out
diff --git a/lass/3modules/default.nix b/lass/3modules/default.nix
index 7c85af3a4..0dcad971c 100644
--- a/lass/3modules/default.nix
+++ b/lass/3modules/default.nix
@@ -2,7 +2,6 @@ _:
{
imports = [
./xresources.nix
- ./bitlbee.nix
./folderPerms.nix
./newsbot-js.nix
./per-user.nix
diff --git a/lass/3modules/dnsmasq.nix b/lass/3modules/dnsmasq.nix
index 99c165479..83a9cb180 100644
--- a/lass/3modules/dnsmasq.nix
+++ b/lass/3modules/dnsmasq.nix
@@ -25,13 +25,6 @@ let
configFile = pkgs.writeText "dnsmasq.conf" cfg.config;
imp = {
- #users.extraUsers.go = {
- # name = "go";
- # uid = 42774411; #genid go
- # description = "go url shortener user";
- # home = "/var/lib/go";
- # createHome = true;
- #};
systemd.services.dnsmasq = {
description = "dnsmasq";
diff --git a/makefu/1systems/gum.nix b/makefu/1systems/gum.nix
index 9de07266e..75607aa46 100644
--- a/makefu/1systems/gum.nix
+++ b/makefu/1systems/gum.nix
@@ -13,15 +13,21 @@ in {
../2configs/fs/single-partition-ext4.nix
# ../2configs/iodined.nix
../2configs/git/cgit-retiolum.nix
-
+ ../2configs/mattermost-docker.nix
];
+
+
+ ###### stable
krebs.build.target = "root@gum.krebsco.de";
krebs.build.host = config.krebs.hosts.gum;
+
+
# Chat
environment.systemPackages = with pkgs;[
weechat
bepasty-client-cli
+ get
];
services.bitlbee.enable = true;
@@ -31,7 +37,6 @@ in {
boot.kernelModules = [ "kvm-intel" ];
# Network
-
services.udev.extraRules = ''
SUBSYSTEM=="net", ATTR{address}=="c8:0a:a9:c8:ee:dd", NAME="et0"
'';
diff --git a/makefu/2configs/base-gui.nix b/makefu/2configs/base-gui.nix
index 7b7f85f13..16a5386ca 100644
--- a/makefu/2configs/base-gui.nix
+++ b/makefu/2configs/base-gui.nix
@@ -10,6 +10,17 @@
#
# if this is not enough, check out main-laptop.nix
+## TODO: .Xdefaults:
+# URxvt*termName: rxvt
+# URxvt.scrollBar : false
+# URxvt*scrollBar_right: false
+# URxvt*borderLess: false
+# URxvt.foreground: white
+# URxvt.background: black
+# URxvt.urgentOnBell: true
+# URxvt.visualBell: false
+# URxvt.font : xft:Terminus
+
with lib;
let
mainUser = config.krebs.build.user.name;
diff --git a/makefu/2configs/default.nix b/makefu/2configs/default.nix
index 3d9174788..760c70789 100644
--- a/makefu/2configs/default.nix
+++ b/makefu/2configs/default.nix
@@ -65,6 +65,7 @@ with lib;
time.timeZone = "Europe/Berlin";
#nix.maxJobs = 1;
+ programs.ssh.startAgent = false;
services.openssh.enable = true;
nix.useChroot = true;
diff --git a/makefu/2configs/git/cgit-retiolum.nix b/makefu/2configs/git/cgit-retiolum.nix
index e12827697..304d39fcd 100644
--- a/makefu/2configs/git/cgit-retiolum.nix
+++ b/makefu/2configs/git/cgit-retiolum.nix
@@ -15,6 +15,7 @@ let
tinc_graphs = {
desc = "Tinc Advanced Graph Generation";
};
+ cac = { };
};
priv-repos = mapAttrs make-priv-repo {
@@ -23,6 +24,9 @@ let
connector-repos = mapAttrs make-priv-repo {
connector = { };
+ mattermost = {
+ desc = "Mattermost Docker files";
+ };
};
diff --git a/makefu/2configs/mattermost-docker.nix b/makefu/2configs/mattermost-docker.nix
new file mode 100644
index 000000000..20a93dff1
--- /dev/null
+++ b/makefu/2configs/mattermost-docker.nix
@@ -0,0 +1,47 @@
+{config, lib, ...}:
+
+with lib;
+let
+ sec = toString <secrets>;
+ ssl_cert = "${sec}/wildcard.krebsco.de.crt";
+ ssl_key = "${sec}/wildcard.krebsco.de.key";
+in {
+ # mattermost docker config and deployment guide: git.euer.krebsco.de
+ virtualisation.docker.enable = true;
+ users.extraUsers.${config.krebs.build.user.name}.extraGroups = [ "docker" ];
+ krebs.nginx = {
+ enable = true;
+ servers.mattermost = {
+ listen = [ "80" "443 ssl" ];
+ server-names = [ "mattermost.euer.krebsco.de" ];
+ extraConfig = ''
+ gzip on;
+ gzip_buffers 4 32k;
+ gzip_types text/plain application/x-javascript text/css;
+ ssl_certificate ${ssl_cert};
+ ssl_certificate_key ${ssl_key};
+ default_type text/plain;
+
+ if ($scheme = http){
+ return 301 https://$server_name$request_uri;
+ }
+
+ client_max_body_size 4G;
+ keepalive_timeout 10;
+
+ '';
+ locations = [
+ (nameValuePair "/" ''
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_redirect off;
+ proxy_pass http://localhost:8065/;
+ '')
+ ];
+ };
+ };
+}
diff --git a/mv/1systems/stro.nix b/mv/1systems/stro.nix
index 9edcea007..38d4b4bc6 100644
--- a/mv/1systems/stro.nix
+++ b/mv/1systems/stro.nix
@@ -12,6 +12,7 @@ with lib;
imports = [
../2configs/hw/x220.nix
+ ../2configs/git.nix
../2configs/mail-client.nix
../2configs/xserver
{
@@ -154,7 +155,7 @@ with lib;
connectTo = [
"cd"
"gum"
- "pigstarter"
+ "wry"
];
};
}
@@ -217,6 +218,7 @@ with lib;
"sendmail" # for cron
];
+ services.bitlbee.enable = true;
services.printing.enable = true;
services.journald.extraConfig = ''
diff --git a/mv/2configs/bash_completion.sh b/mv/2configs/bash_completion.sh
new file mode 100644
index 000000000..537484fb9
--- /dev/null
+++ b/mv/2configs/bash_completion.sh
@@ -0,0 +1,779 @@
+
+# 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"\
<