charmbracelet / charmbracelet/bubbletea

When a large update is performed, it will cause a flash.

Open
#1,032 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
44.9k
Forks
1.3k
PR merge metrics
No merged PRs in 30d

Description

**Describe the bug**
When a large update is performed, it will cause a flash.

**Setup**
- OS: Fedora
- Shell: zsh
- Terminal Emulator: kitty
- Terminal Multiplexer: zellij

**To Reproduce**
Steps to reproduce the behavior:
1. go run main.go
2. Press Tab to let tui update
4. See error

**Source Code**
```golang
package main

import (
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"log"
"math/rand"
"strings"
)

type sessionState uint

const (
timerView sessionState = iota
spinnerView
)

var (
modelStyle = lipgloss.NewStyle().
Width(80).
Height(35).
Align(lipgloss.Center, lipgloss.Center).
BorderStyle(lipgloss.HiddenBorder()).
Background(lipgloss.Color("#4B4B4B"))

focusedModelStyle = lipgloss.NewStyle().
Width(80).
Height(35).
Align(lipgloss.Center, lipgloss.Center).
BorderStyle(lipgloss.NormalBorder()).
BorderForeground(lipgloss.Color("69")).
Background(lipgloss.Color("#4B4B4B"))
)

type mainModel struct {
state sessionState
}

func newModel() mainModel {
m := mainModel{}
return m
}

func (m mainModel) Init() tea.Cmd {
return tea.Batch()
}

func (m mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmds []tea.Cmd
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "ctrl+c", "q":
return m, tea.Quit
case "tab":
if m.state == timerView {
m.state = spinnerView
} else {
m.state = timerView
}
}
}
return m, tea.Batch(cmds...)
}

func (m mainModel) View() string {
var s string
example1 := strings.Repeat("AAAA", 760)
example2 := strings.Repeat("Test", 760)
example := []string{example1, example2}
if m.state == timerView {
s += lipgloss.JoinHorizontal(lipgloss.Top, focusedModelStyle.Render(example[rand.Intn(2)]), modelStyle.Render(example[rand.Intn(2)]))
} else {
s += lipgloss.JoinHorizontal(lipgloss.Top, modelStyle.Render(example[rand.Intn(2)]), focusedModelStyle.Render(example[rand.Intn(2)]))
}
return s
}

func main() {
p := tea.NewProgram(newModel(), tea.WithAltScreen())

if _, err := p.Run(); err != nil {
log.Fatal(err)
}
}
```

**Expected behavior**
Normal update without flash

**Screenshots**
https://github.com/charmbracelet/bubbletea/assets/107802416/4f6337cb-2d4b-44b4-ade1-c31b7866ceef

**Additional context**
https://github.com/yorukot/superfile/issues/122

Contributor guide

Open the contributing guide

Research direction

Run the provided main.go reproduction and begin at tea.NewProgram, Update, and View to trace what happens during the large tab-triggered redraw. Compare the behavior with the linked superfile issue and identify the rendering path involved. Done means the same large update completes without a visible flash.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
cli, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.