gitstack

grindlemire/go-tui code browser

1.5 KB Go 57 lines 2026-02-27 · 6ff1e97 raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package tui

import (
	"io"
	"sync/atomic"
)

// inlineStreamWriter implements io.WriteCloser for streaming text to the
// inline history region. Writes are queued onto the app's main event loop.
// Goroutine-safe.
type inlineStreamWriter struct {
	app    *App
	closed atomic.Bool
}

func newInlineStreamWriter(app *App) *inlineStreamWriter {
	return &inlineStreamWriter{app: app}
}

func (w *inlineStreamWriter) Write(p []byte) (int, error) {
	if w.closed.Load() {
		return 0, io.ErrClosedPipe
	}
	// Copy data so the caller can reuse the slice.
	data := make([]byte, len(p))
	copy(data, p)

	w.app.QueueUpdate(func() {
		w.app.ensureInlineSession()
		w.app.inlineSession.ensureInitialized(&w.app.inlineLayout, w.app.inlineStartRow)
		width, _ := w.app.terminal.Size()
		w.app.inlineSession.appendBytes(&w.app.inlineLayout, w.app.inlineStartRow, width, data)
		w.app.MarkDirty()
	})
	return len(p), nil
}

func (w *inlineStreamWriter) Close() error {
	if w.closed.Swap(true) {
		return nil // already closed
	}
	w.app.QueueUpdate(func() {
		w.app.ensureInlineSession()
		w.app.inlineSession.finalizePartial(&w.app.inlineLayout)
		if w.app.activeStreamWriter == w {
			w.app.activeStreamWriter = nil
		}
		w.app.MarkDirty()
	})
	return nil
}

// nopStreamWriter is returned when StreamAbove is called outside inline mode.
type nopStreamWriter struct{}

func (w *nopStreamWriter) Write(p []byte) (int, error) { return len(p), nil }
func (w *nopStreamWriter) Close() error                { return nil }