tea

package module
v2.0.0-alpha.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 18, 2024 License: MIT Imports: 32 Imported by: 36

README

Bubble Tea

Bubble Tea Title Treatment
Latest Release GoDoc Build Status phorm.ai

The fun, functional and stateful way to build terminal apps. A Go framework based on The Elm Architecture. Bubble Tea is well-suited for simple and complex terminal applications, either inline, full-window, or a mix of both.

Bubble Tea Example

Bubble Tea is in use in production and includes a number of features and performance optimizations we’ve added along the way. Among those is a standard framerate-based renderer, a renderer for high-performance scrollable regions which works alongside the main renderer, and mouse support.

To get started, see the tutorial below, the examples, the docs, the video tutorials and some common resources.

By the way

Be sure to check out Bubbles, a library of common UI components for Bubble Tea.

Bubbles Badge   Text Input Example from Bubbles


Tutorial

Bubble Tea is based on the functional design paradigms of The Elm Architecture, which happens to work nicely with Go. It's a delightful way to build applications.

This tutorial assumes you have a working knowledge of Go.

By the way, the non-annotated source code for this program is available on GitHub.

Enough! Let's get to it.

For this tutorial, we're making a shopping list.

To start we'll define our package and import some libraries. Our only external import will be the Bubble Tea library, which we'll call tea for short.

package main

import (
    "fmt"
    "os"

    tea "github.com/charmbracelet/bubbletea/v2"
)

Bubble Tea programs are comprised of a model that describes the application state and three simple methods on that model:

  • Init, a function that returns an initial command for the application to run.
  • Update, a function that handles incoming events and updates the model accordingly.
  • View, a function that renders the UI based on the data in the model.
The Model

So let's start by defining our model which will store our application's state. It can be any type, but a struct usually makes the most sense.

type model struct {
    choices  []string           // items on the to-do list
    cursor   int                // which to-do list item our cursor is pointing at
    selected map[int]struct{}   // which to-do items are selected
}

Initialization

Next, we’ll define our application’s initial state in the Init method. Init can return a Cmd that could perform some initial I/O. For now, we don't need to do any I/O, so for the command, we'll just return nil, which translates to "no command."

func (m model) Init() (tea.Model, tea.Cmd) {
	m = {
		// Our to-do list is a grocery list
		choices:  []string{"Buy carrots", "Buy celery", "Buy kohlrabi"},

		// A map which indicates which choices are selected. We're using
		// the map like a mathematical set. The keys refer to the indexes
		// of the `choices` slice, above.
		selected: make(map[int]struct{}),
	}

    // Just return `nil`, which means "no I/O right now, please."
    return m, nil
}
The Update Method

Next up is the update method. The update function is called when ”things happen.” Its job is to look at what has happened and return an updated model in response. It can also return a Cmd to make more things happen, but for now don't worry about that part.

In our case, when a user presses the down arrow, Update’s job is to notice that the down arrow was pressed and move the cursor accordingly (or not).

The “something happened” comes in the form of a Msg, which can be any type. Messages are the result of some I/O that took place, such as a keypress, timer tick, or a response from a server.

We usually figure out which type of Msg we received with a type switch, but you could also use a type assertion.

For now, we'll just deal with tea.KeyPressMsg messages, which are automatically sent to the update function when keys are pressed.

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    switch msg := msg.(type) {

    // Is it a key press?
    case tea.KeyPressMsg:

        // Cool, what was the actual key pressed?
        switch msg.String() {

        // These keys should exit the program.
        case "ctrl+c", "q":
            return m, tea.Quit

        // The "up" and "k" keys move the cursor up
        case "up", "k":
            if m.cursor > 0 {
                m.cursor--
            }

        // The "down" and "j" keys move the cursor down
        case "down", "j":
            if m.cursor < len(m.choices)-1 {
                m.cursor++
            }

        // The "enter" key and the space bar (a literal space) toggle the
        // selected state for the item that the cursor is pointing at.
        case "enter", "space":
            _, ok := m.selected[m.cursor]
            if ok {
                delete(m.selected, m.cursor)
            } else {
                m.selected[m.cursor] = struct{}{}
            }
        }
    }

    // Return the updated model to the Bubble Tea runtime for processing.
    // Note that we're not returning a command.
    return m, nil
}

You may have noticed that ctrl+c and q above return a tea.Quit command with the model. That’s a special command which instructs the Bubble Tea runtime to quit, exiting the program.

The View Method

At last, it’s time to render our UI. Of all the methods, the view is the simplest. We look at the model in its current state and use it to return a string. That string is our UI!

Because the view describes the entire UI of your application, you don’t have to worry about redrawing logic and stuff like that. Bubble Tea takes care of it for you.

func (m model) View() string {
    // The header
    s := "What should we buy at the market?\n\n"

    // Iterate over our choices
    for i, choice := range m.choices {

        // Is the cursor pointing at this choice?
        cursor := " " // no cursor
        if m.cursor == i {
            cursor = ">" // cursor!
        }

        // Is this choice selected?
        checked := " " // not selected
        if _, ok := m.selected[i]; ok {
            checked = "x" // selected!
        }

        // Render the row
        s += fmt.Sprintf("%s [%s] %s\n", cursor, checked, choice)
    }

    // The footer
    s += "\nPress q to quit.\n"

    // Send the UI for rendering
    return s
}
All Together Now

The last step is to simply run our program. We pass our initial model to tea.NewProgram and let it rip:

func main() {
    p := tea.NewProgram(initialModel())
    if _, err := p.Run(); err != nil {
        fmt.Printf("Alas, there's been an error: %v", err)
        os.Exit(1)
    }
}

What’s Next?

This tutorial covers the basics of building an interactive terminal UI, but in the real world you'll also need to perform I/O. To learn about that have a look at the Command Tutorial. It's pretty simple.

There are also several Bubble Tea examples available and, of course, there are Go Docs.

Debugging

Debugging with Delve

Since Bubble Tea apps assume control of stdin and stdout, you’ll need to run delve in headless mode and then connect to it:

# Start the debugger
$ dlv debug --headless --api-version=2 --listen=127.0.0.1:43000 .
API server listening at: 127.0.0.1:43000

# Connect to it from another terminal
$ dlv connect 127.0.0.1:43000

If you do not explicitly supply the --listen flag, the port used will vary per run, so passing this in makes the debugger easier to use from a script or your IDE of choice.

Additionally, we pass in --api-version=2 because delve defaults to version 1 for backwards compatibility reasons. However, delve recommends using version 2 for all new development and some clients may no longer work with version 1. For more information, see the Delve documentation.

Logging Stuff

You can’t really log to stdout with Bubble Tea because your TUI is busy occupying that! You can, however, log to a file by including something like the following prior to starting your Bubble Tea program:

