Skip to content

Commit e2a3fd9

Browse files
intel352claude
andcommitted
fix: update autocomplete with all commands, add scroll limit, verify status bar
- NewAutocomplete: add 12 missing slash commands (/plan, /approve, /reject, /fleet, /team, /review, /compact, /loop, /cron, /mcp, /jobs, /login) - View: cap dropdown at maxVisibleItems (10) with ↑/↓ scroll indicators so the dropdown cannot overflow terminal height - StatusBar.View: show provider/model together (e.g. "anthropic/claude-…") when both fields are set, falling back to whichever is available Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 110d3fa commit e2a3fd9

2 files changed

Lines changed: 60 additions & 7 deletions

File tree

internal/tui/components/autocomplete.go

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package components
22

33
import (
4+
"fmt"
45
"strings"
56

67
tea "charm.land/bubbletea/v2"
@@ -29,6 +30,9 @@ type AutocompleteSelectedMsg struct {
2930
Command string
3031
}
3132

33+
// maxVisibleItems is the maximum number of autocomplete items shown at once.
34+
const maxVisibleItems = 10
35+
3236
// NewAutocomplete creates an autocomplete model with all known commands.
3337
func NewAutocomplete() AutocompleteModel {
3438
commands := []CommandEntry{
@@ -40,6 +44,18 @@ func NewAutocomplete() AutocompleteModel {
4044
{Name: "/sessions", Desc: "List sessions"},
4145
{Name: "/provider", Desc: "Provider management"},
4246
{Name: "/exit", Desc: "Quit ratchet"},
47+
{Name: "/plan", Desc: "Show plan mode info"},
48+
{Name: "/approve", Desc: "Approve a proposed plan"},
49+
{Name: "/reject", Desc: "Reject a proposed plan"},
50+
{Name: "/fleet", Desc: "Start fleet execution for a plan"},
51+
{Name: "/team", Desc: "Team management"},
52+
{Name: "/review", Desc: "Run code-reviewer on current git diff"},
53+
{Name: "/compact", Desc: "Compress conversation context"},
54+
{Name: "/loop", Desc: "Schedule a recurring command"},
55+
{Name: "/cron", Desc: "Schedule with cron expression"},
56+
{Name: "/mcp", Desc: "MCP tool management"},
57+
{Name: "/jobs", Desc: "Show job control panel"},
58+
{Name: "/login", Desc: "Re-authenticate provider"},
4359
}
4460
return AutocompleteModel{commands: commands}
4561
}
@@ -109,7 +125,7 @@ func (m AutocompleteModel) Update(msg tea.Msg) (AutocompleteModel, tea.Cmd) {
109125
return m, nil
110126
}
111127

112-
// View renders the autocomplete dropdown.
128+
// View renders the autocomplete dropdown, capped at maxVisibleItems rows.
113129
func (m AutocompleteModel) View(t theme.Theme, width int) string {
114130
if !m.visible || len(m.matches) == 0 {
115131
return ""
@@ -130,17 +146,50 @@ func (m AutocompleteModel) View(t theme.Theme, width int) string {
130146
Foreground(lipgloss.Color("#FFFFFF")).
131147
Width(maxWidth)
132148

149+
mutedStyle := lipgloss.NewStyle().
150+
Foreground(t.Muted).
151+
Width(maxWidth)
152+
153+
total := len(m.matches)
154+
155+
// Compute a window of maxVisibleItems around the cursor.
156+
start := m.cursor - maxVisibleItems/2
157+
if start < 0 {
158+
start = 0
159+
}
160+
end := start + maxVisibleItems
161+
if end > total {
162+
end = total
163+
start = end - maxVisibleItems
164+
if start < 0 {
165+
start = 0
166+
}
167+
}
168+
133169
var sb strings.Builder
134-
for i, cmd := range m.matches {
135-
line := " " + cmd.Name + " " + cmd.Desc
170+
first := true
171+
172+
if start > 0 {
173+
sb.WriteString(mutedStyle.Render(fmt.Sprintf(" ↑ %d more", start)))
174+
first = false
175+
}
176+
177+
for i := start; i < end; i++ {
178+
if !first {
179+
sb.WriteString("\n")
180+
}
181+
first = false
182+
line := " " + m.matches[i].Name + " " + m.matches[i].Desc
136183
if i == m.cursor {
137184
sb.WriteString(selectedStyle.Render(line))
138185
} else {
139186
sb.WriteString(style.Render(line))
140187
}
141-
if i < len(m.matches)-1 {
142-
sb.WriteString("\n")
143-
}
188+
}
189+
190+
if end < total {
191+
sb.WriteString("\n")
192+
sb.WriteString(mutedStyle.Render(fmt.Sprintf(" ↓ %d more", total-end)))
144193
}
145194

146195
return lipgloss.NewStyle().

internal/tui/components/statusbar.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,12 @@ func (s StatusBar) View(t theme.Theme) string {
3535
elapsed := formatElapsed(time.Since(s.SessionStart))
3636

3737
segments := []string{" " + dir}
38-
if s.Model != "" {
38+
if s.Provider != "" && s.Model != "" {
39+
segments = append(segments, s.Provider+"/"+s.Model)
40+
} else if s.Model != "" {
3941
segments = append(segments, s.Model)
42+
} else if s.Provider != "" {
43+
segments = append(segments, s.Provider)
4044
}
4145
if s.ActiveAgents > 0 {
4246
segments = append(segments, fmt.Sprintf("agents: %d", s.ActiveAgents))

0 commit comments

Comments
 (0)