From 440d1a15ba6e8bd4dce65b5d6b87c30ee112cc76 Mon Sep 17 00:00:00 2001 From: jk <47693+sectore@users.noreply.github.com> Date: Wed, 17 Jun 2026 11:57:47 +0200 Subject: [PATCH 1/4] feat(pomodoro): ^up/^down keybindings to in/decrease max rounds Co-Authored-By: Claude Sonnet 4.6 --- src/widgets/footer.rs | 8 +++++ src/widgets/pomodoro.rs | 30 +++++++++++++++++++ ...r_test__menu_pomodoro_auto_switch_off.snap | 2 +- ...er_test__menu_pomodoro_auto_switch_on.snap | 2 +- 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/widgets/footer.rs b/src/widgets/footer.rs index 838994b..e9662d2 100644 --- a/src/widgets/footer.rs +++ b/src/widgets/footer.rs @@ -346,6 +346,14 @@ impl StatefulWidget for Footer { Span::styled(symbol_down, BOLD), Span::from(SPACE), Span::styled("previous round", ITALIC), + Span::from(WIDE_SPACE), + Span::styled(format!("^{}", symbol_up), BOLD), + Span::from(SPACE), + Span::styled("max rounds up", ITALIC), + Span::from(WIDE_SPACE), + Span::styled(format!("^{}", symbol_down), BOLD), + Span::from(SPACE), + Span::styled("max rounds down", ITALIC), ]); } spans diff --git a/src/widgets/pomodoro.rs b/src/widgets/pomodoro.rs index 44e34e1..9532b69 100644 --- a/src/widgets/pomodoro.rs +++ b/src/widgets/pomodoro.rs @@ -243,6 +243,19 @@ impl PomodoroState { self.clock_map.pause.with_decis = with_decis; } + pub fn increase_max_rounds(&mut self) { + self.max_rounds = Some(self.max_rounds.map_or(1, |n| n + 1)); + self.update_clock_names(); + } + + pub fn decrease_max_rounds(&mut self) { + self.max_rounds = self.max_rounds.and_then(|n| (n > 1).then_some(n - 1)); + if let Some(max) = self.max_rounds { + self.round = self.round.min(max); + } + self.update_clock_names(); + } + fn next_round(&mut self) { if !self.is_last_round() { // increase round before (!!) updating the clock @@ -402,6 +415,23 @@ impl TuiEventHandler for PomodoroState { { self.switch_mode(); } + // increase/decrease max rounds + KeyCode::Up if key.modifiers.contains(KeyModifiers::CONTROL) => { + self.increase_max_rounds(); + } + KeyCode::Char('k') + if key.modifiers.contains(KeyModifiers::CONTROL) && self.vim_motions => + { + self.increase_max_rounds(); + } + KeyCode::Down if key.modifiers.contains(KeyModifiers::CONTROL) => { + self.decrease_max_rounds(); + } + KeyCode::Char('j') + if key.modifiers.contains(KeyModifiers::CONTROL) && self.vim_motions => + { + self.decrease_max_rounds(); + } // next round KeyCode::Up => self.next_round(), KeyCode::Char('k') if self.vim_motions => { diff --git a/src/widgets/snapshots/timr_tui__widgets__footer_test__menu_pomodoro_auto_switch_off.snap b/src/widgets/snapshots/timr_tui__widgets__footer_test__menu_pomodoro_auto_switch_off.snap index e0f0579..45529aa 100644 --- a/src/widgets/snapshots/timr_tui__widgets__footer_test__menu_pomodoro_auto_switch_off.snap +++ b/src/widgets/snapshots/timr_tui__widgets__footer_test__menu_pomodoro_auto_switch_off.snap @@ -6,5 +6,5 @@ expression: t.backend() " screens 1 countdown 2 timer 3 pomodoro 4 event 5 local time ← or → switch screens " " appearance , change style . toggle deciseconds : toggle local time " " controls space start e edit r reset clock ^r reset clocks/rounds a enable auto switch " -" ^← or ^→ switch work/pause ↑ next round ↓ previous round " +" ^← or ^→ switch work/pause ↑ next round ↓ previous round ^↑ max rounds up ^↓ max rounds down " " " diff --git a/src/widgets/snapshots/timr_tui__widgets__footer_test__menu_pomodoro_auto_switch_on.snap b/src/widgets/snapshots/timr_tui__widgets__footer_test__menu_pomodoro_auto_switch_on.snap index 7815d67..7947b17 100644 --- a/src/widgets/snapshots/timr_tui__widgets__footer_test__menu_pomodoro_auto_switch_on.snap +++ b/src/widgets/snapshots/timr_tui__widgets__footer_test__menu_pomodoro_auto_switch_on.snap @@ -6,5 +6,5 @@ expression: t.backend() " screens 1 countdown 2 timer 3 pomodoro 4 event 5 local time ← or → switch screens " " appearance , change style . toggle deciseconds : toggle local time " " controls space start e edit r reset clock ^r reset clocks/rounds a disable auto switch " -" ^← or ^→ switch work/pause ↑ next round ↓ previous round " +" ^← or ^→ switch work/pause ↑ next round ↓ previous round ^↑ max rounds up ^↓ max rounds down " " " From 865c6f6926753ca0143fe047249a8e7050e4defe Mon Sep 17 00:00:00 2001 From: jk <47693+sectore@users.noreply.github.com> Date: Wed, 17 Jun 2026 12:09:20 +0200 Subject: [PATCH 2/4] refactor(pomodoro): simplify round labels and fix area width - drop LAST prefix from labels and notifications - clamp round when max_rounds changes - fix label_round not included in area width calc Co-Authored-By: Claude Sonnet 4.6 --- src/widgets/pomodoro.rs | 45 ++++++++----------- ..._pomodoro_test__max_rounds_last_round.snap | 2 +- 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/src/widgets/pomodoro.rs b/src/widgets/pomodoro.rs index 9532b69..e28a4d4 100644 --- a/src/widgets/pomodoro.rs +++ b/src/widgets/pomodoro.rs @@ -203,28 +203,20 @@ impl PomodoroState { } fn update_work_name(&mut self) { - let name = if self.is_last_round() { - "work (last round)".to_owned() - } else { - format!("work ({})", self.round_label()) - }; + let name = format!("work ({})", self.round_label()); self.get_clock_work_mut().set_name(name); } fn update_pause_name(&mut self) { - let name = if self.is_last_round() { - "pause (last round)".to_owned() - } else { - format!( - "{} ({})", - if self.pause_duration.is_special_round(self.round) { - "pause special" - } else { - "pause" - }, - self.round_label() - ) - }; + let name = format!( + "{} ({})", + if self.pause_duration.is_special_round(self.round) { + "pause special" + } else { + "pause" + }, + self.round_label() + ); self.get_clock_pause_mut().set_name(name); } @@ -245,11 +237,15 @@ impl PomodoroState { pub fn increase_max_rounds(&mut self) { self.max_rounds = Some(self.max_rounds.map_or(1, |n| n + 1)); - self.update_clock_names(); + self.clamp_round(); } pub fn decrease_max_rounds(&mut self) { self.max_rounds = self.max_rounds.and_then(|n| (n > 1).then_some(n - 1)); + self.clamp_round(); + } + + fn clamp_round(&mut self) { if let Some(max) = self.max_rounds { self.round = self.round.min(max); } @@ -487,19 +483,16 @@ impl StatefulWidget for PomodoroWidget { )) .to_uppercase(), ); - let label_round = Line::raw(if state.is_last_round() { - "LAST ROUND".to_owned() - } else if let Some(max) = state.get_max_rounds() { - format!("ROUND {} OF {}", state.get_round(), max) - } else { - format!("ROUND {}", state.get_round()) + let label_round = Line::raw(match state.get_max_rounds() { + Some(max) => format!("ROUND {} OF {}", state.get_round(), max), + None => format!("ROUND {}", state.get_round()), }); let area = area.centered( Constraint::Length(max( clock_widget .get_width(state.get_clock().get_format(), state.get_clock().with_decis), - label.width() as u16, + max(label.width() as u16, label_round.width() as u16), )), Constraint::Length( // empty label + height of `label` + `label_round` diff --git a/src/widgets/snapshots/timr_tui__widgets__pomodoro_test__max_rounds_last_round.snap b/src/widgets/snapshots/timr_tui__widgets__pomodoro_test__max_rounds_last_round.snap index 47c102e..c08574c 100644 --- a/src/widgets/snapshots/timr_tui__widgets__pomodoro_test__max_rounds_last_round.snap +++ b/src/widgets/snapshots/timr_tui__widgets__pomodoro_test__max_rounds_last_round.snap @@ -14,7 +14,7 @@ expression: t.backend() " █████ █████ █████ █████ " " " " POMODORO WORK [] " -" LAST ROUND " +" ROUND 3 OF 3 " " " " " " " From 79df410ada655df52d1b40f47b6e72c7713469c2 Mon Sep 17 00:00:00 2001 From: jk <47693+sectore@users.noreply.github.com> Date: Wed, 17 Jun 2026 12:13:13 +0200 Subject: [PATCH 3/4] update CL --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fe4b49..aefb576 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ### Features -- (pomodoro) `--max-rounds` arg to limit sessions [#205](https://github.com/sectore/timr-tui/pull/205) +- (pomodoro) introduce `max rounds` to limit sessions [#205](https://github.com/sectore/timr-tui/pull/205), [#206](https://github.com/sectore/timr-tui/pull/206) - (notification) detailed pomodoro status in system notification [#204](https://github.com/sectore/timr-tui/pull/204) - (cli) Add `--auto-switch` argument [#203](https://github.com/sectore/timr-tui/pull/203) From 5186a7e91aaafa3fcc481797f3ae1ca86df394a8 Mon Sep 17 00:00:00 2001 From: jk <47693+sectore@users.noreply.github.com> Date: Wed, 17 Jun 2026 12:20:36 +0200 Subject: [PATCH 4/4] =?UTF-8?q?docs(readme):=20add=20--max-rounds=20CLI=20?= =?UTF-8?q?arg=20and=20^=E2=86=91/^=E2=86=93=20keybindings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- README.md | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index fe84877..0851323 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,7 @@ Options: -w, --work Work time to count down from. Formats: 'ss', 'mm:ss', 'hh:mm:ss' -p, --pause Pause duration. Single value (every round): '5:00'. Variable: 'regular,special[,every_n_rounds]' - special pause every N rounds, default every 4. Examples: '5:00,25:00' or '5:00,30:00,5'. Duration formats: 'ss', 'mm:ss', 'hh:mm:ss'. --auto-switch Enable auto-switch between `work` and `pause` screens. + --max-rounds Maximum number of pomodoro rounds. 0 = unlimited. -e, --event Event date time and title (optional). Format: 'YYYY-MM-DD HH:MM:SS' or 'time=YYYY-MM-DD HH:MM:SS[,title=...]'. Examples: '2025-10-10 14:30:00' or 'time=2025-10-10 14:30:00,title=My Event'. -d, --decis Show deciseconds. -m, --mode Mode to start with. [possible values: countdown, timer, pomodoro, event, localtime] @@ -176,17 +177,21 @@ Note: To enable Vim motions key binding, run with `--vim=on` once. It will be st **In `Pomodoro` screen only:** -| Key | Description | -| -------------------------------------- | --------------------------------- | -| ctrl+← or ctrl+→ | switch work/pause | -| ctrl+h or ctrl+l | switch work/pause _(Vim motions)_ | -| a | toggle auto switch work/pause | -| | next round | -| k | next round _(Vim motions)_ | -| | previous round | -| j | previous round _(Vim motions)_ | -| ctrl+r | reset rounds | -| ctrl+s | save initial value | +| Key | Description | +| -------------------------------------- | ----------------------------------- | +| ctrl+← or ctrl+→ | switch work/pause | +| ctrl+h or ctrl+l | switch work/pause _(Vim motions)_ | +| a | toggle auto switch work/pause | +| | next round | +| k | next round _(Vim motions)_ | +| | previous round | +| j | previous round _(Vim motions)_ | +| ctrl+↑ | increase max rounds | +| ctrl+k | increase max rounds _(Vim motions)_ | +| ctrl+↓ | decrease max rounds | +| ctrl+j | decrease max rounds _(Vim motions)_ | +| ctrl+r | reset rounds | +| ctrl+s | save initial value | **In `Countdown` screen only:**