if len(os.Getenv("DEBUG")) > 0 {
	f, err := tea.LogToFile("debug.log", "debug")
	if err != nil {
		fmt.Println("fatal:", err)
		os.Exit(1)
	}
	defer f.Close()
}

To see what’s being logged in real time, run tail -f debug.log while you run your program in another window.

Libraries we use with Bubble Tea

  • Bubbles: Common Bubble Tea components such as text inputs, viewports, spinners and so on
  • Lip Gloss: Style, format and layout tools for terminal applications
  • Harmonica: A spring animation library for smooth, natural motion
  • BubbleZone: Easy mouse event tracking for Bubble Tea components
  • ntcharts: A terminal charting library built for Bubble Tea and Lip Gloss
  • Termenv: Advanced ANSI styling for terminal applications
  • Reflow: Advanced ANSI-aware methods for working with text

Bubble Tea in the Wild

There are over 8k applications built with Bubble Tea! Here are a handful of ’em.

Staff favourites
  • chezmoi: securely manage your dotfiles across multiple machines
  • circumflex: read Hacker News in the terminal
  • gh-dash: a GitHub CLI extension for PRs and issues
  • Tetrigo: Tetris in the terminal
In Industry
  • Microsoft Azure – Aztify: bring Microsoft Azure resources under Terraform
  • Daytona – Daytona: open source dev environment manager
  • Truffle Security Co. – Trufflehog: find leaked credentials
  • NVIDIA – container-canary from NVIDIA: a container validator
  • AWS – eks-node-viewer from AWS: a tool for visualizing dynamic node usage within an EKS cluster
  • MinIO – mc from Min.io: the official MinIO client
Charm stuff
  • Glow: a markdown reader, browser, and online markdown stash
  • Huh?: an interactive prompt and form toolkit
  • Mods: AI on the CLI, built for pipelines
  • Wishlist: an SSH directory (and bastion!)
There’s so much more where that came from

For more applications built with Bubble Tea see Charm & Friends. Is there something cool you made with Bubble Tea you want to share? PRs are welcome!

Feedback

We’d love to hear your thoughts on this project. Feel free to drop us a note!

Acknowledgments

Bubble Tea is based on the paradigms of The Elm Architecture by Evan Czaplicki et alia and the excellent go-tea by TJ Holowaychuk. It’s inspired by the many great Zeichenorientierte Benutzerschnittstellen of days past.

License

MIT


Part of Charm.

The Charm logo

Charm热爱开源 • Charm loves open source • نحنُ نحب المصادر المفتوحة

Documentation

Overview

Package tea provides a framework for building rich terminal user interfaces based on the paradigms of The Elm Architecture. It's well-suited for simple and complex terminal applications, either inline, full-window, or a mix of both. It's been battle-tested in several large projects and is production-ready.

A tutorial is available at https://github.com/charmbracelet/bubbletea/tree/master/tutorials

Example programs can be found at https://github.com/charmbracelet/bubbletea/tree/master/examples

Index

Constants

View Source
const (
	KeyUp rune = KeyExtended + iota + 1
	KeyDown
	KeyRight
	KeyLeft
	KeyBegin
	KeyFind
	KeyInsert
	KeyDelete
	KeySelect
	KeyPgUp
	KeyPgDown
	KeyHome
	KeyEnd

	KeyKpEnter
	KeyKpEqual
	KeyKpMultiply
	KeyKpPlus
	KeyKpComma
	KeyKpMinus
	KeyKpDecimal
	KeyKpDivide
	KeyKp0
	KeyKp1
	KeyKp2
	KeyKp3
	KeyKp4
	KeyKp5
	KeyKp6
	KeyKp7
	KeyKp8
	KeyKp9

	// The following are keys defined in the Kitty keyboard protocol.
	// TODO: Investigate the names of these keys
	KeyKpSep
	KeyKpUp
	KeyKpDown
	KeyKpLeft
	KeyKpRight
	KeyKpPgUp
	KeyKpPgDown
	KeyKpHome
	KeyKpEnd
	KeyKpInsert
	KeyKpDelete
	KeyKpBegin

	KeyF1
	KeyF2
	KeyF3
	KeyF4
	KeyF5
	KeyF6
	KeyF7
	KeyF8
	KeyF9
	KeyF10
	KeyF11
	KeyF12
	KeyF13
	KeyF14
	KeyF15
	KeyF16
	KeyF17
	KeyF18
	KeyF19
	KeyF20
	KeyF21
	KeyF22
	KeyF23
	KeyF24
	KeyF25
	KeyF26
	KeyF27
	KeyF28
	KeyF29
	KeyF30
	KeyF31
	KeyF32
	KeyF33
	KeyF34
	KeyF35
	KeyF36
	KeyF37
	KeyF38
	KeyF39
	KeyF40
	KeyF41
	KeyF42
	KeyF43
	KeyF44
	KeyF45
	KeyF46
	KeyF47
	KeyF48
	KeyF49
	KeyF50
	KeyF51
	KeyF52
	KeyF53
	KeyF54
	KeyF55
	KeyF56
	KeyF57
	KeyF58
	KeyF59
	KeyF60
	KeyF61
	KeyF62
	KeyF63

	KeyCapsLock
	KeyScrollLock
	KeyNumLock
	KeyPrintScreen
	KeyPause
	KeyMenu

	KeyMediaPlay
	KeyMediaPause
	KeyMediaPlayPause
	KeyMediaReverse
	KeyMediaStop
	KeyMediaFastForward
	KeyMediaRewind
	KeyMediaNext
	KeyMediaPrev
	KeyMediaRecord

	KeyLowerVol
	KeyRaiseVol
	KeyMute

	KeyLeftShift
	KeyLeftAlt
	KeyLeftCtrl
	KeyLeftSuper
	KeyLeftHyper
	KeyLeftMeta
	KeyRightShift
	KeyRightAlt
	KeyRightCtrl
	KeyRightSuper
	KeyRightHyper
	KeyRightMeta
	KeyIsoLevel3Shift
	KeyIsoLevel5Shift

	KeyBackspace = rune(ansi.DEL)
	KeyTab       = rune(ansi.HT)
	KeyEnter     = rune(ansi.CR)
	KeyReturn    = KeyEnter
	KeyEscape    = rune(ansi.ESC)
	KeyEsc       = KeyEscape

	KeySpace = rune(ansi.SP)
)

Special key symbols.

View Source
const (
	// KeyExtended is a special key code used to signify that a key event
	// contains multiple runes.
	KeyExtended = unicode.MaxRune + 1
)

Variables

View Source
var ErrProgramKilled = errors.New("program was killed")

ErrProgramKilled is returned by Program.Run when the program got killed.

Functions

func LogToFile

func LogToFile(path string, prefix string) (*os.File, error)

