Jump to status options with their first-letter shortcuts.
o/w/d select OPEN/WIP/DONE in the status menu, with the hotkeys shown inline. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
package ticket
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// Status represents the workflow state of a ticket.
|
||||
type Status string
|
||||
@@ -28,6 +31,15 @@ func (s Status) Label() string {
|
||||
}
|
||||
}
|
||||
|
||||
// Shortcut returns the status-menu hotkey (first letter of the label).
|
||||
func (s Status) Shortcut() rune {
|
||||
label := s.Label()
|
||||
if label == "" {
|
||||
return 0
|
||||
}
|
||||
return unicode.ToLower([]rune(label)[0])
|
||||
}
|
||||
|
||||
// Index returns the position in AllStatuses, or 0 if unknown.
|
||||
func (s Status) Index() int {
|
||||
for i, st := range AllStatuses {
|
||||
|
||||
@@ -311,6 +311,13 @@ func (m Model) updateStatus(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
|
||||
m.statusMenu.MoveUp()
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// Jump to option by first letter of its label (o/w/d).
|
||||
if msg.Type == tea.KeyRunes && len(msg.Runes) == 1 {
|
||||
if m.statusMenu.JumpToShortcut(msg.Runes[0]) {
|
||||
return m, nil
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ func (m Model) helpEntries() []helpEntry {
|
||||
case ModeStatus:
|
||||
return []helpEntry{
|
||||
{"j/k", "select"},
|
||||
{"o/w/d", "jump"},
|
||||
{"enter", "apply"},
|
||||
{"esc", "cancel"},
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package views
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
|
||||
@@ -46,6 +48,18 @@ func (m *StatusMenu) MoveUp() {
|
||||
}
|
||||
}
|
||||
|
||||
// JumpToShortcut moves the cursor to the status whose label starts with r.
|
||||
func (m *StatusMenu) JumpToShortcut(r rune) bool {
|
||||
r = unicode.ToLower(r)
|
||||
for i, st := range ticket.AllStatuses {
|
||||
if st.Shortcut() == r {
|
||||
m.Cursor = i
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Selected returns the currently highlighted status.
|
||||
func (m StatusMenu) Selected() ticket.Status {
|
||||
if m.Cursor < 0 || m.Cursor >= len(ticket.AllStatuses) {
|
||||
@@ -59,13 +73,12 @@ func (m StatusMenu) View() string {
|
||||
var lines []string
|
||||
lines = append(lines, m.Styles.Title.Render("Set status"))
|
||||
for i, st := range ticket.AllStatuses {
|
||||
label := " " + st.Label()
|
||||
entry := fmt.Sprintf("%c %s", st.Shortcut(), st.Label())
|
||||
if i == m.Cursor {
|
||||
label = m.Styles.Selected.Render("▸ " + st.Label())
|
||||
lines = append(lines, m.Styles.Selected.Render("▸ "+entry))
|
||||
} else {
|
||||
label = m.Styles.Normal.Render(label)
|
||||
lines = append(lines, m.Styles.Normal.Render(" "+entry))
|
||||
}
|
||||
lines = append(lines, label)
|
||||
}
|
||||
body := strings.Join(lines, "\n")
|
||||
w := m.Width
|
||||
|
||||
Reference in New Issue
Block a user