summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Bütow <1224732+snonux@users.noreply.github.com>2025-06-20 21:27:33 +0300
committerGitHub <noreply@github.com>2025-06-20 21:27:33 +0300
commit6d632ae7b7ce137b125e6687873b7d76edc82c40 (patch)
treed168774cebb660f163958bd487dd3cb156dd9f41
parente04538842128f09e9469ada29579cb4ac2013410 (diff)
parent3239f41ac7a00342dcc4dd26e699230981f168e3 (diff)
Merge pull request #45 from snonux/codex/add-priority-hotkey-with-selection-menu
Add priority selection hotkey
-rw-r--r--internal/ui/table.go56
-rw-r--r--internal/ui/table_test.go47
2 files changed, 103 insertions, 0 deletions
diff --git a/internal/ui/table.go b/internal/ui/table.go
index e293325..6dad110 100644
--- a/internal/ui/table.go
+++ b/internal/ui/table.go
@@ -17,6 +17,8 @@ import (
"tasksamurai/internal/task"
)
+var priorityOptions = []string{"H", "M", "L", ""}
+
func init() {
rand.Seed(time.Now().UnixNano())
}
@@ -36,6 +38,10 @@ type Model struct {
dueID int
dueInput textinput.Model
+ prioritySelecting bool
+ priorityID int
+ priorityIndex int
+
filters []string
tasks []task.Task
@@ -183,6 +189,23 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.dueInput, cmd = m.dueInput.Update(msg)
return m, cmd
}
+ if m.prioritySelecting {
+ switch msg.Type {
+ case tea.KeyEnter:
+ task.SetPriority(m.priorityID, priorityOptions[m.priorityIndex])
+ m.prioritySelecting = false
+ m.reload()
+ return m, nil
+ case tea.KeyEsc:
+ m.prioritySelecting = false
+ return m, nil
+ case tea.KeyLeft:
+ m.priorityIndex = (m.priorityIndex + len(priorityOptions) - 1) % len(priorityOptions)
+ case tea.KeyRight:
+ m.priorityIndex = (m.priorityIndex + 1) % len(priorityOptions)
+ }
+ return m, nil
+ }
switch msg.String() {
case "?":
m.showHelp = true
@@ -261,6 +284,16 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.reload()
}
}
+ case "p":
+ if row := m.tbl.SelectedRow(); row != nil {
+ idStr := ansi.Strip(row[0])
+ if id, err := strconv.Atoi(idStr); err == nil {
+ m.priorityID = id
+ m.prioritySelecting = true
+ m.priorityIndex = 0
+ return m, nil
+ }
+ }
case "a":
if row := m.tbl.SelectedRow(); row != nil {
idStr := ansi.Strip(row[0])
@@ -310,6 +343,7 @@ func (m Model) View() string {
"r: random due date",
"a: annotate task",
"A: replace annotations",
+ "p: set priority",
"q: quit",
"?: help", // show help toggle line
)
@@ -331,6 +365,12 @@ func (m Model) View() string {
m.dueInput.View(),
)
}
+ if m.prioritySelecting {
+ view = lipgloss.JoinVertical(lipgloss.Left,
+ view,
+ m.priorityView(),
+ )
+ }
return view
}
@@ -420,3 +460,19 @@ func formatPriority(p string) string {
}
return style.Render(p)
}
+
+func (m Model) priorityView() string {
+ var parts []string
+ for i, p := range priorityOptions {
+ label := p
+ if label == "" {
+ label = "none"
+ }
+ style := lipgloss.NewStyle()
+ if i == m.priorityIndex {
+ style = style.Foreground(lipgloss.Color("229")).Background(lipgloss.Color("57"))
+ }
+ parts = append(parts, style.Render(label))
+ }
+ return "priority: " + strings.Join(parts, " ")
+}
diff --git a/internal/ui/table_test.go b/internal/ui/table_test.go
index c1862d2..ea904b3 100644
--- a/internal/ui/table_test.go
+++ b/internal/ui/table_test.go
@@ -334,3 +334,50 @@ func TestRandomDueDateHotkey(t *testing.T) {
t.Fatalf("due date out of range: %d", days)
}
}
+
+func TestPriorityHotkey(t *testing.T) {
+ tmp := t.TempDir()
+ taskPath := filepath.Join(tmp, "task")
+ priFile := filepath.Join(tmp, "pri.txt")
+
+ script := "#!/bin/sh\n" +
+ "if echo \"$@\" | grep -q export; then\n" +
+ " echo '{\"id\":1,\"uuid\":\"x\",\"description\":\"d\",\"status\":\"pending\",\"entry\":\"\",\"priority\":\"\",\"urgency\":0}'\n" +
+ " exit 0\n" +
+ "fi\n" +
+ "echo \"$@\" > " + priFile + "\n"
+
+ if err := os.WriteFile(taskPath, []byte(script), 0o755); err != nil {
+ t.Fatal(err)
+ }
+
+ origPath := os.Getenv("PATH")
+ os.Setenv("PATH", tmp+":"+origPath)
+ t.Cleanup(func() { os.Setenv("PATH", origPath) })
+
+ os.Setenv("TASKDATA", tmp)
+ os.Setenv("TASKRC", "/dev/null")
+ t.Cleanup(func() {
+ os.Unsetenv("TASKDATA")
+ os.Unsetenv("TASKRC")
+ })
+
+ m, err := New(nil)
+ if err != nil {
+ t.Fatalf("New: %v", err)
+ }
+
+ mv, _ := m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'p'}})
+ m = mv.(Model)
+ mv, _ = m.Update(tea.KeyMsg{Type: tea.KeyEnter})
+ m = mv.(Model)
+
+ data, err := os.ReadFile(priFile)
+ if err != nil {
+ t.Fatalf("read pri: %v", err)
+ }
+
+ if strings.TrimSpace(string(data)) != "1 modify priority:H" {
+ t.Fatalf("priority not set: %q", data)
+ }
+}