feat(tui): always-visible capture bar with focus cycling
Replace drawer-based input with permanent capture bar at bottom. Focus defaults to capture on startup — open nib, start typing. - Remove stateInput; route via focusCapture/focusList/focusDetail - Tab cycles: capture → list → detail (split) → capture - Esc cascades: clear search → clear filter → focus capture - Capture bar shows blinking cursor when focused, dims when not - Intent cycling moved from tab to i (tab now cycles focus) - Parse preview shown inline in status bar while typing - Content area constant height (no layout thrash from drawer)
This commit is contained in:
+15
-12
@@ -30,12 +30,10 @@ func renderTab(label, key string, active bool) string {
|
||||
func renderStatusBar(m model, width int) string {
|
||||
var leftParts []string
|
||||
|
||||
if m.state == stateList {
|
||||
leftParts = append(leftParts, renderTab("capture", "a", false))
|
||||
}
|
||||
|
||||
if m.status != "" {
|
||||
leftParts = append(leftParts, statusStyle.Render(m.status))
|
||||
} else if preview := m.input.previewText(); m.focus == focusCapture && preview != "" {
|
||||
leftParts = append(leftParts, drawerPreviewStyle.Render(preview))
|
||||
} else {
|
||||
leftParts = append(leftParts, statusStyle.Render(countText(m)))
|
||||
}
|
||||
@@ -76,8 +74,6 @@ func contextHints(m model) []hint {
|
||||
default:
|
||||
return []hint{{"p", "promote"}, {"D", "demote"}, {"c", "copy"}, {"e", "edit"}, {"r", "run"}, {"f", "fill"}, {"!", "pin"}, {"esc", "back"}}
|
||||
}
|
||||
case stateInput:
|
||||
return nil
|
||||
case stateTagFilter:
|
||||
return []hint{{"j/k", "nav"}, {"enter", "select"}, {"esc", "cancel"}}
|
||||
case stateConfirm:
|
||||
@@ -86,16 +82,23 @@ func contextHints(m model) []hint {
|
||||
return []hint{{"j/k", "nav"}, {"enter", "select"}, {"esc", "cancel"}}
|
||||
case stateAbsorb:
|
||||
return []hint{{"j/k", "nav"}, {"enter", "absorb"}, {"esc", "cancel"}}
|
||||
}
|
||||
|
||||
switch m.focus {
|
||||
case focusCapture:
|
||||
return []hint{{"enter", "submit"}, {"esc", "browse"}, {"?…", "search"}, {"-", "todo"}, {"@", "event"}}
|
||||
case focusDetail:
|
||||
if m.splitDetail {
|
||||
return []hint{{"h", "list"}, {"c", "copy"}, {"e", "edit"}, {"p", "promote"}, {"!", "pin"}, {"tab", "capture"}}
|
||||
}
|
||||
return []hint{{"c", "copy"}, {"e", "edit"}, {"p", "promote"}, {"!", "pin"}, {"esc", "back"}}
|
||||
default:
|
||||
if m.splitDetail {
|
||||
if m.focus == focusDetail {
|
||||
return []hint{{"h", "list"}, {"c", "copy"}, {"e", "edit"}, {"p", "promote"}, {"D", "demote"}, {"!", "pin"}, {"esc", "back"}}
|
||||
}
|
||||
return []hint{{"l", "detail"}, {"d", "del"}, {"#", "filter"}, {"esc", "close"}, {"?", "help"}, {"q", "quit"}}
|
||||
return []hint{{"l", "detail"}, {"d", "del"}, {"#", "filter"}, {"tab", "capture"}, {"?", "help"}}
|
||||
}
|
||||
if m.mode == modeCards {
|
||||
return []hint{{"s", "sort"}, {"tab", "intent"}, {"?", "help"}, {"q", "quit"}}
|
||||
return []hint{{"s", "sort"}, {"i", "intent"}, {"tab", "capture"}, {"?", "help"}}
|
||||
}
|
||||
return []hint{{"?", "search"}, {"m", "absorb"}, {"d", "del"}, {"#", "filter"}, {"?", "help"}, {"q", "quit"}}
|
||||
return []hint{{"m", "absorb"}, {"d", "del"}, {"#", "filter"}, {"tab", "capture"}, {"?", "help"}}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user