timerd-rs
timerd-rs is a small Linux terminal timer. Its name combines timer with
the Unix convention of using a trailing d for a daemon. It installs the
simple command timer and supports both a stopwatch and a countdown. A
per-user background process owns timer state, so the foreground display can
detach and attach again without stopping the timer.
Install
Or install it from a local checkout:
The Cargo package is named timerd-rs; the installed executable is named
timer.
Start a timer
Run without arguments for an interactive choice between a stopwatch and a countdown:
Or start one directly:
A bare number is interpreted as seconds. Two-part clock input is MM:SS, and
three-part clock input is HH:MM:SS.
Add a note or start detached:
Foreground controls
While the compact foreground display is active:
| Key | Action |
|---|---|
Space |
Pause or resume |
d |
Detach while keeping the timer running |
Ctrl-B, then D |
tmux-style alias for detach |
x |
Stop the stopwatch or cancel the countdown |
Ctrl-C |
Same as x |
Attach again with the complete command or its short alias:
Without an ID, attach selects the most recently used detached timer. Only one foreground client may control a timer at a time.
Manage timers
Every frequent command has a readable name and a short alias:
When an ID is omitted, the daemon selects the most recently used compatible
timer. clear removes finished, stopped, and cancelled records.
Shell completions
Generate completion code with timer completions SHELL (the singular
completion spelling is also accepted). For Fish:
mkdir -p ~/.config/fish/completions
timer completions fish > ~/.config/fish/completions/timer.fish
For Bash:
For Zsh, generate _timer into a directory included in fpath:
fpath=(/.zfunc )
&&
Elvish and PowerShell are also supported. Generated completions cover commands, aliases, options, and shell names.
Countdown completion
For a detached countdown, the daemon keeps a write handle to the terminal that created it. If that terminal or SSH session is still open, completion appears there as ordinary terminal output:
[timer #3] ✓ countdown finished · stretch break
This does not depend on a desktop notification service, iTerm2 escape codes,
tmux, or screen. If the original terminal has closed, the write is allowed to
fail and the timer still becomes done. Its result remains visible in
timer list.
An asynchronous completion line can visually interrupt text currently being typed at the shell prompt. The typed input remains owned by the shell, but a prompt redraw may occasionally be necessary.
Files and process model
timer is a single crate and a single executable. On first use, that executable
starts itself in a hidden daemon mode. The CLI and foreground renderer talk to
it over a private Unix socket.
Runtime files follow the XDG directory conventions:
$XDG_RUNTIME_DIR/timer-rs/timer.sock
$XDG_STATE_HOME/timer-rs/state.json
$XDG_STATE_HOME/timer-rs/daemon.log
When the corresponding variables are unset, state is stored under
~/.local/state/timer-rs, and the socket uses a user-specific directory under
/tmp.
The daemon can be stopped explicitly:
Shutdown is refused while any timer is running or paused, because stopping the service would prevent timely completion messages.
Active task metadata is persisted, but a terminal write handle cannot survive a daemon restart. On systems configured to kill all user processes at logout, a future systemd user-service integration may be needed for timers that must survive a complete logout.