tea

package module
v0.10.3 Latest Latest
Warning

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

Go to latest
Published: Aug 19, 2020 License: MIT Imports: 15 Imported by: 11,682

README

Bubble Tea

Bubble Tea Title Treatment
GoDoc Build Status

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. It's been battle-tested in several large projects and is production-ready.

It features a standard framerate-based renderer which is used by default as well as a renderer for high-performance scrollable regions, which works alongside the main renderer.

To get started, see the tutorials and examples.

Bubble Tea in the Wild

For some Bubble Tea programs in production, see:

  • Glow: a markdown reader, browser and online markdown stash
  • The Charm Tool: the Charm user account manager

Libraries we use with Bubble Tea

  • Bubbles various Bubble Tea components we've built
  • Termenv: Advanced ANSI styling for terminal applications
  • Reflow: ANSI-aware methods for reflowing blocks of text
  • go-runewidth: Get the physical width of strings in terms of terminal cells. Many runes, such as East Asian charcters and emojis, are two cells wide, so measuring a layout with len() often won't cut it!

Acknowledgments

Based on the paradigms of The Elm Architecture by Evan Czaplicki et alia and the excellent go-tea by TJ Holowaychuk.

License

MIT


A Charm project.

the Charm logo

Charm热爱开源!

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 (
	KeyNull      = keyNUL
	KeyBreak     = keyETX
	KeyEnter     = keyCR
	KeyBackspace = keyBS
	KeyTab       = keyHT
	KeySpace     = keySP
	KeyEsc       = keyESC
	KeyEscape    = keyESC
	KeyDelete    = keyDEL

	KeyCtrlAt           = keyNUL // ctrl+@
	KeyCtrlA            = keySOH
	KeyCtrlB            = keySTX
	KeyCtrlC            = keyETX
	KeyCtrlD            = keyEOT
	KeyCtrlE            = keyENQ
	KeyCtrlF            = keyACK
	KeyCtrlG            = keyBEL
	KeyCtrlH            = keyBS
	KeyCtrlI            = keyHT
	KeyCtrlJ            = keyLF
	KeyCtrlK            = keyVT
	KeyCtrlL            = keyFF
	KeyCtrlM            = keyCR
	KeyCtrlN            = keySO
	KeyCtrlO            = keySI
	KeyCtrlP            = keyDLE
	KeyCtrlQ            = keyDC1
	KeyCtrlR            = keyDC2
	KeyCtrlS            = keyDC3
	KeyCtrlT            = keyDC4
	KeyCtrlU            = keyNAK
	KeyCtrlV            = keySYN
	KeyCtrlW            = keyETB
	KeyCtrlX            = keyCAN
	KeyCtrlY            = keyEM
	KeyCtrlZ            = keySUB
	KeyCtrlOpenBracket  = keyESC // ctrl+[
	KeyCtrlBackslash    = keyFS  // ctrl+\
	KeyCtrlCloseBracket = keyGS  // ctrl+]
	KeyCtrlCaret        = keyRS  // ctrl+^
	KeyCtrlUnderscore   = keyUS  // ctrl+_
	KeyCtrlQuestionMark = keyDEL // ctrl+?
)

Control key aliases:

View Source
const (
	KeyRune = -(iota + 1)
	KeyUp
	KeyDown
	KeyRight
	KeyLeft
	KeyShiftTab
	KeyHome
	KeyEnd
	KeyPgUp
	KeyPgDown
)

Other keys:

Variables

This section is empty.

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()

Types

type Cmd

type Cmd func() Msg

Cmd is an IO operation. 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.

There's almost never a need to use a command to send a message to another part of your program. Instead, it can almost always be done in the update function.

func Batch

func Batch(cmds ...Cmd) Cmd

Batch peforms a bunch of commands concurrently with no ordering guarantees about the results.

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 fnuction 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)
})

func ScrollDown added in v0.9.0

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.

func ScrollUp added in v0.9.0

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.

func SyncScrollArea added in v0.9.0

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.

func Tick

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

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

To produce the command, pass a duration and a fnuction 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)
})

type Init

type Init func() (Model, Cmd)

Init is the first function that will be called. It returns your initial model and runs an optional command.

type Key

