Documentation
¶
Overview ¶
Package twin provides Terminal Window Interaction
Index ¶
- Variables
- func Printable(char rune) bool
- type AttrMask
- type Color
- type ColorCount
- type Event
- type EventExit
- type EventKeyCode
- type EventMouse
- type EventResize
- type EventRune
- type FakeScreen
- func (screen *FakeScreen) Clear()
- func (screen *FakeScreen) Close()
- func (screen *FakeScreen) Events() chan Event
- func (screen *FakeScreen) GetCell(column int, row int) StyledRune
- func (screen *FakeScreen) GetRow(row int) []StyledRune
- func (screen *FakeScreen) PauseAndCall(run func() error) error
- func (screen *FakeScreen) PrintLines(int)
- func (screen *FakeScreen) SetCell(column int, row int, styledRune StyledRune) int
- func (screen *FakeScreen) SetProgress(state ProgressState, percent int)
- func (screen *FakeScreen) Show()
- func (screen *FakeScreen) Size() (width int, height int)
- func (screen *FakeScreen) TerminalBackground() *Color
- type KeyCode
- type Logger
- type MouseButtonMask
- type MouseMode
- type Options
- type Progress
- type ProgressState
- type Screen
- type Style
- func (style Style) Background() Color
- func (style Style) Equal(other Style) bool
- func (style Style) Foreground() Color
- func (style Style) HasAttr(attr AttrMask) bool
- func (style Style) HyperlinkURL() *string
- func (style Style) RenderUpdateFrom(previous Style, terminalColorCount ColorCount) string
- func (style Style) String() string
- func (style Style) WithAttr(attr AttrMask) Style
- func (style Style) WithBackground(color Color) Style
- func (style Style) WithForeground(color Color) Style
- func (style Style) WithHyperlink(hyperlinkURL *string) Style
- func (style Style) WithUnderlineColor(color Color) Style
- func (style Style) WithoutAttr(attr AttrMask) Style
- type StyledRune
Constants ¶
This section is empty.
Variables ¶
var ColorDefault = newColor(ColorCountDefault, 0)
ColorDefault is the terminal's own default foreground / background color, used when no explicit color has been set.
Functions ¶
Types ¶
type AttrMask ¶
type AttrMask uint
AttrMask is a bitmask of text attributes (bold, blink, ...), combined with bitwise OR.
type Color ¶
type Color uint32
Color represents a terminal color. Create one using NewColor16(), NewColor256(), or NewColor24Bit(), or use ColorDefault.
func NewColor16 ¶
NewColor16 creates a 4-bit ANSI color (16 colors) from a palette index 0-15.
Ref: https://en.wikipedia.org/wiki/ANSI_escape_code#3-bit_and_4-bit
func NewColor24Bit ¶
NewColor24Bit creates a 24-bit RGB color from its red, green and blue channels.
func NewColor256 ¶
NewColor256 creates an 8-bit ANSI color (256 colors) from a palette index.
func NewColorHex ¶
NewColorHex creates a 24-bit RGB color from a packed 0xRRGGBB value.
func (Color) Distance ¶
Distance approximates the perceptual difference between two colors, using the formula from https://www.compuphase.com/cmetric.htm, scaled to 0.0-1.0 where 1.0 is the distance between black and white.
Panics if either color is ColorDefault.
func (Color) Mix ¶
Mix blends color and other, weighted 0.0 (all color) to 1.0 (all other).
Panics if either color is ColorDefault, or if weight is outside 0.0-1.0.
type ColorCount ¶
type ColorCount uint8
ColorCount represents the terminal's color capability, one of the ColorCount* constants.
const ( // ColorCountDefault is no explicit color: the terminal's own default // foreground / background. ColorCountDefault ColorCount = iota // ColorCount8 is 3-bit ANSI color (8 colors): // https://en.wikipedia.org/wiki/ANSI_escape_code#3-bit_and_4-bit // // Note that this type is only used for output, on input we store 3 bit // colors as 4 bit colors since they map to the same values. ColorCount8 // ColorCount16 is 4-bit ANSI color (16 colors): // https://en.wikipedia.org/wiki/ANSI_escape_code#3-bit_and_4-bit ColorCount16 // ColorCount256 is 8-bit ANSI color (256 colors): // https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit ColorCount256 // ColorCount24bit is an RGB color: // https://en.wikipedia.org/wiki/ANSI_escape_code#24-bit ColorCount24bit )
type Event ¶
type Event any
Event is the type of value received on a Screen's event channel.
EventRune, EventKeyCode and EventMouse can be constructed directly by embedding applications, to programmatically feed input into the screen.
type EventExit ¶
type EventExit struct {
}
EventExit is sent, and the application should exit, when we're unable to continue showing the screen.
type EventKeyCode ¶
type EventKeyCode struct {
KeyCode KeyCode
}
EventKeyCode is sent when the user presses a non-printable key.
type EventMouse ¶
type EventMouse struct {
Buttons MouseButtonMask
}
EventMouse is sent on mouse wheel activity.
type EventResize ¶
type EventResize struct {
}
EventResize is sent when the terminal window is resized. Query Screen.Size() after receiving this to get the new size.
type EventRune ¶
type EventRune struct {
Rune rune
}
EventRune is sent when the user types a printable rune.
type FakeScreen ¶
type FakeScreen struct {
// contains filtered or unexported fields
}
FakeScreen is an in-memory Screen implementation, needing no real terminal. Typically used for testing code that renders to a Screen, but also suitable for headless rendering in general.
Create one with NewFakeScreen(width, height) and hand it to the code under test. Let that code call SetCell(), Clear(), Show() etc. as it normally would, then call GetRow() or GetCell() afterwards to inspect what ended up on screen.
Events() always returns nil.
func NewFakeScreen ¶
func NewFakeScreen(width int, height int) *FakeScreen
NewFakeScreen creates a FakeScreen of the given size, with all cells set to a space in the default style.
func (*FakeScreen) Clear ¶
func (screen *FakeScreen) Clear()
Clear erases all screen cells, replacing them with spaces in the default style.
func (*FakeScreen) Close ¶
func (screen *FakeScreen) Close()
Close does nothing, since a FakeScreen owns no real terminal to restore.
func (*FakeScreen) Events ¶
func (screen *FakeScreen) Events() chan Event
Events always returns nil, so anything reading from it will block forever.
func (*FakeScreen) GetCell ¶
func (screen *FakeScreen) GetCell(column int, row int) StyledRune
GetCell returns the StyledRune at the given screen position.
Note that this does not read cells from a physical screen, since there is none, but rather from what was previously set using SetCell().
For out-of-bounds requests, a space with default style is returned.
func (*FakeScreen) GetRow ¶
func (screen *FakeScreen) GetRow(row int) []StyledRune
GetRow returns the row's cells, skipping any cell hidden behind a preceding wide rune.
func (*FakeScreen) PauseAndCall ¶
func (screen *FakeScreen) PauseAndCall(run func() error) error
PauseAndCall runs the given function and returns its result. A FakeScreen has no terminal state to pause and resume, so there is nothing else to do.
func (*FakeScreen) PrintLines ¶ added in v0.9.3
func (screen *FakeScreen) PrintLines(int)
PrintLines does nothing, since a FakeScreen has no real terminal to render into.
func (*FakeScreen) SetCell ¶
func (screen *FakeScreen) SetCell(column int, row int, styledRune StyledRune) int
SetCell returns the width of the rune just added, in number of columns.
Note that if you set a wide rune (like '午') in one column, then whatever you put in the next column will be hidden by the wide rune. A wide rune in the last screen column will be replaced by a space, to prevent it from overflowing onto the next line.
func (*FakeScreen) SetProgress ¶
func (screen *FakeScreen) SetProgress(state ProgressState, percent int)
SetProgress does nothing, since a FakeScreen has no terminal to show a progress bar in.
func (*FakeScreen) Show ¶
func (screen *FakeScreen) Show()
Show does nothing, since a FakeScreen has no real terminal to render into.
func (*FakeScreen) Size ¶
func (screen *FakeScreen) Size() (width int, height int)
Size returns the width and height given to NewFakeScreen().
func (*FakeScreen) TerminalBackground ¶
func (screen *FakeScreen) TerminalBackground() *Color
TerminalBackground always returns nil, since a FakeScreen has no real terminal to query.
type Logger ¶
type Logger interface {
// Debug logs low-level diagnostic messages. This level is recommended for
// messages that the user has to explicitly ask to see.
Debug(message string)
// Info logs high-level status messages. This level and up is recommended
// for adding to panic reports.
Info(message string)
// Error logs a problem the user should be told about whether they asked for
// it or not.
Error(message string)
}
Logger receives twin's log messages. Implement it and pass it in Options.Logger to NewScreen to consume those messages.
type MouseButtonMask ¶
type MouseButtonMask uint16
MouseButtonMask is a bitmask of the MouseWheel* constants, used in EventMouse.Buttons.
const ( // MouseWheelUp is set in EventMouse.Buttons when the wheel scrolls up. MouseWheelUp MouseButtonMask = 1 << iota // MouseWheelDown is set in EventMouse.Buttons when the wheel scrolls down. MouseWheelDown // MouseWheelLeft is set in EventMouse.Buttons when the wheel scrolls left. MouseWheelLeft // MouseWheelRight is set in EventMouse.Buttons when the wheel scrolls right. MouseWheelRight )
type MouseMode ¶
type MouseMode int
MouseMode controls how mouse events are captured. See MouseModeAuto, MouseModeSelect and MouseModeScroll for the available behaviors.
const ( // MouseModeAuto auto-detects whether to capture mouse events, based on // the terminal. MouseModeAuto MouseMode = iota // MouseModeSelect doesn't capture mouse events. This makes selecting with // the mouse work. On some terminals mouse scrolling will work using arrow // keys emulation, and on some not. MouseModeSelect // MouseModeScroll captures mouse events. This makes mouse scrolling work. // Special gymnastics will be required for marking with the mouse to copy // text. MouseModeScroll )
type Options ¶
type Options struct {
// MouseMode controls how mouse events are captured. Leave as
// MouseModeAuto to auto-detect based on the terminal.
MouseMode MouseMode
// TerminalColorCount overrides how many colors twin assumes the terminal
// supports. Leave as ColorCountDefault to auto-detect from the
// environment.
TerminalColorCount ColorCount
// Logger receives twin's own log messages. Leave nil to disable logging.
Logger Logger
}
Options configures a new Screen, created with NewScreen.
The zero value auto-detects mouse mode and terminal color count from the environment, and disables twin's own logging.
type Progress ¶
type Progress struct {
State ProgressState
Percent int
}
Progress is a terminal progress bar's state and completion percentage.
type ProgressState ¶
type ProgressState int
ProgressState is a terminal progress bar's state, one of the ProgressState* constants.
const ( // ProgressStateRemove hides the progress bar. ProgressStateRemove ProgressState = 0 // ProgressStateSet shows the progress bar at Progress.Percent. ProgressStateSet ProgressState = 1 // ProgressStateError shows the progress bar, in an error color, at // Progress.Percent. ProgressStateError ProgressState = 2 // ProgressStateIndeterminate shows a busy progress bar with no known // percentage. ProgressStateIndeterminate ProgressState = 3 // ProgressStatePause shows the progress bar, in a paused color, at // Progress.Percent. ProgressStatePause ProgressState = 4 )
ProgressState values. The numbers match the ones from https://rockorager.dev/misc/osc-9-4-progress-bars/.
type Screen ¶
type Screen interface {
// Close restores the terminal to normal state, must be called after you are
// done with the screen returned by NewScreen().
Close()
// Erases all screen cells, replacing them with spaces in the default
// style.
//
// Like Size(), may apply a pending resize; see Size() for how that
// affects the rest of the frame.
Clear()
// Returns the width of the rune just added, in number of columns.
//
// Note that if you set a wide rune (like '午') in one column, then whatever
// you put in the next column will be hidden by the wide rune. A wide rune
// in the last screen column will be replaced by a space, to prevent it from
// overflowing onto the next line.
SetCell(column int, row int, styledRune StyledRune) int
// Returns the StyledRune at the given screen position.
//
// Note that this does not read cells from the physical screen, but rather
// from what was previously set using SetCell().
//
// For out-of-bounds requests, a space with default style is returned.
GetCell(column int, row int) StyledRune
// Ask the terminal to show a progress bar
//
// Ref: https://rockorager.dev/misc/osc-9-4-progress-bars/
SetProgress(state ProgressState, percent int)
// Render our contents into the terminal window.
//
// The first call takes over the terminal: alternate screen, cursor hidden,
// mouse tracked. Until then the user's own screen is left alone.
//
// Renders nothing while somebody else owns the terminal, meaning after
// Close() or during PauseAndCall(); Ctrl-Z handling makes that possible
// without your main loop asking for it.
Show()
// Can be called after Close()ing the screen to fake retaining its output.
// Plain Show() is what you'd call during normal operation.
//
// Unlike Show(), this one never takes over the terminal; it prints where
// the cursor already is.
PrintLines(lineCountToShow int)
// Returns screen width and height.
//
// NOTE: Never cache this response! On window resizes you'll get an
// EventResize on the Screen.Events channel. The new size takes effect the
// next time you call Size() or Clear(), whichever comes first after your
// last Show()/PrintLines() call, and stays consistent for the rest of that
// frame.
Size() (width int, height int)
// The first call may delay up to 50ms while waiting for the terminal to
// respond to a background color query. After that, it's instant.
//
// Can be nil if not (yet?) detected.
TerminalBackground() *Color
// This channel is what your main loop should be checking.
Events() chan Event
// Pause the screen, run the given function, then resume the screen. Blocks
// until the function has completed and the screen has been resumed again.
//
// Error returns mean that either pausing failed or the run function failed.
// If resuming fails, this method will panic.
PauseAndCall(run func() error) error
}
Screen is the main interface for interacting with the terminal, created with NewScreen.
func NewScreen ¶
NewScreen creates a new Screen according to options. Passing the zero value Options{} auto-detects mouse mode and terminal color count, and disables twin's own logging.
The returned Screen requires Close() to be called after you are done with it, most likely somewhere in your shutdown code.
type Style ¶
type Style struct {
// contains filtered or unexported fields
}
Style is a foreground color, background color, underline color, and a set of text attributes (bold, italic, ...), applied together to a piece of text.
var StyleDefault Style
StyleDefault is the zero value Style: default foreground and background colors, no attributes, no hyperlink.
func (Style) Background ¶
Background returns style's background color.
func (Style) Equal ¶
Equal reports whether style and other render identically: same colors, same attributes, and same hyperlink.
func (Style) Foreground ¶
Foreground returns style's foreground color.
func (Style) HyperlinkURL ¶
HyperlinkURL returns the hyperlink URL if set, or nil otherwise.
func (Style) RenderUpdateFrom ¶
func (style Style) RenderUpdateFrom(previous Style, terminalColorCount ColorCount) string
RenderUpdateFrom returns the ANSI escape sequence needed to switch terminal state from previous to style.
func (Style) WithAttr ¶
WithAttr returns a copy of style with attr added. AttrBold and AttrDim are mutually exclusive, so adding one clears the other.
func (Style) WithBackground ¶
WithBackground returns a copy of style with its background color set to color.
func (Style) WithForeground ¶
WithForeground returns a copy of style with its foreground color set to color.
func (Style) WithHyperlink ¶
WithHyperlink returns a copy of style with its hyperlink URL set. Call with nil to remove the link.
func (Style) WithUnderlineColor ¶
WithUnderlineColor returns a copy of style with its underline color set to color.
func (Style) WithoutAttr ¶
WithoutAttr returns a copy of style with attr removed.
type StyledRune ¶
StyledRune is a rune with a style to be written to a one or more cells on the screen. Note that a StyledRune may use more than one cell on the screen ('午' for example).
func (StyledRune) Equal ¶
func (styledRune StyledRune) Equal(other StyledRune) bool
Equal reports whether styledRune and other have the same rune and style.
func (StyledRune) String ¶
func (styledRune StyledRune) String() string
func (StyledRune) Width ¶
func (styledRune StyledRune) Width() int
Width returns how many screen cells this rune will cover. Most runes cover one, but some like '午' will cover two.