LogToFile sets up default logging to log to a file. This is helpful as we can't print to the terminal since our TUI is occupying it. If the file doesn't exist it will be created.

Don't forget to close the file when you're done with it.

  f, err := LogToFile("debug.log", "debug")
  if err != nil {
		fmt.Println("fatal:", err)
		os.Exit(1)
  }
  defer f.Close()

func LogToFileWith

func LogToFileWith(path string, prefix string, log LogOptionsSetter) (*os.File, error)

LogToFileWith does allows to call LogToFile with a custom LogOptionsSetter.

func WithKeyReleases

func WithKeyReleases(k *keyboardEnhancements)

WithKeyReleases enables support for reporting release key events. This is useful for terminals that support the Kitty keyboard protocol "Report event types" progressive enhancement feature.

Note that not all terminals support this feature.

Types

type BackgroundColorMsg

type BackgroundColorMsg struct{ color.Color }

BackgroundColorMsg represents a background color message. This message is emitted when the program requests the terminal background color.

func (BackgroundColorMsg) IsDark

func (e BackgroundColorMsg) IsDark() bool

IsDark returns whether the color is dark.

func (BackgroundColorMsg) String

func (e BackgroundColorMsg) String() string

String returns the hex representation of the color.

type BatchMsg

type BatchMsg []Cmd

BatchMsg is a message used to perform a bunch of commands concurrently with no ordering guarantees. You can send a BatchMsg with Batch.

type BlurMsg

type BlurMsg struct{}

BlurMsg represents a terminal blur message. This occurs when the terminal loses focus.

type CapabilityMsg

type CapabilityMsg string

CapabilityMsg represents a Termcap/Terminfo response event. Termcap responses are generated by the terminal in response to RequestTermcap (XTGETTCAP) requests.

See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands

type ClipboardMsg

type ClipboardMsg string

ClipboardMsg is a clipboard read message event. This message is emitted when a terminal receives an OSC52 clipboard read message event.

func (ClipboardMsg) String

func (e ClipboardMsg) String() string

String returns the string representation of the clipboard message.

type Cmd

type Cmd func() Msg

Cmd is an IO operation that returns a message when it's complete. If it's nil it's considered a no-op. Use it for things like HTTP requests, timers, saving and loading from disk, and so on.

Note that there's almost never a reason to use a command to send a message to another part of your program. That can almost always be done in the update function.

func Batch

func Batch(cmds ...Cmd) Cmd

Batch performs a bunch of commands concurrently with no ordering guarantees about the results. Use a Batch to return several commands.

Example:

    func (m model) Init() Cmd {
	       return tea.Batch(someCommand, someOtherCommand)
    }

func EnableKeyboardEnhancements

func EnableKeyboardEnhancements(enhancements ...KeyboardEnhancement) Cmd

EnableKeyboardEnhancements is a command that enables keyboard enhancements in the terminal.

func Every

func Every(duration time.Duration, fn func(time.Time) Msg) Cmd

Every is a command that ticks in sync with the system clock. So, if you wanted to tick with the system clock every second, minute or hour you could use this. It's also handy for having different things tick in sync.

Because we're ticking with the system clock the tick will likely not run for the entire specified duration. For example, if we're ticking for one minute and the clock is at 12:34:20 then the next tick will happen at 12:35:00, 40 seconds later.

To produce the command, pass a duration and a function which returns a message containing the time at which the tick occurred.

type TickMsg time.Time

cmd := Every(time.Second, func(t time.Time) Msg {
   return TickMsg(t)
})

Beginners' note: Every sends a single message and won't automatically dispatch messages at an interval. To do that, you'll want to return another Every command after receiving your tick message. For example:

type TickMsg time.Time

// Send a message every second.
func tickEvery() Cmd {
    return Every(time.Second, func(t time.Time) Msg {
        return TickMsg(t)
    })
}

func (m model) Init() Cmd {
    // Start ticking.
    return tickEvery()
}

func (m model) Update(msg Msg) (Model, Cmd) {
    switch msg.(type) {
    case TickMsg:
        // Return your Every command again to loop.
        return m, tickEvery()
    }
    return m, nil
}

Every is analogous to Tick in the Elm Architecture.

func Exec

func Exec(c ExecCommand, fn ExecCallback) Cmd

Exec is used to perform arbitrary I/O in a blocking fashion, effectively pausing the Program while execution is running and resuming it when execution has completed.

Most of the time you'll want to use ExecProcess, which runs an exec.Cmd.

For non-interactive i/o you should use a Cmd (that is, a tea.Cmd).

func ExecProcess

func ExecProcess(c *exec.Cmd, fn ExecCallback) Cmd

ExecProcess runs the given *exec.Cmd in a blocking fashion, effectively pausing the Program while the command is running. After the *exec.Cmd exists the Program resumes. It's useful for spawning other interactive applications such as editors and shells from within a Program.

To produce the command, pass an *exec.Cmd and a function which returns a message containing the error which may have occurred when running the ExecCommand.

type VimFinishedMsg struct { err error }

c := exec.Command("vim", "file.txt")

cmd := ExecProcess(c, func(err error) Msg {
    return VimFinishedMsg{err: err}
})

Or, if you don't care about errors, you could simply:

cmd := ExecProcess(exec.Command("vim", "file.txt"), nil)

For non-interactive i/o you should use a Cmd (that is, a tea.Cmd).

func Printf

func Printf(template string, args ...interface{}) Cmd

Printf prints above the Program. It takes a format template followed by values similar to fmt.Printf. This output is unmanaged by the program and will persist across renders by the Program.

Unlike fmt.Printf (but similar to log.Printf) the message will be print on its own line.

If the altscreen is active no output will be printed.

func Println

func Println(args ...interface{}) Cmd

Println prints above the Program. This output is unmanaged by the program and will persist across renders by the Program.

Unlike fmt.Println (but similar to log.Println) the message will be print on its own line.

If the altscreen is active no output will be printed.

func RequestCapability

func RequestCapability(s string) Cmd

RequestCapability is a command that requests the terminal to send its Termcap/Terminfo response for the given capability.

func ScrollDown deprecated

func ScrollDown(newLines []string, topBoundary, bottomBoundary int) Cmd

ScrollDown adds lines to the bottom of the scrollable region, pushing existing lines above up. Lines that are pushed out of the scrollable region disappear from view.

For high-performance, scroll-based rendering only.

Deprecated: This option will be removed in a future version of this package.

func ScrollUp deprecated

func ScrollUp(newLines []string, topBoundary, bottomBoundary int) Cmd

ScrollUp adds lines to the top of the scrollable region, pushing existing lines below down. Lines that are pushed out the scrollable region disappear from view.

For high-performance, scroll-based rendering only.

Deprecated: This option will be removed in a future version of this package.

func Sequence

func Sequence(cmds ...Cmd) Cmd

