@@ -34,6 +34,7 @@ type standardRenderer struct {
34
34
ticker * time.Ticker
35
35
done chan struct {}
36
36
lastRender string
37
+ lastRenderedLines []string
37
38
linesRendered int
38
39
useANSICompressor bool
39
40
once sync.Once
@@ -174,7 +175,6 @@ func (r *standardRenderer) flush() {
174
175
}
175
176
176
177
newLines := strings .Split (r .buf .String (), "\n " )
177
- oldLines := strings .Split (r .lastRender , "\n " )
178
178
179
179
// If we know the output's height, we can use it to determine how many
180
180
// lines we can render. We drop lines from the top of the render buffer if
@@ -184,7 +184,6 @@ func (r *standardRenderer) flush() {
184
184
newLines = newLines [len (newLines )- r .height :]
185
185
}
186
186
187
- numLinesThisFlush := len (newLines )
188
187
flushQueuedMessages := len (r .queuedMessageLines ) > 0 && ! r .altScreenActive
189
188
190
189
if flushQueuedMessages {
@@ -210,7 +209,7 @@ func (r *standardRenderer) flush() {
210
209
// Paint new lines.
211
210
for i := 0 ; i < len (newLines ); i ++ {
212
211
canSkip := ! flushQueuedMessages && // Queuing messages triggers repaint -> we don't have access to previous frame content.
213
- len (oldLines ) > i && oldLines [i ] == newLines [i ] // Previously rendered line is the same.
212
+ len (r . lastRenderedLines ) > i && r . lastRenderedLines [i ] == newLines [i ] // Previously rendered line is the same.
214
213
215
214
if _ , ignore := r .ignoreLines [i ]; ignore || canSkip {
216
215
// Unless this is the last line, move the cursor down.
@@ -257,11 +256,11 @@ func (r *standardRenderer) flush() {
257
256
}
258
257
259
258
// Clearing left over content from last render.
260
- if r .linesRendered > numLinesThisFlush {
259
+ if r .linesRendered > len ( newLines ) {
261
260
buf .WriteString (ansi .EraseScreenBelow )
262
261
}
263
262
264
- r .linesRendered = numLinesThisFlush
263
+ r .linesRendered = len ( newLines )
265
264
266
265
// Make sure the cursor is at the start of the last line to keep rendering
267
266
// behavior consistent.
@@ -276,6 +275,11 @@ func (r *standardRenderer) flush() {
276
275
277
276
_ , _ = r .out .Write (buf .Bytes ())
278
277
r .lastRender = r .buf .String ()
278
+
279
+ // Save previously rendered lines for comparison in the next render. If we
280
+ // don't do this, we can't skip rendering lines that haven't changed.
281
+ // See https://github.com/charmbracelet/bubbletea/pull/1233
282
+ r .lastRenderedLines = newLines
279
283
r .buf .Reset ()
280
284
}
281
285
@@ -299,6 +303,7 @@ func (r *standardRenderer) write(s string) {
299
303
300
304
func (r * standardRenderer ) repaint () {
301
305
r .lastRender = ""
306
+ r .lastRenderedLines = nil
302
307
}
303
308
304
309
func (r * standardRenderer ) clearScreen () {
0 commit comments