charmbracelet / charmbracelet/bubbletea
When a large update is performed, it will cause a flash.
- 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
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