Sequence runs the given commands one at a time, in order. Contrast this with Batch, which runs commands concurrently.

func Sequentially deprecated

func Sequentially(cmds ...Cmd) Cmd

Sequentially produces a command that sequentially executes the given commands. The Msg returned is the first non-nil message returned by a Cmd.

func saveStateCmd() Msg {
   if err := save(); err != nil {
       return errMsg{err}
   }
   return nil
}

cmd := Sequentially(saveStateCmd, Quit)

Deprecated: use Sequence instead.

func SetBackgroundColor

func SetBackgroundColor(c color.Color) Cmd

SetBackgroundColor is a command that sets the terminal background color.

func SetClipboard

func SetClipboard(s string) Cmd

SetClipboard produces a command that sets the system clipboard using OSC52. Note that OSC52 is not supported in all terminals.

func SetCursorColor

func SetCursorColor(c color.Color) Cmd

SetCursorColor is a command that sets the terminal cursor color.

func SetForegroundColor

func SetForegroundColor(c color.Color) Cmd

SetForegroundColor is a command that sets the terminal foreground color.

func SetPrimaryClipboard

func SetPrimaryClipboard(s string) Cmd

SetPrimaryClipboard produces a command that sets the primary clipboard using OSC52. Primary clipboard selection is a feature present in X11 and Wayland only. Note that OSC52 is not supported in all terminals.

func SetWindowTitle

func SetWindowTitle(title string) Cmd

SetWindowTitle produces a command that sets the terminal title.

For example:

func (m model) Init() Cmd {
    // Set title.
    return tea.SetWindowTitle("My App")
}

func SyncScrollArea deprecated

func SyncScrollArea(lines []string, topBoundary int, bottomBoundary int) Cmd

SyncScrollArea performs a paint of the entire region designated to be the scrollable area. This is required to initialize the scrollable region and should also be called on resize (WindowSizeMsg).

For high-performance, scroll-based rendering only.

Deprecated: This option will be removed in a future version of this package.

func Tick

func Tick(d time.Duration, fn func(time.Time) Msg) Cmd

Tick produces a command at an interval independent of the system clock at the given duration. That is, the timer begins precisely when invoked, and runs for its entire duration.

To produce the command, pass a duration and a function which returns a message containing the time at which the tick occurred.

type TickMsg time.Time

cmd := Tick(time.Second, func(t time.Time) Msg {
   return TickMsg(t)
})

Beginners' note: Tick sends a single message and won't automatically dispatch messages at an interval. To do that, you'll want to return another Tick command after receiving your tick message. For example:

type TickMsg time.Time

func doTick() Cmd {
    return Tick(time.Second, func(t time.Time) Msg {
        return TickMsg(t)
    })
}

func (m model) Init() Cmd {
    // Start ticking.
    return doTick()
}

func (m model) Update(msg Msg) (Model, Cmd) {
    switch msg.(type) {
    case TickMsg:
        // Return your Tick command again to loop.
        return m, doTick()
    }
    return m, nil
}

func WindowSize

func WindowSize() Cmd

WindowSize is a command that queries the terminal for its current size. It delivers the results to Update via a WindowSizeMsg. Keep in mind that WindowSizeMsgs will automatically be delivered to Update when the Program starts and when the window dimensions change so in many cases you will not need to explicitly invoke this command.

type CursorColorMsg

type CursorColorMsg struct{ color.Color }

CursorColorMsg represents a cursor color change message. This message is emitted when the program requests the terminal cursor color.

func (CursorColorMsg) IsDark

func (e CursorColorMsg) IsDark() bool

IsDark returns whether the color is dark.

func (CursorColorMsg) String

func (e CursorColorMsg) String() string

String returns the hex representation of the color.

type CursorPositionMsg

type CursorPositionMsg struct {
	// Row is the row number.
	Row int

	// Column is the column number.
	Column int
}

CursorPositionMsg is a message that represents the terminal cursor position.

type ExecCallback

type ExecCallback func(error) Msg

ExecCallback is used when executing an *exec.Command to return a message with an error, which may or may not be nil.

type ExecCommand

type ExecCommand interface {
	Run() error
	SetStdin(io.Reader)
	SetStdout(io.Writer)
	SetStderr(io.Writer)
}

ExecCommand can be implemented to execute things in a blocking fashion in the current terminal.

type FocusMsg

type FocusMsg struct{}

FocusMsg represents a terminal focus message. This occurs when the terminal gains focus.

type ForegroundColorMsg

type ForegroundColorMsg struct{ color.Color }

ForegroundColorMsg represents a foreground color message. This message is emitted when the program requests the terminal foreground color.

func (ForegroundColorMsg) IsDark

func (e ForegroundColorMsg) IsDark() bool

IsDark returns whether the color is dark.

func (ForegroundColorMsg) String

func (e ForegroundColorMsg) String() string

String returns the hex representation of the color.

type Key

type Key struct {
	// Text contains the actual characters received. This usually the same as
	// [Key.Code]. When [Key.Text] is non-empty, it indicates that the key
	// pressed represents printable character(s).
	Text string

	// Mod represents modifier keys, like [ModCtrl], [ModAlt], and so on.
	Mod KeyMod

	// Code represents the key pressed. This is usually a special key like
	// [KeyTab], [KeyEnter], [KeyF1], or a printable character like 'a'.
	Code rune

	// ShiftedCode is the actual, shifted key pressed by the user. For example,
	// if the user presses shift+a, or caps lock is on, [Key.ShiftedCode] will
	// be 'A' and [Key.Code] will be 'a'.
	//
	// In the case of non-latin keyboards, like Arabic, [Key.ShiftedCode] is the
	// unshifted key on the keyboard.
	//
	// This is only available with the Kitty Keyboard Protocol or the Windows
	// Console API.
	ShiftedCode rune

	// BaseCode is the key pressed according to the standard PC-101 key layout.
	// On international keyboards, this is the key that would be pressed if the
	// keyboard was set to US PC-101 layout.
	//
	// For example, if the user presses 'q' on a French AZERTY keyboard,
	// [Key.BaseCode] will be 'q'.
	//
	// This is only available with the Kitty Keyboard Protocol or the Windows
	// Console API.
	BaseCode rune

	// IsRepeat indicates whether the key is being held down and sending events
	// repeatedly.
	//
	// This is only available with the Kitty Keyboard Protocol or the Windows
	// Console API.
	IsRepeat bool
}

Key represents a Key press or release event. It contains information about the Key pressed, like the runes, the type of Key, and the modifiers pressed. There are a couple general patterns you could use to check for key presses or releases:

// Switch on the string representation of the key (shorter)
switch msg := msg.(type) {
case KeyPressMsg:
    switch msg.String() {
    case "enter":
        fmt.Println("you pressed enter!")
    case "a":
        fmt.Println("you pressed a!")
    }
}

