1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-03-19 21:28:28 +02:00

Bump gocui

... and switch back from stefanhaller's tcell fork to the official tcell. This
basically reverts 7ccb871a459.
This commit is contained in:
Stefan Haller 2024-01-03 20:29:25 +01:00
parent ef3d6f4a32
commit cb5d0bca1c
98 changed files with 724 additions and 614 deletions

4
go.mod
View File

@ -9,13 +9,14 @@ require (
github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21
github.com/creack/pty v1.1.11
github.com/fsmiamoto/git-todo-parser v0.0.5
github.com/gdamore/tcell/v2 v2.7.1-0.20240103180601-96e29905643b
github.com/go-errors/errors v1.5.1
github.com/gookit/color v1.4.2
github.com/imdario/mergo v0.3.11
github.com/integrii/flaggy v1.4.0
github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68
github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d
github.com/jesseduffield/gocui v0.3.1-0.20231209142059-968d8b62e1ef
github.com/jesseduffield/gocui v0.3.1-0.20240103192639-2874168c14db
github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10
github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5
github.com/jesseduffield/minimal/gitignore v0.3.3-0.20211018110810-9cde264e6b1e
@ -34,7 +35,6 @@ require (
github.com/sirupsen/logrus v1.4.2
github.com/spf13/afero v1.9.5
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad
github.com/stefanhaller/tcell/v2 v2.6.2-0.20230806061358-2dfa11eddb68
github.com/stretchr/testify v1.8.1
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778
golang.org/x/exp v0.0.0-20220318154914-8dddf5d87bd8

14
go.sum
View File

@ -89,6 +89,8 @@ github.com/fsmiamoto/git-todo-parser v0.0.5/go.mod h1:B+AgTbNE2BARvJqzXygThzqxLI
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/gdamore/tcell/v2 v2.7.1-0.20240103180601-96e29905643b h1:VkiXff8uJUkhjcxcLwwzQLYBCc+k5tJeOVx4W0qMYTk=
github.com/gdamore/tcell/v2 v2.7.1-0.20240103180601-96e29905643b/go.mod h1:hl/KtAANGBecfIPxk+FzKvThTqI84oplgbPEmVX60b8=
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
@ -185,8 +187,8 @@ github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68 h1:EQP2Tv8T
github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68/go.mod h1:+LLj9/WUPAP8LqCchs7P+7X0R98HiFujVFANdNaxhGk=
github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d h1:bO+OmbreIv91rCe8NmscRwhFSqkDJtzWCPV4Y+SQuXE=
github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d/go.mod h1:nGNEErzf+NRznT+N2SWqmHnDnF9aLgANB1CUNEan09o=
github.com/jesseduffield/gocui v0.3.1-0.20231209142059-968d8b62e1ef h1:pMi1UJqTE1j4NRxAeQ835qv+tj364zCocQ+/r9ZLrM0=
github.com/jesseduffield/gocui v0.3.1-0.20231209142059-968d8b62e1ef/go.mod h1:trXE7RRGL2hTsv+Ntk+SHLtRobg9JE138n3Ug/X2Cf4=
github.com/jesseduffield/gocui v0.3.1-0.20240103192639-2874168c14db h1:ihJdYk85/XQLGiG3b6m8P2z+RUohRMtPmX74YR9IT8s=
github.com/jesseduffield/gocui v0.3.1-0.20240103192639-2874168c14db/go.mod h1:9zkyjnUmdL3+sUknJrQy/3HweUu8mVln/3J2wRF/l8M=
github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10 h1:jmpr7KpX2+2GRiE91zTgfq49QvgiqB0nbmlwZ8UnOx0=
github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10/go.mod h1:aA97kHeNA+sj2Hbki0pvLslmE4CbDyhBeSSTUUnOuVo=
github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5 h1:CDuQmfOjAtb1Gms6a1p5L2P8RhbLUq5t8aL7PiQd2uY=
@ -234,7 +236,6 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mgutz/str v1.2.0 h1:4IzWSdIz9qPQWLfKZ0rJcV0jcUDpxvP4JVZ4GXQyvSw=
@ -281,8 +282,6 @@ github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad h1:fiWzISvDn0Csy5H0iwgAuJGQTUpVfEMJJd4nRFXogbc=
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
github.com/stefanhaller/tcell/v2 v2.6.2-0.20230806061358-2dfa11eddb68 h1:NSTj9xAKUu85d6pAdNFyblL84BfiOB1rVnzxQO/cYUk=
github.com/stefanhaller/tcell/v2 v2.6.2-0.20230806061358-2dfa11eddb68/go.mod h1:PuJ7T6QKbsU7iVOHlhRoV3D/ipIAJsyiV4dbwcVaYj8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
@ -364,6 +363,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -398,6 +398,7 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@ -420,6 +421,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20170407050850-f3918c30c5c2/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -467,7 +469,6 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@ -537,6 +538,7 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@ -6,13 +6,13 @@ import (
"strings"
"time"
"github.com/gdamore/tcell/v2"
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/gui/keybindings"
"github.com/jesseduffield/lazygit/pkg/gui/types"
integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types"
"github.com/stefanhaller/tcell/v2"
)
// this gives our integration test a way of interacting with the gui for sending keypresses

View File

@ -66,6 +66,7 @@ A brief, and still somewhat rough, [tutorial](TUTORIAL.md) is available.
- [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
- [lil](https://github.com/andrievsky/lil) - A simple and flexible interface for any service by implementing only list and get operations
- [hero.go](https://github.com/barisbll/hero.go) - 2d monster shooter ([video](https://user-images.githubusercontent.com/40062673/277157369-240d7606-b471-4aa1-8c54-4379a513122b.mp4))
## Pure Go Terminfo Database

View File

@ -172,7 +172,7 @@ import (
"fmt"
"log"
"github.com/stefanhaller/tcell/v2"
"github.com/gdamore/tcell/v2"
)
func drawText(s tcell.Screen, x1, y1, x2, y2 int, style tcell.Style, text string) {

View File

@ -1,4 +1,4 @@
// Copyright 2022 The TCell Authors
// Copyright 2023 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
@ -28,9 +28,10 @@ type cell struct {
lastStyle Style
lastComb []rune
width int
lock bool
}
// CellBuffer represents a two dimensional array of character cells.
// CellBuffer represents a two-dimensional array of character cells.
// This is primarily intended for use by Screen implementors; it
// contains much of the common code they need. To create one, just
// declare a variable of its type; no explicit initialization is necessary.
@ -43,10 +44,12 @@ type CellBuffer struct {
}
// SetContent sets the contents (primary rune, combining runes,
// and style) for a cell at a given location.
// and style) for a cell at a given location. If the background or
// foreground of the style is set to ColorNone, then the respective
// color is left un changed.
func (cb *CellBuffer) SetContent(x int, y int,
mainc rune, combc []rune, style Style) {
mainc rune, combc []rune, style Style,
) {
if x >= 0 && y >= 0 && x < cb.w && y < cb.h {
c := &cb.cells[(y*cb.w)+x]
@ -60,6 +63,12 @@ func (cb *CellBuffer) SetContent(x int, y int,
c.width = runewidth.RuneWidth(mainc)
}
c.currMain = mainc
if style.fg == ColorNone {
style.fg = c.currStyle.fg
}
if style.bg == ColorNone {
style.bg = c.currStyle.bg
}
c.currStyle = style
}
}
@ -96,13 +105,15 @@ func (cb *CellBuffer) Invalidate() {
}
}
// Dirty checks if a character at the given location needs an
// to be refreshed on the physical display. This returns true
// if the cell content is different since the last time it was
// marked clean.
// Dirty checks if a character at the given location needs to be
// refreshed on the physical display. This returns true if the cell
// content is different since the last time it was marked clean.
func (cb *CellBuffer) Dirty(x, y int) bool {
if x >= 0 && y >= 0 && x < cb.w && y < cb.h {
c := &cb.cells[(y*cb.w)+x]
if c.lock {
return false
}
if c.lastMain == rune(0) {
return true
}
@ -143,11 +154,39 @@ func (cb *CellBuffer) SetDirty(x, y int, dirty bool) {
}
}
// LockCell locks a cell from being drawn, effectively marking it "clean" until
// the lock is removed. This can be used to prevent tcell from drawing a given
// cell, even if the underlying content has changed. For example, when drawing a
// sixel graphic directly to a TTY screen an implementer must lock the region
// underneath the graphic to prevent tcell from drawing on top of the graphic.
func (cb *CellBuffer) LockCell(x, y int) {
if x < 0 || y < 0 {
return
}
if x >= cb.w || y >= cb.h {
return
}
c := &cb.cells[(y*cb.w)+x]
c.lock = true
}
// UnlockCell removes a lock from the cell and marks it as dirty
func (cb *CellBuffer) UnlockCell(x, y int) {
if x < 0 || y < 0 {
return
}
if x >= cb.w || y >= cb.h {
return
}
c := &cb.cells[(y*cb.w)+x]
c.lock = false
cb.SetDirty(x, y, true)
}
// Resize is used to resize the cells array, with different dimensions,
// while preserving the original contents. The cells will be invalidated
// so that they can be redrawn.
func (cb *CellBuffer) Resize(w, h int) {
if cb.h == h && cb.w == w {
return
}
@ -172,12 +211,21 @@ func (cb *CellBuffer) Resize(w, h int) {
// Fill fills the entire cell buffer array with the specified character
// and style. Normally choose ' ' to clear the screen. This API doesn't
// support combining characters, or characters with a width larger than one.
// If either the foreground or background are ColorNone, then the respective
// color is unchanged.
func (cb *CellBuffer) Fill(r rune, style Style) {
for i := range cb.cells {
c := &cb.cells[i]
c.currMain = r
c.currComb = nil
c.currStyle = style
cs := style
if cs.fg == ColorNone {
cs.fg = c.currStyle.fg
}
if cs.bg == ColorNone {
cs.bg = c.currStyle.bg
}
c.currStyle = cs
c.width = 1
}
}
@ -192,7 +240,7 @@ func init() {
runewidth.DefaultCondition.EastAsianWidth = false
}
// For performance reasons, we create a lookup table. However some users
// 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") == "" {

View File

@ -1,4 +1,4 @@
// Copyright 2020 The TCell Authors
// Copyright 2023 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,7 @@
package tcell
import (
"fmt"
ic "image/color"
"strconv"
)
@ -838,6 +839,11 @@ const (
// ColorReset is used to indicate that the color should use the
// vanilla terminal colors. (Basically go back to the defaults.)
ColorReset = ColorSpecial | iota
// ColorNone indicates that we should not change the color from
// whatever is already displayed. This can only be used in limited
// circumstances.
ColorNone
)
// ColorNames holds the written names of colors. Useful to present a list of
@ -1001,6 +1007,47 @@ func (c Color) IsRGB() bool {
return c&(ColorValid|ColorIsRGB) == (ColorValid | ColorIsRGB)
}
// CSS returns the CSS hex string ( #ABCDEF ) if valid
// if not a valid color returns empty string
func (c Color) CSS() string {
if !c.Valid() {
return ""
}
return fmt.Sprintf("#%06X", c.Hex())
}
// String implements fmt.Stringer to return either the
// W3C name if it has one or the CSS hex string '#ABCDEF'
func (c Color) String() string {
if !c.Valid() {
switch c {
case ColorNone:
return "none"
case ColorDefault:
return "default"
case ColorReset:
return "reset"
}
return ""
}
return c.Name(true)
}
// Name returns W3C name or an empty string if no arguments
// if passed true as an argument it will falls back to
// the CSS hex string if no W3C name found '#ABCDEF'
func (c Color) Name(css ...bool) string {
for name, hex := range ColorNames {
if c == hex {
return name
}
}
if len(css) > 0 && css[0] {
return c.CSS()
}
return ""
}
// Hex returns the color's hexadecimal RGB 24-bit value with each component
// consisting of a single byte, R << 16 | G << 8 | B. If the color
// is unknown or unset, -1 is returned.

View File

@ -1,7 +1,7 @@
//go:build windows
// +build windows
// Copyright 2022 The TCell Authors
// Copyright 2023 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
@ -33,12 +33,10 @@ type cScreen struct {
out syscall.Handle
cancelflag syscall.Handle
scandone chan struct{}
evch chan Event
quit chan struct{}
curx int
cury int
style Style
clear bool
fini bool
vten bool
truecolor bool
@ -54,11 +52,11 @@ type cScreen struct {
oomode uint32
cells CellBuffer
finiOnce sync.Once
mouseEnabled bool
wg sync.WaitGroup
eventQ chan Event
stopQ chan struct{}
finiOnce sync.Once
sync.Mutex
}
@ -147,7 +145,7 @@ const (
vtSgr0 = "\x1b[0m"
vtBold = "\x1b[1m"
vtUnderline = "\x1b[4m"
vtBlink = "\x1b[5m" // Not sure this is processed
vtBlink = "\x1b[5m" // Not sure if this is processed
vtReverse = "\x1b[7m"
vtSetFg = "\x1b[38;5;%dm"
vtSetBg = "\x1b[48;5;%dm"
@ -176,11 +174,11 @@ var vtCursorStyles = map[CursorStyle]string{
// with the current process. The Screen makes use of the Windows Console
// API to display content and read events.
func NewConsoleScreen() (Screen, error) {
return &cScreen{}, nil
return &baseScreen{screenImpl: &cScreen{}}, nil
}
func (s *cScreen) Init() error {
s.evch = make(chan Event, 10)
s.eventQ = make(chan Event, 10)
s.quit = make(chan struct{})
s.scandone = make(chan struct{})
@ -231,7 +229,7 @@ func (s *cScreen) Init() error {
// 24-bit color is opt-in for now, because we can't figure out
// to make it work consistently.
if s.truecolor {
s.setOutMode(modeVtOutput | modeNoAutoNL | modeCookedOut)
s.setOutMode(modeVtOutput | modeNoAutoNL | modeCookedOut | modeUnderline)
var om uint32
s.getOutMode(&om)
if om&modeVtOutput == modeVtOutput {
@ -287,7 +285,10 @@ func (s *cScreen) EnableFocus() {}
func (s *cScreen) DisableFocus() {}
func (s *cScreen) Fini() {
s.disengage()
s.finiOnce.Do(func() {
close(s.quit)
s.disengage()
})
}
func (s *cScreen) disengage() {
@ -338,7 +339,7 @@ func (s *cScreen) engage() error {
s.enableMouse(s.mouseEnabled)
if s.vten {
s.setOutMode(modeVtOutput | modeNoAutoNL | modeCookedOut)
s.setOutMode(modeVtOutput | modeNoAutoNL | modeCookedOut | modeUnderline)
} else {
s.setOutMode(0)
}
@ -357,52 +358,6 @@ func (s *cScreen) engage() error {
return nil
}
func (s *cScreen) PostEventWait(ev Event) {
s.evch <- ev
}
func (s *cScreen) PostEvent(ev Event) error {
select {
case s.evch <- ev:
return nil
default:
return ErrEventQFull
}
}
func (s *cScreen) ChannelEvents(ch chan<- Event, quit <-chan struct{}) {
defer close(ch)
for {
select {
case <-quit:
return
case <-s.stopQ:
return
case ev := <-s.evch:
select {
case <-quit:
return
case <-s.stopQ:
return
case ch <- ev:
}
}
}
}
func (s *cScreen) PollEvent() Event {
select {
case <-s.stopQ:
return nil
case ev := <-s.evch:
return ev
}
}
func (s *cScreen) HasPendingEvent() bool {
return len(s.evch) > 0
}
type cursorInfo struct {
size uint32
visible uint32
@ -644,12 +599,17 @@ func geti16(v []byte) int16 {
func mod2mask(cks uint32) ModMask {
mm := ModNone
// Left or right control
if (cks & (0x0008 | 0x0004)) != 0 {
mm |= ModCtrl
}
ctrl := (cks & (0x0008 | 0x0004)) != 0
// Left or right alt
if (cks & (0x0002 | 0x0001)) != 0 {
mm |= ModAlt
alt := (cks & (0x0002 | 0x0001)) != 0
// Filter out ctrl+alt (it means AltGr)
if !(ctrl && alt) {
if ctrl {
mm |= ModCtrl
}
if alt {
mm |= ModAlt
}
}
// Any shift
if (cks & 0x0010) != 0 {
@ -702,6 +662,13 @@ func mrec2btns(mbtns, flags uint32) ButtonMask {
return btns
}
func (s *cScreen) postEvent(ev Event) {
select {
case s.eventQ <- ev:
case <-s.quit:
}
}
func (s *cScreen) getConsoleInput() error {
// cancelFlag comes first as WaitForMultipleObjects returns the lowest index
// in the event that both events are signalled.
@ -744,7 +711,7 @@ func (s *cScreen) getConsoleInput() error {
krec.mod = getu32(rec.data[12:])
if krec.isdown == 0 || krec.repeat < 1 {
// its a key release event, ignore it
// it's a key release event, ignore it
return nil
}
if krec.ch != 0 {
@ -752,11 +719,9 @@ func (s *cScreen) getConsoleInput() error {
for krec.repeat > 0 {
// convert shift+tab to backtab
if mod2mask(krec.mod) == ModShift && krec.ch == vkTab {
s.PostEventWait(NewEventKey(KeyBacktab, 0,
ModNone))
s.postEvent(NewEventKey(KeyBacktab, 0, ModNone))
} else {
s.PostEventWait(NewEventKey(KeyRune, rune(krec.ch),
mod2mask(krec.mod)))
s.postEvent(NewEventKey(KeyRune, rune(krec.ch), mod2mask(krec.mod)))
}
krec.repeat--
}
@ -768,8 +733,7 @@ func (s *cScreen) getConsoleInput() error {
return nil
}
for krec.repeat > 0 {
s.PostEventWait(NewEventKey(key, rune(krec.ch),
mod2mask(krec.mod)))
s.postEvent(NewEventKey(key, rune(krec.ch), mod2mask(krec.mod)))
krec.repeat--
}
@ -782,14 +746,13 @@ func (s *cScreen) getConsoleInput() error {
mrec.flags = getu32(rec.data[12:])
btns := mrec2btns(mrec.btns, mrec.flags)
// we ignore double click, events are delivered normally
s.PostEventWait(NewEventMouse(int(mrec.x), int(mrec.y), btns,
mod2mask(mrec.mod)))
s.postEvent(NewEventMouse(int(mrec.x), int(mrec.y), btns, mod2mask(mrec.mod)))
case resizeEvent:
var rrec resizeRecord
rrec.x = geti16(rec.data[0:])
rrec.y = geti16(rec.data[2:])
s.PostEventWait(NewEventResize(int(rrec.x), int(rrec.y)))
s.postEvent(NewEventResize(int(rrec.x), int(rrec.y)))
default:
}
@ -895,29 +858,6 @@ func (s *cScreen) mapStyle(style Style) uint16 {
return attr
}
func (s *cScreen) SetCell(x, y int, style Style, ch ...rune) {
if len(ch) > 0 {
s.SetContent(x, y, ch[0], ch[1:], style)
} else {
s.SetContent(x, y, ' ', nil, style)
}
}
func (s *cScreen) SetContent(x, y int, primary rune, combining []rune, style Style) {
s.Lock()
if !s.fini {
s.cells.SetContent(x, y, primary, combining, style)
}
s.Unlock()
}
func (s *cScreen) GetContent(x, y int) (rune, []rune, Style, int) {
s.Lock()
primary, combining, style, width := s.cells.GetContent(x, y)
s.Unlock()
return primary, combining, style, width
}
func (s *cScreen) sendVtStyle(style Style) {
esc := &strings.Builder{}
@ -972,11 +912,6 @@ func (s *cScreen) writeString(x, y int, style Style, ch []uint16) {
func (s *cScreen) draw() {
// allocate a scratch line bit enough for no combining chars.
// if you have combining characters, you may pay for extra allocations.
if s.clear {
s.clearScreen(s.style, s.vten)
s.clear = false
s.cells.Invalidate()
}
buf := make([]uint16, 0, s.w)
wcs := buf[:]
lstyle := styleInvalid
@ -1157,20 +1092,10 @@ func (s *cScreen) resize() {
uintptr(s.out),
uintptr(1),
uintptr(unsafe.Pointer(&r)))
_ = s.PostEvent(NewEventResize(w, h))
}
func (s *cScreen) Clear() {
s.Fill(' ', s.style)
}
func (s *cScreen) Fill(r rune, style Style) {
s.Lock()
if !s.fini {
s.cells.Fill(r, style)
s.clear = true
select {
case s.eventQ <- NewEventResize(w, h):
default:
}
s.Unlock()
}
func (s *cScreen) clearScreen(style Style, vtEnable bool) {
@ -1217,6 +1142,7 @@ const (
modeCookedOut uint32 = 0x0001
modeVtOutput = 0x0004
modeNoAutoNL = 0x0008
modeUnderline = 0x0010 // ENABLE_LVB_GRID_WORLDWIDE, needed for underlines
// modeWrapEOL = 0x0002
)
@ -1331,3 +1257,19 @@ func (s *cScreen) Suspend() error {
func (s *cScreen) Resume() error {
return s.engage()
}
func (s *cScreen) Tty() (Tty, bool) {
return nil, false
}
func (s *cScreen) GetCells() *CellBuffer {
return &s.cells
}
func (s *cScreen) EventQ() chan Event {
return s.eventQ
}
func (s *cScreen) StopQ() <-chan struct{} {
return s.stopQ
}

View File

@ -69,7 +69,6 @@ var encodingFallback EncodingFallback = EncodingFallbackFail
// 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()
charset = strings.ToLower(charset)

View File

@ -18,7 +18,7 @@ import (
"errors"
"time"
"github.com/stefanhaller/tcell/v2/terminfo"
"github.com/gdamore/tcell/v2/terminfo"
)
var (

View File

@ -20,15 +20,18 @@ import (
// EventResize is sent when the window size changes.
type EventResize struct {
t time.Time
w int
h int
t time.Time
ws WindowSize
}
// NewEventResize creates an EventResize with the new updated window size,
// which is given in character cells.
func NewEventResize(width, height int) *EventResize {
return &EventResize{t: time.Now(), w: width, h: height}
ws := WindowSize{
Width: width,
Height: height,
}
return &EventResize{t: time.Now(), ws: ws}
}
// When returns the time when the Event was created.
@ -38,5 +41,26 @@ func (ev *EventResize) When() time.Time {
// Size returns the new window size as width, height in character cells.
func (ev *EventResize) Size() (int, int) {
return ev.w, ev.h
return ev.ws.Width, ev.ws.Height
}
// PixelSize returns the new window size as width, height in pixels. The size
// will be 0,0 if the screen doesn't support this feature
func (ev *EventResize) PixelSize() (int, int) {
return ev.ws.PixelWidth, ev.ws.PixelHeight
}
type WindowSize struct {
Width int
Height int
PixelWidth int
PixelHeight int
}
// CellDimensions returns the dimensions of a single cell, in pixels
func (ws WindowSize) CellDimensions() (int, int) {
if ws.PixelWidth == 0 || ws.PixelHeight == 0 {
return 0, 0
}
return (ws.PixelWidth / ws.Width), (ws.PixelHeight / ws.Height)
}

View File

@ -1,4 +1,4 @@
// Copyright 2022 The TCell Authors
// Copyright 2023 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
@ -14,6 +14,8 @@
package tcell
import "sync"
// Screen represents the physical (or emulated) screen.
// This can be a terminal window or a physical console. Platforms implement
// this differently.
@ -255,6 +257,14 @@ type Screen interface {
// does not support application-initiated resizing, whereas the legacy terminal does.
// Also, some emulators can support this but may have it disabled by default.
SetSize(int, int)
// LockRegion sets or unsets a lock on a region of cells. A lock on a
// cell prevents the cell from being redrawn.
LockRegion(x, y, width, height int, lock bool)
// Tty returns the underlying Tty. If the screen is not a terminal, the
// returned bool will be false
Tty() (Tty, bool)
}
// NewScreen returns a default Screen suitable for the user's terminal
@ -293,3 +303,164 @@ const (
CursorStyleBlinkingBar
CursorStyleSteadyBar
)
// screenImpl is a subset of Screen that can be used with baseScreen to formulate
// a complete implementation of Screen. See Screen for doc comments about methods.
type screenImpl interface {
Init() error
Fini()
SetStyle(style Style)
ShowCursor(x int, y int)
HideCursor()
SetCursorStyle(CursorStyle)
Size() (width, height int)
EnableMouse(...MouseFlags)
DisableMouse()
EnablePaste()
DisablePaste()
EnableFocus()
DisableFocus()
HasMouse() bool
Colors() int
Show()
Sync()
CharacterSet() string
RegisterRuneFallback(r rune, subst string)
UnregisterRuneFallback(r rune)
CanDisplay(r rune, checkFallbacks bool) bool
Resize(int, int, int, int)
HasKey(Key) bool
Suspend() error
Resume() error
Beep() error
SetSize(int, int)
Tty() (Tty, bool)
// Following methods are not part of the Screen api, but are used for interaction with
// the common layer code.
// Locker locks the underlying data structures so that we can access them
// in a thread-safe way.
sync.Locker
// GetCells returns a pointer to the underlying CellBuffer that the implementation uses.
// Various methods will write to these for performance, but will use the lock to do so.
GetCells() *CellBuffer
// StopQ is closed when the screen is shut down via Fini. It remains open if the screen
// is merely suspended.
StopQ() <-chan struct{}
// EventQ delivers events. Events are posted to this by the screen in response to
// key presses, resizes, etc. Application code receives events from this via the
// Screen.PollEvent, Screen.ChannelEvents APIs.
EventQ() chan Event
}
type baseScreen struct {
screenImpl
}
func (b *baseScreen) SetCell(x int, y int, style Style, ch ...rune) {
if len(ch) > 0 {
b.SetContent(x, y, ch[0], ch[1:], style)
} else {
b.SetContent(x, y, ' ', nil, style)
}
}
func (b *baseScreen) Clear() {
b.Fill(' ', StyleDefault)
}
func (b *baseScreen) Fill(r rune, style Style) {
cb := b.GetCells()
b.Lock()
cb.Fill(r, style)
b.Unlock()
}
func (b *baseScreen) SetContent(x, y int, mainc rune, combc []rune, st Style) {
cells := b.GetCells()
b.Lock()
cells.SetContent(x, y, mainc, combc, st)
b.Unlock()
}
func (b *baseScreen) GetContent(x, y int) (rune, []rune, Style, int) {
var primary rune
var combining []rune
var style Style
var width int
cells := b.GetCells()
b.Lock()
primary, combining, style, width = cells.GetContent(x, y)
b.Unlock()
return primary, combining, style, width
}
func (b *baseScreen) LockRegion(x, y, width, height int, lock bool) {
cells := b.GetCells()
b.Lock()
for j := y; j < (y + height); j += 1 {
for i := x; i < (x + width); i += 1 {
switch lock {
case true:
cells.LockCell(i, j)
case false:
cells.UnlockCell(i, j)
}
}
}
b.Unlock()
}
func (b *baseScreen) ChannelEvents(ch chan<- Event, quit <-chan struct{}) {
defer close(ch)
for {
select {
case <-quit:
return
case <-b.StopQ():
return
case ev := <-b.EventQ():
select {
case <-quit:
return
case <-b.StopQ():
return
case ch <- ev:
}
}
}
}
func (b *baseScreen) PollEvent() Event {
select {
case <-b.StopQ():
return nil
case ev := <-b.EventQ():
return ev
}
}
func (b *baseScreen) HasPendingEvent() bool {
return len(b.EventQ()) > 0
}
func (b *baseScreen) PostEventWait(ev Event) {
select {
case b.EventQ() <- ev:
case <-b.StopQ():
}
}
func (b *baseScreen) PostEvent(ev Event) error {
select {
case b.EventQ() <- ev:
return nil
default:
return ErrEventQFull
}
}

View File

@ -1,4 +1,4 @@
// Copyright 2022 The TCell Authors
// Copyright 2023 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
@ -27,14 +27,17 @@ func NewSimulationScreen(charset string) SimulationScreen {
if charset == "" {
charset = "UTF-8"
}
s := &simscreen{charset: charset}
return s
ss := &simscreen{charset: charset}
ss.Screen = &baseScreen{screenImpl: ss}
return ss
}
// SimulationScreen represents a screen simulation. This is intended to
// be a superset of normal Screens, but also adds some important interfaces
// for testing.
type SimulationScreen interface {
Screen
// InjectKeyBytes injects a stream of bytes corresponding to
// the native encoding (see charset). It turns true if the entire
// set of bytes were processed and delivered as KeyEvents, false
@ -57,8 +60,6 @@ type SimulationScreen interface {
// GetCursor returns the cursor details.
GetCursor() (x int, y int, visible bool)
Screen
}
// SimCell represents a simulated screen cell. The purpose of this
@ -98,6 +99,7 @@ type simscreen struct {
fillstyle Style
fallback map[rune]string
Screen
sync.Mutex
}
@ -150,43 +152,6 @@ func (s *simscreen) SetStyle(style Style) {
s.Unlock()
}
func (s *simscreen) Clear() {
s.Fill(' ', s.style)
}
func (s *simscreen) Fill(r rune, style Style) {
s.Lock()
s.back.Fill(r, style)
s.Unlock()
}
func (s *simscreen) SetCell(x, y int, style Style, ch ...rune) {
if len(ch) > 0 {
s.SetContent(x, y, ch[0], ch[1:], style)
} else {
s.SetContent(x, y, ' ', nil, style)
}
}
func (s *simscreen) SetContent(x, y int, mainc rune, combc []rune, st Style) {
s.Lock()
s.back.SetContent(x, y, mainc, combc, st)
s.Unlock()
}
func (s *simscreen) GetContent(x, y int) (rune, []rune, Style, int) {
var mainc rune
var combc []rune
var style Style
var width int
s.Lock()
mainc, combc, style, width = s.back.GetContent(x, y)
s.Unlock()
return mainc, combc, style, width
}
func (s *simscreen) drawCell(x, y int) int {
mainc, combc, style, width := s.back.GetContent(x, y)
@ -344,7 +309,7 @@ func (s *simscreen) resize() {
if w != ow || h != oh {
s.back.Resize(w, h)
ev := NewEventResize(w, h)
s.PostEvent(ev)
s.postEvent(ev)
}
}
@ -352,60 +317,21 @@ func (s *simscreen) Colors() int {
return 256
}
func (s *simscreen) ChannelEvents(ch chan<- Event, quit <-chan struct{}) {
defer close(ch)
for {
select {
case <-quit:
return
case <-s.quit:
return
case ev := <-s.evch:
select {
case <-quit:
return
case <-s.quit:
return
case ch <- ev:
}
}
}
}
func (s *simscreen) PollEvent() Event {
select {
case <-s.quit:
return nil
case ev := <-s.evch:
return ev
}
}
func (s *simscreen) HasPendingEvent() bool {
return len(s.evch) > 0
}
func (s *simscreen) PostEventWait(ev Event) {
s.evch <- ev
}
func (s *simscreen) PostEvent(ev Event) error {
func (s *simscreen) postEvent(ev Event) {
select {
case s.evch <- ev:
return nil
default:
return ErrEventQFull
case <-s.quit:
}
}
func (s *simscreen) InjectMouse(x, y int, buttons ButtonMask, mod ModMask) {
ev := NewEventMouse(x, y, buttons, mod)
s.PostEvent(ev)
s.postEvent(ev)
}
func (s *simscreen) InjectKey(key Key, r rune, mod ModMask) {
ev := NewEventKey(key, r, mod)
s.PostEvent(ev)
s.postEvent(ev)
}
func (s *simscreen) InjectKeyBytes(b []byte) bool {
@ -416,7 +342,7 @@ outer:
if b[0] >= ' ' && b[0] <= 0x7F {
// printable ASCII easy to deal with -- no encodings
ev := NewEventKey(KeyRune, rune(b[0]), ModNone)
s.PostEvent(ev)
s.postEvent(ev)
b = b[1:]
continue
}
@ -428,7 +354,7 @@ outer:
mod = ModCtrl
}
ev := NewEventKey(Key(b[0]), 0, mod)
s.PostEvent(ev)
s.postEvent(ev)
b = b[1:]
continue
}
@ -442,7 +368,7 @@ outer:
r, _ := utf8.DecodeRune(utfb[:nout])
if r != utf8.RuneError {
ev := NewEventKey(KeyRune, r, ModNone)
s.PostEvent(ev)
s.postEvent(ev)
}
b = b[nin:]
continue outer
@ -553,3 +479,19 @@ func (s *simscreen) Suspend() error {
func (s *simscreen) Resume() error {
return nil
}
func (s *simscreen) Tty() (Tty, bool) {
return nil, false
}
func (s *simscreen) GetCells() *CellBuffer {
return &s.back
}
func (s *simscreen) EventQ() chan Event {
return s.evch
}
func (s *simscreen) StopQ() <-chan struct{} {
return s.quit
}

View File

@ -27,6 +27,7 @@ import (
"syscall"
"time"
"golang.org/x/sys/unix"
"golang.org/x/term"
)
@ -133,11 +134,14 @@ func (tty *stdIoTty) Stop() error {
return nil
}
func (tty *stdIoTty) WindowSize() (int, int, error) {
w, h, err := term.GetSize(tty.fd)
func (tty *stdIoTty) WindowSize() (WindowSize, error) {
size := WindowSize{}
ws, err := unix.IoctlGetWinsize(tty.fd, unix.TIOCGWINSZ)
if err != nil {
return 0, 0, err
return size, err
}
w := int(ws.Col)
h := int(ws.Row)
if w == 0 {
w, _ = strconv.Atoi(os.Getenv("COLUMNS"))
}
@ -150,7 +154,11 @@ func (tty *stdIoTty) WindowSize() (int, int, error) {
if h == 0 {
h = 25 // default
}
return w, h, nil
size.Width = w
size.Height = h
size.PixelWidth = int(ws.Xpixel)
size.PixelHeight = int(ws.Ypixel)
return size, nil
}
func (tty *stdIoTty) NotifyResize(cb func()) {

View File

@ -2,7 +2,7 @@
package aixterm
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package alacritty
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package alacritty
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package ansi
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package beterm
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -24,9 +24,9 @@ package base
import (
// The following imports just register themselves --
// thse are the terminal types we aggregate in this package.
_ "github.com/stefanhaller/tcell/v2/terminfo/a/ansi"
_ "github.com/stefanhaller/tcell/v2/terminfo/v/vt100"
_ "github.com/stefanhaller/tcell/v2/terminfo/v/vt102"
_ "github.com/stefanhaller/tcell/v2/terminfo/v/vt220"
_ "github.com/stefanhaller/tcell/v2/terminfo/x/xterm"
_ "github.com/gdamore/tcell/v2/terminfo/a/ansi"
_ "github.com/gdamore/tcell/v2/terminfo/v/vt100"
_ "github.com/gdamore/tcell/v2/terminfo/v/vt102"
_ "github.com/gdamore/tcell/v2/terminfo/v/vt220"
_ "github.com/gdamore/tcell/v2/terminfo/x/xterm"
)

View File

@ -2,7 +2,7 @@
package cygwin
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package dtterm
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -29,7 +29,7 @@ import (
"strconv"
"strings"
"github.com/stefanhaller/tcell/v2/terminfo"
"github.com/gdamore/tcell/v2/terminfo"
)
type termcap struct {
@ -185,16 +185,10 @@ func (tc *termcap) setupterm(name string) error {
func LoadTerminfo(name string) (*terminfo.Terminfo, string, error) {
var tc termcap
if err := tc.setupterm(name); err != nil {
if err != nil {
return nil, "", err
}
return nil, "", err
}
t := &terminfo.Terminfo{}
// If this is an alias record, then just emit the alias
t.Name = tc.name
if t.Name != name {
return t, "", nil
}
t.Aliases = tc.aliases
t.Colors = tc.getnum("colors")
t.Columns = tc.getnum("cols")
@ -314,6 +308,8 @@ func LoadTerminfo(name string) (*terminfo.Terminfo, string, error) {
// but modern XTerm and emulators often have them. Let's add them,
// if the shifted right and left arrows are defined.
if t.KeyShfRight == "\x1b[1;2C" && t.KeyShfLeft == "\x1b[1;2D" {
t.Modifiers = terminfo.ModifiersXTerm
t.KeyShfUp = "\x1b[1;2A"
t.KeyShfDown = "\x1b[1;2B"
t.KeyMetaUp = "\x1b[1;9A"

View File

@ -2,7 +2,7 @@
package emacs
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -0,0 +1,58 @@
// Copyright 2020 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 extended contains an extended set of terminal descriptions.
// Applications desiring to have a better chance of Just Working by
// default should include this package. This will significantly increase
// the size of the program.
package extended
import (
// The following imports just register themselves --
// these are the terminal types we aggregate in this package.
_ "github.com/gdamore/tcell/v2/terminfo/a/aixterm"
_ "github.com/gdamore/tcell/v2/terminfo/a/alacritty"
_ "github.com/gdamore/tcell/v2/terminfo/a/ansi"
_ "github.com/gdamore/tcell/v2/terminfo/b/beterm"
_ "github.com/gdamore/tcell/v2/terminfo/c/cygwin"
_ "github.com/gdamore/tcell/v2/terminfo/d/dtterm"
_ "github.com/gdamore/tcell/v2/terminfo/e/emacs"
_ "github.com/gdamore/tcell/v2/terminfo/f/foot"
_ "github.com/gdamore/tcell/v2/terminfo/g/gnome"
_ "github.com/gdamore/tcell/v2/terminfo/h/hpterm"
_ "github.com/gdamore/tcell/v2/terminfo/k/konsole"
_ "github.com/gdamore/tcell/v2/terminfo/k/kterm"
_ "github.com/gdamore/tcell/v2/terminfo/l/linux"
_ "github.com/gdamore/tcell/v2/terminfo/p/pcansi"
_ "github.com/gdamore/tcell/v2/terminfo/r/rxvt"
_ "github.com/gdamore/tcell/v2/terminfo/s/screen"
_ "github.com/gdamore/tcell/v2/terminfo/s/simpleterm"
_ "github.com/gdamore/tcell/v2/terminfo/s/sun"
_ "github.com/gdamore/tcell/v2/terminfo/t/termite"
_ "github.com/gdamore/tcell/v2/terminfo/t/tmux"
_ "github.com/gdamore/tcell/v2/terminfo/v/vt100"
_ "github.com/gdamore/tcell/v2/terminfo/v/vt102"
_ "github.com/gdamore/tcell/v2/terminfo/v/vt220"
_ "github.com/gdamore/tcell/v2/terminfo/v/vt320"
_ "github.com/gdamore/tcell/v2/terminfo/v/vt400"
_ "github.com/gdamore/tcell/v2/terminfo/v/vt420"
_ "github.com/gdamore/tcell/v2/terminfo/v/vt52"
_ "github.com/gdamore/tcell/v2/terminfo/w/wy50"
_ "github.com/gdamore/tcell/v2/terminfo/w/wy60"
_ "github.com/gdamore/tcell/v2/terminfo/w/wy99_ansi"
_ "github.com/gdamore/tcell/v2/terminfo/x/xfce"
_ "github.com/gdamore/tcell/v2/terminfo/x/xterm"
_ "github.com/gdamore/tcell/v2/terminfo/x/xterm_kitty"
_ "github.com/gdamore/tcell/v2/terminfo/x/xterm_termite"
)

View File

@ -2,7 +2,7 @@
package foot
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package gnome
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -1,3 +1,4 @@
#!/bin/bash
while read line
do
case "$line" in

View File

@ -2,7 +2,7 @@
package hpterm
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package konsole
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package kterm
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package linux
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package pcansi
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package rxvt
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package screen
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package simpleterm
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -20,7 +20,7 @@
package sun
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package termite
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package tmux
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package vt100
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package vt102
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package vt220
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package vt320
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package vt400
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package vt420
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package vt52
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package wy50
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package wy60
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package wy99_ansi
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package xfce
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -20,7 +20,7 @@
package xterm
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package xterm
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package xterm_kitty
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -2,7 +2,7 @@
package xterm_termite
import "github.com/stefanhaller/tcell/v2/terminfo"
import "github.com/gdamore/tcell/v2/terminfo"
func init() {

View File

@ -20,5 +20,5 @@ package tcell
import (
// This imports the default terminal entries. To disable, use the
// tcell_minimal build tag.
_ "github.com/stefanhaller/tcell/v2/terminfo/extended"
_ "github.com/gdamore/tcell/v2/terminfo/extended"
)

View File

@ -25,8 +25,8 @@ import (
// also don't support Android here, because you really don't want
// to run external programs there. Generally the android terminals
// will be automatically included anyway.
"github.com/stefanhaller/tcell/v2/terminfo"
"github.com/stefanhaller/tcell/v2/terminfo/dynamic"
"github.com/gdamore/tcell/v2/terminfo"
"github.com/gdamore/tcell/v2/terminfo/dynamic"
)
func loadDynamicTerminfo(term string) (*terminfo.Terminfo, error) {

View File

@ -20,7 +20,7 @@ package tcell
import (
"errors"
"github.com/stefanhaller/tcell/v2/terminfo"
"github.com/gdamore/tcell/v2/terminfo"
)
func loadDynamicTerminfo(_ string) (*terminfo.Terminfo, error) {

View File

@ -1,4 +1,4 @@
// Copyright 2022 The TCell Authors
// Copyright 2023 The TCell Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License.
@ -31,10 +31,10 @@ import (
"golang.org/x/term"
"golang.org/x/text/transform"
"github.com/stefanhaller/tcell/v2/terminfo"
"github.com/gdamore/tcell/v2/terminfo"
// import the stock terminals
_ "github.com/stefanhaller/tcell/v2/terminfo/base"
_ "github.com/gdamore/tcell/v2/terminfo/base"
)
// NewTerminfoScreen returns a Screen that uses the stock TTY interface
@ -94,7 +94,7 @@ func NewTerminfoScreenFromTtyTerminfo(tty Tty, ti *terminfo.Terminfo) (s Screen,
t.fallback[k] = v
}
return t, nil
return &baseScreen{screenImpl: t}, nil
}
// NewTerminfoScreenFromTty returns a Screen using a custom Tty implementation.
@ -123,7 +123,6 @@ type tScreen struct {
buf bytes.Buffer
curstyle Style
style Style
evch chan Event
resizeQ chan bool
quit chan struct{}
keyexist map[Key]bool
@ -159,6 +158,7 @@ type tScreen struct {
cursorStyle CursorStyle
saved *term.State
stopQ chan struct{}
eventQ chan Event
running bool
wg sync.WaitGroup
mouseFlags MouseFlags
@ -173,7 +173,6 @@ func (t *tScreen) Init() error {
return e
}
t.evch = make(chan Event, 10)
t.keychan = make(chan []byte, 10)
t.keytimer = time.NewTimer(time.Millisecond * 50)
t.charset = "UTF-8"
@ -217,6 +216,7 @@ func (t *tScreen) Init() error {
}
t.quit = make(chan struct{})
t.eventQ = make(chan Event, 10)
t.Lock()
t.cx = -1
@ -349,8 +349,8 @@ func (t *tScreen) prepareBracketedPaste() {
func (t *tScreen) prepareExtendedOSC() {
// Linux is a special beast - because it has a mouse entry, but does
// not swallow these OSC commands properly.
if (strings.Contains(t.ti.Name, "linux")) {
return;
if strings.Contains(t.ti.Name, "linux") {
return
}
// More stuff for limits in terminfo. This time we are applying
// the most common OSC (operating system commands). Generally
@ -595,41 +595,6 @@ func (t *tScreen) SetStyle(style Style) {
t.Unlock()
}
func (t *tScreen) Clear() {
t.Fill(' ', t.style)
}
func (t *tScreen) Fill(r rune, style Style) {
t.Lock()
if !t.fini {
t.cells.Fill(r, style)
}
t.Unlock()
}
func (t *tScreen) SetContent(x, y int, mainc rune, combc []rune, style Style) {
t.Lock()
if !t.fini {
t.cells.SetContent(x, y, mainc, combc, style)
}
t.Unlock()
}
func (t *tScreen) GetContent(x, y int) (rune, []rune, Style, int) {
t.Lock()
mainc, combc, style, width := t.cells.GetContent(x, y)
t.Unlock()
return mainc, combc, style, width
}
func (t *tScreen) SetCell(x, y int, style Style, ch ...rune) {
if len(ch) > 0 {
t.SetContent(x, y, ch[0], ch[1:], style)
} else {
t.SetContent(x, y, ' ', nil, style)
}
}
func (t *tScreen) encodeRune(r rune, buf []byte) []byte {
nb := make([]byte, 6)
@ -1091,18 +1056,24 @@ func (t *tScreen) Size() (int, int) {
}
func (t *tScreen) resize() {
if w, h, e := t.tty.WindowSize(); e == nil {
if w != t.w || h != t.h {
t.cx = -1
t.cy = -1
ws, err := t.tty.WindowSize()
if err != nil {
return
}
if ws.Width == t.w && ws.Height == t.h {
return
}
t.cx = -1
t.cy = -1
t.cells.Resize(w, h)
t.cells.Invalidate()
t.h = h
t.w = w
ev := NewEventResize(w, h)
_ = t.PostEvent(ev)
}
t.cells.Resize(ws.Width, ws.Height)
t.cells.Invalidate()
t.h = ws.Height
t.w = ws.Width
ev := &EventResize{t: time.Now(), ws: ws}
select {
case t.eventQ <- ev:
default:
}
}
@ -1121,39 +1092,6 @@ func (t *tScreen) nColors() int {
return t.ti.Colors
}
func (t *tScreen) ChannelEvents(ch chan<- Event, quit <-chan struct{}) {
defer close(ch)
for {
select {
case <-quit:
return
case <-t.quit:
return
case ev := <-t.evch:
select {
case <-quit:
return
case <-t.quit:
return
case ch <- ev:
}
}
}
}
func (t *tScreen) PollEvent() Event {
select {
case <-t.quit:
return nil
case ev := <-t.evch:
return ev
}
}
func (t *tScreen) HasPendingEvent() bool {
return len(t.evch) > 0
}
// vtACSNames is a map of bytes defined by terminfo that are used in
// the terminals Alternate Character Set to represent other glyphs.
// For example, the upper left corner of the box drawing set can be
@ -1218,19 +1156,6 @@ func (t *tScreen) buildAcsMap() {
}
}
func (t *tScreen) PostEventWait(ev Event) {
t.evch <- ev
}
func (t *tScreen) PostEvent(ev Event) error {
select {
case t.evch <- ev:
return nil
default:
return ErrEventQFull
}
}
func (t *tScreen) clip(x, y int) (int, int) {
w, h := t.cells.Size()
if x < 0 {
@ -1311,6 +1236,7 @@ func (t *tScreen) parseSgrMouse(buf *bytes.Buffer, evs *[]Event) (bool, bool) {
dig := false
neg := false
motion := false
scroll := false
i := 0
val := 0
@ -1385,6 +1311,7 @@ func (t *tScreen) parseSgrMouse(buf *bytes.Buffer, evs *[]Event) (bool, bool) {
y = val - 1
motion = (btn & 32) != 0
scroll = (btn & 0x42) == 0x40
btn &^= 32
if b[i] == 'm' {
// mouse release, clear all buttons
@ -1403,7 +1330,7 @@ func (t *tScreen) parseSgrMouse(buf *bytes.Buffer, evs *[]Event) (bool, bool) {
btn |= 3
btn &^= 0x40
}
} else {
} else if !scroll {
t.buttondn = true
}
// consume the event bytes
@ -1590,7 +1517,11 @@ func (t *tScreen) scanInput(buf *bytes.Buffer, expire bool) {
evs := t.collectEventsFromInput(buf, expire)
for _, ev := range evs {
t.PostEventWait(ev)
select {
case t.eventQ <- ev:
case <-t.quit:
return
}
}
}
@ -1659,7 +1590,7 @@ func (t *tScreen) collectEventsFromInput(buf *bytes.Buffer, expire bool) []Event
_, _ = buf.ReadByte()
continue
}
// Nothing was going to match, or we timed out
// Nothing was going to match, or we timed-out
// waiting for more data -- just deliver the characters
// to the app & let them sort it out. Possibly we
// should only do this for control characters like ESC.
@ -1754,7 +1685,10 @@ func (t *tScreen) inputLoop(stopQ chan struct{}) {
running := t.running
t.Unlock()
if running {
_ = t.PostEvent(NewEventError(e))
select {
case t.eventQ <- NewEventError(e):
case <-t.quit:
}
}
return
}
@ -1850,6 +1784,10 @@ func (t *tScreen) Resume() error {
return t.engage()
}
func (t *tScreen) Tty() (Tty, bool) {
return t.tty, true
}
// engage is used to place the terminal in raw mode and establish screen size, etc.
// Think of this is as tcell "engaging" the clutch, as it's going to be driving the
// terminal interface.
@ -1872,8 +1810,8 @@ func (t *tScreen) engage() error {
return err
}
t.running = true
if w, h, err := t.tty.WindowSize(); err == nil && w != 0 && h != 0 {
t.cells.Resize(w, h)
if ws, err := t.tty.WindowSize(); err == nil && ws.Width != 0 && ws.Height != 0 {
t.cells.Resize(ws.Width, ws.Height)
}
stopQ := make(chan struct{})
t.stopQ = stopQ
@ -1922,7 +1860,7 @@ func (t *tScreen) disengage() {
t.cells.Resize(0, 0)
t.TPuts(ti.ShowCursor)
if t.cursorStyles != nil && t.cursorStyle != CursorStyleDefault {
t.TPuts(t.cursorStyles[t.cursorStyle])
t.TPuts(t.cursorStyles[CursorStyleDefault])
}
t.TPuts(ti.ResetFgBg)
t.TPuts(ti.AttrOff)
@ -1948,3 +1886,15 @@ func (t *tScreen) finalize() {
t.disengage()
_ = t.tty.Close()
}
func (t *tScreen) StopQ() <-chan struct{} {
return t.stopQ
}
func (t *tScreen) EventQ() chan Event {
return t.eventQ
}
func (t *tScreen) GetCells() *CellBuffer {
return &t.cells
}

View File

@ -50,7 +50,7 @@ type Tty interface {
// WindowSize is called to determine the terminal dimensions. This might be determined
// by an ioctl or other means.
WindowSize() (width int, height int, err error)
WindowSize() (WindowSize, error)
io.ReadWriteCloser
}

View File

@ -27,6 +27,7 @@ import (
"syscall"
"time"
"golang.org/x/sys/unix"
"golang.org/x/term"
)
@ -136,11 +137,14 @@ func (tty *devTty) Stop() error {
return nil
}
func (tty *devTty) WindowSize() (int, int, error) {
w, h, err := term.GetSize(tty.fd)
func (tty *devTty) WindowSize() (WindowSize, error) {
size := WindowSize{}
ws, err := unix.IoctlGetWinsize(tty.fd, unix.TIOCGWINSZ)
if err != nil {
return 0, 0, err
return size, err
}
w := int(ws.Col)
h := int(ws.Row)
if w == 0 {
w, _ = strconv.Atoi(os.Getenv("COLUMNS"))
}
@ -153,7 +157,11 @@ func (tty *devTty) WindowSize() (int, int, error) {
if h == 0 {
h = 25 // default
}
return w, h, nil
size.Width = w
size.Height = h
size.PixelWidth = int(ws.Xpixel)
size.PixelHeight = int(ws.Ypixel)
return size, nil
}
func (tty *devTty) NotifyResize(cb func()) {

View File

@ -19,6 +19,7 @@ package tcell
import (
"errors"
"github.com/gdamore/tcell/v2/terminfo"
"strings"
"sync"
"syscall/js"
@ -29,7 +30,7 @@ func NewTerminfoScreen() (Screen, error) {
t := &wScreen{}
t.fallback = make(map[rune]string)
return t, nil
return &baseScreen{screenImpl: t}, nil
}
type wScreen struct {
@ -48,6 +49,7 @@ type wScreen struct {
quit chan struct{}
evch chan Event
fallback map[rune]string
finiOnce sync.Once
sync.Mutex
}
@ -69,7 +71,9 @@ func (t *wScreen) Init() error {
}
func (t *wScreen) Fini() {
close(t.quit)
t.finiOnce.Do(func() {
close(t.quit)
})
}
func (t *wScreen) SetStyle(style Style) {
@ -78,65 +82,34 @@ func (t *wScreen) SetStyle(style Style) {
t.Unlock()
}
func (t *wScreen) Clear() {
t.Fill(' ', t.style)
}
func (t *wScreen) Fill(r rune, style Style) {
t.Lock()
t.cells.Fill(r, style)
t.Unlock()
}
func (t *wScreen) SetContent(x, y int, mainc rune, combc []rune, style Style) {
t.Lock()
t.cells.SetContent(x, y, mainc, combc, style)
t.Unlock()
}
func (t *wScreen) GetContent(x, y int) (rune, []rune, Style, int) {
t.Lock()
mainc, combc, style, width := t.cells.GetContent(x, y)
t.Unlock()
return mainc, combc, style, width
}
func (t *wScreen) SetCell(x, y int, style Style, ch ...rune) {
if len(ch) > 0 {
t.SetContent(x, y, ch[0], ch[1:], style)
} else {
t.SetContent(x, y, ' ', nil, style)
}
}
// paletteColor gives a more natural palette color actually matching
// typical XTerm. We might in the future want to permit styling these
// via CSS.
var palette = map[Color]int32{
ColorBlack: 0x000000,
ColorMaroon: 0xcd0000,
ColorGreen: 0x00cd00,
ColorOlive: 0xcdcd00,
ColorNavy: 0x0000ee,
ColorPurple: 0xcd00cd,
ColorTeal: 0x00cdcd,
ColorSilver: 0xe5e5e5,
ColorGray: 0x7f7f7f,
ColorRed: 0xff0000,
ColorLime: 0x00ff00,
ColorYellow: 0xffff00,
ColorBlue: 0x5c5cff,
ColorBlack: 0x000000,
ColorMaroon: 0xcd0000,
ColorGreen: 0x00cd00,
ColorOlive: 0xcdcd00,
ColorNavy: 0x0000ee,
ColorPurple: 0xcd00cd,
ColorTeal: 0x00cdcd,
ColorSilver: 0xe5e5e5,
ColorGray: 0x7f7f7f,
ColorRed: 0xff0000,
ColorLime: 0x00ff00,
ColorYellow: 0xffff00,
ColorBlue: 0x5c5cff,
ColorFuchsia: 0xff00ff,
ColorAqua: 0x00ffff,
ColorWhite: 0xffffff,
ColorAqua: 0x00ffff,
ColorWhite: 0xffffff,
}
func paletteColor(c Color) int32 {
if (c.IsRGB()) {
return int32(c & 0xffffff);
if c.IsRGB() {
return int32(c & 0xffffff)
}
if (c >= ColorBlack && c <= ColorWhite) {
if c >= ColorBlack && c <= ColorWhite {
return palette[c]
}
return c.Hex()
@ -154,11 +127,11 @@ func (t *wScreen) drawCell(x, y int) int {
}
fg, bg := paletteColor(style.fg), paletteColor(style.bg)
if (fg == -1) {
fg = 0xe5e5e5;
if fg == -1 {
fg = 0xe5e5e5
}
if (bg == -1) {
bg = 0x000000;
if bg == -1 {
bg = 0x000000
}
var combcarr []interface{} = make([]interface{}, len(combc))
@ -275,6 +248,18 @@ func (t *wScreen) enablePasting(on bool) {
}
}
func (t *wScreen) EnableFocus() {
t.Lock()
js.Global().Set("onFocus", js.FuncOf(t.onFocus))
t.Unlock()
}
func (t *wScreen) DisableFocus() {
t.Lock()
js.Global().Set("onFocus", js.FuncOf(t.unset))
t.Unlock()
}
func (t *wScreen) Size() (int, int) {
t.Lock()
w, h := t.w, t.h
@ -290,52 +275,6 @@ func (t *wScreen) Colors() int {
return 16777216 // 256 ^ 3
}
func (t *wScreen) ChannelEvents(ch chan<- Event, quit <-chan struct{}) {
defer close(ch)
for {
select {
case <-quit:
return
case <-t.quit:
return
case ev := <-t.evch:
select {
case <-quit:
return
case <-t.quit:
return
case ch <- ev:
}
}
}
}
func (t *wScreen) PollEvent() Event {
select {
case <-t.quit:
return nil
case ev := <-t.evch:
return ev
}
}
func (t *wScreen) HasPendingEvent() bool {
return len(t.evch) > 0
}
func (t *wScreen) PostEventWait(ev Event) {
t.evch <- ev
}
func (t *wScreen) PostEvent(ev Event) error {
select {
case t.evch <- ev:
return nil
default:
return ErrEventQFull
}
}
func (t *wScreen) clip(x, y int) (int, int) {
w, h := t.cells.Size()
if x < 0 {
@ -353,6 +292,13 @@ func (t *wScreen) clip(x, y int) (int, int) {
return x, y
}
func (t *wScreen) postEvent(ev Event) {
select {
case t.evch <- ev:
case <-t.quit:
}
}
func (t *wScreen) onMouseEvent(this js.Value, args []js.Value) interface{} {
mod := ModNone
button := ButtonNone
@ -384,7 +330,7 @@ func (t *wScreen) onMouseEvent(this js.Value, args []js.Value) interface{} {
mod |= ModCtrl
}
t.PostEventWait(NewEventMouse(args[0].Int(), args[1].Int(), button, mod))
t.postEvent(NewEventMouse(args[0].Int(), args[1].Int(), button, mod))
return nil
}
@ -416,25 +362,30 @@ func (t *wScreen) onKeyEvent(this js.Value, args []js.Value) interface{} {
// check for special case of Ctrl + key
if mod == ModCtrl {
if k, ok := WebKeyNames["Ctrl-"+strings.ToLower(key)]; ok {
t.PostEventWait(NewEventKey(k, 0, mod))
t.postEvent(NewEventKey(k, 0, mod))
return nil
}
}
// next try function keys
if k, ok := WebKeyNames[key]; ok {
t.PostEventWait(NewEventKey(k, 0, mod))
t.postEvent(NewEventKey(k, 0, mod))
return nil
}
// finally try normal, printable chars
r, _ := utf8.DecodeRuneInString(key)
t.PostEventWait(NewEventKey(KeyRune, r, mod))
t.postEvent(NewEventKey(KeyRune, r, mod))
return nil
}
func (t *wScreen) onPaste(this js.Value, args []js.Value) interface{} {
t.PostEventWait(NewEventPaste(args[0].Bool()))
t.postEvent(NewEventPaste(args[0].Bool()))
return nil
}
func (t *wScreen) onFocus(this js.Value, args []js.Value) interface{} {
t.postEvent(NewEventFocus(args[0].Bool()))
return nil
}
@ -501,7 +452,7 @@ func (t *wScreen) SetSize(w, h int) {
t.cells.Resize(w, h)
js.Global().Call("resize", w, h)
t.w, t.h = w, h
t.PostEvent(NewEventResize(w, h))
t.postEvent(NewEventResize(w, h))
}
func (t *wScreen) Resize(int, int, int, int) {}
@ -544,6 +495,22 @@ func (t *wScreen) Beep() error {
return nil
}
func (t *wScreen) Tty() (Tty, bool) {
return nil, false
}
func (t *wScreen) GetCells() *CellBuffer {
return &t.cells
}
func (t *wScreen) EventQ() chan Event {
return t.evch
}
func (t *wScreen) StopQ() <-chan struct{} {
return t.quit
}
// WebKeyNames maps string names reported from HTML
// (KeyboardEvent.key) to tcell accepted keys.
var WebKeyNames = map[string]Key{
@ -676,3 +643,7 @@ var curStyleClasses = map[CursorStyle]string{
CursorStyleBlinkingBar: "cursor-blinking-bar",
CursorStyleSteadyBar: "cursor-steady-bar",
}
func LookupTerminfo(name string) (ti *terminfo.Terminfo, e error) {
return nil, errors.New("LookupTermInfo not supported")
}

View File

@ -4,7 +4,7 @@
package gocui
import "github.com/stefanhaller/tcell/v2"
import "github.com/gdamore/tcell/v2"
// Attribute affects the presentation of characters, such as color, boldness, etc.
type Attribute uint64

View File

@ -12,9 +12,9 @@ import (
"sync"
"time"
"github.com/gdamore/tcell/v2"
"github.com/go-errors/errors"
"github.com/mattn/go-runewidth"
"github.com/stefanhaller/tcell/v2"
)
// OutputMode represents an output mode, which determines how colors

View File

@ -7,7 +7,7 @@ package gocui
import (
"strings"
"github.com/stefanhaller/tcell/v2"
"github.com/gdamore/tcell/v2"
)
// Key represents special keys or keys combinations.

View File

@ -5,8 +5,8 @@
package gocui
import (
"github.com/gdamore/tcell/v2"
"github.com/mattn/go-runewidth"
"github.com/stefanhaller/tcell/v2"
)
// We probably don't want this being a global variable for YOLO for now

View File

@ -13,9 +13,9 @@ import (
"unicode"
"unicode/utf8"
"github.com/gdamore/tcell/v2"
"github.com/go-errors/errors"
"github.com/mattn/go-runewidth"
"github.com/stefanhaller/tcell/v2"
)
// Constants for overlapping edges

View File

@ -1,58 +0,0 @@
// Copyright 2020 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 extended contains an extended set of terminal descriptions.
// Applications desiring to have a better chance of Just Working by
// default should include this package. This will significantly increase
// the size of the program.
package extended
import (
// The following imports just register themselves --
// these are the terminal types we aggregate in this package.
_ "github.com/stefanhaller/tcell/v2/terminfo/a/aixterm"
_ "github.com/stefanhaller/tcell/v2/terminfo/a/alacritty"
_ "github.com/stefanhaller/tcell/v2/terminfo/a/ansi"
_ "github.com/stefanhaller/tcell/v2/terminfo/b/beterm"
_ "github.com/stefanhaller/tcell/v2/terminfo/c/cygwin"
_ "github.com/stefanhaller/tcell/v2/terminfo/d/dtterm"
_ "github.com/stefanhaller/tcell/v2/terminfo/e/emacs"
_ "github.com/stefanhaller/tcell/v2/terminfo/f/foot"
_ "github.com/stefanhaller/tcell/v2/terminfo/g/gnome"
_ "github.com/stefanhaller/tcell/v2/terminfo/h/hpterm"
_ "github.com/stefanhaller/tcell/v2/terminfo/k/konsole"
_ "github.com/stefanhaller/tcell/v2/terminfo/k/kterm"
_ "github.com/stefanhaller/tcell/v2/terminfo/l/linux"
_ "github.com/stefanhaller/tcell/v2/terminfo/p/pcansi"
_ "github.com/stefanhaller/tcell/v2/terminfo/r/rxvt"
_ "github.com/stefanhaller/tcell/v2/terminfo/s/screen"
_ "github.com/stefanhaller/tcell/v2/terminfo/s/simpleterm"
_ "github.com/stefanhaller/tcell/v2/terminfo/s/sun"
_ "github.com/stefanhaller/tcell/v2/terminfo/t/termite"
_ "github.com/stefanhaller/tcell/v2/terminfo/t/tmux"
_ "github.com/stefanhaller/tcell/v2/terminfo/v/vt100"
_ "github.com/stefanhaller/tcell/v2/terminfo/v/vt102"
_ "github.com/stefanhaller/tcell/v2/terminfo/v/vt220"
_ "github.com/stefanhaller/tcell/v2/terminfo/v/vt320"
_ "github.com/stefanhaller/tcell/v2/terminfo/v/vt400"
_ "github.com/stefanhaller/tcell/v2/terminfo/v/vt420"
_ "github.com/stefanhaller/tcell/v2/terminfo/v/vt52"
_ "github.com/stefanhaller/tcell/v2/terminfo/w/wy50"
_ "github.com/stefanhaller/tcell/v2/terminfo/w/wy60"
_ "github.com/stefanhaller/tcell/v2/terminfo/w/wy99_ansi"
_ "github.com/stefanhaller/tcell/v2/terminfo/x/xfce"
_ "github.com/stefanhaller/tcell/v2/terminfo/x/xterm"
_ "github.com/stefanhaller/tcell/v2/terminfo/x/xterm_kitty"
_ "github.com/stefanhaller/tcell/v2/terminfo/x/xterm_termite"
)

84
vendor/modules.txt vendored
View File

@ -39,6 +39,47 @@ github.com/fsmiamoto/git-todo-parser/todo
# github.com/gdamore/encoding v1.0.0
## explicit; go 1.9
github.com/gdamore/encoding
# github.com/gdamore/tcell/v2 v2.7.1-0.20240103180601-96e29905643b
## explicit; go 1.12
github.com/gdamore/tcell/v2
github.com/gdamore/tcell/v2/terminfo
github.com/gdamore/tcell/v2/terminfo/a/aixterm
github.com/gdamore/tcell/v2/terminfo/a/alacritty
github.com/gdamore/tcell/v2/terminfo/a/ansi
github.com/gdamore/tcell/v2/terminfo/b/beterm
github.com/gdamore/tcell/v2/terminfo/base
github.com/gdamore/tcell/v2/terminfo/c/cygwin
github.com/gdamore/tcell/v2/terminfo/d/dtterm
github.com/gdamore/tcell/v2/terminfo/dynamic
github.com/gdamore/tcell/v2/terminfo/e/emacs
github.com/gdamore/tcell/v2/terminfo/extended
github.com/gdamore/tcell/v2/terminfo/f/foot
github.com/gdamore/tcell/v2/terminfo/g/gnome
github.com/gdamore/tcell/v2/terminfo/h/hpterm
github.com/gdamore/tcell/v2/terminfo/k/konsole
github.com/gdamore/tcell/v2/terminfo/k/kterm
github.com/gdamore/tcell/v2/terminfo/l/linux
github.com/gdamore/tcell/v2/terminfo/p/pcansi
github.com/gdamore/tcell/v2/terminfo/r/rxvt
github.com/gdamore/tcell/v2/terminfo/s/screen
github.com/gdamore/tcell/v2/terminfo/s/simpleterm
github.com/gdamore/tcell/v2/terminfo/s/sun
github.com/gdamore/tcell/v2/terminfo/t/termite
github.com/gdamore/tcell/v2/terminfo/t/tmux
github.com/gdamore/tcell/v2/terminfo/v/vt100
github.com/gdamore/tcell/v2/terminfo/v/vt102
github.com/gdamore/tcell/v2/terminfo/v/vt220
github.com/gdamore/tcell/v2/terminfo/v/vt320
github.com/gdamore/tcell/v2/terminfo/v/vt400
github.com/gdamore/tcell/v2/terminfo/v/vt420
github.com/gdamore/tcell/v2/terminfo/v/vt52
github.com/gdamore/tcell/v2/terminfo/w/wy50
github.com/gdamore/tcell/v2/terminfo/w/wy60
github.com/gdamore/tcell/v2/terminfo/w/wy99_ansi
github.com/gdamore/tcell/v2/terminfo/x/xfce
github.com/gdamore/tcell/v2/terminfo/x/xterm
github.com/gdamore/tcell/v2/terminfo/x/xterm_kitty
github.com/gdamore/tcell/v2/terminfo/x/xterm_termite
# github.com/go-errors/errors v1.5.1
## explicit; go 1.14
github.com/go-errors/errors
@ -132,7 +173,7 @@ github.com/jesseduffield/go-git/v5/utils/merkletrie/filesystem
github.com/jesseduffield/go-git/v5/utils/merkletrie/index
github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame
github.com/jesseduffield/go-git/v5/utils/merkletrie/noder
# github.com/jesseduffield/gocui v0.3.1-0.20231209142059-968d8b62e1ef
# github.com/jesseduffield/gocui v0.3.1-0.20240103192639-2874168c14db
## explicit; go 1.12
github.com/jesseduffield/gocui
# github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10
@ -232,47 +273,6 @@ github.com/spf13/afero/mem
# github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad
## explicit
github.com/spkg/bom
# github.com/stefanhaller/tcell/v2 v2.6.2-0.20230806061358-2dfa11eddb68
## explicit; go 1.12
github.com/stefanhaller/tcell/v2
github.com/stefanhaller/tcell/v2/terminfo
github.com/stefanhaller/tcell/v2/terminfo/a/aixterm
github.com/stefanhaller/tcell/v2/terminfo/a/alacritty
github.com/stefanhaller/tcell/v2/terminfo/a/ansi
github.com/stefanhaller/tcell/v2/terminfo/b/beterm
github.com/stefanhaller/tcell/v2/terminfo/base
github.com/stefanhaller/tcell/v2/terminfo/c/cygwin
github.com/stefanhaller/tcell/v2/terminfo/d/dtterm
github.com/stefanhaller/tcell/v2/terminfo/dynamic
github.com/stefanhaller/tcell/v2/terminfo/e/emacs
github.com/stefanhaller/tcell/v2/terminfo/extended
github.com/stefanhaller/tcell/v2/terminfo/f/foot
github.com/stefanhaller/tcell/v2/terminfo/g/gnome
github.com/stefanhaller/tcell/v2/terminfo/h/hpterm
github.com/stefanhaller/tcell/v2/terminfo/k/konsole
github.com/stefanhaller/tcell/v2/terminfo/k/kterm
github.com/stefanhaller/tcell/v2/terminfo/l/linux
github.com/stefanhaller/tcell/v2/terminfo/p/pcansi
github.com/stefanhaller/tcell/v2/terminfo/r/rxvt
github.com/stefanhaller/tcell/v2/terminfo/s/screen
github.com/stefanhaller/tcell/v2/terminfo/s/simpleterm
github.com/stefanhaller/tcell/v2/terminfo/s/sun
github.com/stefanhaller/tcell/v2/terminfo/t/termite
github.com/stefanhaller/tcell/v2/terminfo/t/tmux
github.com/stefanhaller/tcell/v2/terminfo/v/vt100
github.com/stefanhaller/tcell/v2/terminfo/v/vt102
github.com/stefanhaller/tcell/v2/terminfo/v/vt220
github.com/stefanhaller/tcell/v2/terminfo/v/vt320
github.com/stefanhaller/tcell/v2/terminfo/v/vt400
github.com/stefanhaller/tcell/v2/terminfo/v/vt420
github.com/stefanhaller/tcell/v2/terminfo/v/vt52
github.com/stefanhaller/tcell/v2/terminfo/w/wy50
github.com/stefanhaller/tcell/v2/terminfo/w/wy60
github.com/stefanhaller/tcell/v2/terminfo/w/wy99_ansi
github.com/stefanhaller/tcell/v2/terminfo/x/xfce
github.com/stefanhaller/tcell/v2/terminfo/x/xterm
github.com/stefanhaller/tcell/v2/terminfo/x/xterm_kitty
github.com/stefanhaller/tcell/v2/terminfo/x/xterm_termite
# github.com/stretchr/testify v1.8.1
## explicit; go 1.13
github.com/stretchr/testify/assert