made with this prompt:
pomodomo timer, solarized dark theme, programmable queue, native, raylib in odin, data model is pairs of ints and strings, config format is endline sperated optional string with a command "repeat(N){"
then 10-ish one liner complaints
A native, single-window Pomodoro timer with a Solarized Dark theme and a programmable queue file.
- Odin compiler (ships with
vendor:raylibbindings and prebuilt raylib libs for Windows/macOS/Linux) - No other dependencies — raylib is vendored with the Odin distribution.
odin build . -out:pomodoro
./pomodoro # uses queue.txt in the current directory
./pomodoro path/to/other.txtOn Linux you may need raylib's system dependencies (X11/Wayland, OpenGL, ALSA) installed — see the raylib wiki for your distro if the build fails to link.
odin build . -out:pomodoro
cp pomodoro ~/bin/
cp pomodoro.desktop ~/.local/share/applications/
update-desktop-database ~/.local/share/applications/When launched from the application menu the working directory is $HOME,
so the timer will look for ~/queue.txt. Either place your queue file
there or edit the Exec line in pomodoro.desktop to pass an explicit
path, e.g.:
Exec=/home/monkyyy/bin/pomodoro /path/to/your/queue.txt
| Key | Action |
|---|---|
SPACE |
Pause / resume |
N |
Skip to next queue item |
R |
Restart the current item |
Shift+R |
Reload config from disk |
UP / DOWN |
Scroll the "up next" list |
ESC |
Quit |
Each non-blank, non-comment line is one queue item:
<minutes> <optional label>
minutesis a required integer.- Everything after the first space is the (optional) label, shown as the session name. If omitted, "Pomodoro" is displayed.
- Lines starting with
#are comments.
Blocks can be repeated with repeat(N){ ... }, and repeat blocks can be
nested:
5 Warm Up
repeat(4){
25 Focus
5 Short Break
}
25 Focus
15 Long Break
This expands to: Warm Up, then (Focus, Short Break) × 4, then Focus, then Long Break — 10 items in total, in that order.
Sessions whose label contains "break" or "rest" (case-insensitive) are drawn in Solarized cyan; everything else uses Solarized yellow. The final item turns green once the whole queue is complete.
Internally the parsed queue is just a list of pairs:
Queue_Item :: struct {
minutes: int,
label: string,
}The config parser (parse_lines in main.odin) is a small recursive-descent
parser: it reads lines sequentially, and when it hits a repeat(N){ line it
recurses to collect the inner block, then appends that block to the output
N times before continuing.