on main help sign in
fix: use canvas to render UI view
4c223c3Ayman Bagabas
internal/ui/model/ui.go+17−2
@@ -23,6 +23,7 @@ import (
23 "github.com/charmbracelet/crush/internal/version"
23 "github.com/charmbracelet/crush/internal/version"
24 uv "github.com/charmbracelet/ultraviolet"
24 uv "github.com/charmbracelet/ultraviolet"
25 "github.com/charmbracelet/ultraviolet/screen"
25 "github.com/charmbracelet/ultraviolet/screen"
26+ "github.com/charmbracelet/x/ansi"
26)
27)
27
28
28// uiFocusState represents the current focus state of the UI.
29// uiFocusState represents the current focus state of the UI.
@@ -224,7 +225,7 @@ func (m *UI) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
224}
225}
225
226
226// Draw implements [tea.Layer] and draws the UI model.
227// Draw implements [tea.Layer] and draws the UI model.
227−func (m *UI) Draw(scr tea.Screen, area tea.Rectangle) {
228+func (m *UI) Draw(scr uv.Screen, area uv.Rectangle) {
228 layout := generateLayout(m, area.Dx(), area.Dy())
229 layout := generateLayout(m, area.Dx(), area.Dy())
229
230
230 // Clear the screen first
231 // Clear the screen first
@@ -334,7 +335,21 @@ func (m *UI) View() tea.View {
334 v.Cursor = cur
335 v.Cursor = cur
335 }
336 }
336
337
338+ // TODO: Switch to lipgloss.Canvas when available
339+ canvas := uv.NewScreenBuffer(m.width, m.height)
340+ canvas.Method = ansi.GraphemeWidth
341+
342+ m.Draw(canvas, canvas.Bounds())
343+
344+ content := strings.ReplaceAll(canvas.Render(), "\r\n", "\n") // normalize newlines
345+ contentLines := strings.Split(content, "\n")
346+ for i, line := range contentLines {
347+ // Trim trailing spaces for concise rendering
348+ contentLines[i] = strings.TrimRight(line, " ")
349+ }
350+
351+ content = strings.Join(contentLines, "\n")
337− v.Content = m
352+ v.Content = content
338 if m.sendProgressBar && m.com.App != nil && m.com.App.AgentCoordinator != nil && m.com.App.AgentCoordinator.IsBusy() {
353 if m.sendProgressBar && m.com.App != nil && m.com.App.AgentCoordinator != nil && m.com.App.AgentCoordinator.IsBusy() {
339 // HACK: use a random percentage to prevent ghostty from hiding it
354 // HACK: use a random percentage to prevent ghostty from hiding it
340 // after a timeout.
355 // after a timeout.