on main help sign in
chore: small ui fixes
3603a74Kujtim Hoxha
go.mod+1−1
@@ -32,7 +32,6 @@ require (
32 github.com/pressly/goose/v3 v3.24.2
32 github.com/pressly/goose/v3 v3.24.2
33 github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
33 github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
34 github.com/sahilm/fuzzy v0.1.1
34 github.com/sahilm/fuzzy v0.1.1
35− github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3
36 github.com/spf13/cobra v1.9.1
35 github.com/spf13/cobra v1.9.1
37 github.com/spf13/viper v1.20.0
36 github.com/spf13/viper v1.20.0
38 github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c
37 github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c
@@ -105,6 +104,7 @@ require (
105 github.com/rivo/uniseg v0.4.7
104 github.com/rivo/uniseg v0.4.7
106 github.com/rogpeppe/go-internal v1.14.1 // indirect
105 github.com/rogpeppe/go-internal v1.14.1 // indirect
107 github.com/sagikazarmark/locafero v0.7.0 // indirect
106 github.com/sagikazarmark/locafero v0.7.0 // indirect
107+ github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
108 github.com/sethvargo/go-retry v0.3.0 // indirect
108 github.com/sethvargo/go-retry v0.3.0 // indirect
109 github.com/sourcegraph/conc v0.3.0 // indirect
109 github.com/sourcegraph/conc v0.3.0 // indirect
110 github.com/spf13/afero v1.12.0 // indirect
110 github.com/spf13/afero v1.12.0 // indirect
internal/tui/components/chat/messages/renderer.go+6−5
@@ -125,7 +125,7 @@ func (br baseRenderer) makeHeader(v *toolCallCmp, tool string, width int, params
125 icon = t.S().Muted.Render(styles.ToolPending)
125 icon = t.S().Muted.Render(styles.ToolPending)
126 }
126 }
127 tool = t.S().Base.Foreground(t.Blue).Render(tool)
127 tool = t.S().Base.Foreground(t.Blue).Render(tool)
128− prefix := fmt.Sprintf("%s %s: ", icon, tool)
128+ prefix := fmt.Sprintf("%s %s ", icon, tool)
129 return prefix + renderParamList(width-lipgloss.Width(prefix), params...)
129 return prefix + renderParamList(width-lipgloss.Width(prefix), params...)
130}
130}
131
131
@@ -517,6 +517,7 @@ func (tr agentRenderer) Render(v *toolCallCmp) string {
517
517
518// renderParamList renders params, params[0] (params[1]=params[2] ....)
518// renderParamList renders params, params[0] (params[1]=params[2] ....)
519func renderParamList(paramsWidth int, params ...string) string {
519func renderParamList(paramsWidth int, params ...string) string {
520+ t := styles.CurrentTheme()
520 if len(params) == 0 {
521 if len(params) == 0 {
521 return ""
522 return ""
522 }
523 }
@@ -526,7 +527,7 @@ func renderParamList(paramsWidth int, params ...string) string {
526 }
527 }
527
528
528 if len(params) == 1 {
529 if len(params) == 1 {
529− return mainParam
530+ return t.S().Subtle.Render(mainParam)
530 }
531 }
531 otherParams := params[1:]
532 otherParams := params[1:]
532 // create pairs of key/value
533 // create pairs of key/value
@@ -548,14 +549,14 @@ func renderParamList(paramsWidth int, params ...string) string {
548 remainingWidth := paramsWidth - lipgloss.Width(partsRendered) - 3 // count for " ()"
549 remainingWidth := paramsWidth - lipgloss.Width(partsRendered) - 3 // count for " ()"
549 if remainingWidth < 30 {
550 if remainingWidth < 30 {
550 // No space for the params, just show the main
551 // No space for the params, just show the main
551− return mainParam
552+ return t.S().Subtle.Render(mainParam)
552 }
553 }
553
554
554 if len(parts) > 0 {
555 if len(parts) > 0 {
555 mainParam = fmt.Sprintf("%s (%s)", mainParam, strings.Join(parts, ", "))
556 mainParam = fmt.Sprintf("%s (%s)", mainParam, strings.Join(parts, ", "))
556 }
557 }
557
558
558− return ansi.Truncate(mainParam, paramsWidth, "...")
559+ return t.S().Subtle.Render(ansi.Truncate(mainParam, paramsWidth, "..."))
559}
560}
560
561
561// earlyState returns immediately‑rendered error/cancelled/ongoing states.
562// earlyState returns immediately‑rendered error/cancelled/ongoing states.
@@ -580,7 +581,7 @@ func earlyState(header string, v *toolCallCmp) (string, bool) {
580func joinHeaderBody(header, body string) string {
581func joinHeaderBody(header, body string) string {
581 t := styles.CurrentTheme()
582 t := styles.CurrentTheme()
582 body = t.S().Base.PaddingLeft(2).Render(body)
583 body = t.S().Base.PaddingLeft(2).Render(body)
583− return lipgloss.JoinVertical(lipgloss.Left, header, body, "")
584+ return lipgloss.JoinVertical(lipgloss.Left, header, "", body, "")
584}
585}
585
586
586func renderPlainContent(v *toolCallCmp, content string) string {
587func renderPlainContent(v *toolCallCmp, content string) string {
internal/tui/components/core/status/status.go+25−8
@@ -1,6 +1,7 @@
1package status
1package status
2
2
3import (
3import (
4+ "strings"
4 "time"
5 "time"
5
6
6 "github.com/charmbracelet/bubbles/v2/help"
7 "github.com/charmbracelet/bubbles/v2/help"
@@ -10,6 +11,8 @@ import (
10 "github.com/charmbracelet/crush/internal/session"
11 "github.com/charmbracelet/crush/internal/session"
11 "github.com/charmbracelet/crush/internal/tui/styles"
12 "github.com/charmbracelet/crush/internal/tui/styles"
12 "github.com/charmbracelet/crush/internal/tui/util"
13 "github.com/charmbracelet/crush/internal/tui/util"
14+ "github.com/charmbracelet/lipgloss/v2"
15+ "github.com/charmbracelet/x/ansi"
13)
16)
14
17
15type StatusCmp interface {
18type StatusCmp interface {
@@ -94,18 +97,32 @@ func (m *statusCmp) View() tea.View {
94 t := styles.CurrentTheme()
97 t := styles.CurrentTheme()
95 status := t.S().Base.Padding(0, 1, 1, 1).Render(m.help.View(m.keyMap))
98 status := t.S().Base.Padding(0, 1, 1, 1).Render(m.help.View(m.keyMap))
96 if m.info.Msg != "" {
99 if m.info.Msg != "" {
97− switch m.info.Type {
100+ status = m.infoMsg()
98− case util.InfoTypeError:
99− status = t.S().Base.Background(t.Error).Padding(0, 1).Width(m.width).Render(m.info.Msg)
100− case util.InfoTypeWarn:
101− status = t.S().Base.Background(t.Warning).Padding(0, 1).Width(m.width).Render(m.info.Msg)
102− default:
103− status = t.S().Base.Background(t.Info).Padding(0, 1).Width(m.width).Render(m.info.Msg)
104− }
105 }
101 }
106 return tea.NewView(status)
102 return tea.NewView(status)
107}
103}
108
104
105+func (m *statusCmp) infoMsg() string {
106+ t := styles.CurrentTheme()
107+ message := ""
108+ infoType := ""
109+ switch m.info.Type {
110+ case util.InfoTypeError:
111+ infoType = t.S().Base.Background(t.Red).Padding(0, 1).Render("ERROR")
112+ width := m.width - lipgloss.Width(infoType)
113+ message = t.S().Base.Background(t.Error).Foreground(t.White).Padding(0, 1).Width(width).Render(ansi.Truncate(m.info.Msg, width, "…"))
114+ case util.InfoTypeWarn:
115+ infoType = t.S().Base.Foreground(t.BgOverlay).Background(t.Yellow).Padding(0, 1).Render("WARNING")
116+ width := m.width - lipgloss.Width(infoType)
117+ message = t.S().Base.Foreground(t.BgOverlay).Background(t.Warning).Padding(0, 1).Width(width).Render(ansi.Truncate(m.info.Msg, width, "…"))
118+ default:
119+ infoType = t.S().Base.Foreground(t.BgOverlay).Background(t.Green).Padding(0, 1).Render("OKAY!")
120+ width := m.width - lipgloss.Width(infoType)
121+ message = t.S().Base.Background(t.Success).Foreground(t.White).Padding(0, 1).Width(width).Render(ansi.Truncate(m.info.Msg, width, "…"))
122+ }
123+ return strings.Join([]string{infoType, message}, "")
124+}
125+
109func (m *statusCmp) ToggleFullHelp() {
126func (m *statusCmp) ToggleFullHelp() {
110 m.help.ShowAll = !m.help.ShowAll
127 m.help.ShowAll = !m.help.ShowAll
111}
128}
internal/tui/keys.go+2−2
@@ -61,8 +61,8 @@ func (k KeyMap) FullHelp() [][]key.Binding {
61 }
61 }
62 }
62 }
63
63
64− for i := 0; i < len(cleaned); i += 2 {
64+ for i := 0; i < len(cleaned); i += 3 {
65− end := min(i+2, len(cleaned))
65+ end := min(i+3, len(cleaned))
66 m = append(m, cleaned[i:end])
66 m = append(m, cleaned[i:end])
67 }
67 }
68 return m
68 return m
internal/tui/styles/crush.go+2
@@ -41,6 +41,8 @@ func NewCrushTheme() *Theme {
41
41
42 Blue: charmtone.Malibu,
42 Blue: charmtone.Malibu,
43
43
44+ Yellow: charmtone.Mustard,
45+
44 Green: charmtone.Julep,
46 Green: charmtone.Julep,
45 GreenDark: charmtone.Guac,
47 GreenDark: charmtone.Guac,
46 GreenLight: charmtone.Bok,
48 GreenLight: charmtone.Bok,
internal/tui/styles/theme.go+4−2
@@ -54,9 +54,13 @@ type Theme struct {
54 // Colors
54 // Colors
55 // White
55 // White
56 White color.Color
56 White color.Color
57+
57 // Blues
58 // Blues
58 Blue color.Color
59 Blue color.Color
59
60
61+ // Yellows
62+ Yellow color.Color
63+
60 // Greens
64 // Greens
61 Green color.Color
65 Green color.Color
62 GreenDark color.Color
66 GreenDark color.Color
@@ -67,8 +71,6 @@ type Theme struct {
67 RedDark color.Color
71 RedDark color.Color
68 RedLight color.Color
72 RedLight color.Color
69
73
70− // TODO: add any others needed
71−
72 styles *Styles
74 styles *Styles
73}
75}
74
76
internal/tui/tui.go+1−7
@@ -94,12 +94,6 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
94
94
95 switch msg := msg.(type) {
95 switch msg := msg.(type) {
96 case tea.KeyboardEnhancementsMsg:
96 case tea.KeyboardEnhancementsMsg:
97− logging.Info(
98− "Keyboard enhancements detected",
99− "Disambiguation", msg.SupportsKeyDisambiguation(),
100− "ReleaseKeys", msg.SupportsKeyReleases(),
101− "UniformKeys", msg.SupportsUniformKeyLayout(),
102− )
103 return a, nil
97 return a, nil
104 case tea.WindowSizeMsg:
98 case tea.WindowSizeMsg:
105 return a, a.handleWindowResize(msg.Width, msg.Height)
99 return a, a.handleWindowResize(msg.Width, msg.Height)
@@ -260,7 +254,7 @@ func (a *appModel) handleWindowResize(width, height int) tea.Cmd {
260 var cmds []tea.Cmd
254 var cmds []tea.Cmd
261 a.wWidth, a.wHeight = width, height
255 a.wWidth, a.wHeight = width, height
262 if a.showingFullHelp {
256 if a.showingFullHelp {
263− height -= 3
257+ height -= 4
264 } else {
258 } else {
265 height -= 2
259 height -= 2
266 }
260 }