Improve delete UX and wrap the helpbar on narrow terminals.
Confirm with x, force-delete with X, and wrap keybinding hints so all shortcuts stay visible. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+75
-38
@@ -42,6 +42,11 @@ func (m Model) helpEntries() []helpEntry {
|
||||
{"enter", "apply"},
|
||||
{"esc", "cancel"},
|
||||
}
|
||||
case ModeConfirmDelete:
|
||||
return []helpEntry{
|
||||
{"y/enter", "confirm"},
|
||||
{"esc", "cancel"},
|
||||
}
|
||||
default:
|
||||
return []helpEntry{
|
||||
{"j/k", "navigate"},
|
||||
@@ -52,64 +57,96 @@ func (m Model) helpEntries() []helpEntry {
|
||||
{"p", "project"},
|
||||
{"l", "list"},
|
||||
{"s", "status"},
|
||||
{"X", "delete"},
|
||||
{"x", "delete"},
|
||||
{"X", "force delete"},
|
||||
{"q", "quit"},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m Model) renderHelpbar() string {
|
||||
var parts []string
|
||||
func (m Model) helpParts() []string {
|
||||
parts := make([]string, 0, len(m.helpEntries()))
|
||||
for _, e := range m.helpEntries() {
|
||||
parts = append(parts, m.styles.HelpKey.Render(e.key)+" "+m.styles.HelpDesc.Render(e.desc))
|
||||
}
|
||||
return parts
|
||||
}
|
||||
|
||||
func (m Model) helpSep() string {
|
||||
sep := m.styles.HelpSep.String()
|
||||
if sep == "" {
|
||||
sep = " "
|
||||
return " "
|
||||
}
|
||||
return strings.Join(parts, sep)
|
||||
return sep
|
||||
}
|
||||
|
||||
// wrapHelpParts packs styled help snippets into lines that fit within width.
|
||||
func wrapHelpParts(parts []string, width int, sep string) []string {
|
||||
if width < 1 {
|
||||
width = 1
|
||||
}
|
||||
sepW := lipgloss.Width(sep)
|
||||
var lines []string
|
||||
var cur string
|
||||
|
||||
for _, p := range parts {
|
||||
pw := lipgloss.Width(p)
|
||||
if cur == "" {
|
||||
cur = p
|
||||
// Oversized single entry still gets its own line so nothing is dropped.
|
||||
if pw > width {
|
||||
lines = append(lines, cur)
|
||||
cur = ""
|
||||
}
|
||||
continue
|
||||
}
|
||||
if lipgloss.Width(cur)+sepW+pw <= width {
|
||||
cur = cur + sep + p
|
||||
continue
|
||||
}
|
||||
lines = append(lines, cur)
|
||||
cur = p
|
||||
if pw > width {
|
||||
lines = append(lines, cur)
|
||||
cur = ""
|
||||
}
|
||||
}
|
||||
if cur != "" {
|
||||
lines = append(lines, cur)
|
||||
}
|
||||
if len(lines) == 0 {
|
||||
return []string{""}
|
||||
}
|
||||
return lines
|
||||
}
|
||||
|
||||
func (m Model) renderFooter() string {
|
||||
help := m.renderHelpbar()
|
||||
ver := m.styles.Version.Render(m.version)
|
||||
|
||||
width := m.width
|
||||
if width <= 0 {
|
||||
width = lipgloss.Width(help) + lipgloss.Width(ver) + 1
|
||||
width = 80
|
||||
}
|
||||
|
||||
helpW := lipgloss.Width(help)
|
||||
ver := m.styles.Version.Render(m.version)
|
||||
verW := lipgloss.Width(ver)
|
||||
gap := width - helpW - verW
|
||||
if gap < 1 {
|
||||
maxHelp := width - verW - 1
|
||||
if maxHelp < 0 {
|
||||
maxHelp = 0
|
||||
}
|
||||
help = truncateWidth(help, maxHelp)
|
||||
helpW = lipgloss.Width(help)
|
||||
gap = width - helpW - verW
|
||||
if gap < 1 {
|
||||
gap = 1
|
||||
}
|
||||
}
|
||||
return help + strings.Repeat(" ", gap) + ver
|
||||
}
|
||||
sep := m.helpSep()
|
||||
parts := m.helpParts()
|
||||
|
||||
func truncateWidth(s string, max int) string {
|
||||
if max <= 0 {
|
||||
return ""
|
||||
}
|
||||
if lipgloss.Width(s) <= max {
|
||||
return s
|
||||
}
|
||||
runes := []rune(s)
|
||||
for len(runes) > 0 {
|
||||
runes = runes[:len(runes)-1]
|
||||
if lipgloss.Width(string(runes)) <= max-1 {
|
||||
return string(runes) + "…"
|
||||
// Wrap help across the full width so all bindings stay visible.
|
||||
lines := wrapHelpParts(parts, width, sep)
|
||||
|
||||
// Place version on the last line to the right when it fits; otherwise
|
||||
// put it on an extra right-aligned line.
|
||||
last := lines[len(lines)-1]
|
||||
gap := width - lipgloss.Width(last) - verW
|
||||
if gap >= 1 {
|
||||
lines[len(lines)-1] = last + strings.Repeat(" ", gap) + ver
|
||||
} else {
|
||||
pad := width - verW
|
||||
if pad < 0 {
|
||||
pad = 0
|
||||
}
|
||||
lines = append(lines, strings.Repeat(" ", pad)+ver)
|
||||
}
|
||||
return ""
|
||||
|
||||
return strings.Join(lines, "\n")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user