// Switch on the key type (more foolproof)
switch msg := msg.(type) {
case KeyMsg:
    // catch both KeyPressMsg and KeyReleaseMsg
    switch key := msg.Key(); key.Code {
    case KeyEnter:
        fmt.Println("you pressed enter!")
    default:
        switch key.Text {
        case "a":
            fmt.Println("you pressed a!")
        }
    }
}

Note that [Key.Text] will be empty for special keys like KeyEnter, KeyTab, and for keys that don't represent printable characters like key combos with modifier keys. In other words, [Key.Text] is populated only for keys that represent printable characters shifted or unshifted (like 'a', 'A', '1', '!', etc.).

func (Key) String

func (k Key) String() string

String implements fmt.Stringer and is used to convert a key to a string. While less type safe than looking at the individual fields, it will usually be more convenient and readable to use this method when matching against keys.

Note that modifier keys are always printed in the following order:

  • ctrl
  • alt
  • shift
  • meta
  • hyper
  • super

For example, you'll always see "ctrl+shift+alt+a" and never "shift+ctrl+alt+a".

type KeyMod

type KeyMod int

KeyMod represents modifier keys.

const (
	ModShift KeyMod = 1 << iota
	ModAlt
	ModCtrl
	ModMeta

	ModHyper
	ModSuper // Windows/Command keys

	ModCapsLock
	ModNumLock
	ModScrollLock // Defined in Windows API only
)

Modifier keys.

func (KeyMod) Contains

func (m KeyMod) Contains(mods KeyMod) bool

Contains reports whether m contains the given modifiers.

Example:

m := ModAlt | ModCtrl
m.Contains(ModCtrl) // true
m.Contains(ModAlt | ModCtrl) // true
m.Contains(ModAlt | ModCtrl | ModShift) // false

type KeyMsg

type KeyMsg interface {
	fmt.Stringer

	// Key returns the underlying key event.
	Key() Key
}

KeyMsg represents a key event. This can be either a key press or a key release event.

type KeyPressMsg

type KeyPressMsg Key

KeyPressMsg represents a key press message.

func (KeyPressMsg) Key

func (k KeyPressMsg) Key() Key

Key returns the underlying key event. This is a syntactic sugar for casting the key event to a Key.

func (KeyPressMsg) String

func (k KeyPressMsg) String() string

String implements fmt.Stringer and is quite useful for matching key events. For details, on what this returns see Key.String.

type KeyReleaseMsg

type KeyReleaseMsg Key

KeyReleaseMsg represents a key release message.

func (KeyReleaseMsg) Key

func (k KeyReleaseMsg) Key() Key

Key returns the underlying key event. This is a convenience method and syntactic sugar to satisfy the KeyMsg interface, and cast the key event to Key.

func (KeyReleaseMsg) String

func (k KeyReleaseMsg) String() string

String implements fmt.Stringer and is quite useful for matching key events. For details, on what this returns see Key.String.

type KeyboardEnhancement

type KeyboardEnhancement func(k *keyboardEnhancements)

KeyboardEnhancement is a type that represents a keyboard enhancement.

type KeyboardEnhancementsMsg

type KeyboardEnhancementsMsg keyboardEnhancements

KeyboardEnhancementsMsg is a message that gets sent when the terminal supports keyboard enhancements.

func (KeyboardEnhancementsMsg) SupportsKeyDisambiguation

func (k KeyboardEnhancementsMsg) SupportsKeyDisambiguation() bool

SupportsKeyDisambiguation returns whether the terminal supports reporting disambiguous keys as escape codes.

func (KeyboardEnhancementsMsg) SupportsKeyReleases

func (k KeyboardEnhancementsMsg) SupportsKeyReleases() bool

SupportsKeyReleases returns whether the terminal supports key release events.

type LogOptionsSetter

type LogOptionsSetter interface {
	SetOutput(io.Writer)
	SetPrefix(string)
}

LogOptionsSetter is an interface implemented by stdlib's log and charm's log libraries.

type Model

type Model interface {
	// Init is the first function that will be called. It returns an optional
	// initial command. To not perform an initial command return nil.
	Init() (Model, Cmd)

	// Update is called when a message is received. Use it to inspect messages
	// and, in response, update the model and/or send a command.
	Update(Msg) (Model, Cmd)

	// View renders the program's UI, which is just a string. The view is
	// rendered after every Update.
	View() string
}

Model contains the program's state as well as its core functions.

type Mouse

type Mouse struct {
	X, Y   int
	Button MouseButton
	Mod    KeyMod
}

Mouse represents a Mouse message. Use MouseMsg to represent all mouse messages.

The X and Y coordinates are zero-based, with (0,0) being the upper left corner of the terminal.

// Catch all mouse events
switch msg := msg.(type) {
case MouseMsg:
    m := msg.Mouse()
    fmt.Println("Mouse event:", m.X, m.Y, m)
}

// Only catch mouse click events
switch msg := msg.(type) {
case MouseClickMsg:
    fmt.Println("Mouse click event:", msg.X, msg.Y, msg)
}

func (Mouse) String

func (m Mouse) String() (s string)

String returns a string representation of the mouse message.

type MouseButton

type MouseButton int

MouseButton represents the button that was pressed during a mouse message.

const (
	MouseNone MouseButton = iota
	MouseLeft
	MouseMiddle
	MouseRight
	MouseWheelUp
	MouseWheelDown
	MouseWheelLeft
	MouseWheelRight
	MouseBackward
	MouseForward
	MouseExtra1
	MouseExtra2
)

Mouse event buttons

This is based on X11 mouse button codes.

1 = left button
2 = middle button (pressing the scroll wheel)
3 = right button
4 = turn scroll wheel up
5 = turn scroll wheel down
6 = push scroll wheel left
7 = push scroll wheel right
8 = 4th button (aka browser backward button)
9 = 5th button (aka browser forward button)
10
11

Other buttons are not supported.

func (MouseButton) String

func (b MouseButton) String() string

String returns a string representation of the mouse button.

type MouseClickMsg

type MouseClickMsg Mouse

MouseClickMsg represents a mouse button click message.

func (MouseClickMsg) Mouse

func (e MouseClickMsg) Mouse() Mouse

Mouse returns the underlying mouse event. This is a convenience method and syntactic sugar to satisfy the MouseMsg interface, and cast the mouse event to Mouse.

func (MouseClickMsg) String

func (e MouseClickMsg) String() string

String returns a string representation of the mouse click message.

type MouseMotionMsg

type MouseMotionMsg Mouse

MouseMotionMsg represents a mouse motion message.

func (MouseMotionMsg) Mouse

func (e MouseMotionMsg) Mouse() Mouse

