mirror of https://github.com/gdamore/tcell.git
fixes #26 Improved docs desired
This commit is contained in:
parent
c2130fd973
commit
b19d7067f2
5
attr.go
5
attr.go
|
@ -14,7 +14,8 @@
|
|||
|
||||
package tcell
|
||||
|
||||
// AttrMask represents a mask of text attributes.
|
||||
// AttrMask represents a mask of text attributes, apart from color.
|
||||
// Note that support for attributes may vary widely across terminals.
|
||||
type AttrMask int
|
||||
|
||||
// NB: the colors listed here are in the order that ANSI terminals expect.
|
||||
|
@ -25,5 +26,7 @@ const (
|
|||
AttrReverse
|
||||
AttrUnderline
|
||||
AttrDim
|
||||
|
||||
// AttrNone is just normal text.
|
||||
AttrNone AttrMask = 0
|
||||
)
|
||||
|
|
7
cell.go
7
cell.go
|
@ -81,6 +81,9 @@ func (c *Cell) SetCell(ch []rune, style Style) {
|
|||
c.PutStyle(style)
|
||||
}
|
||||
|
||||
// PutChars is a handy way to write runes to the Cell, without changing its
|
||||
// style. The first rune should be a printable non-zero width value, and
|
||||
// subsequent values may be combining marks.
|
||||
func (c *Cell) PutChars(ch []rune) {
|
||||
|
||||
var mainc rune
|
||||
|
@ -120,10 +123,14 @@ func (c *Cell) PutChars(ch []rune) {
|
|||
c.Width = width
|
||||
}
|
||||
|
||||
// PutChar writes a single rune into the cells location. The rune should be a
|
||||
// a normal (not combining) printable character.
|
||||
func (c *Cell) PutChar(ch rune) {
|
||||
c.PutChars([]rune{ch})
|
||||
}
|
||||
|
||||
// PutStyle changes the style of the given Cell, without altering the character
|
||||
// content.
|
||||
func (c *Cell) PutStyle(style Style) {
|
||||
if c.Style != style {
|
||||
c.Style = style
|
||||
|
|
2
color.go
2
color.go
|
@ -20,6 +20,8 @@ package tcell
|
|||
type Color int16
|
||||
|
||||
const (
|
||||
// ColorDefault is used to leave the Color unchanged from whatever
|
||||
// system or teminal default may exist.
|
||||
ColorDefault Color = iota
|
||||
ColorBlack
|
||||
ColorRed
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright 2015 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
// You may obtain a copy of the license at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package tcell provides a lower-level, portable API for building
|
||||
// programs that interact with terminals or consoles. It works with
|
||||
// both common (and many uncommon!) terminals or terminal emulators,
|
||||
// and Windows console implementations.
|
||||
//
|
||||
// It provides support for up to 256 colors, text attributes, and box drawing
|
||||
// elements. A database of terminals built from a real terminfo database
|
||||
// is provided, along with code to generate new database entries.
|
||||
//
|
||||
// Tcell offers very rich support for mice, dependent upon the terminal
|
||||
// of course. (Windows, XTerm, and iTerm 2 are known to work very well.)
|
||||
//
|
||||
// If the environment is not Unicode by default, such as an ISO8859 based
|
||||
// locale or GB18030, Tcell can convert input and outupt, so that your
|
||||
// terminal can operate in whatever locale is most convenient, while the
|
||||
// application program can just assume "everything is UTF-8". Reasonable
|
||||
// defaults are used for updating characters to something suitable for
|
||||
// display. Unicode box drawing characters will be converted to use the
|
||||
// alternate character set of your terminal, if native conversions are
|
||||
// not available. If no ACS is available, then some ASCII fallbacks will
|
||||
// be used.
|
||||
//
|
||||
// A rich set of keycodes is supported, with support for up to 65 function
|
||||
// keys, and various other special keys.
|
||||
//
|
||||
package tcell
|
54
encoding.go
54
encoding.go
|
@ -23,38 +23,46 @@ import (
|
|||
var encodings map[string]encoding.Encoding
|
||||
var encodingLk sync.Mutex
|
||||
|
||||
// RegisterEncoding may be called by the application to register an encoding. The
|
||||
// presence of additional encodings will facilitate application usage with terminal
|
||||
// environments where the I/O subsystem does not support Unicode. Please see the
|
||||
// Go documentation for encodings -- most of the common ones exist already as stock
|
||||
// variables. For example, ISO8859-15 can be registered using the following code:
|
||||
// RegisterEncoding may be called by the application to register an encoding.
|
||||
// The presence of additional encodings will facilitate application usage with
|
||||
// terminal environments where the I/O subsystem does not support Unicode.
|
||||
// Please see the Go documentation for golang.org/x/text/encoding -- most of
|
||||
// the common ones exist already as stock variables. For example, ISO8859-15
|
||||
// can be registered using the following code:
|
||||
//
|
||||
// import "golang.org/x/text/encoding/charmap"
|
||||
//
|
||||
// ...
|
||||
// RegisterEncoding("ISO8859-15", charmap.ISO8859_15)
|
||||
//
|
||||
// Aliases can be registered as well, for example "8859-15" could be an alias for
|
||||
// "ISO8859-15".
|
||||
// Aliases can be registered as well, for example "8859-15" could be an alias
|
||||
// for "ISO8859-15".
|
||||
//
|
||||
// For POSIX systems, the tcell pacakge will check the environment variables LC_ALL, LC_CTYPE,
|
||||
// and LANG (in that order) to determine the character set. These are expected to have the
|
||||
// following pattern: $language[.$codeset[@$variant] We extract only the $codeset part,
|
||||
// which will usually be something like UTF-8 or ISO8859-15 or KOI8-R. Note that if the
|
||||
// locale is either "POSIX" or "C", then we assume US-ASCII (the POSIX 'portable character set'
|
||||
// For POSIX systems, the tcell pacakge will check the environment variables
|
||||
// LC_ALL, LC_CTYPE, and LANG (in that order) to determine the character set.
|
||||
// These are expected to have the following pattern:
|
||||
//
|
||||
// $language[.$codeset[@$variant]
|
||||
|
||||
// We extract only the $codeset part, which will usually be something like
|
||||
// UTF-8 or ISO8859-15 or KOI8-R. Note that if the locale is either "POSIX"
|
||||
// or "C", then we assume US-ASCII (the POSIX 'portable character set'
|
||||
// and assume all other characters are somehow invalid.)
|
||||
//
|
||||
// On Windows systems, the Console is assumed to be UTF-16LE. As we communicate with the
|
||||
// console subsystem using UTF-16LE, no conversions are necessary. So none of this is required
|
||||
// for Windows systems.
|
||||
// On Windows systems, the Console is assumed to be UTF-16LE. As we
|
||||
// communicate with the console subsystem using UTF-16LE, no conversions are
|
||||
// necessary. So none of this is required for Windows systems.
|
||||
//
|
||||
// Modern POSIX systems and terminal emulators may use UTF-8, and for those systems, this
|
||||
// API is also unnecessary. For example, Darwin (MacOS X) and modern Linux running modern
|
||||
// xterm generally will out of the box without any of this.
|
||||
// Modern POSIX systems and terminal emulators may use UTF-8, and for those
|
||||
// systems, this API is also unnecessary. For example, Darwin (MacOS X) and
|
||||
// modern Linux running modern xterm generally will out of the box without
|
||||
// any of this. Use of UTF-8 is recommended when possible, as it saves
|
||||
// quite a lot processing overhead.
|
||||
//
|
||||
// Note that some encodings are quite large (for example GB18030 which is a superset of
|
||||
// Unicode) and so the application size can be expected ot increase quite a bit as each
|
||||
// encoding is added.
|
||||
// Note that some encodings are quite large (for example GB18030 which is a
|
||||
// superset of Unicode) and so the application size can be expected ot
|
||||
// increase quite a bit as each encoding is added. The East Asian encodings
|
||||
// have been seen to add 100-200K per encoding to the application size.
|
||||
//
|
||||
func RegisterEncoding(name string, enc encoding.Encoding) {
|
||||
encodingLk.Lock()
|
||||
|
@ -65,6 +73,10 @@ func RegisterEncoding(name string, enc encoding.Encoding) {
|
|||
encodingLk.Unlock()
|
||||
}
|
||||
|
||||
// GetEncoding is used by Screen implementors who want to locate an encoding
|
||||
// for the given character set name. Note that this will return nil for
|
||||
// either the Unicode (UTF-8) or ASCII encodings, since we don't use
|
||||
// encodings for them but instead have our own native methods.
|
||||
func GetEncoding(name string) encoding.Encoding {
|
||||
encodingLk.Lock()
|
||||
defer encodingLk.Unlock()
|
||||
|
|
18
key.go
18
key.go
|
@ -40,7 +40,8 @@ import (
|
|||
//
|
||||
// Generally, terminal applications have far less visibility into keyboard
|
||||
// activity than graphical applications. Hence, they should avoid depending
|
||||
// overly much on availability of such details.
|
||||
// overly much on availability of modifiers, or the availability of any
|
||||
// specific keys.
|
||||
type EventKey struct {
|
||||
t time.Time
|
||||
mod ModMask
|
||||
|
@ -48,22 +49,37 @@ type EventKey struct {
|
|||
ch rune
|
||||
}
|
||||
|
||||
// When returns the time when this Event was created, which should closely
|
||||
// match the time when the key was pressed.
|
||||
func (*EventKey) When() time.Time {
|
||||
return time.Now()
|
||||
}
|
||||
|
||||
// Rune returns the rune corresponding to the key press, if it makes sense.
|
||||
// The result is only defined if the value of Key() is KeyRune.
|
||||
func (ev *EventKey) Rune() rune {
|
||||
return ev.ch
|
||||
}
|
||||
|
||||
// Key returns a virtual key code. We use this to identify specific key
|
||||
// codes, such as KeyEnter, etc. Most control and function keys are reported
|
||||
// with unique Key values. Normal alphanumeric and punctuation keys will
|
||||
// generally return KeyRune here; the specific key can be further decoded
|
||||
// using the Rune() function.
|
||||
func (ev *EventKey) Key() Key {
|
||||
return ev.key
|
||||
}
|
||||
|
||||
// ModMask returns the modifiers that were present with the key press. Note
|
||||
// that not all platforms and terminals support this equally well, and some
|
||||
// cases we will not not know for sure. Hence, applications should avoid
|
||||
// using this in most circumstances.
|
||||
func (ev *EventKey) Mod() ModMask {
|
||||
return ev.mod
|
||||
}
|
||||
|
||||
// Name returns a printable value or the key stroke. This can be used
|
||||
// when printing the event, for example.
|
||||
func (ev *EventKey) Name() string {
|
||||
s := ""
|
||||
m := []string{}
|
||||
|
|
18
mouse.go
18
mouse.go
|
@ -25,10 +25,12 @@ import (
|
|||
// without any intervening button release.
|
||||
//
|
||||
// Mouse wheel events, when reported, may appear on their own as individual
|
||||
// impulses.
|
||||
// impulses; that is, there will normally not be a release event delivered
|
||||
// for mouse wheel movements.
|
||||
//
|
||||
// Most terminals cannot report the state of more than one button at a time --
|
||||
// and few can report motion events.
|
||||
// and many cannot report motion events. (Windows consoles, modern XTerm, and
|
||||
// modern emulators like iTerm2, are known to support this well, though.)
|
||||
//
|
||||
// Applications can inspect the time between events to figure out double clicks
|
||||
// and such.
|
||||
|
@ -44,18 +46,25 @@ func (ev *EventMouse) When() time.Time {
|
|||
return ev.t
|
||||
}
|
||||
|
||||
// ButtonMask returns the list of buttons that were pressed.
|
||||
func (ev *EventMouse) Buttons() ButtonMask {
|
||||
return ev.btn
|
||||
}
|
||||
|
||||
// Modifiers returns a list of keyboard modifiers that were pressed
|
||||
// with the mouse button(s).
|
||||
func (ev *EventMouse) Modifiers() ModMask {
|
||||
return ev.mod
|
||||
}
|
||||
|
||||
// Position returns the mouse position in character cells. The origin
|
||||
// 0, 0 is at the upper left corner.
|
||||
func (ev *EventMouse) Position() (int, int) {
|
||||
return ev.x, ev.y
|
||||
}
|
||||
|
||||
// NewEventMouse is used to create a new mouse event. Applications
|
||||
// shouldn't need to use this; its mostly for screen implementors.
|
||||
func NewEventMouse(x, y int, btn ButtonMask, mod ModMask) *EventMouse {
|
||||
return &EventMouse{t: time.Now(), x: x, y: y, btn: btn, mod: mod}
|
||||
}
|
||||
|
@ -64,15 +73,20 @@ func NewEventMouse(x, y int, btn ButtonMask, mod ModMask) *EventMouse {
|
|||
type ButtonMask int16
|
||||
|
||||
const (
|
||||
// Button1 is usually the left mouse button.
|
||||
Button1 ButtonMask = 1 << iota
|
||||
// Button2 is usually the middle mouse button, for three button mice.
|
||||
Button2
|
||||
// Button3 is usually the right mouse button on 2 or 3 button mice.
|
||||
Button3
|
||||
Button4
|
||||
Button5
|
||||
Button6
|
||||
Button7
|
||||
Button8
|
||||
// WheelUp indicates the wheel being moved up, away from the user.
|
||||
WheelUp
|
||||
// WheelDown indicates the wheel being moved down, towards the user.
|
||||
WheelDown
|
||||
WheelLeft
|
||||
WheelRight
|
||||
|
|
21
screen.go
21
screen.go
|
@ -14,10 +14,9 @@
|
|||
|
||||
package tcell
|
||||
|
||||
// Screen represents the physical (or emulated) screen, without any buffering.
|
||||
// Screen represents the physical (or emulated) screen.
|
||||
// This can be a terminal window or a physical console. Platforms implement
|
||||
// this differerently. Applications are unlikely to interface directly with
|
||||
// this.
|
||||
// this differerently.
|
||||
type Screen interface {
|
||||
// Init initializes the screen for use.
|
||||
Init() error
|
||||
|
@ -25,7 +24,9 @@ type Screen interface {
|
|||
// Fini finalizes the screen also releasing resources.
|
||||
Fini()
|
||||
|
||||
// Clear erases the screen.
|
||||
// Clear erases the screen. The contents of any screen buffers
|
||||
// will also be cleared. This has the logical effect of
|
||||
// filling the screen with spaces, using the global default style.
|
||||
Clear()
|
||||
|
||||
// SetCell sets the cell at the given location.
|
||||
|
@ -61,7 +62,7 @@ type Screen interface {
|
|||
GetCell(x, y int) *Cell
|
||||
|
||||
// SetStyle sets the default style to use when clearing the screen
|
||||
// or when StyleDefault is specified. If it is also STyleDefault,
|
||||
// or when StyleDefault is specified. If it is also StyleDefault,
|
||||
// then whatever system/terminal default is relevant will be used.
|
||||
SetStyle(style Style)
|
||||
|
||||
|
@ -93,13 +94,13 @@ type Screen interface {
|
|||
DisableMouse()
|
||||
|
||||
// Colors returns the number of colors. All colors are assumed to
|
||||
// use the ANSI color map.
|
||||
// use the ANSI color map. If a terminal is monochrome, it will
|
||||
// return 0.
|
||||
Colors() int
|
||||
|
||||
// Show takes any output that was deferred due to buffering, and
|
||||
// flushes it to the physical display. It does so in the least
|
||||
// expensive and disruptive manner possible, only making writes that
|
||||
// are believed to actually be necessary.
|
||||
// flushes it to the physical display. It does so in the most
|
||||
// efficient and least visually disruptive manner possible.
|
||||
Show()
|
||||
|
||||
// Sync works like Show(), but it updates every visible cell on the
|
||||
|
@ -119,6 +120,8 @@ type Screen interface {
|
|||
CharacterSet() string
|
||||
}
|
||||
|
||||
// NewScreen returns a default Screen suitable for the user's terminal
|
||||
// environment.
|
||||
func NewScreen() (Screen, error) {
|
||||
// First we attempt to obtain a terminfo screen. This should work
|
||||
// in most places if $TERM is set.
|
||||
|
|
28
style.go
28
style.go
|
@ -14,10 +14,15 @@
|
|||
|
||||
package tcell
|
||||
|
||||
// Color represents a color. We encode it in a 64-bit int for efficiency.
|
||||
// Style represents a complete text style, including both foreground
|
||||
// and background color. We encode it in a 64-bit int for efficiency.
|
||||
// The coding is (MSB): <16b rsvd><16b attr><16b fgcolor><16b bgcolor>.
|
||||
// This gives 16bit color options, if it ever becomes truly necessary.
|
||||
// I can't see a need to get beyond 256 colors.
|
||||
// However, applications must not rely on this encoding.
|
||||
//
|
||||
// Note that not all terminals can display all colors or attributes, and
|
||||
// many might have specific incompatibilities between specific attributes
|
||||
// and color combinations.
|
||||
type Style int64
|
||||
|
||||
func NewStyle() Style {
|
||||
|
@ -26,15 +31,21 @@ func NewStyle() Style {
|
|||
|
||||
const StyleDefault Style = 0
|
||||
|
||||
// Foreground returns a new style based on s, with the foreground color set
|
||||
// as requested. ColorDefault can be used to select the global default.
|
||||
func (s Style) Foreground(c Color) Style {
|
||||
return (s &^ Style(0xffff0000)) | (Style(c) << 16)
|
||||
}
|
||||
|
||||
// Background returns a new style based on s, with the background color set
|
||||
// as requested. ColorDefault can be used to select the global default.
|
||||
func (s Style) Background(c Color) Style {
|
||||
return (s &^ (0xffff)) | Style(c)
|
||||
}
|
||||
|
||||
func (s Style) Decompose() (Color, Color, AttrMask) {
|
||||
// Decompose breaks a style up, returning the foreground, background,
|
||||
// and other attributes.
|
||||
func (s Style) Decompose() (fg Color, bg Color, attr AttrMask) {
|
||||
return Color((s >> 16) & 0xffff),
|
||||
Color(s & 0xfffff),
|
||||
AttrMask((s >> 32) & 0xffff)
|
||||
|
@ -53,22 +64,33 @@ func (s Style) Normal() Style {
|
|||
return s &^ (Style(0xfffff) << 32)
|
||||
}
|
||||
|
||||
// Bold returns a new style based on s, with the bold attribute set
|
||||
// as requested.
|
||||
func (s Style) Bold(on bool) Style {
|
||||
return s.setAttrs(Style(AttrBold), on)
|
||||
}
|
||||
|
||||
// Blink returns a new style based on s, with the blink attribute set
|
||||
// as requested.
|
||||
func (s Style) Blink(on bool) Style {
|
||||
return s.setAttrs(Style(AttrBlink), on)
|
||||
}
|
||||
|
||||
// Dim returns a new style based on s, with the dim attribute set
|
||||
// as requested.
|
||||
func (s Style) Dim(on bool) Style {
|
||||
return s.setAttrs(Style(AttrDim), on)
|
||||
}
|
||||
|
||||
// Reverse returns a new style based on s, with the reverse attribute set
|
||||
// as requested. (Reverse usually changes the foreground and background
|
||||
// colors.)
|
||||
func (s Style) Reverse(on bool) Style {
|
||||
return s.setAttrs(Style(AttrReverse), on)
|
||||
}
|
||||
|
||||
// Reverse returns a new style based on s, with the underline attribute set
|
||||
// as requested.
|
||||
func (s Style) Underline(on bool) Style {
|
||||
return s.setAttrs(Style(AttrUnderline), on)
|
||||
}
|
||||
|
|
13
tscreen.go
13
tscreen.go
|
@ -26,6 +26,14 @@ import (
|
|||
"golang.org/x/text/transform"
|
||||
)
|
||||
|
||||
// NewTerminfoScreen returns a Screen that uses the stock TTY interface
|
||||
// and POSIX termios, combined with a terminfo description taken from
|
||||
// the $TERM environment variable. It returns an error if the terminal
|
||||
// is not supported for any reason.
|
||||
//
|
||||
// For terminals that do not support dynamic resize events, the $LINES
|
||||
// $COLUMNS environment variables can be set to the actual window size,
|
||||
// otherwise defaults taken from the terminal database are used.
|
||||
func NewTerminfoScreen() (Screen, error) {
|
||||
ti, e := LookupTerminfo(os.Getenv("TERM"))
|
||||
if e != nil {
|
||||
|
@ -285,7 +293,6 @@ func (t *tScreen) GetCell(x, y int) *Cell {
|
|||
return &cell
|
||||
}
|
||||
|
||||
|
||||
func (t *tScreen) encodeRune(r rune, buf []byte) []byte {
|
||||
|
||||
// all the character sets we care about are ASCII supersets
|
||||
|
@ -323,7 +330,7 @@ func (t *tScreen) encodeRune(r rune, buf []byte) []byte {
|
|||
buf = append(buf, '?')
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
buf = append(buf, nb...)
|
||||
}
|
||||
} else if len(buf) == 0 {
|
||||
|
@ -925,7 +932,7 @@ func (t *tScreen) parseRune(buf *bytes.Buffer) (bool, bool) {
|
|||
ev := NewEventKey(KeyRune, r, ModNone)
|
||||
t.PostEvent(ev)
|
||||
}
|
||||
for eat := 0; eat < nin; eat++ {
|
||||
for eat := 0; eat < nin; eat++ {
|
||||
buf.ReadByte()
|
||||
}
|
||||
return true, true
|
||||
|
|
|
@ -20,6 +20,8 @@ import (
|
|||
"errors"
|
||||
)
|
||||
|
||||
// This stub file is for systems that have no termios.
|
||||
|
||||
type termiosPrivate struct{}
|
||||
|
||||
func (t *tScreen) termioInit() error {
|
||||
|
|
Loading…
Reference in New Issue