build: bump gocui

This commit is contained in:
Ryooooooga 2023-01-06 10:59:09 +09:00
parent 00b922604a
commit 657b1e897f
No known key found for this signature in database
GPG key ID: 07CF200DFCC20C25
84 changed files with 1710 additions and 3272 deletions

View file

@ -6,16 +6,17 @@ _Tcell_ is a _Go_ package that provides a cell based view for text terminals, li
It was inspired by _termbox_, but includes many additional improvements.
[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://stand-with-ukraine.pp.ua)
[![Linux](https://img.shields.io/github/workflow/status/gdamore/tcell/linux?logoColor=grey&logo=linux&label=)](https://github.com/gdamore/tcell/actions/workflows/linux.yml)
[![Windows](https://img.shields.io/github/workflow/status/gdamore/tcell/windows?logoColor=grey&logo=windows&label=)](https://github.com/gdamore/tcell/actions/workflows/windows.yml)
[![Linux](https://img.shields.io/github/actions/workflow/status/gdamore/tcell/linux.yml?branch=main&logoColor=grey&logo=linux&label=)](https://github.com/gdamore/tcell/actions/workflows/linux.yml)
[![Windows](https://img.shields.io/github/actions/workflow/status/gdamore/tcell/windows.yml?branch=main&logoColor=grey&logo=windows&label=)](https://github.com/gdamore/tcell/actions/workflows/windows.yml)
[![Apache License](https://img.shields.io/github/license/gdamore/tcell.svg?logoColor=silver&logo=opensourceinitiative&color=blue&label=)](https://github.com/gdamore/tcell/blob/master/LICENSE)
[![Docs](https://img.shields.io/badge/godoc-reference-blue.svg?label=&logo=go)](https://pkg.go.dev/github.com/gdamore/tcell/v2)
[![Discord](https://img.shields.io/discord/639503822733180969?label=&logo=discord)](https://discord.gg/urTTxDN)
[![Coverage](https://img.shields.io/codecov/c/github/gdamore/tcell?logoColor=grey&logo=codecov&label=)](https://codecov.io/gh/gdamore/tcell)
[![Go Report Card](https://goreportcard.com/badge/github.com/gdamore/tcell/v2)](https://goreportcard.com/report/github.com/gdamore/tcell/v2)
Please see [here](UKRAINE.md) for an important message for the people of Russia.
NOTE: This is version 2 of _Tcell_. There are breaking changes relative to version 1.
NOTE: This is version 2 of _Tcell_. There are breaking changes relative to version 1.
Version 1.x remains available using the import `github.com/gdamore/tcell`.
## Tutorial
@ -24,51 +25,51 @@ A brief, and still somewhat rough, [tutorial](TUTORIAL.md) is available.
## Examples
* [proxima5](https://github.com/gdamore/proxima5) - space shooter ([video](https://youtu.be/jNxKTCmY_bQ))
* [govisor](https://github.com/gdamore/govisor) - service management UI ([screenshot](http://2.bp.blogspot.com/--OsvnfzSNow/Vf7aqMw3zXI/AAAAAAAAARo/uOMtOvw4Sbg/s1600/Screen%2BShot%2B2015-09-20%2Bat%2B9.08.41%2BAM.png))
* mouse demo - included mouse test ([screenshot](http://2.bp.blogspot.com/-fWvW5opT0es/VhIdItdKqJI/AAAAAAAAATE/7Ojc0L1SpB0/s1600/Screen%2BShot%2B2015-10-04%2Bat%2B11.47.13%2BPM.png))
* [gomatrix](https://github.com/gdamore/gomatrix) - converted from Termbox
* [micro](https://github.com/zyedidia/micro/) - lightweight text editor with syntax-highlighting and themes
* [godu](https://github.com/viktomas/godu) - utility to discover large files/folders
* [tview](https://github.com/rivo/tview/) - rich interactive widgets
* [cview](https://code.rocketnine.space/tslocum/cview) - user interface toolkit (fork of _tview_)
* [awsome gocui](https://github.com/awesome-gocui/gocui) - Go Console User Interface
* [gomandelbrot](https://github.com/rgm3/gomandelbrot) - Mandelbrot!
* [WTF](https://github.com/senorprogrammer/wtf) - personal information dashboard
* [browsh](https://github.com/browsh-org/browsh) - modern web browser ([video](https://www.youtube.com/watch?v=HZq86XfBoRo))
* [go-life](https://github.com/sachaos/go-life) - Conway's Game of Life
* [gowid](https://github.com/gcla/gowid) - compositional widgets for terminal UIs, inspired by _urwid_
* [termshark](https://termshark.io) - interface for _tshark_, inspired by Wireshark, built on _gowid_
* [go-tetris](https://github.com/MichaelS11/go-tetris) - Go Tetris with AI option
* [fzf](https://github.com/junegunn/fzf) - command-line fuzzy finder
* [ascii-fluid](https://github.com/esimov/ascii-fluid) - fluid simulation controlled by webcam
* [cbind](https://code.rocketnine.space/tslocum/cbind) - key event encoding, decoding and handling
* [tpong](https://github.com/spinzed/tpong) - old-school Pong
* [aerc](https://git.sr.ht/~sircmpwn/aerc) - email client
* [tblogs](https://github.com/ezeoleaf/tblogs) - development blogs reader
* [spinc](https://github.com/lallassu/spinc) - _irssi_ inspired chat application for Cisco Spark/WebEx
* [gorss](https://github.com/lallassu/gorss) - RSS/Atom feed reader
* [memoryalike](https://github.com/Bios-Marcel/memoryalike) - memorization game
* [lf](https://github.com/gokcehan/lf) - file manager
* [goful](https://github.com/anmitsu/goful) - CUI file manager
* [gokeybr](https://github.com/bunyk/gokeybr) - deliberately practice your typing
* [gonano](https://github.com/jbaramidze/gonano) - editor, mimics _nano_
* [uchess](https://github.com/tmountain/uchess) - UCI chess client
* [min](https://github.com/a-h/min) - Gemini browser
* [ov](https://github.com/noborus/ov) - file pager
* [tmux-wormhole](https://github.com/gcla/tmux-wormhole) - _tmux_ plugin to transfer files
* [gruid-tcell](https://github.com/anaseto/gruid-tcell) - driver for the grid based UI and game framework
* [aretext](https://github.com/aretext/aretext) - minimalist text editor with _vim_ key bindings
* [sync](https://github.com/kyprifog/sync) - GitHub repo synchronization tool
* [statusbar](https://github.com/kyprifog/statusbar) - statusbar motivation tool for tracking periodic tasks/goals
* [todo](https://github.com/kyprifog/todo) - simple todo app
* [gosnakego](https://github.com/liweiyi88/gosnakego) - a snake game
- [proxima5](https://github.com/gdamore/proxima5) - space shooter ([video](https://youtu.be/jNxKTCmY_bQ))
- [govisor](https://github.com/gdamore/govisor) - service management UI ([screenshot](http://2.bp.blogspot.com/--OsvnfzSNow/Vf7aqMw3zXI/AAAAAAAAARo/uOMtOvw4Sbg/s1600/Screen%2BShot%2B2015-09-20%2Bat%2B9.08.41%2BAM.png))
- mouse demo - included mouse test ([screenshot](http://2.bp.blogspot.com/-fWvW5opT0es/VhIdItdKqJI/AAAAAAAAATE/7Ojc0L1SpB0/s1600/Screen%2BShot%2B2015-10-04%2Bat%2B11.47.13%2BPM.png))
- [gomatrix](https://github.com/gdamore/gomatrix) - converted from Termbox
- [micro](https://github.com/zyedidia/micro/) - lightweight text editor with syntax-highlighting and themes
- [godu](https://github.com/viktomas/godu) - utility to discover large files/folders
- [tview](https://github.com/rivo/tview/) - rich interactive widgets
- [cview](https://code.rocketnine.space/tslocum/cview) - user interface toolkit (fork of _tview_)
- [awsome gocui](https://github.com/awesome-gocui/gocui) - Go Console User Interface
- [gomandelbrot](https://github.com/rgm3/gomandelbrot) - Mandelbrot!
- [WTF](https://github.com/senorprogrammer/wtf) - personal information dashboard
- [browsh](https://github.com/browsh-org/browsh) - modern web browser ([video](https://www.youtube.com/watch?v=HZq86XfBoRo))
- [go-life](https://github.com/sachaos/go-life) - Conway's Game of Life
- [gowid](https://github.com/gcla/gowid) - compositional widgets for terminal UIs, inspired by _urwid_
- [termshark](https://termshark.io) - interface for _tshark_, inspired by Wireshark, built on _gowid_
- [go-tetris](https://github.com/MichaelS11/go-tetris) - Go Tetris with AI option
- [fzf](https://github.com/junegunn/fzf) - command-line fuzzy finder
- [ascii-fluid](https://github.com/esimov/ascii-fluid) - fluid simulation controlled by webcam
- [cbind](https://code.rocketnine.space/tslocum/cbind) - key event encoding, decoding and handling
- [tpong](https://github.com/spinzed/tpong) - old-school Pong
- [aerc](https://git.sr.ht/~sircmpwn/aerc) - email client
- [tblogs](https://github.com/ezeoleaf/tblogs) - development blogs reader
- [spinc](https://github.com/lallassu/spinc) - _irssi_ inspired chat application for Cisco Spark/WebEx
- [gorss](https://github.com/lallassu/gorss) - RSS/Atom feed reader
- [memoryalike](https://github.com/Bios-Marcel/memoryalike) - memorization game
- [lf](https://github.com/gokcehan/lf) - file manager
- [goful](https://github.com/anmitsu/goful) - CUI file manager
- [gokeybr](https://github.com/bunyk/gokeybr) - deliberately practice your typing
- [gonano](https://github.com/jbaramidze/gonano) - editor, mimics _nano_
- [uchess](https://github.com/tmountain/uchess) - UCI chess client
- [min](https://github.com/a-h/min) - Gemini browser
- [ov](https://github.com/noborus/ov) - file pager
- [tmux-wormhole](https://github.com/gcla/tmux-wormhole) - _tmux_ plugin to transfer files
- [gruid-tcell](https://github.com/anaseto/gruid-tcell) - driver for the grid based UI and game framework
- [aretext](https://github.com/aretext/aretext) - minimalist text editor with _vim_ key bindings
- [sync](https://github.com/kyprifog/sync) - GitHub repo synchronization tool
- [statusbar](https://github.com/kyprifog/statusbar) - statusbar motivation tool for tracking periodic tasks/goals
- [todo](https://github.com/kyprifog/todo) - simple todo app
- [gosnakego](https://github.com/liweiyi88/gosnakego) - a snake game
- [gbb](https://github.com/sdemingo/gbb) - A classical bulletin board app for tildes or public unix servers
## Pure Go Terminfo Database
_Tcell_ includes a full parser and expander for terminfo capability strings,
so that it can avoid hard coding escape strings for formatting. It also favors
so that it can avoid hard coding escape strings for formatting. It also favors
portability, and includes support for all POSIX systems.
The database is also flexible & extensible, and can be modified by either running
@ -113,7 +114,7 @@ For example attempts to emit color sequences on VT100 terminals
won't result in unintended consequences.
In legacy Windows mode, _Tcell_ supports 16 colors, bold, dim, and reverse,
instead of just termbox's 8 colors with reverse. (Note that there is some
instead of just termbox's 8 colors with reverse. (Note that there is some
conflation with bold/dim and colors.)
Modern Windows 10 can benefit from much richer colors however.
@ -126,7 +127,7 @@ _Tcell_ supports enhanced mouse tracking mode, so your application can receive
regular mouse motion events, and wheel events, if your terminal supports it.
(Note: The Windows 10 Terminal application suffers from a flaw in this regard,
and does not support mouse interaction. The stock Windows 10 console host
and does not support mouse interaction. The stock Windows 10 console host
fired up with cmd.exe or PowerShell works fine however.)
## _Termbox_ Compatibility
@ -151,7 +152,7 @@ The `SetContent()` API takes a primary rune, and an optional list of combining r
If any of the runes is a wide (East Asian) rune occupying two cells,
then the library will skip output from the following cell. Care must be
taken in the application to avoid explicitly attempting to set content in the
next cell, otherwise the results are undefined. (Normally the wide character
next cell, otherwise the results are undefined. (Normally the wide character
is displayed, and the other character is not; do not depend on that behavior.)
Older terminal applications (especially on systems like Windows 8) lack support
@ -160,15 +161,15 @@ for advanced Unicode, and thus may not fare well.
## Colors
_Tcell_ assumes the ANSI/XTerm color model, including the 256 color map that
XTerm uses when it supports 256 colors. The terminfo guidance will be
honored, with respect to the number of colors supported. Also, only
XTerm uses when it supports 256 colors. The terminfo guidance will be
honored, with respect to the number of colors supported. Also, only
terminals which expose ANSI style `setaf` and `setab` will support color;
if you have a color terminal that only has `setf` and `setb`, please submit
a ticket.
## 24-bit Color
_Tcell_ _supports 24-bit color!_ (That is, if your terminal can support it.)
_Tcell_ _supports 24-bit color!_ (That is, if your terminal can support it.)
NOTE: Technically the approach of using 24-bit RGB values for color is more
accurately described as "direct color", but most people use the term "true color".
@ -176,26 +177,26 @@ We follow the (inaccurate) common convention.
There are a few ways you can enable (or disable) true color.
* For many terminals, we can detect it automatically if your terminal
includes the `RGB` or `Tc` capabilities (or rather it did when the database
was updated.)
- For many terminals, we can detect it automatically if your terminal
includes the `RGB` or `Tc` capabilities (or rather it did when the database
was updated.)
* You can force this one by setting the `COLORTERM` environment variable to
`24-bit`, `truecolor` or `24bit`. This is the same method used
by most other terminal applications that support 24-bit color.
- You can force this one by setting the `COLORTERM` environment variable to
`24-bit`, `truecolor` or `24bit`. This is the same method used
by most other terminal applications that support 24-bit color.
* If you set your `TERM` environment variable to a value with the suffix `-truecolor`
then 24-bit color compatible with XTerm and ECMA-48 will be assumed.
(This feature is deprecated.
It is recommended to use one of other methods listed above.)
- If you set your `TERM` environment variable to a value with the suffix `-truecolor`
then 24-bit color compatible with XTerm and ECMA-48 will be assumed.
(This feature is deprecated.
It is recommended to use one of other methods listed above.)
* You can disable 24-bit color by setting `TCELL_TRUECOLOR=disable` in your
environment.
- You can disable 24-bit color by setting `TCELL_TRUECOLOR=disable` in your
environment.
When using TrueColor, programs will display the colors that the programmer
intended, overriding any "`themes`" you may have set in your terminal
emulator. (For some cases, accurate color fidelity is more important
than respecting themes. For other cases, such as typical text apps that
emulator. (For some cases, accurate color fidelity is more important
than respecting themes. For other cases, such as typical text apps that
only use a few colors, its more desirable to respect the themes that
the user has established.)
@ -209,7 +210,7 @@ avoiding repeated sequences or drawing the same cell on refresh updates.
(Not relevant for Windows users.)
The Terminfo implementation operates with a built-in database.
This should satisfy most users. However, it can also (on systems
This should satisfy most users. However, it can also (on systems
with ncurses installed), dynamically parse the output from `infocmp`
for terminals it does not already know about.
@ -226,8 +227,8 @@ since the early 1970s.
Mouse support is detected via the `kmous` terminfo variable, however,
enablement/disablement and decoding mouse events is done using hard coded
sequences based on the XTerm X11 model. All popular
terminals with mouse tracking support this model. (Full terminfo support
sequences based on the XTerm X11 model. All popular
terminals with mouse tracking support this model. (Full terminfo support
is not possible as terminfo sequences are not defined.)
On Windows, the mouse works normally.
@ -240,12 +241,12 @@ Modern _xterm_, macOS _Terminal_, and _iTerm_ all work well.
## Bracketed Paste
Terminals that appear to support the XTerm mouse model also can support
bracketed paste, for applications that opt-in. See `EnablePaste()` for details.
bracketed paste, for applications that opt-in. See `EnablePaste()` for details.
## Testability
There is a `SimulationScreen`, that can be used to simulate a real screen
for automated testing. The supplied tests do this. The simulation contains
for automated testing. The supplied tests do this. The simulation contains
event delivery, screen resizing support, and capabilities to inject events
and examine "`physical`" screen contents.
@ -253,8 +254,8 @@ and examine "`physical`" screen contents.
### POSIX (Linux, FreeBSD, macOS, Solaris, etc.)
Everything works using pure Go on mainstream platforms. Some more esoteric
platforms (e.g., AIX) may need to be added. Pull requests are welcome!
Everything works using pure Go on mainstream platforms. Some more esoteric
platforms (e.g., AIX) may need to be added. Pull requests are welcome!
### Windows
@ -267,15 +268,15 @@ support all the good features (resize, mouse tracking, etc.)
These platforms won't work, but compilation stubs are supplied
for folks that want to include parts of this in software for those
platforms. The Simulation screen works, but as _Tcell_ doesn't know how to
platforms. The Simulation screen works, but as _Tcell_ doesn't know how to
allocate a real screen object on those platforms, `NewScreen()` will fail.
If anyone has wisdom about how to improve support for these,
please let me know. PRs are especially welcome.
please let me know. PRs are especially welcome.
### Commercial Support
_Tcell_ is absolutely free, but if you want to obtain commercial, professional support, there are options.
* [TideLift](https://tidelift.com/) subscriptions include support for _Tcell_, as well as many other open source packages.
* [Staysail Systems Inc.](mailto:info@staysail.tech) offers direct support, and custom development around _Tcell_ on an hourly basis.
- [TideLift](https://tidelift.com/) subscriptions include support for _Tcell_, as well as many other open source packages.
- [Staysail Systems Inc.](mailto:info@staysail.tech) offers direct support, and custom development around _Tcell_ on an hourly basis.

View file

@ -18,7 +18,7 @@ to the terminal capabilities.
Applications receive an event of type `EventResize` when they are first initialized and each time the terminal is resized.
The new size is available as `Size`.
```golang
```go
switch ev := ev.(type) {
case *tcell.EventResize:
w, h := ev.Size()
@ -35,7 +35,7 @@ When a rune key is pressed, an event with its `Key` set to `KeyRune` is dispatch
When a non-rune key is pressed, it is available as the `Key` of the event.
```golang
```go
switch ev := ev.(type) {
case *tcell.EventKey:
mod, key, ch := ev.Mod(), ev.Key(), ev.Rune()
@ -62,7 +62,7 @@ Mouse events are only delivered if
The mouse buttons being pressed (if any) are available as `Buttons`, and the position of the mouse is available as `Position`.
```golang
```go
switch ev := ev.(type) {
case *tcell.EventMouse:
mod := ev.Modifiers()
@ -81,12 +81,16 @@ Button2 | ButtonSecondary | Right button
Button3 | ButtonMiddle | Middle button
Button4 | | Side button (thumb/next)
Button5 | | Side button (thumb/prev)
WheelUp | | Scroll wheel up
WheelDown | | Scroll wheel down
WheelLeft | | Horizontal wheel left
WheelRight | | Horizontal wheel right
## Usage
To create a tcell application, first initialize a screen to hold it.
To create a _Tcell_ application, first initialize a screen to hold it.
```golang
```go
s, err := tcell.NewScreen()
if err != nil {
log.Fatalf("%+v", err)
@ -105,7 +109,7 @@ s.Clear()
Text may be drawn on the screen using `SetContent`.
```golang
```go
s.SetContent(0, 0, 'H', nil, defStyle)
s.SetContent(1, 0, 'i', nil, defStyle)
s.SetContent(2, 0, '!', nil, defStyle)
@ -113,7 +117,7 @@ s.SetContent(2, 0, '!', nil, defStyle)
To draw text more easily, define a render function.
```golang
```go
func drawText(s tcell.Screen, x1, y1, x2, y2 int, style tcell.Style, text string) {
row := y1
col := x1
@ -133,7 +137,7 @@ func drawText(s tcell.Screen, x1, y1, x2, y2 int, style tcell.Style, text string
Lastly, define an event loop to handle user input and update application state.
```golang
```go
quit := func() {
s.Fini()
os.Exit(0)
@ -161,13 +165,12 @@ for {
The following demonstrates how to initialize a screen, draw text/graphics and handle user input.
```golang
```go
package main
import (
"fmt"
"log"
"os"
"github.com/gdamore/tcell/v2"
)
@ -245,12 +248,29 @@ func main() {
drawBox(s, 1, 1, 42, 7, boxStyle, "Click and drag to draw a box")
drawBox(s, 5, 9, 32, 14, boxStyle, "Press C to reset")
quit := func() {
// You have to catch panics in a defer, clean up, and
// re-raise them - otherwise your application can
// die without leaving any diagnostic trace.
maybePanic := recover()
s.Fini()
if maybePanic != nil {
panic(maybePanic)
}
}
defer quit()
// Here's how to get the screen size when you need it.
// xmax, ymax := s.Size()
// Here's an example of how to inject a keystroke where it will
// be picked up by the next PollEvent call. Note that the
// queue is LIFO, it has a limited length, and PostEvent() can
// return an error.
// s.PostEvent(tcell.NewEventKey(tcell.KeyRune, rune('a'), 0))
// Event loop
ox, oy := -1, -1
quit := func() {
s.Fini()
os.Exit(0)
}
for {
// Update screen
s.Show()
@ -264,7 +284,7 @@ func main() {
s.Sync()
case *tcell.EventKey:
if ev.Key() == tcell.KeyEscape || ev.Key() == tcell.KeyCtrlC {
quit()
return
} else if ev.Key() == tcell.KeyCtrlL {
s.Sync()
} else if ev.Rune() == 'C' || ev.Rune() == 'c' {
@ -272,14 +292,13 @@ func main() {
}
case *tcell.EventMouse:
x, y := ev.Position()
button := ev.Buttons()
// Only process button events, not wheel events
button &= tcell.ButtonMask(0xff)
if button != tcell.ButtonNone && ox < 0 {
ox, oy = x, y
}
switch ev.Buttons() {
case tcell.Button1, tcell.Button2:
if ox < 0 {
ox, oy = x, y // record location when click started
}
case tcell.ButtonNone:
if ox >= 0 {
label := fmt.Sprintf("%d,%d to %d,%d", ox, oy, x, y)
@ -291,3 +310,4 @@ func main() {
}
}
```

View file

@ -1,4 +1,4 @@
// Copyright 2019 The TCell Authors
// Copyright 2022 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
@ -15,6 +15,8 @@
package tcell
import (
"os"
runewidth "github.com/mattn/go-runewidth"
)
@ -175,3 +177,20 @@ func (cb *CellBuffer) Fill(r rune, style Style) {
c.width = 1
}
}
var runeConfig *runewidth.Condition;
func init() {
// The defaults for the runewidth package are poorly chosen for terminal
// applications. We however will honor the setting in the environment if
// it is set.
if os.Getenv("RUNEWIDTH_EASTASIAN") == "" {
runewidth.DefaultCondition.EastAsianWidth = false;
}
// For performance reasons, we create a lookup table. However some users
// might be more memory conscious. If that's you, set the TCELL_MINIMIZE
// environment variable.
if os.Getenv("TCELL_MINIMIZE") == "" {
runewidth.CreateLUT()
}
}

View file

@ -1,3 +1,4 @@
//go:build plan9 || nacl
// +build plan9 nacl
// Copyright 2015 The TCell Authors

View file

@ -1,3 +1,4 @@
//go:build !windows && !nacl && !plan9
// +build !windows,!nacl,!plan9
// Copyright 2016 The TCell Authors

View file

@ -1,3 +1,4 @@
//go:build windows
// +build windows
// Copyright 2015 The TCell Authors

View file

@ -15,8 +15,9 @@
package tcell
import (
"github.com/lucasb-eyer/go-colorful"
"math"
"github.com/lucasb-eyer/go-colorful"
)
// FindColor attempts to find a given color, or the best match possible for it,

View file

@ -1,3 +1,4 @@
//go:build !windows
// +build !windows
// Copyright 2015 The TCell Authors

View file

@ -36,13 +36,12 @@
//
// Note that support for non-UTF-8 locales (other than C) must be enabled
// by the application using RegisterEncoding() -- we don't have them all
// enabled by default to avoid bloating the application unneccessarily.
// enabled by default to avoid bloating the application unnecessarily.
// (These days UTF-8 is good enough for almost everyone, and nobody should
// be using legacy locales anymore.) Also, actual glyphs for various code
// point will only be displayed if your terminal or emulator (or the font
// the emulator is using) supports them.
//
// A rich set of keycodes is supported, with support for up to 65 function
// A rich set of key codes is supported, with support for up to 65 function
// keys, and various other special keys.
//
package tcell

View file

@ -1,4 +1,4 @@
// Copyright 2015 The TCell Authors
// Copyright 2022 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
@ -38,19 +38,19 @@ var encodingFallback EncodingFallback = EncodingFallbackFail
// 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"
// import "golang.org/x/text/encoding/charmap"
//
// ...
// RegisterEncoding("ISO8859-15", charmap.ISO8859_15)
// ...
// RegisterEncoding("ISO8859-15", charmap.ISO8859_15)
//
// Aliases can be registered as well, for example "8859-15" could be an alias
// for "ISO8859-15".
//
// For POSIX systems, the tcell package will check the environment variables
// For POSIX systems, this package 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]
// $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"
@ -64,9 +64,11 @@ var encodingFallback EncodingFallback = EncodingFallbackFail
// 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. The East Asian encodings
// have been seen to add 100-200K per encoding to the application size.
// superset of Unicode) and so the application size can be expected to
// increase quite a bit as each encoding is added.
// The East Asian encodings have been seen to add 100-200K per encoding to the
// size of the resulting binary.
//
func RegisterEncoding(charset string, enc encoding.Encoding) {
encodingLk.Lock()
@ -75,7 +77,7 @@ func RegisterEncoding(charset string, enc encoding.Encoding) {
encodingLk.Unlock()
}
// EncodingFallback describes how the system behavees when the locale
// EncodingFallback describes how the system behaves when the locale
// requires a character set that we do not support. The system always
// supports UTF-8 and US-ASCII. On Windows consoles, UTF-16LE is also
// supported automatically. Other character sets must be added using the
@ -88,7 +90,7 @@ const (
// when it cannot find an encoding.
EncodingFallbackFail = iota
// EncodingFallbackASCII behaviore causes GetEncoding to fall back
// EncodingFallbackASCII behavior causes GetEncoding to fall back
// to a 7-bit ASCII encoding, if no other encoding can be found.
EncodingFallbackASCII

View file

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
// +build darwin dragonfly freebsd netbsd openbsd
package tcell

View file

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build linux || aix || zos || solaris
// +build linux aix zos solaris
package tcell

View file

@ -24,12 +24,13 @@ type Screen interface {
// Fini finalizes the screen also releasing resources.
Fini()
// 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 logically erases the screen.
// This is effectively a short-cut for Fill(' ', StyleDefault).
Clear()
// Fill fills the screen with the given character and style.
// The effect of filling the screen is not visible until Show
// is called (or Sync).
Fill(rune, Style)
// SetCell is an older API, and will be removed. Please use
@ -42,7 +43,7 @@ type Screen interface {
// and may not actually be what is displayed, but rather are what will
// be displayed if Show() or Sync() is called. The width is the width
// in screen cells; most often this will be 1, but some East Asian
// characters require two cells.
// characters and emoji require two cells.
GetContent(x, y int) (primary rune, combining []rune, style Style, width int)
// SetContent sets the contents of the given cell location. If
@ -54,7 +55,7 @@ type Screen interface {
//
// The results are not displayed until Show() or Sync() is called.
//
// Note that wide (East Asian full width) runes occupy two cells,
// Note that wide (East Asian full width and emoji) runes occupy two cells,
// and attempts to place character at next cell to the right will have
// undefined effects. Wide runes that are printed in the
// last column will be replaced with a single width space on output.

View file

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package tcell
@ -60,7 +61,7 @@ func (tty *stdIoTty) Start() error {
defer tty.l.Unlock()
// We open another copy of /dev/tty. This is a workaround for unusual behavior
// observed in macOS, apparently caused when a subshell (for example) closes our
// observed in macOS, apparently caused when a sub-shell (for example) closes our
// own tty device (when it exits for example). Getting a fresh new one seems to
// resolve the problem. (We believe this is a bug in the macOS tty driver that
// fails to account for dup() references to the same file before applying close()
@ -162,7 +163,7 @@ func (tty *stdIoTty) NotifyResize(cb func()) {
func NewStdIoTty() (Tty, error) {
tty := &stdIoTty{
sig: make(chan os.Signal),
in: os.Stdin,
in: os.Stdin,
out: os.Stdout,
}
var err error

View file

@ -27,6 +27,7 @@ type Style struct {
bg Color
attrs AttrMask
url string
urlId string
}
// StyleDefault represents a default style, based upon the context.
@ -44,6 +45,7 @@ func (s Style) Foreground(c Color) Style {
bg: s.bg,
attrs: s.attrs,
url: s.url,
urlId: s.urlId,
}
}
@ -55,6 +57,7 @@ func (s Style) Background(c Color) Style {
bg: c,
attrs: s.attrs,
url: s.url,
urlId: s.urlId,
}
}
@ -71,6 +74,7 @@ func (s Style) setAttrs(attrs AttrMask, on bool) Style {
bg: s.bg,
attrs: s.attrs | attrs,
url: s.url,
urlId: s.urlId,
}
}
return Style{
@ -78,6 +82,7 @@ func (s Style) setAttrs(attrs AttrMask, on bool) Style {
bg: s.bg,
attrs: s.attrs &^ attrs,
url: s.url,
urlId: s.urlId,
}
}
@ -139,6 +144,7 @@ func (s Style) Attributes(attrs AttrMask) Style {
bg: s.bg,
attrs: attrs,
url: s.url,
urlId: s.urlId,
}
}
@ -151,5 +157,20 @@ func (s Style) Url(url string) Style {
bg: s.bg,
attrs: s.attrs,
url: url,
urlId: s.urlId,
}
}
// UrlId returns a style with the UrlId set. If the provided UrlId is not empty,
// any marked up Url with this style will be given the UrlId also. If the
// terminal supports it, any text with the same UrlId will be grouped as if it
// were one Url, even if it spans multiple lines.
func (s Style) UrlId(id string) Style {
return Style{
fg: s.fg,
bg: s.bg,
attrs: s.attrs,
url: s.url,
urlId: "id=" + id,
}
}

View file

@ -8,63 +8,63 @@ func init() {
// foot terminal emulator
terminfo.AddTerminfo(&terminfo.Terminfo{
Name: "foot",
Aliases: []string{"foot-extra"},
Columns: 80,
Lines: 24,
Colors: 256,
Bell: "\a",
Clear: "\x1b[H\x1b[2J",
EnterCA: "\x1b[?1049h\x1b[22;0;0t",
ExitCA: "\x1b[?1049l\x1b[23;0;0t",
ShowCursor: "\x1b[?12l\x1b[?25h",
HideCursor: "\x1b[?25l",
AttrOff: "\x1b(B\x1b[m",
Underline: "\x1b[4m",
Bold: "\x1b[1m",
Dim: "\x1b[2m",
Italic: "\x1b[3m",
Blink: "\x1b[5m",
Reverse: "\x1b[7m",
EnterKeypad: "\x1b[?1h\x1b=",
ExitKeypad: "\x1b[?1l\x1b>",
SetFg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38:5:%p1%d%;m",
SetBg: "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48:5:%p1%d%;m",
SetFgBg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38:5:%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48:5:%p2%d%;m",
ResetFgBg: "\x1b[39;49m",
AltChars: "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
EnterAcs: "\x1b(0",
ExitAcs: "\x1b(B",
Name: "foot",
Aliases: []string{"foot-extra"},
Columns: 80,
Lines: 24,
Colors: 256,
Bell: "\a",
Clear: "\x1b[H\x1b[2J",
EnterCA: "\x1b[?1049h\x1b[22;0;0t",
ExitCA: "\x1b[?1049l\x1b[23;0;0t",
ShowCursor: "\x1b[?12l\x1b[?25h",
HideCursor: "\x1b[?25l",
AttrOff: "\x1b(B\x1b[m",
Underline: "\x1b[4m",
Bold: "\x1b[1m",
Dim: "\x1b[2m",
Italic: "\x1b[3m",
Blink: "\x1b[5m",
Reverse: "\x1b[7m",
EnterKeypad: "\x1b[?1h\x1b=",
ExitKeypad: "\x1b[?1l\x1b>",
SetFg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38:5:%p1%d%;m",
SetBg: "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48:5:%p1%d%;m",
SetFgBg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38:5:%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48:5:%p2%d%;m",
ResetFgBg: "\x1b[39;49m",
AltChars: "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
EnterAcs: "\x1b(0",
ExitAcs: "\x1b(B",
StrikeThrough: "\x1b[9m",
Mouse: "\x1b[M",
SetCursor: "\x1b[%i%p1%d;%p2%dH",
CursorBack1: "\b",
CursorUp1: "\x1b[A",
KeyUp: "\x1bOA",
KeyDown: "\x1bOB",
KeyRight: "\x1bOC",
KeyLeft: "\x1bOD",
KeyInsert: "\x1b[2~",
KeyDelete: "\x1b[3~",
KeyBackspace: "\u007f",
KeyHome: "\x1bOH",
KeyEnd: "\x1bOF",
KeyPgUp: "\x1b[5~",
KeyPgDn: "\x1b[6~",
KeyF1: "\x1bOP",
KeyF2: "\x1bOQ",
KeyF3: "\x1bOR",
KeyF4: "\x1bOS",
KeyF5: "\x1b[15~",
KeyF6: "\x1b[17~",
KeyF7: "\x1b[18~",
KeyF8: "\x1b[19~",
KeyF9: "\x1b[20~",
KeyF10: "\x1b[21~",
KeyF11: "\x1b[23~",
KeyF12: "\x1b[24~",
KeyBacktab: "\x1b[Z",
Modifiers: 1,
AutoMargin: true,
Mouse: "\x1b[M",
SetCursor: "\x1b[%i%p1%d;%p2%dH",
CursorBack1: "\b",
CursorUp1: "\x1b[A",
KeyUp: "\x1bOA",
KeyDown: "\x1bOB",
KeyRight: "\x1bOC",
KeyLeft: "\x1bOD",
KeyInsert: "\x1b[2~",
KeyDelete: "\x1b[3~",
KeyBackspace: "\u007f",
KeyHome: "\x1bOH",
KeyEnd: "\x1bOF",
KeyPgUp: "\x1b[5~",
KeyPgDn: "\x1b[6~",
KeyF1: "\x1bOP",
KeyF2: "\x1bOQ",
KeyF3: "\x1bOR",
KeyF4: "\x1bOS",
KeyF5: "\x1b[15~",
KeyF6: "\x1b[17~",
KeyF7: "\x1b[18~",
KeyF8: "\x1b[19~",
KeyF9: "\x1b[20~",
KeyF10: "\x1b[21~",
KeyF11: "\x1b[23~",
KeyF12: "\x1b[24~",
KeyBacktab: "\x1b[Z",
Modifiers: 1,
AutoMargin: true,
})
}

View file

@ -240,15 +240,14 @@ const (
type stack []interface{}
func (st stack) Push(v interface{}) stack {
return append(st, v)
}
func (st stack) Pop() (interface{}, stack) {
if len(st) > 0 {
e := st[len(st)-1]
return e, st[:len(st)-1]
if b, ok := v.(bool); ok {
if b {
return append(st, 1)
} else {
return append(st, 0)
}
}
return 0, st
return append(st, v)
}
func (st stack) PopString() (string, stack) {
@ -258,8 +257,6 @@ func (st stack) PopString() (string, stack) {
switch v := e.(type) {
case int:
s = strconv.Itoa(v)
case bool:
s = strconv.FormatBool(v)
case string:
s = v
}
@ -275,12 +272,6 @@ func (st stack) PopInt() (int, stack) {
switch v := e.(type) {
case int:
i = v
case bool:
if v {
i = 1
} else {
i = 0
}
case string:
i, _ = strconv.Atoi(v)
}
@ -289,42 +280,18 @@ func (st stack) PopInt() (int, stack) {
return 0, st
}
func (st stack) PopBool() (bool, stack) {
var b bool
if len(st) > 0 {
e := st[len(st)-1]
switch v := e.(type) {
case int:
b = v != 0
case bool:
b = v
case string:
b = v != "" && v != "false"
}
return b, st[:len(st)-1]
}
return false, st
}
// static vars
var svars [26]string
// paramsBuffer handles some persistent state for TParam. Technically we
// could probably dispense with this, but caching buffer arrays gives us
// a nice little performance boost. Furthermore, we know that TParam is
// rarely (never?) called re-entrantly, so we can just reuse the same
// buffers, making it thread-safe by stashing a lock.
type paramsBuffer struct {
out bytes.Buffer
buf bytes.Buffer
lk sync.Mutex
}
// Start initializes the params buffer with the initial string data.
// It also locks the paramsBuffer. The caller must call End() when
// finished.
func (pb *paramsBuffer) Start(s string) {
pb.lk.Lock()
pb.out.Reset()
pb.buf.Reset()
pb.buf.WriteString(s)
@ -333,7 +300,6 @@ func (pb *paramsBuffer) Start(s string) {
// End returns the final output from TParam, but it also releases the lock.
func (pb *paramsBuffer) End() string {
s := pb.out.String()
pb.lk.Unlock()
return s
}
@ -352,18 +318,16 @@ func (pb *paramsBuffer) PutString(s string) {
pb.out.WriteString(s)
}
var pb = &paramsBuffer{}
// TParm takes a terminfo parameterized string, such as setaf or cup, and
// evaluates the string, and returns the result with the parameter
// applied.
func (t *Terminfo) TParm(s string, p ...interface{}) string {
var stk stack
var a, b string
var a string
var ai, bi int
var ab bool
var dvars [26]string
var params [9]interface{}
var pb = &paramsBuffer{}
pb.Start(s)
@ -373,7 +337,13 @@ func (t *Terminfo) TParm(s string, p ...interface{}) string {
params[i] = p[i]
}
nest := 0
const (
emit = iota
toEnd
toElse
)
skip := emit
for {
@ -383,7 +353,9 @@ func (t *Terminfo) TParm(s string, p ...interface{}) string {
}
if ch != '%' {
pb.PutCh(ch)
if skip == emit {
pb.PutCh(ch)
}
continue
}
@ -392,6 +364,17 @@ func (t *Terminfo) TParm(s string, p ...interface{}) string {
// XXX Error
break
}
if skip == toEnd {
if ch == ';' {
skip = emit
}
continue
} else if skip == toElse {
if ch == 'e' || ch == ';' {
skip = emit
}
continue
}
switch ch {
case '%': // quoted %
@ -405,18 +388,23 @@ func (t *Terminfo) TParm(s string, p ...interface{}) string {
params[1] = i + 1
}
case 'c', 's':
// NB: these, and 'd' below are special cased for
case 's':
// NB: 's', 'c', and 'd' below are special cased for
// efficiency. They could be handled by the richer
// format support below, less efficiently.
a, stk = stk.PopString()
pb.PutString(a)
case 'c':
// Integer as special character.
ai, stk = stk.PopInt()
pb.PutCh(byte(ai))
case 'd':
ai, stk = stk.PopInt()
pb.PutString(strconv.Itoa(ai))
case '0', '1', '2', '3', '4', 'x', 'X', 'o', ':':
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'x', 'X', 'o', ':':
// This is pretty suboptimal, but this is rarely used.
// None of the mainstream terminals use any of this,
// and it would surprise me if this code is ever
@ -438,9 +426,12 @@ func (t *Terminfo) TParm(s string, p ...interface{}) string {
case 'd', 'x', 'X', 'o':
ai, stk = stk.PopInt()
pb.PutString(fmt.Sprintf(f, ai))
case 'c', 's':
case 's':
a, stk = stk.PopString()
pb.PutString(fmt.Sprintf(f, a))
case 'c':
ai, stk = stk.PopInt()
pb.PutString(fmt.Sprintf(f, ai))
}
case 'p': // push parameter
@ -468,10 +459,10 @@ func (t *Terminfo) TParm(s string, p ...interface{}) string {
stk = stk.Push(dvars[int(ch-'a')])
}
case '\'': // push(char)
case '\'': // push(char) - the integer value of it
ch, _ = pb.NextCh()
_, _ = pb.NextCh() // must be ' but we don't check
stk = stk.Push(string(ch))
stk = stk.Push(int(ch))
case '{': // push(int)
ai = 0
@ -542,12 +533,12 @@ func (t *Terminfo) TParm(s string, p ...interface{}) string {
case '!': // logical NOT
ai, stk = stk.PopInt()
stk = stk.Push(ai != 0)
stk = stk.Push(ai == 0)
case '=': // numeric compare or string compare
b, stk = stk.PopString()
a, stk = stk.PopString()
stk = stk.Push(a == b)
case '=': // numeric compare
bi, stk = stk.PopInt()
ai, stk = stk.PopInt()
stk = stk.Push(ai == bi)
case '>': // greater than, numeric
bi, stk = stk.PopInt()
@ -561,68 +552,20 @@ func (t *Terminfo) TParm(s string, p ...interface{}) string {
case '?': // start conditional
case ';':
skip = emit
case 't':
ab, stk = stk.PopBool()
if ab {
// just keep going
break
}
nest = 0
ifloop:
// this loop consumes everything until we hit our else,
// or the end of the conditional
for {
ch, err = pb.NextCh()
if err != nil {
break
}
if ch != '%' {
continue
}
ch, _ = pb.NextCh()
switch ch {
case ';':
if nest == 0 {
break ifloop
}
nest--
case '?':
nest++
case 'e':
if nest == 0 {
break ifloop
}
}
ai, stk = stk.PopInt()
if ai == 0 {
skip = toElse
}
case 'e':
// if we got here, it means we didn't use the else
// in the 't' case above, and we should skip until
// the end of the conditional
nest = 0
elloop:
for {
ch, err = pb.NextCh()
if err != nil {
break
}
if ch != '%' {
continue
}
ch, _ = pb.NextCh()
switch ch {
case ';':
if nest == 0 {
break elloop
}
nest--
case '?':
nest++
}
}
case ';': // endif
skip = toEnd
default:
pb.PutString("%" + string(ch))
}
}

View file

@ -1,3 +1,4 @@
//go:build !tcell_minimal
// +build !tcell_minimal
// Copyright 2019 The TCell Authors

View file

@ -1,3 +1,4 @@
//go:build !tcell_minimal && !nacl && !js && !zos && !plan9 && !windows && !android
// +build !tcell_minimal,!nacl,!js,!zos,!plan9,!windows,!android
// Copyright 2019 The TCell Authors

View file

@ -1,3 +1,4 @@
//go:build tcell_minimal || nacl || js || zos || plan9 || windows || android
// +build tcell_minimal nacl js zos plan9 windows android
// Copyright 2019 The TCell Authors

View file

@ -134,7 +134,6 @@ type tScreen struct {
clear bool
cursorx int
cursory int
wasbtn bool
acs map[rune]string
charset string
encoder transform.Transformer
@ -199,9 +198,13 @@ func (t *tScreen) Init() error {
if os.Getenv("TCELL_TRUECOLOR") == "disable" {
t.truecolor = false
}
t.colors = make(map[Color]Color)
t.palette = make([]Color, t.nColors())
for i := 0; i < t.nColors(); i++ {
nColors := t.nColors()
if nColors > 256 {
nColors = 256 // clip to reasonable limits
}
t.colors = make(map[Color]Color, nColors)
t.palette = make([]Color, nColors)
for i := 0; i < nColors; i++ {
t.palette[i] = Color(i) | ColorValid
// identity map for our builtin colors
t.colors[Color(i)|ColorValid] = Color(i) | ColorValid
@ -346,7 +349,7 @@ func (t *tScreen) prepareExtendedOSC() {
t.enterUrl = t.ti.EnterUrl
t.exitUrl = t.ti.ExitUrl
} else if t.ti.Mouse != "" {
t.enterUrl = "\x1b]8;;%p1%s\x1b\\"
t.enterUrl = "\x1b]8;%p2%s;%p1%s\x1b\\"
t.exitUrl = "\x1b]8;;\x1b\\"
}
@ -572,18 +575,6 @@ func (t *tScreen) SetStyle(style Style) {
func (t *tScreen) Clear() {
t.Fill(' ', t.style)
t.Lock()
t.clear = true
w, h := t.cells.Size()
// because we are going to clear (see t.clear) in the next cycle,
// let's also unmark the dirty bit so that we don't waste cycles
// drawing things that are already dealt with via the clear escape sequence.
for row := 0; row < h; row++ {
for col := 0; col < w; col++ {
t.cells.SetDirty(col, row, false)
}
}
t.Unlock()
}
func (t *tScreen) Fill(r rune, style Style) {
@ -794,7 +785,7 @@ func (t *tScreen) drawCell(x, y int) int {
// URL string can be long, so don't send it unless we really need to
if t.enterUrl != "" && t.curstyle != style {
if style.url != "" {
t.TPuts(ti.TParm(t.enterUrl, style.url))
t.TPuts(ti.TParm(t.enterUrl, style.url, style.urlId))
} else {
t.TPuts(t.exitUrl)
}
@ -1229,28 +1220,16 @@ func (t *tScreen) buildMouseEvent(x, y, btn int) *EventMouse {
switch btn & 0x43 {
case 0:
button = Button1
t.wasbtn = true
case 1:
button = Button3 // Note we prefer to treat right as button 2
t.wasbtn = true
case 2:
button = Button2 // And the middle button as button 3
t.wasbtn = true
case 3:
button = ButtonNone
t.wasbtn = false
case 0x40:
if !t.wasbtn {
button = WheelUp
} else {
button = Button1
}
button = WheelUp
case 0x41:
if !t.wasbtn {
button = WheelDown
} else {
button = Button2
}
button = WheelDown
}
if btn&0x4 != 0 {

View file

@ -1,6 +1,7 @@
//go:build js || plan9 || windows
// +build js plan9 windows
// Copyright 2021 The TCell Authors
// Copyright 2022 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
@ -21,5 +22,11 @@ package tcell
// that we can obtain with the console API present on Windows.
func (t *tScreen) initialize() error {
return ErrNoScreen
if t.tty == nil {
return ErrNoScreen
}
// If a tty was supplied (custom), it should work.
// Custom screen implementations will need to provide a TTY
// implementation that we can use.
return nil
}

View file

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package tcell

View file

@ -53,4 +53,4 @@ type Tty interface {
WindowSize() (width int, height int, err error)
io.ReadWriteCloser
}
}

View file

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package tcell

View file

@ -5,6 +5,7 @@
package gocui
import (
"context"
standardErrors "errors"
"log"
"runtime"
@ -1357,7 +1358,7 @@ func (g *Gui) execKeybinding(v *View, kb *keybinding) (bool, error) {
return true, nil
}
func (g *Gui) StartTicking() {
func (g *Gui) StartTicking(ctx context.Context) {
go func() {
g.Mutexes.tickingMutex.Lock()
defer g.Mutexes.tickingMutex.Unlock()
@ -1379,6 +1380,8 @@ func (g *Gui) StartTicking() {
}
}
return
case <-ctx.Done():
return
case <-g.stop:
return
}