From 91b4dd563092c4dc08cdc2d2f1714912cd3eaf14 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sat, 28 Jun 2025 14:24:41 +0300 Subject: feat: add 'T' hotkey to convert first tag to project MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement a new 'T' hotkey that automatically converts the first tag of a task into its project field. This provides a quick workflow for users who initially tag tasks and later want to organize them into projects. The operation: - Takes the first tag from the selected task - Sets it as the task's project - Removes the tag from the task's tag list This is useful for migrating from tag-based organization to project-based organization in Taskwarrior. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- internal/ui/keyhandlers.go | 34 ++++++++++++++++++++++++++++++++++ internal/ui/table.go | 1 + 2 files changed, 35 insertions(+) (limited to 'internal') diff --git a/internal/ui/keyhandlers.go b/internal/ui/keyhandlers.go index 204d08f..71a0ddc 100644 --- a/internal/ui/keyhandlers.go +++ b/internal/ui/keyhandlers.go @@ -87,6 +87,8 @@ func (m *Model) handleNormalMode(msg tea.KeyMsg) (tea.Model, tea.Cmd) { return m.handleEditTags() case "J": return m.handleEditProject() + case "T": + return m.handleTagToProject() case "c": return m.handleRandomTheme() case "C": @@ -411,6 +413,38 @@ func (m *Model) handleEditProject() (tea.Model, tea.Cmd) { return m, nil } +func (m *Model) handleTagToProject() (tea.Model, tea.Cmd) { + id, err := m.getSelectedTaskID() + if err != nil { + return m, nil + } + + // Get the task at cursor + currentTask := m.getTaskAtCursor() + if currentTask == nil || len(currentTask.Tags) == 0 { + // No tags to convert + return m, nil + } + + // Get the first tag + firstTag := currentTask.Tags[0] + + // Set the tag as project + if err := task.SetProject(id, firstTag); err != nil { + m.showError(err) + return m, nil + } + + // Remove the tag from the task + if err := task.RemoveTags(id, []string{firstTag}); err != nil { + m.showError(err) + return m, nil + } + + m.reload() + return m, m.startBlink(id, false) +} + func (m *Model) handleRandomTheme() (tea.Model, tea.Cmd) { m.theme = RandomTheme() m.applyTheme() diff --git a/internal/ui/table.go b/internal/ui/table.go index 9def986..8366b57 100644 --- a/internal/ui/table.go +++ b/internal/ui/table.go @@ -707,6 +707,7 @@ func (m Model) buildHelpContent() string { m.formatHelpLine("R", "edit recurrence", keyStyle, descStyle), m.formatHelpLine("t", "edit tags", keyStyle, descStyle), m.formatHelpLine("J", "edit project", keyStyle, descStyle), + m.formatHelpLine("T", "convert first tag to project", keyStyle, descStyle), m.formatHelpLine("a, A", "add/replace annotations", keyStyle, descStyle), m.formatHelpLine("o", "open URL from description", keyStyle, descStyle), "") -- cgit v1.2.3