type Key struct {
	Type KeyType
	Rune rune
	Alt  bool
}

Key contains information about a keypress.

type KeyMsg

type KeyMsg Key

KeyMsg contains information about a keypress. KeyMsgs are always sent to the program's update function. There are a couple general patterns you could use to check for keypresses:

// Switch on the type (safer)
switch msg := msg.(type) {
case KeyMsg:
    switch msg.Type {
    case KeyEnter:
        fmt.Println("you pressed enter!")
    case KeyRune:
        switch msg.Rune {
        case 'a':
            fmt.Println("you pressed a!")
        }
    }
}

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

func (*KeyMsg) IsRune

func (k *KeyMsg) IsRune() bool

IsRune returns whether or not the key is a rune.

func (*KeyMsg) String

func (k *KeyMsg) String() (str string)

String returns a friendly name for a key.

k := KeyType{Type: KeyEnter}
fmt.Println(k)
// Output: enter

type KeyType

type KeyType int

KeyType indicates the key pressed, such as KeyEnter or KeyBreak or KeyCtrlC. All other keys will be type KeyRune. To get the rune value, check the Rune method on a Key struct, or use the Key.String() method:

k := Key{Type: KeyRune, Rune: 'a', Alt: true}
if k.Type == KeyRune {

    fmt.Println(k.Rune)
    // Output: a

    fmt.Println(k.String())
    // Output: alt+a

}

type Model

type Model interface{}

Model contains the program's state.

type MouseButton added in v0.10.0

type MouseButton int

MouseButton represents a mouse button event.

const (
	MouseUnknown MouseButton = iota
	MouseLeft
	MouseRight
	MouseMiddle
	MouseRelease
	MouseWheelUp
	MouseWheelDown
	MouseMotion
)

type MouseEvent added in v0.10.0

type MouseEvent struct {
	X      int
	Y      int
	Button MouseButton
	Alt    bool
	Ctrl   bool
}

MouseEvent represents a mouse event, which could be a click, a scroll wheel movement, a cursor movement, or a combination.

func (MouseEvent) String added in v0.10.0

func (m MouseEvent) String() (s string)

String returns a string representation of a mouse event.

type MouseMsg added in v0.10.0

type MouseMsg MouseEvent

type Msg

type Msg interface{}

Msg represents an action and is usually the result of an IO operation. It's triggers the Update function, and henceforth, the UI.

func ClearScrollArea added in v0.9.0

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.

func Quit

func Quit() Msg

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

type Program

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

Program is a terminal user interface.

func NewProgram

func NewProgram(init Init, update Update, view View) *Program

NewProgram creates a new Program.

func (*Program) DisableMouseAllMotion added in v0.10.0

func (p *Program) DisableMouseAllMotion()

DisableMouseAllMotion disables All Motion mouse tracking. If you've enabled All Motion mouse tracking be sure you call this as your program is exiting or your users will be very upset!

func (*Program) DisableMouseCellMotion added in v0.10.0

func (p *Program) DisableMouseCellMotion()

DisableMouseCellMotion disables Mouse Cell Motion tracking. If you've enabled Cell Motion mouse trakcing be sure to call this as your program is exiting or your users will be very upset!

func (*Program) EnableMouseAllMotion added in v0.10.0

func (p *Program) EnableMouseAllMotion()

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

func (*Program) EnableMouseCellMotion added in v0.10.0

func (p *Program) EnableMouseCellMotion()

EnableMouseCellMotion enables mouse click, release, wheel and motion events if a button is pressed.

func (*Program) EnterAltScreen added in v0.10.0

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.

func (*Program) ExitAltScreen added in v0.10.0

func (p *Program) ExitAltScreen()

ExitAltScreen exits the alternate screen buffer.

func (*Program) Start

func (p *Program) Start() error

Start initializes the program.

type Update

type Update func(Msg, Model) (Model, Cmd)

Update is called when a message is received. Use it to inspect messages and, in repsonse, update the model and/or send a command.

type View

type View func(Model) string

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

type WindowSizeMsg added in v0.9.0

type WindowSizeMsg struct {
	Width  int
	Height int
}

WindowSizeMsg is used to report on the terminal size. Its sent to Update once initially and then on every terminal resize.

Jump to

Keyboard shortcuts

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