Mouse returns the underlying mouse event. This is a convenience method and syntactic sugar to satisfy the MouseMsg interface, and cast the mouse event to Mouse.

func (MouseMotionMsg) String

func (e MouseMotionMsg) String() string

String returns a string representation of the mouse motion message.

type MouseMsg

type MouseMsg interface {
	fmt.Stringer

	// Mouse returns the underlying mouse event.
	Mouse() Mouse
}

MouseMsg represents a mouse message. This is a generic mouse message that can represent any kind of mouse event.

type MouseReleaseMsg

type MouseReleaseMsg Mouse

MouseReleaseMsg represents a mouse button release message.

func (MouseReleaseMsg) Mouse

func (e MouseReleaseMsg) Mouse() Mouse

Mouse returns the underlying mouse event. This is a convenience method and syntactic sugar to satisfy the MouseMsg interface, and cast the mouse event to Mouse.

func (MouseReleaseMsg) String

func (e MouseReleaseMsg) String() string

String returns a string representation of the mouse release message.

type MouseWheelMsg

type MouseWheelMsg Mouse

MouseWheelMsg represents a mouse wheel message event.

func (MouseWheelMsg) Mouse

func (e MouseWheelMsg) Mouse() Mouse

Mouse returns the underlying mouse event. This is a convenience method and syntactic sugar to satisfy the MouseMsg interface, and cast the mouse event to Mouse.

func (MouseWheelMsg) String

func (e MouseWheelMsg) String() string

String returns a string representation of the mouse wheel message.

type Msg

type Msg interface{}

Msg contain data from the result of a IO operation. Msgs trigger the update function and, henceforth, the UI.

func BackgroundColor

func BackgroundColor() Msg

BackgroundColor is a command that requests the terminal background color.

func ClearScreen

func ClearScreen() Msg

ClearScreen is a special command that tells the program to clear the screen before the next update. This can be used to move the cursor to the top left of the screen and clear visual clutter when the alt screen is not in use.

Note that it should never be necessary to call ClearScreen() for regular redraws.

func ClearScrollArea deprecated

func ClearScrollArea() Msg

ClearScrollArea deallocates the scrollable region and returns the control of those lines to the main rendering routine.

For high-performance, scroll-based rendering only.

Deprecated: This option will be removed in a future version of this package.

func CursorColor

func CursorColor() Msg

CursorColor is a command that requests the terminal cursor color.

func DisableBracketedPaste

func DisableBracketedPaste() Msg

DisableBracketedPaste is a special command that tells the Bubble Tea program to accept bracketed paste input.

Note that bracketed paste will be automatically disabled when the program quits.

func DisableGraphemeClustering

func DisableGraphemeClustering() Msg

DisableGraphemeClustering is a special command that tells the Bubble Tea program to disable grapheme clustering. This mode will be disabled automatically when the program quits.

func DisableKeyboardEnhancements

func DisableKeyboardEnhancements() Msg

DisableKeyboardEnhancements is a command that disables keyboard enhancements in the terminal.

func DisableMouse

func DisableMouse() Msg

DisableMouse is a special command that stops listening for mouse events.

func DisabledReportFocus

func DisabledReportFocus() Msg

DisabledReportFocus is a special command that tells the Bubble Tea program to disable focus reporting.

func EnableBracketedPaste

func EnableBracketedPaste() Msg

EnableBracketedPaste is a special command that tells the Bubble Tea program to accept bracketed paste input.

Note that bracketed paste will be automatically disabled when the program quits.

func EnableGraphemeClustering

func EnableGraphemeClustering() Msg

EnableGraphemeClustering is a special command that tells the Bubble Tea program to enable grapheme clustering. This is enabled by default.

func EnableMouseAllMotion

func EnableMouseAllMotion() Msg

EnableMouseAllMotion is a special command that enables mouse click, release, wheel, and motion events, which are delivered regardless of whether a mouse button is pressed, effectively enabling support for hover interactions.

Many modern terminals support this, but not all. If in doubt, use EnableMouseCellMotion instead.

Because commands run asynchronously, this command should not be used in your model's Init function. Use the WithMouseAllMotion ProgramOption instead.

func EnableMouseCellMotion

func EnableMouseCellMotion() Msg

EnableMouseCellMotion is a special command that enables mouse click, release, and wheel events. Mouse movement events are also captured if a mouse button is pressed (i.e., drag events).

Because commands run asynchronously, this command should not be used in your model's Init function. Use the WithMouseCellMotion ProgramOption instead.

func EnabledReportFocus

func EnabledReportFocus() Msg

EnabledReportFocus is a special command that tells the Bubble Tea program to enable focus reporting.

func EnterAltScreen

func EnterAltScreen() Msg

EnterAltScreen is a special command that tells the Bubble Tea program to enter the alternate screen buffer.

Because commands run asynchronously, this command should not be used in your model's Init function. To initialize your program with the altscreen enabled use the WithAltScreen ProgramOption instead.

func ExitAltScreen

func ExitAltScreen() Msg

ExitAltScreen is a special command that tells the Bubble Tea program to exit the alternate screen buffer. This command should be used to exit the alternate screen buffer while the program is running.

Note that the alternate screen buffer will be automatically exited when the program quits.

func ForegroundColor

func ForegroundColor() Msg

ForegroundColor is a command that requests the terminal foreground color.

func HideCursor

func HideCursor() Msg

HideCursor is a special command for manually instructing Bubble Tea to hide the cursor. In some rare cases, certain operations will cause the terminal to show the cursor, which is normally hidden for the duration of a Bubble Tea program's lifetime. You will most likely not need to use this command.

func Quit

func Quit() Msg

Quit is a special command that tells the Bubble Tea program to exit.

func ReadClipboard

func ReadClipboard() Msg

ReadClipboard produces a command that reads the system clipboard using OSC52. Note that OSC52 is not supported in all terminals.

func ReadPrimaryClipboard

func ReadPrimaryClipboard() Msg

ReadPrimaryClipboard produces a command that reads the primary clipboard using OSC52. Primary clipboard selection is a feature present in X11 and Wayland only. Note that OSC52 is not supported in all terminals.

func ShowCursor

func ShowCursor() Msg

ShowCursor is a special command for manually instructing Bubble Tea to show the cursor.

func Suspend

func Suspend() Msg

Suspend is a special command that tells the Bubble Tea program to suspend.

func TerminalVersion

func TerminalVersion() Msg

TerminalVersion is a command that queries the terminal for its version using XTVERSION. Note that some terminals may not support this command.

type PasteEndMsg

type PasteEndMsg struct{}

PasteEndMsg is an message that is emitted when the terminal ends the bracketed-paste text.

type PasteMsg

type PasteMsg string

PasteMsg is an message that is emitted when a terminal receives pasted text using bracketed-paste.

type PasteStartMsg

type PasteStartMsg struct{}

