From 13e52e288052a458ea57e4e2ca749848c775c5da Mon Sep 17 00:00:00 2001 From: Rasmus Wejlgaard Date: Sat, 8 Nov 2025 13:29:28 +0000 Subject: [PATCH] images and getting closer to feature complete --- .imgs/capture_prompt.png | Bin 0 -> 12255 bytes .imgs/delete_prompt.png | Bin 0 -> 14986 bytes .imgs/editing.png | Bin 0 -> 18819 bytes .imgs/list_view.png | Bin 0 -> 65953 bytes README.md | 16 +++ internal/model/item.go | 12 ++ internal/parser/parser.go | 50 ++++++-- internal/parser/writer.go | 21 ++++ internal/ui/app.go | 41 ++++++ internal/ui/keybindings.go | 16 ++- internal/ui/modes.go | 209 +++++++++++++++++++++++++++++-- internal/ui/views.go | 247 +++++++++++++++++++++++++++++-------- 12 files changed, 531 insertions(+), 81 deletions(-) create mode 100644 .imgs/capture_prompt.png create mode 100644 .imgs/delete_prompt.png create mode 100644 .imgs/editing.png create mode 100644 .imgs/list_view.png create mode 100644 README.md diff --git a/.imgs/capture_prompt.png b/.imgs/capture_prompt.png new file mode 100644 index 0000000000000000000000000000000000000000..5d6f7643ede69b0373a567390c252b810dbc4e69 GIT binary patch literal 12255 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 literal 0 HcmV?d00001 diff --git a/.imgs/delete_prompt.png b/.imgs/delete_prompt.png new file mode 100644 index 0000000000000000000000000000000000000000..e9c2641f8ac8a17d1bfa75db6d84e164e70c768f GIT binary patch literal 14986 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 literal 0 HcmV?d00001 diff --git a/.imgs/list_view.png b/.imgs/list_view.png new file mode 100644 index 0000000000000000000000000000000000000000..d952b9712b375fb5f5fde522d0a0adb0185bb35a GIT binary patch literal 65953 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 Pkl!i$E%xz@jzs]+)>`) - deadlinePattern = regexp.MustCompile(`DEADLINE:\s*<([^>]+)>`) - clockPattern = regexp.MustCompile(`CLOCK:\s*\[([^\]]+)\](?:--\[([^\]]+)\])?`) - drawerStart = regexp.MustCompile(`^\s*:LOGBOOK:\s*$`) - drawerEnd = regexp.MustCompile(`^\s*:END:\s*$`) - codeBlockStart = regexp.MustCompile(`^\s*#\+BEGIN_SRC`) - codeBlockEnd = regexp.MustCompile(`^\s*#\+END_SRC`) + headingPattern = regexp.MustCompile(`^(\*+)\s+(?:(TODO|PROG|BLOCK|DONE)\s+)?(?:\[#([A-C])\]\s+)?(.+)$`) + scheduledPattern = regexp.MustCompile(`SCHEDULED:\s*<([^>]+)>`) + deadlinePattern = regexp.MustCompile(`DEADLINE:\s*<([^>]+)>`) + clockPattern = regexp.MustCompile(`CLOCK:\s*\[([^\]]+)\](?:--\[([^\]]+)\])?`) + effortPattern = regexp.MustCompile(`^\s*:EFFORT:\s*(.+)$`) + logbookDrawerStart = regexp.MustCompile(`^\s*:LOGBOOK:\s*$`) + propertiesDrawerStart = regexp.MustCompile(`^\s*:PROPERTIES:\s*$`) + drawerEnd = regexp.MustCompile(`^\s*:END:\s*$`) + codeBlockStart = regexp.MustCompile(`^\s*#\+BEGIN_SRC`) + codeBlockEnd = regexp.MustCompile(`^\s*#\+END_SRC`) ) // ParseOrgFile reads and parses an org-mode file @@ -40,25 +42,42 @@ func ParseOrgFile(path string) (*model.OrgFile, error) { var itemStack []*model.Item // Stack to track parent items var inCodeBlock bool var inLogbookDrawer bool + var inPropertiesDrawer bool for scanner.Scan() { line := scanner.Text() // Check for drawer boundaries - if drawerStart.MatchString(line) { + if logbookDrawerStart.MatchString(line) { inLogbookDrawer = true if currentItem != nil { currentItem.Notes = append(currentItem.Notes, line) } continue } - if drawerEnd.MatchString(line) && inLogbookDrawer { - inLogbookDrawer = false + if propertiesDrawerStart.MatchString(line) { + inPropertiesDrawer = true if currentItem != nil { currentItem.Notes = append(currentItem.Notes, line) } continue } + if drawerEnd.MatchString(line) { + if inLogbookDrawer { + inLogbookDrawer = false + if currentItem != nil { + currentItem.Notes = append(currentItem.Notes, line) + } + continue + } + if inPropertiesDrawer { + inPropertiesDrawer = false + if currentItem != nil { + currentItem.Notes = append(currentItem.Notes, line) + } + continue + } + } // Check for code block boundaries if codeBlockStart.MatchString(line) { @@ -88,11 +107,13 @@ func ParseOrgFile(path string) (*model.OrgFile, error) { if matches := headingPattern.FindStringSubmatch(line); matches != nil { level := len(matches[1]) state := model.TodoState(matches[2]) - title := matches[3] + priority := model.Priority(matches[3]) + title := matches[4] item := &model.Item{ Level: level, State: state, + Priority: priority, Title: title, Notes: []string{}, Children: []*model.Item{}, @@ -132,6 +153,11 @@ func ParseOrgFile(path string) (*model.OrgFile, error) { } } + // Check for EFFORT (inside PROPERTIES drawer) + if matches := effortPattern.FindStringSubmatch(line); matches != nil { + currentItem.Effort = strings.TrimSpace(matches[1]) + } + // Check for CLOCK (can be inside or outside drawer) if matches := clockPattern.FindStringSubmatch(line); matches != nil { if startTime, err := parseClockTimestamp(matches[1]); err == nil { diff --git a/internal/parser/writer.go b/internal/parser/writer.go index 791f232..06020ab 100644 --- a/internal/parser/writer.go +++ b/internal/parser/writer.go @@ -37,6 +37,9 @@ func writeItem(writer *bufio.Writer, item *model.Item) error { if item.State != model.StateNone { line += " " + string(item.State) } + if item.Priority != model.PriorityNone { + line += " [#" + string(item.Priority) + "]" + } line += " " + item.Title + "\n" if _, err := writer.WriteString(line); err != nil { @@ -47,6 +50,7 @@ func writeItem(writer *bufio.Writer, item *model.Item) error { hasScheduled := false hasDeadline := false hasLogbook := false + hasProperties := false for _, note := range item.Notes { if strings.Contains(note, "SCHEDULED:") { hasScheduled = true @@ -57,6 +61,9 @@ func writeItem(writer *bufio.Writer, item *model.Item) error { if strings.Contains(note, ":LOGBOOK:") { hasLogbook = true } + if strings.Contains(note, ":PROPERTIES:") { + hasProperties = true + } } if item.Scheduled != nil && !hasScheduled { @@ -73,6 +80,20 @@ func writeItem(writer *bufio.Writer, item *model.Item) error { } } + // Write effort in :PROPERTIES: drawer if not already in notes + if item.Effort != "" && !hasProperties { + if _, err := writer.WriteString(":PROPERTIES:\n"); err != nil { + return err + } + effortLine := fmt.Sprintf(":EFFORT: %s\n", item.Effort) + if _, err := writer.WriteString(effortLine); err != nil { + return err + } + if _, err := writer.WriteString(":END:\n"); err != nil { + return err + } + } + // Write clock entries in :LOGBOOK: drawer if not already in notes if len(item.ClockEntries) > 0 && !hasLogbook { if _, err := writer.WriteString(":LOGBOOK:\n"); err != nil { diff --git a/internal/ui/app.go b/internal/ui/app.go index 11a13f5..b5968d7 100644 --- a/internal/ui/app.go +++ b/internal/ui/app.go @@ -20,11 +20,14 @@ const ( modeCapture modeAddSubTask modeSetDeadline + modeSetPriority + modeSetEffort ) type uiModel struct { orgFile *model.OrgFile cursor int + scrollOffset int // Track the scroll position mode viewMode help help.Model keys keyMap @@ -78,6 +81,44 @@ func (m uiModel) getVisibleItems() []*model.Item { return m.orgFile.GetAllItems() } +func (m *uiModel) updateScrollOffset(availableHeight int) { + items := m.getVisibleItems() + if len(items) == 0 { + return + } + + // Build line count for each item + itemLineCount := make([]int, len(items)) + for i, item := range items { + lineCount := 1 // The item itself + if !item.Folded && len(item.Notes) > 0 && m.mode == modeList { + // Count note lines (simplified - just count notes) + lineCount += len(item.Notes) + } + itemLineCount[i] = lineCount + } + + // Calculate total lines up to cursor + totalLinesBeforeCursor := 0 + for i := 0; i < m.cursor && i < len(itemLineCount); i++ { + totalLinesBeforeCursor += itemLineCount[i] + } + + // Adjust scroll offset to keep cursor visible + if totalLinesBeforeCursor < m.scrollOffset { + // Cursor is above visible area, scroll up + m.scrollOffset = totalLinesBeforeCursor + } else if totalLinesBeforeCursor >= m.scrollOffset+availableHeight { + // Cursor is below visible area, scroll down + m.scrollOffset = totalLinesBeforeCursor - availableHeight + 1 + } + + // Ensure scroll offset doesn't go negative + if m.scrollOffset < 0 { + m.scrollOffset = 0 + } +} + // RunUI starts the terminal UI func RunUI(orgFile *model.OrgFile) error { p := tea.NewProgram(initialModel(orgFile), tea.WithAltScreen()) diff --git a/internal/ui/keybindings.go b/internal/ui/keybindings.go index 5e80f90..73f3f1f 100644 --- a/internal/ui/keybindings.go +++ b/internal/ui/keybindings.go @@ -23,6 +23,8 @@ type keyMap struct { ClockIn key.Binding ClockOut key.Binding SetDeadline key.Binding + SetPriority key.Binding + SetEffort key.Binding } var keys = keyMap{ @@ -75,8 +77,8 @@ var keys = keyMap{ key.WithHelp("s", "add sub-task"), ), Delete: key.NewBinding( - key.WithKeys("shift+d"), - key.WithHelp("shift+d", "delete item"), + key.WithKeys("D"), + key.WithHelp("D", "delete item"), ), Save: key.NewBinding( key.WithKeys("ctrl+s"), @@ -98,6 +100,14 @@ var keys = keyMap{ key.WithKeys("d"), key.WithHelp("d", "set deadline"), ), + SetPriority: key.NewBinding( + key.WithKeys("p"), + key.WithHelp("p", "set priority"), + ), + SetEffort: key.NewBinding( + key.WithKeys("e"), + key.WithHelp("e", "set effort"), + ), Help: key.NewBinding( key.WithKeys("?"), key.WithHelp("?", "toggle help"), @@ -128,7 +138,7 @@ func (k keyMap) getAllBindings() []key.Binding { k.Up, k.Down, k.Left, k.Right, k.ToggleFold, k.EditNotes, k.ToggleReorder, k.Capture, k.AddSubTask, k.Delete, k.Save, - k.ClockIn, k.ClockOut, k.SetDeadline, + k.ClockIn, k.ClockOut, k.SetDeadline, k.SetPriority, k.SetEffort, k.ToggleView, k.Help, k.Quit, } } diff --git a/internal/ui/modes.go b/internal/ui/modes.go index 0568fa5..97df9b4 100644 --- a/internal/ui/modes.go +++ b/internal/ui/modes.go @@ -26,6 +26,10 @@ func (m uiModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m.updateAddSubTask(msg) case modeSetDeadline: return m.updateSetDeadline(msg) + case modeSetPriority: + return m.updateSetPriority(msg) + case modeSetEffort: + return m.updateSetEffort(msg) } switch msg := msg.(type) { @@ -35,6 +39,7 @@ func (m uiModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.help.Width = msg.Width m.textarea.SetWidth(msg.Width - 4) m.textarea.SetHeight(msg.Height - 10) + m.textinput.Width = 50 // Set a reasonable width for the text input return m, nil case tea.KeyMsg: @@ -52,6 +57,12 @@ func (m uiModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } else { if m.cursor > 0 { m.cursor-- + // Update scroll to keep cursor visible + availableHeight := m.height - 6 // Approximate + if availableHeight < 5 { + availableHeight = 5 + } + m.updateScrollOffset(availableHeight) } } @@ -62,6 +73,12 @@ func (m uiModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { items := m.getVisibleItems() if m.cursor < len(items)-1 { m.cursor++ + // Update scroll to keep cursor visible + availableHeight := m.height - 6 // Approximate + if availableHeight < 5 { + availableHeight = 5 + } + m.updateScrollOffset(availableHeight) } } @@ -203,6 +220,25 @@ func (m uiModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.textinput.Focus() return m, textinput.Blink } + + case key.Matches(msg, m.keys.SetPriority): + items := m.getVisibleItems() + if len(items) > 0 && m.cursor < len(items) { + m.editingItem = items[m.cursor] + m.mode = modeSetPriority + return m, nil + } + + case key.Matches(msg, m.keys.SetEffort): + items := m.getVisibleItems() + if len(items) > 0 && m.cursor < len(items) { + m.editingItem = items[m.cursor] + m.mode = modeSetEffort + m.textinput.SetValue("") + m.textinput.Placeholder = "e.g., 8h, 2d, 1w" + m.textinput.Focus() + return m, textinput.Blink + } } } @@ -273,6 +309,7 @@ func (m uiModel) updateCapture(msg tea.Msg) (tea.Model, tea.Cmd) { case tea.WindowSizeMsg: m.width = msg.Width m.height = msg.Height + m.textinput.Width = 50 case tea.KeyMsg: switch msg.Type { @@ -314,6 +351,7 @@ func (m uiModel) updateAddSubTask(msg tea.Msg) (tea.Model, tea.Cmd) { case tea.WindowSizeMsg: m.width = msg.Width m.height = msg.Height + m.textinput.Width = 50 case tea.KeyMsg: switch msg.Type { @@ -356,6 +394,7 @@ func (m uiModel) updateSetDeadline(msg tea.Msg) (tea.Model, tea.Cmd) { case tea.WindowSizeMsg: m.width = msg.Width m.height = msg.Height + m.textinput.Width = 50 case tea.KeyMsg: switch msg.Type { @@ -453,6 +492,98 @@ func parseDeadlineInput(input string) (time.Time, error) { return time.Time{}, fmt.Errorf("unable to parse date: %s (use YYYY-MM-DD or +N)", input) } +func (m uiModel) updateSetPriority(msg tea.Msg) (tea.Model, tea.Cmd) { + switch msg := msg.(type) { + case tea.WindowSizeMsg: + m.width = msg.Width + m.height = msg.Height + + case tea.KeyMsg: + switch msg.String() { + case "A", "a": + if m.editingItem != nil { + m.editingItem.Priority = model.PriorityA + m.setStatus("Priority set to A") + } + m.mode = modeList + m.editingItem = nil + return m, nil + case "B", "b": + if m.editingItem != nil { + m.editingItem.Priority = model.PriorityB + m.setStatus("Priority set to B") + } + m.mode = modeList + m.editingItem = nil + return m, nil + case "C", "c": + if m.editingItem != nil { + m.editingItem.Priority = model.PriorityC + m.setStatus("Priority set to C") + } + m.mode = modeList + m.editingItem = nil + return m, nil + case " ", "enter": + // Clear priority + if m.editingItem != nil { + m.editingItem.Priority = model.PriorityNone + m.setStatus("Priority cleared") + } + m.mode = modeList + m.editingItem = nil + return m, nil + case "esc": + m.mode = modeList + m.editingItem = nil + m.setStatus("Cancelled") + return m, nil + } + } + return m, nil +} + +func (m uiModel) updateSetEffort(msg tea.Msg) (tea.Model, tea.Cmd) { + var cmd tea.Cmd + + switch msg := msg.(type) { + case tea.WindowSizeMsg: + m.width = msg.Width + m.height = msg.Height + m.textinput.Width = 50 + + case tea.KeyMsg: + switch msg.Type { + case tea.KeyEnter: + input := strings.TrimSpace(m.textinput.Value()) + if m.editingItem != nil { + if input == "" { + // Empty input clears the effort + m.editingItem.Effort = "" + m.setStatus("Effort cleared!") + } else { + // Set the effort value + m.editingItem.Effort = input + m.setStatus("Effort set!") + } + } + m.mode = modeList + m.textinput.Blur() + m.editingItem = nil + return m, nil + case tea.KeyEsc: + m.mode = modeList + m.textinput.Blur() + m.editingItem = nil + m.setStatus("Cancelled") + return m, nil + } + } + + m.textinput, cmd = m.textinput.Update(msg) + return m, cmd +} + func (m *uiModel) cycleStateBackward(item *model.Item) { switch item.State { case model.StateNone: @@ -491,17 +622,25 @@ func (m *uiModel) moveItemUp() { } currentItem := items[m.cursor] - prevItem := items[m.cursor-1] - // Can only swap items at the same level - if currentItem.Level != prevItem.Level { - m.setStatus("Cannot move across different levels") + // Find the previous sibling (not child, not parent's sibling) + prevSibling := m.findPreviousSibling(currentItem) + if prevSibling == nil { + m.setStatus("Cannot move - already at top of list") return } - m.swapItems(currentItem, prevItem) - m.cursor-- + m.swapItems(currentItem, prevSibling) m.setStatus("Item moved up") + + // Update cursor to follow the item + items = m.getVisibleItems() + for i, item := range items { + if item == currentItem { + m.cursor = i + break + } + } } func (m *uiModel) moveItemDown() { @@ -511,17 +650,63 @@ func (m *uiModel) moveItemDown() { } currentItem := items[m.cursor] - nextItem := items[m.cursor+1] - // Can only swap items at the same level - if currentItem.Level != nextItem.Level { - m.setStatus("Cannot move across different levels") + // Find the next sibling (not child, not parent's sibling) + nextSibling := m.findNextSibling(currentItem) + if nextSibling == nil { + m.setStatus("Cannot move - already at bottom of list") return } - m.swapItems(currentItem, nextItem) - m.cursor++ + m.swapItems(currentItem, nextSibling) m.setStatus("Item moved down") + + // Update cursor to follow the item + items = m.getVisibleItems() + for i, item := range items { + if item == currentItem { + m.cursor = i + break + } + } +} + +func (m *uiModel) findPreviousSibling(item *model.Item) *model.Item { + // Find the parent list containing this item and return the previous sibling + var findInList func([]*model.Item) *model.Item + findInList = func(items []*model.Item) *model.Item { + for i, it := range items { + if it == item && i > 0 { + // Found the item and there's a previous sibling + return items[i-1] + } + // Recursively check children + if result := findInList(it.Children); result != nil { + return result + } + } + return nil + } + return findInList(m.orgFile.Items) +} + +func (m *uiModel) findNextSibling(item *model.Item) *model.Item { + // Find the parent list containing this item and return the next sibling + var findInList func([]*model.Item) *model.Item + findInList = func(items []*model.Item) *model.Item { + for i, it := range items { + if it == item && i < len(items)-1 { + // Found the item and there's a next sibling + return items[i+1] + } + // Recursively check children + if result := findInList(it.Children); result != nil { + return result + } + } + return nil + } + return findInList(m.orgFile.Items) } func (m *uiModel) swapItems(item1, item2 *model.Item) { diff --git a/internal/ui/views.go b/internal/ui/views.go index 3ae3a83..177b157 100644 --- a/internal/ui/views.go +++ b/internal/ui/views.go @@ -81,6 +81,10 @@ func (m uiModel) View() string { return m.viewAddSubTask() case modeSetDeadline: return m.viewSetDeadline() + case modeSetPriority: + return m.viewSetPriority() + case modeSetEffort: + return m.viewSetEffort() } // Build footer (status + help) @@ -130,12 +134,84 @@ func (m uiModel) View() string { content.WriteString("No items. Press 'c' to capture a new TODO.\n") } + // Build a map of item index to line count (for scrolling) + itemLineCount := make([]int, len(items)) + for i, item := range items { + lineCount := 1 // The item itself + if !item.Folded && len(item.Notes) > 0 && m.mode == modeList { + filteredNotes := filterLogbookDrawer(item.Notes) + highlightedNotes := renderNotesWithHighlighting(filteredNotes) + lineCount += len(highlightedNotes) + } + itemLineCount[i] = lineCount + } + + // Calculate total lines up to cursor + totalLinesBeforeCursor := 0 + for i := 0; i < m.cursor && i < len(itemLineCount); i++ { + totalLinesBeforeCursor += itemLineCount[i] + } + + // Determine the scroll offset (without modifying m - View should be pure) + scrollOffset := m.scrollOffset + if totalLinesBeforeCursor < scrollOffset { + // Cursor is above visible area, scroll up + scrollOffset = totalLinesBeforeCursor + } else if totalLinesBeforeCursor >= scrollOffset+availableHeight { + // Cursor is below visible area, scroll down + scrollOffset = totalLinesBeforeCursor - availableHeight + 1 + } + + // Render items starting from scroll offset itemLines := 0 for i, item := range items { - if itemLines >= availableHeight { - break // Don't render more items than fit + // Calculate which line this item starts at + itemStartLine := 0 + for j := 0; j < i; j++ { + itemStartLine += itemLineCount[j] } + // Skip items before scroll offset + if itemStartLine+itemLineCount[i] <= scrollOffset { + continue + } + + // Stop if we've filled the screen + if itemLines >= availableHeight { + break + } + + // Skip partial items at the top if needed + if itemStartLine < scrollOffset { + // This item is partially scrolled off the top + linesToSkip := scrollOffset - itemStartLine + if linesToSkip < itemLineCount[i] { + // Render the visible parts + if linesToSkip == 0 { + line := m.renderItem(item, i == m.cursor) + content.WriteString(line) + content.WriteString("\n") + itemLines++ + linesToSkip++ + } + + // Render remaining notes + if !item.Folded && len(item.Notes) > 0 && m.mode == modeList { + indent := strings.Repeat(" ", item.Level) + filteredNotes := filterLogbookDrawer(item.Notes) + highlightedNotes := renderNotesWithHighlighting(filteredNotes) + for noteIdx := linesToSkip - 1; noteIdx < len(highlightedNotes) && itemLines < availableHeight; noteIdx++ { + content.WriteString(indent) + content.WriteString(" " + highlightedNotes[noteIdx]) + content.WriteString("\n") + itemLines++ + } + } + } + continue + } + + // Render the full item line := m.renderItem(item, i == m.cursor) content.WriteString(line) content.WriteString("\n") @@ -144,7 +220,6 @@ func (m uiModel) View() string { // Show notes if not folded if !item.Folded && len(item.Notes) > 0 && m.mode == modeList { indent := strings.Repeat(" ", item.Level) - // Filter out LOGBOOK drawer and apply syntax highlighting to notes filteredNotes := filterLogbookDrawer(item.Notes) highlightedNotes := renderNotesWithHighlighting(filteredNotes) for _, note := range highlightedNotes { @@ -177,8 +252,6 @@ func (m uiModel) View() string { } func (m uiModel) viewConfirmDelete() string { - var b strings.Builder - dialogStyle := lipgloss.NewStyle(). Border(lipgloss.RoundedBorder()). BorderForeground(lipgloss.Color("196")). @@ -202,21 +275,11 @@ func (m uiModel) viewConfirmDelete() string { dialog := dialogStyle.Render(content.String()) - // Center the dialog - if m.height > 0 { - verticalPadding := (m.height - lipgloss.Height(dialog)) / 2 - if verticalPadding > 0 { - b.WriteString(strings.Repeat("\n", verticalPadding)) - } - } - b.WriteString(dialog) - - return b.String() + // Center the dialog horizontally and vertically + return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center, dialog) } func (m uiModel) viewCapture() string { - var b strings.Builder - dialogStyle := lipgloss.NewStyle(). Border(lipgloss.RoundedBorder()). BorderForeground(lipgloss.Color("99")). @@ -232,21 +295,11 @@ func (m uiModel) viewCapture() string { dialog := dialogStyle.Render(content.String()) - // Center the dialog - if m.height > 0 { - verticalPadding := (m.height - lipgloss.Height(dialog)) / 2 - if verticalPadding > 0 { - b.WriteString(strings.Repeat("\n", verticalPadding)) - } - } - b.WriteString(dialog) - - return b.String() + // Center the dialog horizontally and vertically + return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center, dialog) } func (m uiModel) viewAddSubTask() string { - var b strings.Builder - dialogStyle := lipgloss.NewStyle(). Border(lipgloss.RoundedBorder()). BorderForeground(lipgloss.Color("99")). @@ -266,21 +319,11 @@ func (m uiModel) viewAddSubTask() string { dialog := dialogStyle.Render(content.String()) - // Center the dialog - if m.height > 0 { - verticalPadding := (m.height - lipgloss.Height(dialog)) / 2 - if verticalPadding > 0 { - b.WriteString(strings.Repeat("\n", verticalPadding)) - } - } - b.WriteString(dialog) - - return b.String() + // Center the dialog horizontally and vertically + return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center, dialog) } func (m uiModel) viewSetDeadline() string { - var b strings.Builder - dialogStyle := lipgloss.NewStyle(). Border(lipgloss.RoundedBorder()). BorderForeground(lipgloss.Color("141")). @@ -304,16 +347,78 @@ func (m uiModel) viewSetDeadline() string { dialog := dialogStyle.Render(content.String()) - // Center the dialog - if m.height > 0 { - verticalPadding := (m.height - lipgloss.Height(dialog)) / 2 - if verticalPadding > 0 { - b.WriteString(strings.Repeat("\n", verticalPadding)) + // Center the dialog horizontally and vertically + return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center, dialog) +} + +func (m uiModel) viewSetPriority() string { + dialogStyle := lipgloss.NewStyle(). + Border(lipgloss.RoundedBorder()). + BorderForeground(lipgloss.Color("214")). + Padding(1, 2). + Width(60) + + var content strings.Builder + content.WriteString(titleStyle.Render("Set Priority")) + content.WriteString("\n") + if m.editingItem != nil { + content.WriteString(statusStyle.Render(fmt.Sprintf("For: %s", m.editingItem.Title))) + content.WriteString("\n") + if m.editingItem.Priority != model.PriorityNone { + content.WriteString(statusStyle.Render(fmt.Sprintf("Current: [#%s]", m.editingItem.Priority))) } } - b.WriteString(dialog) + content.WriteString("\n\n") - return b.String() + // Show priority options with styling + priorityAStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("196")).Bold(true) + priorityBStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("214")).Bold(true) + priorityCStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("226")).Bold(true) + + content.WriteString(priorityAStyle.Render("[A] High Priority") + "\n") + content.WriteString(priorityBStyle.Render("[B] Medium Priority") + "\n") + content.WriteString(priorityCStyle.Render("[C] Low Priority") + "\n") + content.WriteString("\n") + content.WriteString(statusStyle.Render("Press Space/Enter to clear priority")) + content.WriteString("\n") + content.WriteString(statusStyle.Render("Press ESC to cancel")) + + dialog := dialogStyle.Render(content.String()) + + // Center the dialog horizontally and vertically + return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center, dialog) +} + +func (m uiModel) viewSetEffort() string { + dialogStyle := lipgloss.NewStyle(). + Border(lipgloss.RoundedBorder()). + BorderForeground(lipgloss.Color("141")). + Padding(1, 2). + Width(60) + + var content strings.Builder + content.WriteString(titleStyle.Render("Set Effort")) + content.WriteString("\n") + if m.editingItem != nil { + content.WriteString(statusStyle.Render(fmt.Sprintf("For: %s", m.editingItem.Title))) + content.WriteString("\n") + if m.editingItem.Effort != "" { + content.WriteString(statusStyle.Render(fmt.Sprintf("Current: %s", m.editingItem.Effort))) + } + } + content.WriteString("\n\n") + content.WriteString(m.textinput.View()) + content.WriteString("\n\n") + content.WriteString(statusStyle.Render("Examples: 8h, 2d, 1w, 4h30m")) + content.WriteString("\n") + content.WriteString(statusStyle.Render("Leave empty to clear effort")) + content.WriteString("\n") + content.WriteString(statusStyle.Render("Press Enter to save • ESC to cancel")) + + dialog := dialogStyle.Render(content.String()) + + // Center the dialog horizontally and vertically + return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center, dialog) } func (m uiModel) viewEditMode() string { @@ -332,10 +437,11 @@ func (m uiModel) viewEditMode() string { return b.String() } -// filterLogbookDrawer removes LOGBOOK drawer content and scheduling metadata from notes +// filterLogbookDrawer removes LOGBOOK and PROPERTIES drawer content and scheduling metadata from notes func filterLogbookDrawer(notes []string) []string { var filtered []string inLogbook := false + inProperties := false for _, note := range notes { trimmed := strings.TrimSpace(note) @@ -346,14 +452,26 @@ func filterLogbookDrawer(notes []string) []string { continue } - // Check for end of LOGBOOK drawer - if trimmed == ":END:" && inLogbook { - inLogbook = false + // Check for start of PROPERTIES drawer + if trimmed == ":PROPERTIES:" { + inProperties = true continue } - // Skip lines inside LOGBOOK drawer - if inLogbook { + // Check for end of drawer + if trimmed == ":END:" { + if inLogbook { + inLogbook = false + continue + } + if inProperties { + inProperties = false + continue + } + } + + // Skip lines inside LOGBOOK or PROPERTIES drawer + if inLogbook || inProperties { continue } @@ -517,9 +635,30 @@ func (m uiModel) renderItem(item *model.Item, isCursor bool) string { b.WriteString(stateStr) b.WriteString(" ") + // Priority + if item.Priority != model.PriorityNone { + var priorityStyle lipgloss.Style + switch item.Priority { + case model.PriorityA: + priorityStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("196")).Bold(true) + case model.PriorityB: + priorityStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("214")).Bold(true) + case model.PriorityC: + priorityStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("226")).Bold(true) + } + b.WriteString(priorityStyle.Render(fmt.Sprintf("[#%s] ", item.Priority))) + } + // Title b.WriteString(item.Title) + // Effort + if item.Effort != "" { + effortStr := fmt.Sprintf(" (Effort: %s)", item.Effort) + effortStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("141")) // Purple + b.WriteString(effortStyle.Render(effortStr)) + } + // Clock status if item.IsClockedIn() { duration := item.GetCurrentClockDuration()