aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md11
-rwxr-xr-xhooks/on_done43
-rwxr-xr-xhooks/on_quit36
-rwxr-xr-xhooks/on_start52
-rw-r--r--timer.134
5 files changed, 120 insertions, 56 deletions
diff --git a/README.md b/README.md
index c85527c..e865c82 100644
--- a/README.md
+++ b/README.md
@@ -56,10 +56,13 @@ arguments: mode (`countdown`/`stopwatch`), seconds, and the `-c`
comment. Dropping in an executable file is the only thing needed to
enable one.
-Three commented examples ship in `hooks/` and are installed to
-`$(PREFIX)/share/doc/ttym/hooks/` -- terminal title, desktop
-notification plus sound on completion, and a TSV record of abandoned
-sessions:
+The three are independent -- installing only `on_quit` is a normal
+setup. Three commented examples ship in `hooks/` and are installed to
+`$(PREFIX)/share/doc/ttym/hooks/`. They record intent against outcome
+(the duration you asked for is visible only to `on_start`, so the log
+behind `timer -r` cannot show whether a session was cut short), and
+run a focus mode that pauses dunst notifications and music during a
+countdown. A commented timewarrior bridge is included:
mkdir -p ~/.config/ttym/hooks
cp /usr/local/share/doc/ttym/hooks/on_done ~/.config/ttym/hooks/
diff --git a/hooks/on_done b/hooks/on_done
index 955cd13..cfe57f2 100755
--- a/hooks/on_done
+++ b/hooks/on_done
@@ -1,31 +1,36 @@
#!/bin/sh
# ttym on_done -- runs when a countdown reaches zero.
#
-# $1 mode always "countdown" (a stopwatch never completes)
+# $1 mode always "countdown" -- a stopwatch never completes
# $2 seconds the full duration that elapsed
# $3 comment the -c text, or an empty string
#
-# timer waits for this to exit before ringing the bell and entering the
-# alert loop, so background anything slow.
+# Nothing here duplicates the notify patch: if your build has it, the
+# desktop notification and sound have already fired by the time this
+# runs. Use this for what the binary does not do.
+#
+# timer waits for this before the completion bell and the alert loop, so
+# background anything slow with &.
-seconds=$2 comment=$3
-mins=$((seconds / 60))
+mode=$1 seconds=$2 comment=$3
-# Desktop notification. Gives the base build what the notify patch adds.
-if command -v notify-send > /dev/null 2>&1; then
- notify-send -u critical "Timer" "${mins}m done${comment:+ -- $comment}" &
+# --- session record ------------------------------------------------------
+state=${XDG_STATE_HOME:-$HOME/.local/state}/ttym
+if mkdir -p "$state" 2>/dev/null; then
+ printf '%s\tDONE\t%s\t%s\t%s\n' \
+ "$(date +%Y-%m-%dT%H:%M:%S)" "$mode" "$seconds" "$comment" \
+ >> "$state/sessions.tsv"
fi
-# A sound, first player that exists wins. Backgrounded so it never blocks.
-for player in paplay aplay mpv ffplay; do
- if command -v "$player" > /dev/null 2>&1; then
- sound=/usr/share/sounds/freedesktop/stereo/complete.oga
- [ -r "$sound" ] && "$player" "$sound" > /dev/null 2>&1 &
- break
- fi
-done
+# --- leave focus mode ----------------------------------------------------
+# Note the ordering: the notify patch emits its completion popup *before*
+# this hook runs, so with dunst paused that popup is queued and appears
+# the moment the next line unpauses. Delayed, not lost.
+command -v dunstctl > /dev/null 2>&1 && dunstctl set-paused false
+command -v playerctl > /dev/null 2>&1 && playerctl play 2>/dev/null
+command -v mpc > /dev/null 2>&1 && mpc -q play 2>/dev/null
-# Push to your phone (uncomment and set your topic):
-# curl -fsS -d "${mins}m done${comment:+ -- $comment}" ntfy.sh/your-topic &
+# --- timewarrior ---------------------------------------------------------
+# command -v timew > /dev/null 2>&1 && timew stop > /dev/null 2>&1
-wait
+exit 0
diff --git a/hooks/on_quit b/hooks/on_quit
index 44957e8..f89f6cf 100755
--- a/hooks/on_quit
+++ b/hooks/on_quit
@@ -7,22 +7,30 @@
# $2 seconds time actually elapsed, excluding time spent paused
# $3 comment the -c text, or an empty string
#
-# A countdown abandoned after two seconds reports 2, not the duration
-# you asked for. That is what makes this useful for tracking follow-
-# through rather than intent.
+# $2 is what really ran, not what you asked for: a 25m countdown
+# abandoned after four minutes reports 240. Compare against the START
+# line written by on_start to see follow-through.
+#
+# If your build has the logging patch, `timer -r` already records this
+# session -- it logs every run, completed or not. What it cannot show is
+# that the run was cut short, which is what the record below adds.
mode=$1 seconds=$2 comment=$3
-log=${XDG_STATE_HOME:-$HOME/.local/state}/ttym
-mkdir -p "$log" 2>/dev/null || exit 0
+# --- session record ------------------------------------------------------
+state=${XDG_STATE_HOME:-$HOME/.local/state}/ttym
+if mkdir -p "$state" 2>/dev/null; then
+ printf '%s\tQUIT\t%s\t%s\t%s\n' \
+ "$(date +%Y-%m-%dT%H:%M:%S)" "$mode" "$seconds" "$comment" \
+ >> "$state/sessions.tsv"
+fi
+
+# --- leave focus mode ----------------------------------------------------
+command -v dunstctl > /dev/null 2>&1 && dunstctl set-paused false
+[ "$mode" = countdown ] && command -v playerctl > /dev/null 2>&1 && playerctl play 2>/dev/null
+[ "$mode" = countdown ] && command -v mpc > /dev/null 2>&1 && mpc -q play 2>/dev/null
-printf '%s\t%s\t%s\t%s\n' \
- "$(date +%Y-%m-%dT%H:%M:%S)" "$mode" "$seconds" "$comment" \
- >> "$log/abandoned.tsv"
+# --- timewarrior ---------------------------------------------------------
+# command -v timew > /dev/null 2>&1 && timew stop > /dev/null 2>&1
-# Restore the terminal title set by on_start.
-case $TERM in
-xterm*|rxvt*|tmux*|screen*|alacritty|foot*)
- printf '\033]0;%s\007' "${SHELL##*/}" > /dev/tty
- ;;
-esac
+exit 0
diff --git a/hooks/on_start b/hooks/on_start
index 441d6f1..fa38f7c 100755
--- a/hooks/on_start
+++ b/hooks/on_start
@@ -2,25 +2,45 @@
# ttym on_start -- runs when a session begins.
#
# $1 mode countdown | stopwatch
-# $2 seconds requested duration for a countdown, 0 for a stopwatch
+# $2 seconds requested duration of a countdown, 0 for a stopwatch
# $3 comment the -c text, or an empty string
#
-# stdin, stdout and stderr are /dev/null: printing here goes nowhere and
-# cannot corrupt the redrawn progress line. timer waits for this to exit,
-# so keep it quick or background the slow part with &.
+# Each hook works on its own: install only the ones you want. A hook that
+# is missing or not executable is skipped silently.
+#
+# timer waits for this to exit, so keep it quick. stdout and stderr go to
+# /dev/null -- printing here goes nowhere and cannot corrupt the progress
+# line. To debug, run the hook by hand:
+#
+# ~/.config/ttym/hooks/on_start countdown 1500 "+work"
mode=$1 seconds=$2 comment=$3
-# Name the terminal window after what is running.
-case $TERM in
-xterm*|rxvt*|tmux*|screen*|alacritty|foot*)
- if [ "$mode" = countdown ]; then
- printf '\033]0;timer %sm %s\007' "$((seconds / 60))" "$comment" > /dev/tty
- else
- printf '\033]0;stopwatch %s\007' "$comment" > /dev/tty
- fi
- ;;
-esac
+# --- session record ------------------------------------------------------
+# The log behind `timer -r` stores elapsed seconds only. It cannot tell a
+# finished 25m from an abandoned 30m that ran 25m, because the duration
+# you *asked for* is visible here and nowhere else. Pair this with the
+# matching lines in on_done and on_quit to get intent versus outcome.
+state=${XDG_STATE_HOME:-$HOME/.local/state}/ttym
+if mkdir -p "$state" 2>/dev/null; then
+ printf '%s\tSTART\t%s\t%s\t%s\n' \
+ "$(date +%Y-%m-%dT%H:%M:%S)" "$mode" "$seconds" "$comment" \
+ >> "$state/sessions.tsv"
+fi
+
+# --- focus mode ----------------------------------------------------------
+# Countdowns only: a stopwatch has no end, and silencing notifications
+# indefinitely is not what you want. If the process is killed with -9
+# nothing restores these; recover with `dunstctl set-paused false`.
+if [ "$mode" = countdown ]; then
+ command -v dunstctl > /dev/null 2>&1 && dunstctl set-paused true
+ command -v playerctl > /dev/null 2>&1 && playerctl pause 2>/dev/null
+ command -v mpc > /dev/null 2>&1 && mpc -q pause 2>/dev/null
+fi
+
+# --- timewarrior ---------------------------------------------------------
+# Turns -c comments into timew tags, so `timew summary :week +work` covers
+# timer sessions alongside everything else you track. Uncomment to use.
+# command -v timew > /dev/null 2>&1 && timew start ${comment:-timer} > /dev/null 2>&1
-# Pause music while a countdown runs (uncomment to use):
-# [ "$mode" = countdown ] && playerctl pause 2>/dev/null
+exit 0
diff --git a/timer.1 b/timer.1
index e3fe0bc..e7850f9 100644
--- a/timer.1
+++ b/timer.1
@@ -256,6 +256,9 @@ or when a stopwatch is stopped.
.PP
A hook is any executable file at that name; there is nothing to enable.
A file that is missing or not marked executable is skipped silently.
+The three are independent: installing only
+.BR on_quit ,
+for instance, is a complete and normal setup.
.SS Arguments
Each hook is run with exactly three positional arguments.
.TP
@@ -316,9 +319,34 @@ line like any other.
Three commented, working examples ship with the source and are installed
to
.IR PREFIX/share/doc/ttym/hooks/ .
-They set the terminal title, send a desktop notification and play a
-sound on completion, and record abandoned sessions to a TSV file. Copy
-the ones you want and edit:
+They form one coherent set but each works alone. Together they do two
+things the binary cannot:
+.IP \(bu 2
+Record intent against outcome. The session log behind
+.B timer \-r
+stores elapsed seconds only, so a finished 25m and an abandoned 30m that
+ran 25m look identical in it. The duration you asked for is visible to
+.B on_start
+and nowhere else, so the examples write a START/DONE/QUIT record to
+.I $XDG_STATE_HOME/ttym/sessions.tsv
+that shows follow\-through.
+.IP \(bu 2
+Focus mode. During a countdown they pause
+.BR dunst (1)
+notifications and any
+.BR playerctl (1)
+or
+.BR mpc (1)
+playback, and restore both when it ends. Every external command is
+guarded, so the examples are harmless on a machine without them.
+.PP
+A commented
+.BR timew (1)
+bridge is included but off by default; it turns
+.B \-c
+comments into timewarrior tags.
+.PP
+Copy the ones you want and edit:
.PP
.RS
.nf