PasteStartMsg is an message that is emitted when the terminal starts the bracketed-paste text

type PrimaryClipboardMsg

type PrimaryClipboardMsg string

PrimaryClipboardMsg is a primary clipboard read message event. This message is emitted when a terminal receives an OSC52 primary clipboard read message event. Primary clipboard selection is a feature present in X11 and Wayland only.

func (PrimaryClipboardMsg) String

func (e PrimaryClipboardMsg) String() string

String returns the string representation of the primary clipboard message.

type PrimaryDeviceAttributesMsg

type PrimaryDeviceAttributesMsg []int

PrimaryDeviceAttributesMsg is a message that represents the terminal primary device attributes.

type Program

type Program struct {
	// contains filtered or unexported fields
}

Program is a terminal user interface.

func NewProgram

func NewProgram(model Model, opts ...ProgramOption) *Program

NewProgram creates a new Program.

func (*Program) DisableMouseAllMotion deprecated

func (p *Program) DisableMouseAllMotion()

DisableMouseAllMotion disables All Motion mouse tracking. This will be called automatically when exiting a Bubble Tea program.

Deprecated: The mouse will automatically be disabled when the program exits.

func (*Program) DisableMouseCellMotion deprecated

func (p *Program) DisableMouseCellMotion()

DisableMouseCellMotion disables Mouse Cell Motion tracking. This will be called automatically when exiting a Bubble Tea program.

Deprecated: The mouse will automatically be disabled when the program exits.

func (*Program) EnableMouseAllMotion deprecated

func (p *Program) EnableMouseAllMotion()

EnableMouseAllMotion enables mouse click, release, wheel and motion events, regardless of whether a mouse button is pressed. Many modern terminals support this, but not all.

Deprecated: Use the WithMouseAllMotion ProgramOption instead.

func (*Program) EnableMouseCellMotion deprecated

func (p *Program) EnableMouseCellMotion()

EnableMouseCellMotion enables mouse click, release, wheel and motion events if a mouse button is pressed (i.e., drag events).

Deprecated: Use the WithMouseCellMotion ProgramOption instead.

func (*Program) EnterAltScreen deprecated

func (p *Program) EnterAltScreen()

EnterAltScreen enters the alternate screen buffer, which consumes the entire terminal window. ExitAltScreen will return the terminal to its former state.

Deprecated: Use the WithAltScreen ProgramOption instead.

func (*Program) ExitAltScreen deprecated

func (p *Program) ExitAltScreen()

ExitAltScreen exits the alternate screen buffer.

Deprecated: The altscreen will exited automatically when the program exits.

func (*Program) Kill

func (p *Program) Kill()

Kill stops the program immediately and restores the former terminal state. The final render that you would normally see when quitting will be skipped. [program.Run] returns a ErrProgramKilled error.

func (*Program) Printf

func (p *Program) Printf(template string, args ...interface{})

Printf prints above the Program. It takes a format template followed by values similar to fmt.Printf. This output is unmanaged by the program and will persist across renders by the Program.

Unlike fmt.Printf (but similar to log.Printf) the message will be print on its own line.

If the altscreen is active no output will be printed.

func (*Program) Println

func (p *Program) Println(args ...interface{})

Println prints above the Program. This output is unmanaged by the program and will persist across renders by the Program.

If the altscreen is active no output will be printed.

func (*Program) Quit

func (p *Program) Quit()

Quit is a convenience function for quitting Bubble Tea programs. Use it when you need to shut down a Bubble Tea program from the outside.

If you wish to quit from within a Bubble Tea program use the Quit command.

If the program is not running this will be a no-op, so it's safe to call if the program is unstarted or has already exited.

func (*Program) ReleaseTerminal

func (p *Program) ReleaseTerminal() error

ReleaseTerminal restores the original terminal state and cancels the input reader. You can return control to the Program with RestoreTerminal.

func (*Program) RestoreTerminal

func (p *Program) RestoreTerminal() error

RestoreTerminal reinitializes the Program's input reader, restores the terminal to the former state when the program was running, and repaints. Use it to reinitialize a Program after running ReleaseTerminal.

func (*Program) Run

func (p *Program) Run() (Model, error)

Run initializes the program and runs its event loops, blocking until it gets terminated by either Program.Quit, Program.Kill, or its signal handler. Returns the final model.

func (*Program) Send

func (p *Program) Send(msg Msg)

Send sends a message to the main update function, effectively allowing messages to be injected from outside the program for interoperability purposes.

If the program hasn't started yet this will be a blocking operation. If the program has already been terminated this will be a no-op, so it's safe to send messages after the program has exited.

func (*Program) SetWindowTitle deprecated

func (p *Program) SetWindowTitle(title string)

SetWindowTitle sets the terminal window title.

Deprecated: Use the SetWindowTitle command instead.

func (*Program) Start deprecated

func (p *Program) Start() error

Start initializes the program and runs its event loops, blocking until it gets terminated by either Program.Quit, Program.Kill, or its signal handler.

Deprecated: please use Program.Run instead.

func (*Program) StartReturningModel deprecated

func (p *Program) StartReturningModel() (Model, error)

StartReturningModel initializes the program and runs its event loops, blocking until it gets terminated by either Program.Quit, Program.Kill, or its signal handler. Returns the final model.

Deprecated: please use Program.Run instead.

func (*Program) Wait

func (p *Program) Wait()

Wait waits/blocks until the underlying Program finished shutting down.

type ProgramOption

type ProgramOption func(*Program)

ProgramOption is used to set options when initializing a Program. Program can accept a variable number of options.

Example usage:

p := NewProgram(model, WithInput(someInput), WithOutput(someOutput))

func WithANSICompressor deprecated

func WithANSICompressor() ProgramOption

WithANSICompressor removes redundant ANSI sequences to produce potentially smaller output, at the cost of some processing overhead.

This feature is provisional, and may be changed or removed in a future version of this package.

Deprecated: this incurs a noticable performance hit. A future release will optimize ANSI automatically without the performance penalty.

func WithAltScreen

func WithAltScreen() ProgramOption

WithAltScreen starts the program with the alternate screen buffer enabled (i.e. the program starts in full window mode). Note that the altscreen will be automatically exited when the program quits.

Example:

p := tea.NewProgram(Model{}, tea.WithAltScreen())
if _, err := p.Run(); err != nil {
    fmt.Println("Error running program:", err)
    os.Exit(1)
}

To enter the altscreen once the program has already started running use the EnterAltScreen command.

func WithContext

func WithContext(ctx context.Context) ProgramOption

WithContext lets you specify a context in which to run the Program. This is useful if you want to cancel the execution from outside. When a Program gets cancelled it will exit with an error ErrProgramKilled.

func WithEnvironment

func WithEnvironment(env []string) ProgramOption

