summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-06-29 13:23:36 +0300
committerPaul Buetow <paul@buetow.org>2025-06-29 13:23:36 +0300
commit1c0f5ce0d07434cad0f82a80d08a08df50db38b7 (patch)
tree000506686871c1a6551bd20d76d72bfc086ff448
parentf71ecf2b59417dadd68a14978ad6c95d9699200e (diff)
feat: add random task jump hotkeys and document navigation keys
- Add hotkey '1' to jump to a random pending task - Add hotkey '2' to jump to a random pending task without due date - Both hotkeys include visual feedback with blink animation - Document '0' key as synonym for 'g' and 'Home' in help screen - Update help screen navigation section with all new hotkeys 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
-rw-r--r--internal/ui/keyhandlers.go64
-rw-r--r--internal/ui/table.go5
2 files changed, 68 insertions, 1 deletions
diff --git a/internal/ui/keyhandlers.go b/internal/ui/keyhandlers.go
index 14f6abc..027d5db 100644
--- a/internal/ui/keyhandlers.go
+++ b/internal/ui/keyhandlers.go
@@ -2,6 +2,7 @@ package ui
import (
"fmt"
+ "math/rand"
"os/exec"
"strings"
"time"
@@ -107,6 +108,10 @@ func (m *Model) handleNormalMode(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
return m.handleShowTaskDetail()
case "i":
return m.handleEnterOrEdit()
+ case "1":
+ return m.handleJumpToRandomTask()
+ case "2":
+ return m.handleJumpToRandomTaskNoDue()
default:
// Pass through to table for navigation
return m.handleTableNavigation(msg)
@@ -735,4 +740,63 @@ func (m *Model) handleTableNavigation(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
func (m *Model) showError(err error) {
m.statusMsg = fmt.Sprintf("Error: %v", err)
// Note: we can't return a Cmd from here, so the error will stay until next update
+}
+
+// handleJumpToRandomTask jumps to a random pending task
+func (m *Model) handleJumpToRandomTask() (tea.Model, tea.Cmd) {
+ if len(m.tasks) == 0 {
+ m.statusMsg = "No tasks to jump to"
+ return m, nil
+ }
+
+ // Pick a random index
+ randomIndex := rand.Intn(len(m.tasks))
+
+ // Update cursor position
+ prevRow := m.tbl.Cursor()
+ prevCol := m.tbl.ColumnCursor()
+ m.tbl.SetCursor(randomIndex)
+ m.updateSelectionHighlight(prevRow, randomIndex, prevCol, m.tbl.ColumnCursor())
+
+ // Blink the task to indicate jump
+ if randomIndex < len(m.tasks) {
+ taskID := m.tasks[randomIndex].ID
+ return m, m.startBlink(taskID, false)
+ }
+
+ return m, nil
+}
+
+// handleJumpToRandomTaskNoDue jumps to a random pending task without a due date
+func (m *Model) handleJumpToRandomTaskNoDue() (tea.Model, tea.Cmd) {
+ // Find all tasks without due dates
+ var noDueTasks []int
+ for i, task := range m.tasks {
+ if task.Due == "" {
+ noDueTasks = append(noDueTasks, i)
+ }
+ }
+
+ if len(noDueTasks) == 0 {
+ m.statusMsg = "No tasks without due date to jump to"
+ return m, nil
+ }
+
+ // Pick a random task from the no-due list
+ randomChoice := rand.Intn(len(noDueTasks))
+ randomIndex := noDueTasks[randomChoice]
+
+ // Update cursor position
+ prevRow := m.tbl.Cursor()
+ prevCol := m.tbl.ColumnCursor()
+ m.tbl.SetCursor(randomIndex)
+ m.updateSelectionHighlight(prevRow, randomIndex, prevCol, m.tbl.ColumnCursor())
+
+ // Blink the task to indicate jump
+ if randomIndex < len(m.tasks) {
+ taskID := m.tasks[randomIndex].ID
+ return m, m.startBlink(taskID, false)
+ }
+
+ return m, nil
} \ No newline at end of file
diff --git a/internal/ui/table.go b/internal/ui/table.go
index a3157af..65837a6 100644
--- a/internal/ui/table.go
+++ b/internal/ui/table.go
@@ -684,8 +684,11 @@ func (m Model) buildHelpContent() string {
sections = append(sections, headerStyle.Render("Navigation"),
m.formatHelpLine("↑/k, ↓/j", "move up/down", keyStyle, descStyle),
m.formatHelpLine("←/h, →/l", "move left/right", keyStyle, descStyle),
- m.formatHelpLine("g/Home, G/End", "go to start/end", keyStyle, descStyle),
+ m.formatHelpLine("0, g, Home", "go to start", keyStyle, descStyle),
+ m.formatHelpLine("G, End", "go to end", keyStyle, descStyle),
m.formatHelpLine("pgup/pgdn, b", "page up/down", keyStyle, descStyle),
+ m.formatHelpLine("1", "jump to random task", keyStyle, descStyle),
+ m.formatHelpLine("2", "jump to random task (no due date)", keyStyle, descStyle),
"")
// Task Management section