diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-25 19:02:35 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-25 19:02:35 +0200 |
| commit | 8f99f1650e4a7363af1d83190b4082fb72a9f73f (patch) | |
| tree | 86ed3b714c376e95f98d33d7572e76d6b43f06d3 /timer.1 | |
| parent | 2f6b29abd0d766ef477eb29c5a7bf6c1e88e9630 (diff) | |
| download | ttym-8f99f1650e4a7363af1d83190b4082fb72a9f73f.tar.gz ttym-8f99f1650e4a7363af1d83190b4082fb72a9f73f.zip | |
ttym 3.0: fix terminal and config bugs, fold terminal-only patches into base
Correctness fixes:
- restore the terminal on SIGQUIT and SIGHUP. atexit never runs on an
uncaught fatal signal, so Ctrl+\ left the cursor hidden and autowrap
disabled.
- drop the unconditional newline in restore_tty. Every run emitted a
stray blank line, including piped output.
- treat EINTR as an interruption rather than a poll() failure, which
delayed Ctrl+C by up to one 100ms frame.
config-file patch:
- make comment stripping quote-aware so a value may contain '#', and
strip one matched pair of quotes. bar_fill = "#" was silently dropped,
despite '#' being the glyph of the hash style this build ships.
- resolve bar_fill/bar_empty inside resolve_bar and clear them on --bar,
so command-line flags beat the config file as documented. Previously
config glyphs silently overrode --bar.
- report unknown keys, unparseable booleans and malformed lines on
stderr. flash = enabled silently meant off.
- never write to disk. --dump-config prints a commented template on
stdout instead of the binary creating ~/.config/ttym/config on first
run.
Patch set:
- fold persist-alert, flash and bar-styles into the base. The base is
now terminal-only: it opens /dev/tty, draws and exits, with no file
writes and no subprocesses. Everything still in patches/ changes what
the program touches.
- seven patches become four; config-file's prerequisites drop from six
patches to one (notify), so it is regenerable mechanically.
- regenerate every patch. All apply with zero fuzz and compile.
Source:
- rewrite argv in place rather than into a malloc'd copy (C99
5.1.2.2.1), removing die(), four free() calls and <stdarg.h>.
- fold the duplicated elapsed-time expression into elapsed().
- drop dead code: have_any, (void)cfg, and an unreachable branch in
parse_duration.
- replace hand-counted padding with \033[K.
Docs and build:
- timer.1: -c is the third hook argument, not the fourth. Add EXIT
STATUS (a stopwatch always exits 130 -- it has no natural end) and
ENVIRONMENT. Document config precedence and quoting.
- wire VERSION into a dist target; it was defined and never used.
- track .gitignore, which previously ignored itself, so a fresh clone
had no ignore rules.
Claude-Session: https://claude.ai/code/session_01APLBs8RB1FcUaC4viVkzbP
Diffstat (limited to 'timer.1')
| -rw-r--r-- | timer.1 | 153 |
1 files changed, 116 insertions, 37 deletions
@@ -1,9 +1,25 @@ -.TH TIMER 1 "ttym 2.0" +.TH TIMER 1 "ttym 3.0" .SH NAME timer \- terminal countdown and stopwatch .SH SYNOPSIS .B timer .RB [ \-qs ] +.RB [ \-\-no\-persist ] +.RB [ \-\-flash +.BR on | off ] +.RB [ \-\-bar +.IR style ] +.RB [ \-\- ] +.RI [ duration ] +.PP +The remaining forms exist only when the corresponding patch is applied; +each is annotated +.RI [patch: name ] +under +.BR OPTIONS . +.PP +.B timer +.RB [ \-qs ] .RB [ \-c .IR text ] .RB [ \-\-no\-persist ] @@ -11,6 +27,7 @@ timer \- terminal countdown and stopwatch .BR on | off ] .RB [ \-\-bar .IR style ] +.RB [ \-\-dump\-config ] .RB [ \-\- ] .RI [ duration ] .RI [ message @@ -32,9 +49,11 @@ The progress bar, current elapsed time and time remaining are redrawn on the same line ten times per second. .PP The binary is intentionally small and modular. -Beyond the base build (countdown, stopwatch, ASCII progress bar, -pause/resume, one\-shot terminal bell on completion) every feature is -an optional patch under +The base build is terminal\-only: countdown, stopwatch, pause/resume, +the progress bar and its eight styles, and the alert\-until\-keypress +loop with its optional terminal flash. It writes no files and spawns no +processes. Every feature that touches the filesystem, runs a subprocess +or depends on an external binary is an optional patch under .IR patches/ . Each section below describing a non\-base feature is annotated with .RI [patch: name ]; @@ -46,8 +65,11 @@ always reflects the actual build. .SS Base .TP .B \-q -Suppress the one\-shot completion bell. -Persistent alert loops, if enabled by a patch, still ring the bell. +Suppress the one\-shot completion bell. With the +.B notify +patch it also suppresses the completion sound, though not the desktop +notification. Persistent alert loops, if enabled by a patch, still ring +the bell. .TP .B \-s Silent. No bell, no notification, no alert loop. @@ -60,36 +82,22 @@ Print usage and exit. Reflects the actual build. End of options. Subsequent arguments are treated as positional even if they begin with .BR \- . -.SS Optional, added by patches -.TP -.BR \-c \ \fItext\fR -.RI [patch: logging, -.RI hooks] -Comment associated with this session. With the -.B logging -patch, it is written as the third TSV field and any -.BI + tag -tokens within it are picked up by -.BR "timer \-\-stats" . -With the -.B hooks -patch, it is passed as the fourth argument to each hook script. .TP .B \-\-no\-persist -.RI [patch: persist\-alert] Skip the alert\-until\-keypress loop. .B timer -emits one bell and one notification, then exits. +emits one bell, then exits. .TP .BR \-\-flash \ \fBon\fR | \fBoff\fR -.RI [patch: flash] Toggle the reverse\-video terminal flash that runs during the persistent alert loop. Accepts .BR on / off / true / false / 1 / 0 / yes / no . -Default is build\-dependent. +Default is +.B FLASH +in +.IR config.h . .TP .BR \-\-bar \ \fIstyle\fR -.RI [patch: bar\-styles] Progress bar style. One of .BR unicode , .BR ascii , @@ -99,12 +107,40 @@ Progress bar style. One of .BR block , .BR arrow , .BR minimal . -With no patch applied the bar uses the compile\-time +Unset (the default) auto\-detects: unicode on a UTF\-8 locale, +otherwise ascii. The .B BAR_FILL and .B BAR_EMPTY -glyphs from -.IR config.h . +glyphs in +.I config.h +are the fallback when no style matches. +.SS Optional, added by patches +.TP +.BR \-c \ \fItext\fR +.RI [patch: logging, +.RI hooks] +Comment associated with this session. With the +.B logging +patch, it is written as the third TSV field and any +.BI + tag +tokens within it are picked up by +.BR "timer \-\-stats" . +With the +.B hooks +patch, it is passed as the third argument to each hook script. +.TP +.B \-\-dump\-config +.RI [patch: config\-file] +Print a commented configuration template on stdout and exit. +.B timer +never creates the file itself: +.PP +.RS +.nf +timer \-\-dump\-config > ~/.config/ttym/config +.fi +.RE .SH SUBCOMMANDS .SS timer \-r [\-n N] [\-\-raw] .RI [patch: logging] @@ -178,7 +214,6 @@ Quit immediately. Logs the partial session if logging is enabled. Same as .BR q . .SH ALERT LOOP -.RI [patch: persist\-alert] When a countdown reaches zero, instead of emitting one bell and exiting, the program rings the bell every \(ti1.5 s and polls for a keypress. Any key acknowledges and exits. @@ -191,12 +226,14 @@ Background jobs .IR ... \ &) get one bell and exit normally, leaving the shell quiet. .PP -If the -.B flash -patch is also applied, each beat of the loop briefly inverts the -terminal colours (reverse\-video). The flash can be suppressed without -disabling the loop via -.BR "\-\-flash off" . +Each beat of the loop briefly inverts the terminal colours +(reverse\-video). The flash can be suppressed without disabling the +loop via +.BR "\-\-flash off" , +or permanently via +.B FLASH +in +.IR config.h . .SH HOOKS .RI [patch: hooks] On state transitions @@ -228,12 +265,54 @@ or the others come from the running session. Hooks must be marked executable. Standard streams are redirected to .IR /dev/null . +.SH EXIT STATUS +.TP +.B 0 +A countdown ran to completion. +.TP +.B 1 +Usage error: an unknown option, or a duration that could not be parsed. +.TP +.B 130 +The session was cut short, either by +.B q +or by +.BR SIGINT , +.BR SIGTERM , +.BR SIGQUIT +or +.BR SIGHUP . +The terminal is restored in every case. +A stopwatch always exits this way \(em it has no natural end. +.SH ENVIRONMENT +.TP +.B XDG_CONFIG_HOME +Base directory for the files below. Defaults to +.I ~/.config +when unset or empty. .SH FILES .TP +.I /etc/ttym.conf +.RI [patch: config\-file] +System\-wide runtime configuration, read before the per\-user file. +.TP .I ~/.config/ttym/config .RI [patch: config\-file] -Runtime configuration. Auto\-generated on first run with all keys -commented out. +Per\-user runtime configuration; +.BR key " = " value +lines. A +.B # +begins a comment at the start of a line or after whitespace, and never +inside quotes; quote a value to protect surrounding spaces or a leading +.BR # . +Unknown keys and unparseable values are reported on stderr. +Command\-line flags override this file, which overrides +.IR /etc/ttym.conf , +which overrides the compile\-time defaults in +.IR config.h . +.B timer +never creates this file \(em see +.BR \-\-dump\-config . .TP .I ~/.config/ttym/ttym.log .RI [patch: logging] |