WithEnvironment sets the environment variables that the program will use. This useful when the program is running in a remote session (e.g. SSH) and you want to pass the environment variables from the remote session to the program.

Example:

var sess ssh.Session // ssh.Session is a type from the github.com/charmbracelet/ssh package
pty, _, _ := sess.Pty()
environ := append(sess.Environ(), "TERM="+pty.Term)
p := tea.NewProgram(model, tea.WithEnvironment(environ)

func WithFPS

func WithFPS(fps int) ProgramOption

WithFPS sets a custom maximum FPS at which the renderer should run. If less than 1, the default value of 60 will be used. If over 120, the FPS will be capped at 120.

func WithFilter

func WithFilter(filter func(Model, Msg) Msg) ProgramOption

WithFilter supplies an event filter that will be invoked before Bubble Tea processes a tea.Msg. The event filter can return any tea.Msg which will then get handled by Bubble Tea instead of the original event. If the event filter returns nil, the event will be ignored and Bubble Tea will not process it.

As an example, this could be used to prevent a program from shutting down if there are unsaved changes.

Example:

func filter(m tea.Model, msg tea.Msg) tea.Msg {
	if _, ok := msg.(tea.QuitMsg); !ok {
		return msg
	}

	model := m.(myModel)
	if model.hasChanges {
		return nil
	}

	return msg
}

p := tea.NewProgram(Model{}, tea.WithFilter(filter));

if _,err := p.Run(); err != nil {
	fmt.Println("Error running program:", err)
	os.Exit(1)
}

func WithInput

func WithInput(input io.Reader) ProgramOption

WithInput sets the input which, by default, is stdin. In most cases you won't need to use this. To disable input entirely pass nil.

p := NewProgram(model, WithInput(nil))

func WithInputTTY

func WithInputTTY() ProgramOption

WithInputTTY opens a new TTY for input (or console input device on Windows).

func WithKeyboardEnhancements

func WithKeyboardEnhancements(enhancements ...KeyboardEnhancement) ProgramOption

WithKeyboardEnhancements enables support for enhanced keyboard features. You can enable different keyboard features by passing one or more KeyboardEnhancement functions.

This is not supported on all terminals. On Windows, these features are enabled by default.

func WithMouseAllMotion

func WithMouseAllMotion() ProgramOption

WithMouseAllMotion starts the program with the mouse enabled in "all motion" mode.

EnableMouseAllMotion is a special command that enables mouse click, release, wheel, and motion events, which are delivered regardless of whether a mouse button is pressed, effectively enabling support for hover interactions.

This will try to enable the mouse in extended mode (SGR), if that is not supported by the terminal it will fall back to normal mode (X10).

Many modern terminals support this, but not all. If in doubt, use EnableMouseCellMotion instead.

To enable the mouse once the program has already started running use the EnableMouseAllMotion command. To disable the mouse when the program is running use the DisableMouse command.

The mouse will be automatically disabled when the program exits.

func WithMouseCellMotion

func WithMouseCellMotion() ProgramOption

WithMouseCellMotion starts the program with the mouse enabled in "cell motion" mode.

Cell motion mode enables mouse click, release, and wheel events. Mouse movement events are also captured if a mouse button is pressed (i.e., drag events). Cell motion mode is better supported than all motion mode.

This will try to enable the mouse in extended mode (SGR), if that is not supported by the terminal it will fall back to normal mode (X10).

To enable mouse cell motion once the program has already started running use the EnableMouseCellMotion command. To disable the mouse when the program is running use the DisableMouse command.

The mouse will be automatically disabled when the program exits.

func WithOutput

func WithOutput(output io.Writer) ProgramOption

WithOutput sets the output which, by default, is stdout. In most cases you won't need to use this.

func WithReportFocus

func WithReportFocus() ProgramOption

WithReportFocus enables reporting when the terminal gains and loses focus. When this is enabled FocusMsg and BlurMsg messages will be sent to your Update method.

Note that while most terminals and multiplexers support focus reporting, some do not. Also note that tmux needs to be configured to report focus events.

func WithoutBracketedPaste

func WithoutBracketedPaste() ProgramOption

WithoutBracketedPaste starts the program with bracketed paste disabled.

func WithoutCatchPanics

func WithoutCatchPanics() ProgramOption

WithoutCatchPanics disables the panic catching that Bubble Tea does by default. If panic catching is disabled the terminal will be in a fairly unusable state after a panic because Bubble Tea will not perform its usual cleanup on exit.

func WithoutGraphemeClustering

func WithoutGraphemeClustering() ProgramOption

WithoutGraphemeClustering disables grapheme clustering. This is useful if you want to disable grapheme clustering for your program.

Grapheme clustering is a character width calculation method that accurately calculates the width of wide characters in a terminal. This is useful for properly rendering double width characters such as emojis and CJK characters.

See https://mitchellh.com/writing/grapheme-clusters-in-terminals

func WithoutRenderer

func WithoutRenderer() ProgramOption

WithoutRenderer disables the renderer. When this is set output and log statements will be plainly sent to stdout (or another output if one is set) without any rendering and redrawing logic. In other words, printing and logging will behave the same way it would in a non-TUI commandline tool. This can be useful if you want to use the Bubble Tea framework for a non-TUI application, or to provide an additional non-TUI mode to your Bubble Tea programs. For example, your program could behave like a daemon if output is not a TTY.

func WithoutSignalHandler

func WithoutSignalHandler() ProgramOption

WithoutSignalHandler disables the signal handler that Bubble Tea sets up for Programs. This is useful if you want to handle signals yourself.

func WithoutSignals

func WithoutSignals() ProgramOption

WithoutSignals will ignore OS signals. This is mainly useful for testing.

type QuitMsg

type QuitMsg struct{}

QuitMsg signals that the program should quit. You can send a QuitMsg with Quit.

type ResumeMsg

type ResumeMsg struct{}

ResumeMsg can be listen to to do something once a program is resumed back from a suspend state.

type SuspendMsg

type SuspendMsg struct{}

SuspendMsg signals the program should suspend. This usually happens when ctrl+z is pressed on common programs, but since bubbletea puts the terminal in raw mode, we need to handle it in a per-program basis. You can send this message with Suspend.

type TerminalVersionMsg

type TerminalVersionMsg string

TerminalVersionMsg is a message that represents the terminal version.

type UnknownMsg

type UnknownMsg string

UnknownMsg represents an unknown message.

func (UnknownMsg) String

func (e UnknownMsg) String() string

String returns a string representation of the unknown message.

type WindowSizeMsg

type WindowSizeMsg struct {
	Width  int
	Height int
}

WindowSizeMsg is used to report the terminal size. It's sent to Update once initially and then on every terminal resize. Note that Windows does not have support for reporting when resizes occur as it does not support the SIGWINCH signal.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL