The OS-parity batch from the vicinae plan, tasks 1 through 7. The audit came back better than the plan guessed: the calculator already links libqalculate, the built-in file index answers in under 100ms across all of home, quicklinks and snippets ship as built-in stores -- so zero new packages, and `vicinae dmenu` replaces the planned compiled extension outright. What was missing gets built: a power menu (lock, suspend, log out through uwsm, restart, power off), reminders as transient systemd timers with a pick-to-cancel list, a color picker over hyprpicker, and dmenu pick-lists for window switching, force quit, kill process, SSH hosts, and recent files -- all through one panama-pick helper. The launcher commands contract exercises the reminder parsing and every pick-list against stubs, including killing its own sacrificial sleep.
96 lines
3.6 KiB
Bash
Executable File
96 lines
3.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# Reminders without an app: transient user timers.
|
|
#
|
|
# panama-remind add "20m" "stand up" relative: 90s, 20m, 1h, 1h30m
|
|
# panama-remind add "9:30" "standup" clock time: today, or tomorrow if past
|
|
# panama-remind list one line per pending reminder
|
|
# panama-remind pick choose one in the launcher; cancel it
|
|
# panama-remind cancel <unit> cancel by unit name
|
|
#
|
|
# systemd-run carries the whole feature: the timer survives shell exit, fires
|
|
# notify-send inside the user session with its activation environment intact,
|
|
# and cleans itself up after firing. The message rides the unit Description so
|
|
# list can show it without a state file. Everything relative is converted to
|
|
# seconds first, so there is exactly one systemd-run form to get right.
|
|
|
|
set -euo pipefail
|
|
|
|
usage() {
|
|
echo 'usage: panama-remind add "<20m|1h30m|9:30>" "<text>" | list | pick | cancel <unit>' >&2
|
|
exit 2
|
|
}
|
|
|
|
seconds_until() {
|
|
local when="$1" total=0 rest num unit
|
|
if [[ "$when" =~ ^([0-9]{1,2}):([0-9]{2})$ ]]; then
|
|
local target now
|
|
target="$(date -d "$when" +%s 2>/dev/null)" || return 1
|
|
now="$(date +%s)"
|
|
(( target <= now )) && target=$(( target + 86400 ))
|
|
echo $(( target - now ))
|
|
return 0
|
|
fi
|
|
rest="$when"
|
|
[[ "$rest" =~ ^([0-9]+[smh])+$ ]] || return 1
|
|
while [[ "$rest" =~ ^([0-9]+)([smh])(.*)$ ]]; do
|
|
num="${BASH_REMATCH[1]}" unit="${BASH_REMATCH[2]}" rest="${BASH_REMATCH[3]}"
|
|
case "$unit" in
|
|
s) total=$(( total + num ));;
|
|
m) total=$(( total + num * 60 ));;
|
|
h) total=$(( total + num * 3600 ));;
|
|
esac
|
|
done
|
|
(( total > 0 )) || return 1
|
|
echo "$total"
|
|
}
|
|
|
|
cmd="${1:-}"
|
|
case "$cmd" in
|
|
add)
|
|
when="${2:-}" text="${3:-}"
|
|
[[ -n "$when" && -n "$text" ]] || usage
|
|
if ! secs="$(seconds_until "$when")"; then
|
|
notify-send "Reminder not set" "Could not read \"$when\" — try 20m, 1h30m, or 9:30" 2>/dev/null || true
|
|
echo "panama-remind: could not parse \"$when\"" >&2
|
|
exit 1
|
|
fi
|
|
unit="panama-remind-$(date +%s)-$RANDOM"
|
|
systemd-run --user --collect --unit="$unit" \
|
|
--description="$text" \
|
|
--on-active="${secs}s" --timer-property=AccuracySec=1s \
|
|
notify-send --urgency=critical --icon=alarm-symbolic "Reminder" "$text" \
|
|
>/dev/null
|
|
notify-send "Reminder set" "\"$text\" in $when" 2>/dev/null || true
|
|
;;
|
|
list)
|
|
# unit <TAB> when it fires <TAB> message, one per pending reminder.
|
|
# `next` is microseconds since the epoch.
|
|
systemctl --user list-timers 'panama-remind-*' --output=json 2>/dev/null \
|
|
| jq -r '.[] | [.unit, ((.next // 0) / 1000000 | floor)] | @tsv' \
|
|
| while IFS=$'\t' read -r unit next; do
|
|
desc="$(systemctl --user show "$unit" --property=Description --value 2>/dev/null)"
|
|
printf '%s\t%s\t%s\n' "$unit" "$(date -d "@$next" '+%H:%M:%S' 2>/dev/null)" "$desc"
|
|
done
|
|
;;
|
|
pick)
|
|
lines="$("$0" list)"
|
|
if [[ -z "$lines" ]]; then
|
|
notify-send "Reminders" "Nothing pending" 2>/dev/null || true
|
|
exit 0
|
|
fi
|
|
chosen="$(awk -F'\t' '{ printf "%s — %s\n", $3, $2 }' <<<"$lines" \
|
|
| vicinae dmenu --navigation-title "Cancel a reminder" \
|
|
--section-title 'Pending ({count})' --format index)" || exit 0
|
|
[[ -n "$chosen" ]] || exit 0
|
|
unit="$(sed -n "$(( chosen + 1 ))p" <<<"$lines" | cut -f1)"
|
|
[[ -n "$unit" ]] && "$0" cancel "$unit"
|
|
;;
|
|
cancel)
|
|
unit="${2:-}"; [[ -n "$unit" ]] || usage
|
|
systemctl --user stop "${unit%.timer}.timer" 2>/dev/null || true
|
|
notify-send "Reminder cancelled" 2>/dev/null || true
|
|
;;
|
|
*) usage;;
|
|
esac
|