summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormakefu <github@syntax-fehler.de>2015-12-04 10:16:09 +0100
committermakefu <github@syntax-fehler.de>2015-12-04 10:16:09 +0100
commit65cc52e01e18c823016a3043b8cf41822934cc3c (patch)
tree58aa8971a4e571234a762eee20c7ec7f57a2b4d4
parent597f9e8597c95ac9e4cba1689322c433bb0c9a75 (diff)
parentb5ffb88ba3a77d4f399d7a2815e2c61d53545f5d (diff)
Merge branch 'master' of pnp:stockholm
Conflicts: makefu/1systems/gum.nix
-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"\
+ "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
diff --git a/mv/2configs/default.nix b/mv/2configs/default.nix
index f5b647558..9c412099e 100644
--- a/mv/2configs/default.nix
+++ b/mv/2configs/default.nix
@@ -1,12 +1,15 @@
{ config, lib, pkgs, ... }:
with lib;
+let
+ HOME = getEnv "HOME";
+in
{
krebs.enable = true;
krebs.build = {
- user = config.krebs.users.tv;
+ user = config.krebs.users.mv;
target = mkDefault "root@${config.krebs.build.host.name}";
source = {
git.nixpkgs = {
@@ -15,10 +18,10 @@ with lib;
target-path = mkDefault "/var/src/nixpkgs";
};
dir.secrets = {
- path = mkDefault "/home/tv/secrets/${config.krebs.build.host.name}";
+ path = mkDefault "${HOME}/secrets/${config.krebs.build.host.name}";
};
dir.stockholm = {
- path = mkDefault "/home/tv/stockholm";
+ path = mkDefault "${HOME}/stockholm";
target-path = mkDefault "/var/src/stockholm";
};
};
@@ -40,16 +43,16 @@ with lib;
defaultUserShell = "/run/current-system/sw/bin/bash";
mutableUsers = false;
users = {
- tv = {
+ mv = {
isNormalUser = true;
- uid = 1337;
+ uid = 1338;
};
};
};
}
{
security.sudo.extraConfig = ''
- Defaults mailto="${config.krebs.users.tv.mail}"
+ Defaults mailto="${config.krebs.users.mv.mail}"
'';
time.timeZone = "Europe/Berlin";
}
diff --git a/mv/2configs/git.nix b/mv/2configs/git.nix
new file mode 100644
index 000000000..991d0c410
--- /dev/null
+++ b/mv/2configs/git.nix
@@ -0,0 +1,58 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ out = {
+ krebs.git = {
+ enable = true;
+ 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: { desc ? null, section ? null, ... }: {
+ inherit name desc section;
+ 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
diff --git a/mv/2configs/xserver/default.nix b/mv/2configs/xserver/default.nix
index afc2d699c..44539c54b 100644
--- a/mv/2configs/xserver/default.nix
+++ b/mv/2configs/xserver/default.nix
@@ -4,7 +4,7 @@ with lib;
let
# TODO krebs.build.user
- user = config.users.users.tv;
+ user = config.users.users.mv;
out = {
services.xserver.display = 11;
diff --git a/mv/5pkgs/default.nix b/mv/5pkgs/default.nix
new file mode 100644
index 000000000..0c72c450e
--- /dev/null
+++ b/mv/5pkgs/default.nix
@@ -0,0 +1,23 @@
+{ pkgs, ... }:
+
+{
+ # TODO use XDG_RUNTIME_DIR?
+ 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 {};
+}
diff --git a/mv/5pkgs/xmonad-tv/.gitignore b/mv/5pkgs/xmonad-tv/.gitignore
new file mode 100644
index 000000000..616204547
--- /dev/null
+++ b/mv/5pkgs/xmonad-tv/.gitignore
@@ -0,0 +1 @@
+/shell.nix
diff --git a/mv/5pkgs/xmonad-tv/Main.hs b/mv/5pkgs/xmonad-tv/Main.hs
new file mode 100644
index 000000000..2258b34a6
--- /dev/null
+++ b/mv/5pkgs/xmonad-tv/Main.hs
@@ -0,0 +1,277 @@
+{-# 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]
diff --git a/mv/5pkgs/xmonad-tv/Makefile b/mv/5pkgs/xmonad-tv/Makefile
new file mode 100644
index 000000000..cbb0776e6
--- /dev/null
+++ b/mv/5pkgs/xmonad-tv/Makefile
@@ -0,0 +1,6 @@
+.PHONY: ghci
+ghci: shell.nix
+ nix-shell --command 'exec ghci -Wall'
+
+shell.nix: xmonad.cabal
+ cabal2nix --shell . > $@
diff --git a/mv/5pkgs/xmonad-tv/xmonad.cabal b/mv/5pkgs/xmonad-tv/xmonad.cabal
new file mode 100644
index 000000000..2246524fc
--- /dev/null
+++ b/mv/5pkgs/xmonad-tv/xmonad.cabal
@@ -0,0 +1,17 @@
+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
diff --git a/tv/1systems/wu.nix b/tv/1systems/wu.nix
index 3fa5481e2..cd3139754 100644
--- a/tv/1systems/wu.nix
+++ b/tv/1systems/wu.nix
@@ -10,6 +10,7 @@ with lib;
#../2configs/consul-client.nix
../2configs/git.nix
../2configs/mail-client.nix
+ ../2configs/pulse.nix
../2configs/xserver
{
environment.systemPackages = with pkgs; [
@@ -193,7 +194,6 @@ with lib;
hardware.bumblebee.group = "video";
hardware.enableAllFirmware = true;
hardware.opengl.driSupport32Bit = true;
- hardware.pulseaudio.enable = true;
environment.systemPackages = with pkgs; [
xlibs.fontschumachermisc
diff --git a/tv/1systems/xu.nix b/tv/1systems/xu.nix
index 94656ab61..eac36fafb 100644
--- a/tv/1systems/xu.nix
+++ b/tv/1systems/xu.nix
@@ -13,6 +13,7 @@ with lib;
#../2configs/consul-client.nix
../2configs/git.nix
../2configs/mail-client.nix
+ ../2configs/pulse.nix
../2configs/xserver
{
environment.systemPackages = with pkgs; [
@@ -195,7 +196,6 @@ with lib;
#hardware.bumblebee.group = "video";
hardware.enableAllFirmware = true;
#hardware.opengl.driSupport32Bit = true;
- hardware.pulseaudio.enable = true;
environment.systemPackages = with pkgs; [
#xlibs.fontschumachermisc
diff --git a/tv/2configs/pulse.nix b/tv/2configs/pulse.nix
new file mode 100644
index 000000000..0ddc52789
--- /dev/null
+++ b/tv/2configs/pulse.nix
@@ -0,0 +1,83 @@
+{ config, lib, pkgs, ... }:
+
+let
+ pkg = pkgs.pulseaudioLight;
+ runDir = "/run/pulse";
+
+ alsaConf = pkgs.writeText "asound.conf" ''
+ ctl_type.pulse {
+ libs.native = ${pkgs.alsaPlugins}/lib/alsa-lib/libasound_module_ctl_pulse.so;
+ }
+ pcm_type.pulse {
+ libs.native = ${pkgs.alsaPlugins}/lib/alsa-lib/libasound_module_pcm_pulse.so;
+ }
+ ctl.!default {
+ type pulse
+ }
+ pcm.!default {
+ type pulse
+ }
+ '';
+
+ clientConf = pkgs.writeText "client.conf" ''
+ autospawn=no
+ default-server = unix:${runDir}/socket
+ '';
+
+ configFile = pkgs.writeText "default.pa" ''
+ .include ${pkg}/etc/pulse/default.pa
+ load-module ${toString [
+ "module-native-protocol-unix"
+ "auth-anonymous=1"
+ "socket=${runDir}/socket"
+ ]}
+ '';
+in
+
+{
+ systemd.tmpfiles.rules = [
+ "d ${runDir} 0750 pulse pulse - -"
+ "d ${runDir}/home 0700 pulse pulse - -"
+ ];
+
+ system.activationScripts.pulseaudio-hack = ''
+ ln -fns ${clientConf} /etc/pulse/client.conf
+ '';
+
+ environment = {
+ etc = {
+ "asound.conf".source = alsaConf;
+ #"pulse/client.conf" = lib.mkForce { source = clientConf; };
+ "pulse/default.pa".source = configFile;
+ };
+ systemPackages = [ pkg ];
+ };
+
+ # Allow PulseAudio to get realtime priority using rtkit.
+ security.rtkit.enable = true;
+
+ systemd.services.pulse = {
+ wantedBy = [ "sound.target" ];
+ before = [ "sound.target" ];
+ environment = {
+ PULSE_RUNTIME_PATH = "${runDir}/home";
+ #DISPLAY = ":${toString config.services.xserver.display}";
+ };
+ serviceConfig = {
+ ExecStart = "${pkg}/bin/pulseaudio";
+ User = "pulse";
+ };
+ };
+
+ users = let
+ id = 3768151709; # genid pulse
+ in {
+ groups.pulse.gid = id;
+ users.pulse = {
+ uid = id;
+ group = "pulse";
+ extraGroups = [ "audio" ];
+ home = "${runDir}/home";
+ };
+ };
+}
diff --git a/tv/2configs/xserver/default.nix b/tv/2configs/xserver/default.nix
index afc2d699c..f56da7dcc 100644
--- a/tv/2configs/xserver/default.nix
+++ b/tv/2configs/xserver/default.nix
@@ -101,6 +101,8 @@ let
#! ${pkgs.bash}/bin/bash
set -efu
export PATH; PATH=${makeSearchPath "bin" [
+ # TODO put paths into a Haskell module instead of PATH
+ pkgs.alsaUtils
pkgs.rxvt_unicode
]}:/var/setuid-wrappers
settle() {(
diff --git a/tv/5pkgs/xmonad-tv/Main.hs b/tv/5pkgs/xmonad-tv/Main.hs
index 2258b34a6..6482d9cc8 100644
--- a/tv/5pkgs/xmonad-tv/Main.hs
+++ b/tv/5pkgs/xmonad-tv/Main.hs
@@ -7,6 +7,7 @@
module Main where
import Control.Exception
+import Graphics.X11.ExtraTypes.XF86
import Text.Read (readEither)
import XMonad
import System.IO (hPutStrLn, stderr)
@@ -187,6 +188,9 @@ myKeys conf = Map.fromList $
--, (_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 })
+ , ((noModMask, xF86XK_AudioLowerVolume), spawn "amixer sset Master 5%-")
+ , ((noModMask, xF86XK_AudioRaiseVolume), spawn "amixer sset Master 5%+")
+ , ((noModMask, xF86XK_AudioMute), spawn "amixer sset Master toggle")
]
where
_4 = mod4Mask
diff --git a/tv/5pkgs/xmonad-tv/xmonad.cabal b/tv/5pkgs/xmonad-tv/xmonad.cabal
index 2246524fc..f9ea4dd7d 100644
--- a/tv/5pkgs/xmonad-tv/xmonad.cabal
+++ b/tv/5pkgs/xmonad-tv/xmonad.cabal
@@ -10,6 +10,7 @@ Executable xmonad
base,
containers,
unix,
+ X11,
xmonad,
xmonad-contrib,
xmonad-stockholm
[cgit] Unable to lock slot /tmp/cgit/b5000000.lock: No such file or directory (2)