{ pkgs, lib # tzselect is your frind do find timezones , timeZones ? [ ], timeColor ? 9, timeZoneColor ? 10, calBackgroundColor ? 10 , calWeekColor ? 13, calDayColor ? 9, enableIntelBacklight ? true , 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 = .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 aux \ | ${pkgs.gawk}/bin/awk '{ print $1 }' \ | ${pkgs.gnused}/bin/sed '1 d' \ | ${pkgs.coreutils}/bin/sort \ | ${pkgs.coreutils}/bin/uniq \ | ${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} ''