on main help sign in
chore: small ui fixes

- fixed the tool call header - fixed the status error style - other small things

commit3603a74dd4561380651f542d87178096fc465b8e authorKujtim Hoxha <kujtimii.h@gmail.com> dateThu 19 Jun 2025, 12:33 (1 year ago) parent771835f
7 files changed+41−25
go.mod+1−1 internal/tui/components/chat/messages/renderer.go+6−5 internal/tui/components/core/status/status.go+25−8 internal/tui/keys.go+2−2 internal/tui/styles/crush.go+2 internal/tui/styles/theme.go+4−2 internal/tui/tui.go+1−7
go.mod+1−1
@@ -32,7 +32,6 @@ require (
3232 github.com/pressly/goose/v3 v3.24.2
3333 github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
3434 github.com/sahilm/fuzzy v0.1.1
35− github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3
3635 github.com/spf13/cobra v1.9.1
3736 github.com/spf13/viper v1.20.0
3837 github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c
@@ -105,6 +104,7 @@ require (
105104 github.com/rivo/uniseg v0.4.7
106105 github.com/rogpeppe/go-internal v1.14.1 // indirect
107106 github.com/sagikazarmark/locafero v0.7.0 // indirect
107+ github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
108108 github.com/sethvargo/go-retry v0.3.0 // indirect
109109 github.com/sourcegraph/conc v0.3.0 // indirect
110110 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
125125 icon = t.S().Muted.Render(styles.ToolPending)
126126 }
127127 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)
129129 return prefix + renderParamList(width-lipgloss.Width(prefix), params...)
130130}
131131
@@ -517,6 +517,7 @@ func (tr agentRenderer) Render(v *toolCallCmp) string {
517517
518518// renderParamList renders params, params[0] (params[1]=params[2] ....)
519519func renderParamList(paramsWidth int, params ...string) string {
520+ t := styles.CurrentTheme()
520521 if len(params) == 0 {
521522 return ""
522523 }
@@ -526,7 +527,7 @@ func renderParamList(paramsWidth int, params ...string) string {
526527 }
527528
528529 if len(params) == 1 {
529− return mainParam
530+ return t.S().Subtle.Render(mainParam)
530531 }
531532 otherParams := params[1:]
532533 // create pairs of key/value
@@ -548,14 +549,14 @@ func renderParamList(paramsWidth int, params ...string) string {
548549 remainingWidth := paramsWidth - lipgloss.Width(partsRendered) - 3 // count for " ()"
549550 if remainingWidth < 30 {
550551 // No space for the params, just show the main
551− return mainParam
552+ return t.S().Subtle.Render(mainParam)
552553 }
553554
554555 if len(parts) > 0 {
555556 mainParam = fmt.Sprintf("%s (%s)", mainParam, strings.Join(parts, ", "))
556557 }
557558
558− return ansi.Truncate(mainParam, paramsWidth, "...")
559+ return t.S().Subtle.Render(ansi.Truncate(mainParam, paramsWidth, "..."))
559560}
560561
561562// earlyState returns immediately‑rendered error/cancelled/ongoing states.
@@ -580,7 +581,7 @@ func earlyState(header string, v *toolCallCmp) (string, bool) {
580581func joinHeaderBody(header, body string) string {
581582 t := styles.CurrentTheme()
582583 body = t.S().Base.PaddingLeft(2).Render(body)
583− return lipgloss.JoinVertical(lipgloss.Left, header, body, "")
584+ return lipgloss.JoinVertical(lipgloss.Left, header, "", body, "")
584585}
585586
586587func renderPlainContent(v *toolCallCmp, content string) string {
internal/tui/components/core/status/status.go+25−8
@@ -1,6 +1,7 @@
11package status
22
33import (
4+ "strings"
45 "time"
56
67 "github.com/charmbracelet/bubbles/v2/help"
@@ -10,6 +11,8 @@ import (
1011 "github.com/charmbracelet/crush/internal/session"
1112 "github.com/charmbracelet/crush/internal/tui/styles"
1213 "github.com/charmbracelet/crush/internal/tui/util"
14+ "github.com/charmbracelet/lipgloss/v2"
15+ "github.com/charmbracelet/x/ansi"
1316)
1417
1518type StatusCmp interface {
@@ -94,18 +97,32 @@ func (m *statusCmp) View() tea.View {
9497 t := styles.CurrentTheme()
9598 status := t.S().Base.Padding(0, 1, 1, 1).Render(m.help.View(m.keyMap))
9699 if m.info.Msg != "" {
97− switch m.info.Type {
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− }
100+ status = m.infoMsg()
105101 }
106102 return tea.NewView(status)
107103}
108104
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+
109126func (m *statusCmp) ToggleFullHelp() {
110127 m.help.ShowAll = !m.help.ShowAll
111128}
internal/tui/keys.go+2−2
@@ -61,8 +61,8 @@ func (k KeyMap) FullHelp() [][]key.Binding {
6161 }
6262 }
6363
64− for i := 0; i < len(cleaned); i += 2 {
65− end := min(i+2, len(cleaned))
64+ for i := 0; i < len(cleaned); i += 3 {
65+ end := min(i+3, len(cleaned))
6666 m = append(m, cleaned[i:end])
6767 }
6868 return m
internal/tui/styles/crush.go+2
@@ -41,6 +41,8 @@ func NewCrushTheme() *Theme {
4141
4242 Blue: charmtone.Malibu,
4343
44+ Yellow: charmtone.Mustard,
45+
4446 Green: charmtone.Julep,
4547 GreenDark: charmtone.Guac,
4648 GreenLight: charmtone.Bok,
internal/tui/styles/theme.go+4−2
@@ -54,9 +54,13 @@ type Theme struct {
5454 // Colors
5555 // White
5656 White color.Color
57+
5758 // Blues
5859 Blue color.Color
5960
61+ // Yellows
62+ Yellow color.Color
63+
6064 // Greens
6165 Green color.Color
6266 GreenDark color.Color
@@ -67,8 +71,6 @@ type Theme struct {
6771 RedDark color.Color
6872 RedLight color.Color
6973
70− // TODO: add any others needed
71−
7274 styles *Styles
7375}
7476
internal/tui/tui.go+1−7
@@ -94,12 +94,6 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
9494
9595 switch msg := msg.(type) {
9696 case tea.KeyboardEnhancementsMsg:
97− logging.Info(
98− "Keyboard enhancements detected",
99− "Disambiguation", msg.SupportsKeyDisambiguation(),
100− "ReleaseKeys", msg.SupportsKeyReleases(),
101− "UniformKeys", msg.SupportsUniformKeyLayout(),
102− )
10397 return a, nil
10498 case tea.WindowSizeMsg:
10599 return a, a.handleWindowResize(msg.Width, msg.Height)
@@ -260,7 +254,7 @@ func (a *appModel) handleWindowResize(width, height int) tea.Cmd {
260254 var cmds []tea.Cmd
261255 a.wWidth, a.wHeight = width, height
262256 if a.showingFullHelp {
263− height -= 3
257+ height -= 4
264258 } else {
265259 height -= 2
266260 }