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}