renderer.go

  1package tea
  2
  3import (
  4	"fmt"
  5	"image/color"
  6
  7	"github.com/charmbracelet/colorprofile"
  8)
  9
 10const (
 11	// defaultFramerate specifies the maximum interval at which we should
 12	// update the view.
 13	defaultFPS = 60
 14	maxFPS     = 120
 15)
 16
 17// renderer is the interface for Bubble Tea renderers.
 18type renderer interface {
 19	// close closes the renderer and flushes any remaining data.
 20	close() error
 21
 22	// render renders a frame to the output.
 23	render(View)
 24
 25	// hit returns possible hit messages for the renderer.
 26	hit(MouseMsg) []Msg
 27
 28	// flush flushes the renderer's buffer to the output.
 29	flush(*Program) error
 30
 31	// reset resets the renderer's state to its initial state.
 32	reset()
 33
 34	// insertAbove inserts unmanaged lines above the renderer.
 35	insertAbove(string)
 36
 37	// enterAltScreen enters the alternate screen buffer.
 38	enterAltScreen()
 39
 40	// exitAltScreen exits the alternate screen buffer.
 41	exitAltScreen()
 42
 43	// showCursor shows the cursor.
 44	showCursor()
 45
 46	// hideCursor hides the cursor.
 47	hideCursor()
 48
 49	// setCursorColor sets the terminal's cursor color.
 50	setCursorColor(color.Color)
 51
 52	// setForegroundColor sets the terminal's foreground color.
 53	setForegroundColor(color.Color)
 54
 55	// setBackgroundColor sets the terminal's background color.
 56	setBackgroundColor(color.Color)
 57
 58	// setWindowTitle sets the terminal window title.
 59	setWindowTitle(string)
 60
 61	// resize notify the renderer of a terminal resize.
 62	resize(int, int)
 63
 64	// setColorProfile sets the color profile.
 65	setColorProfile(colorprofile.Profile)
 66
 67	// clearScreen clears the screen.
 68	clearScreen()
 69
 70	// repaint forces a full repaint.
 71	repaint()
 72
 73	writeString(string) (int, error)
 74
 75	// resetLinesRendered ensures exec output remains on screen on exit
 76	resetLinesRendered()
 77}
 78
 79// repaintMsg forces a full repaint.
 80type repaintMsg struct{}
 81
 82type printLineMessage struct {
 83	messageBody string
 84}
 85
 86// Println prints above the Program. This output is unmanaged by the program and
 87// will persist across renders by the Program.
 88//
 89// Unlike fmt.Println (but similar to log.Println) the message will be print on
 90// its own line.
 91//
 92// If the altscreen is active no output will be printed.
 93func Println(args ...any) Cmd {
 94	return func() Msg {
 95		return printLineMessage{
 96			messageBody: fmt.Sprint(args...),
 97		}
 98	}
 99}
100
101// Printf prints above the Program. It takes a format template followed by
102// values similar to fmt.Printf. This output is unmanaged by the program and
103// will persist across renders by the Program.
104//
105// Unlike fmt.Printf (but similar to log.Printf) the message will be print on
106// its own line.
107//
108// If the altscreen is active no output will be printed.
109func Printf(template string, args ...any) Cmd {
110	return func() Msg {
111		return printLineMessage{
112			messageBody: fmt.Sprintf(template, args...),
113		}
114	}
115}
116
117// encodeCursorStyle returns the integer value for the given cursor style and
118// blink state.
119func encodeCursorStyle(style CursorShape, blink bool) int {
120	// We're using the ANSI escape sequence values for cursor styles.
121	// We need to map both [style] and [steady] to the correct value.
122	style = (style * 2) + 1 //nolint:mnd
123	if !blink {
124		style++
125	}
126	return int(style)
127}