nixos-config/pkgs/q/default.nix
2020-01-02 11:52:08 +13:00

346 lines
10 KiB
Nix
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{ pkgs, lib
# tzselect is your frind do find timezones
, timeZones ? [ ], timeColor ? 9, timeZoneColor ? 10, calBackgroundColor ? 10
, calWeekColor ? 13, calDayColor ? 9, enableIntelBacklight ? true
, userHighlight ? [ "palo" ], enableBattery ? true, ... }:
let
hrule = "${pkgs.terminal-tools}/bin/hrule";
q-cal = let
# Maximum width of cal's output.
calwidth = 23;
# Number of space characters between two calendars.
hspace = 2;
# Return number of columns required to print n calenders side by side.
need_width = n: assert n >= 1; n * calwidth + (n - 1) * hspace;
lpad = n: c: s: if lib.stringLength s < n then lpad n c (c + s) else s;
pad = ''
{
${pkgs.gnused}/bin/sed '
# rtrim
s/ *$//
# delete last empty line
''${/^$/d}
' \
| ${pkgs.gawk}/bin/awk '{printf "%-${
toString calwidth
}s\n", $0}' \
| ${pkgs.gnused}/bin/sed "
# colorize header
1,2s/.*/[38;5;${toString calBackgroundColor}m&/
# highlight current week
s/^$(${pkgs.coreutils}/bin/date +%W)/[38;5;${
toString calWeekColor
}m&/
# colorize week number
s/^[ 1-9][0-9]/[38;5;${
toString calBackgroundColor
}m&/
"
}'';
in ''
cols=$(${pkgs.ncurses}/bin/tput cols)
${pkgs.coreutils}/bin/paste \
<(if test $cols -ge ${toString (need_width 3)}; then
${pkgs.utillinux}/bin/cal -mw \
$(${pkgs.coreutils}/bin/date +'%m %Y' -d 'last month') \
| ${pad}
fi) \
<(if test $cols -ge ${toString (need_width 1)}; then
${pkgs.utillinux}/bin/cal -mw \
| ${pkgs.gnused}/bin/sed '
# colorize day of month
s/\(^\| \)'"$(${pkgs.coreutils}/bin/date +%e)"'\>/[38;5;${
toString calDayColor
}m&/
' \
| ${pad}
fi) \
<(if test $cols -ge ${toString (need_width 2)}; then
${pkgs.utillinux}/bin/cal -mw \
$(${pkgs.coreutils}/bin/date +'%m %Y' -d 'next month') \
| ${pad}
fi) \
| ${pkgs.gnused}/bin/sed '
s/^\t//
s/\t$//
s/\t/${lpad hspace " " ""}/g
'
'';
q-timeZoneDate = size: zone:
let
dateString = comment:
"'+%Y-%m-%dT[;38;5;${
toString timeColor
}m%H:%M:%S[;38;5;${toString timeZoneColor}m%:z ${comment}' ";
timeZoneVariable = lib.optionalString (zone != null) "TZ=${zone}";
comment = lib.optionalString (zone != null)
" : ${lib.fixedWidthString size " " zone}";
# sh
in ''
${timeZoneVariable} ${pkgs.coreutils}/bin/date ${
dateString comment
} | ${pkgs.terminal-tools}/bin/center
'';
q-timeZoneDates = if timeZones == [ ] then
q-timeZoneDate 0 null
else
let size = lib.foldr lib.max 0 (map builtins.stringLength timeZones);
in lib.concatMapStringsSep "\n" (q-timeZoneDate size) timeZones;
q-intel_backlight = ''
cd /sys/class/backlight/intel_backlight
</dev/null exec ${pkgs.gawk}/bin/awk '
END {
getline actual_brightness < "actual_brightness"
getline max_brightness < "max_brightness"
getline brightness < "brightness"
printf "%20s %d%% %d/%d\n" \
, "intel_backlight" \
, actual_brightness / max_brightness * 100 \
, actual_brightness \
, max_brightness
}
'
'';
q-power_supply = let
power_supply = pkgs.writers.writeBash "power_supply" ''
set -efu
uevent=$1
eval "$(${pkgs.gnused}/bin/sed -n '
s/^\([A-Z_]\+=[0-9A-Za-z_-]*\)$/export \1/p
' $uevent)"
case $POWER_SUPPLY_NAME in
AC)
exit # not battery
;;
esac
exec </dev/null
exec ${pkgs.gawk}/bin/awk '
function die(s) {
printf "%20s %s\n", name, s
exit 1
}
function print_hm(h, m) {
m = (h - int(h)) * 60
return sprintf("%dh%dm", h, m)
}
function print_bar(bar_size, charge, full_bars, empty_bars, full_color) {
full_bars = int(charge * bar_size)
empty_bars = bar_size - full_bars
if (charge >= .42) full_color = "2"
else if (charge >= .23) full_color = "3"
else full_color = "1"
left_arrow = 1
middle_arrow = 1
right_arrow = 1
if (full_bars == 0) {
left_arrow = 0
middle_arrow = 0
}
if (empty_bars == 0) {
middle_arrow = 0
right_arrow = 0
}
empty_color = "0";
return sgr("38;5;" 8) sgr("48;5;" full_color) strdup("",left_arrow) strdup(" ", full_bars) sgr("48;5;" empty_color) sgr("38;5;" full_color) strdup("",middle_arrow) strdup(" ", empty_bars) sgr() sgr("38;5;" empty_color) strdup("",right_arrow) sgr()
}
function sgr(p) {
return "\x1b[" p "m"
}
function strdup(s,n,t) {
t = sprintf("%"n"s","")
gsub(/ /,s,t)
return t
}
END {
name = ENVIRON["POWER_SUPPLY_NAME"]
charge_unit = "Ah"
charge_now = ENVIRON["POWER_SUPPLY_CHARGE_NOW"] / 10^6
charge_full = ENVIRON["POWER_SUPPLY_CHARGE_FULL"] / 10^6
current_unit = "A"
current_now = ENVIRON["POWER_SUPPLY_CURRENT_NOW"] / 10^6
energy_unit = "Wh"
energy_now = ENVIRON["POWER_SUPPLY_ENERGY_NOW"] / 10^6
energy_full = ENVIRON["POWER_SUPPLY_ENERGY_FULL"] / 10^6
power_unit = "W"
power_now = ENVIRON["POWER_SUPPLY_POWER_NOW"] / 10^6
voltage_unit = "V"
voltage_now = ENVIRON["POWER_SUPPLY_VOLTAGE_NOW"] / 10^6
voltage_min_design = ENVIRON["POWER_SUPPLY_VOLTAGE_MIN_DESIGN"] / 10^6
#printf "charge_now: %s\n", charge_now
#printf "charge_full: %s\n", charge_full
#printf "current_now: %s\n", current_now
#printf "energy_now: %s\n", energy_now
#printf "energy_full: %s\n", energy_full
#printf "energy_full: %s\n", ENVIRON["POWER_SUPPLY_ENERGY_FULL"]
#printf "energy_full: %s\n", ENVIRON["POWER_SUPPLY_ENERGY_FULL"] / 10^6
#printf "power_now: %s\n", power_now
#printf "voltage_now: %s\n", voltage_now
if (current_now == 0 && voltage_now != 0) {
current_now = power_now / voltage_now
}
if (power_now == 0) {
power_now = current_now * voltage_now
}
if (charge_now == 0 && voltage_min_design != 0) {
charge_now = energy_now / voltage_min_design
}
if (energy_now == 0) {
energy_now = charge_now * voltage_min_design
}
if (charge_full == 0 && voltage_min_design != 0) {
charge_full = energy_full / voltage_min_design
}
if (energy_full == 0) {
energy_full = charge_full * voltage_min_design
}
if (charge_now == 0 || charge_full == 0) {
die("unknown charge")
}
charge_ratio = charge_now / charge_full
out = out sprintf("%20s ", name)
out = out sprintf(" %s", print_bar(10, charge_ratio))
out = out sprintf(" %d%", charge_ratio * 100)
out = out sprintf(" %.2f%s", charge_now, charge_unit)
if (current_now != 0) {
out = out sprintf("/%.1f%s", current_now, current_unit)
}
out = out sprintf(" %d%s", energy_full, energy_unit)
if (power_now != 0) {
out = out sprintf("/%.1f%s", power_now, power_unit)
}
if (current_now != 0) {
out = out sprintf(" %s", print_hm(charge_now / current_now))
}
print out
}
'
'';
in ''
for uevent in /sys/class/power_supply/*/uevent; do
${power_supply} "$uevent" || :
done
'';
q-virtualization = ''
printf '%20s %s\n' "VT" \
$(${pkgs.systemd}/bin/systemd-detect-virt)
'';
q-wireless = ''
for dev in $(
${pkgs.iw}/bin/iw dev \
| ${pkgs.gnused}/bin/sed -n 's/^\s*Interface\s\+\([0-9a-z]\+\)$/\1/p'
); do
inet=$(${pkgs.iproute}/bin/ip addr show $dev \
| ${pkgs.gnused}/bin/sed -n '
s/.*inet \([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\).*/\1/p
') \
|| unset inet
ssid=$(${pkgs.iw}/bin/iw dev $dev link \
| ${pkgs.gnused}/bin/sed -n '
s/.*\tSSID: \(.*\)/\1/p
') \
|| unset ssid
printf '%20s %s %s\n' $dev ''${inet+ $inet} ''${ssid+ $ssid}
done
'';
q-online = ''
if ${pkgs.curl}/bin/curl -s google.com >/dev/null; then
echo ' status online'
else
echo ' status offline '
fi
'';
q-thermal_zone = ''
for i in /sys/class/thermal/thermal_zone*; do
type=$(${pkgs.coreutils}/bin/cat $i/type)
temp=$(${pkgs.coreutils}/bin/cat $i/temp)
printf '%20s %s°C\n' $type $(echo $temp / 1000 | ${pkgs.bc}/bin/bc)
done
'';
q-show-users = ''
${pkgs.procps}/bin/ps -eo user \
| ${pkgs.gnused}/bin/sed '1 d' \
| ${pkgs.coreutils}/bin/sort \
| ${pkgs.coreutils}/bin/uniq \
| ${pkgs.gnugrep}/bin/egrep --color=always '(${
lib.concatStringsSep "|" userHighlight
})|$' \
| ${pkgs.utillinux}/bin/column
'';
q-task-checklist = ''
${pkgs.taskwarrior}/bin/task export +checklist status:pending +READY | \
${pkgs.jq}/bin/jq \
--raw-output '
sort_by(.description) | reverse |
.[] |
"[ \( .id ) ] \( .description )"
'
'';
q-task-active = ''
${pkgs.taskwarrior}/bin/task export \
+ACTIVE status:pending \
| ${pkgs.jq}/bin/jq --raw-output '.[] | " \(.id) \(.description)"'
'';
# bash needed for <(...)
in pkgs.writers.writeBashBin "q" ''
set -eu
export PATH=/var/empty
${hrule}
${q-cal}
${hrule}
${q-timeZoneDates}
${hrule}
${lib.optionalString enableIntelBacklight "(${q-intel_backlight}) &"}
${lib.optionalString enableBattery "(${q-power_supply}) &"}
(${q-virtualization}) &
(${q-wireless}) &
(${q-online}) &
(${q-thermal_zone}) & wait
${hrule}
${q-task-active}
${hrule}
${q-task-checklist}
${hrule}
${q-show-users}
''