tea

package module
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: May 26, 2020 License: MIT Imports: 15 Imported by: 4,363

README

Bubble Tea

The fun, functional way to build terminal apps. A Go framework based on The Elm Architecture.

⚠️ This project is a pre-release so the API is subject to change a little. That said, we're using it in production.

Simple example

package main

// A simple program that counts down from 5 and then exits.

import (
	"fmt"
	"log"
	"time"
	"github.com/charmbracelet/tea"
)

type model int

type tickMsg time.Time

func main() {
	p := tea.NewProgram(init, update, view, subscriptions)
	if err := p.Start(); err != nil {
		log.Fatal(err)
	}
}

// Listen for messages and update the model accordingly
func update(msg tea.Msg, mdl tea.Model) (tea.Model, tea.Cmd) {
	m, _ := mdl.(model)

	switch msg.(type) {
	case tickMsg:
        m--
		if m == 0 {
			return m, tea.Quit
		}
	}
	return m, nil
}

// Render to the terminal
func view(mdl tea.Model) string {
	m, _ := mdl.(model)
	return fmt.Sprintf("Hi. This program will exit in %d seconds...\n", m)
}

// Subscribe to events
func subscriptions(_ tea.Model) tea.Subs {
    return tea.Subs{
        "tick": time.Every(time.Second, func(t time.Time) tea.Msg {
            return tickMsg(t)
        },
    }
}

Hungry for more? See the other examples.

Other Resources

  • Termenv: advanced ANSI style and color support for your terminal applications. Very useful when rendering your views.
  • Reflow: a collection of ANSI-aware text formatting tools. Also useful for view rendering.

Acknowledgments

Heavily inspired by both The Elm Architecture by Evan Czaplicki et al. and go-tea by TJ Holowaychuk.

License

MIT


Part of Charm.

the Charm logo

Charm热爱开源!

Documentation

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            = keyETB
	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+?
)

Aliases

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

Other keys we track

Variables

This section is empty.

Functions

func AltScreen

func AltScreen()

AltScreen exits the altscreen. This is just a wrapper around the termenv function.

func ExitAltScreen

func ExitAltScreen()

ExitAltScreen exits the altscreen. This is just a wrapper around the termenv function.

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 UseSysLog

func UseSysLog(programName string) error

UseSysLog sets up logging to log the system log. This becomes helpful when debugging since we can't print to the terminal since our TUI is occupying it.

On macOS this is a just a matter of: tail -f /var/log/system.log On Linux this varies depending on distribution.

Types

type Cmd

type Cmd func() Msg

Cmd is an IO operation. If it's nil it's considered a no-op.

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.

Note that 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.

func GetTerminalSize

func GetTerminalSize(newMsgFunc func(int, int, error) TerminalSizeMsg) Cmd

GetTerminalSize is used to get

func OnResize

func OnResize(newMsgFunc func() Msg) Cmd

OnResize is used to listen for window resizes. Use GetTerminalSize to get the windows dimensions. We don't fetch the window size with this command to avoid a potential performance hit making the necessary system calls, since this command could potentially run a lot. On that note, consider debouncing this function.

func Tick

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

Tick is 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.

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.

func ReadKey

func ReadKey(r io.Reader) (Key, error)

ReadKey reads keypress input from a TTY and returns a string representation of a key.

type KeyMsg

type KeyMsg Key

KeyMsg contains information about a keypress.

func (*KeyMsg) IsRune

func (k *KeyMsg) IsRune() bool

IsRune returns weather or not the key is a rune.

func (*KeyMsg) String

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

String returns a friendly name for a key.

type KeyType

type KeyType int

KeyType indicates the key pressed.

type Model

type Model interface{}

Model contains the program's state.

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 Quit

func Quit() Msg

Quit is a command that tells the 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) Start

func (p *Program) Start() error

Start initializes the program.

type TerminalSizeMsg

type TerminalSizeMsg interface {

	// Size returns the terminal width and height, in that order
	Size() (int, int)

	// Error returns the error, if any, received when fetching the terminal size
	Error() error
}

TerminalSizeMsg defines an interface for a message that contains terminal sizing as sent by GetTerminalSize.

type Update

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

Update is called when a message is received. It may update the model and/or send a command.

type View

type View func(Model) string

View produces a string which will be rendered to the terminal.

Jump to

Keyboard shortcuts

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