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:
parent
ef3d6f4a32
commit
cb5d0bca1c
4
go.mod
4
go.mod
@ -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
14
go.sum
@ -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=
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) {
|
@ -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") == "" {
|
@ -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.
|
@ -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
|
||||
}
|
@ -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)
|
@ -18,7 +18,7 @@ import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/stefanhaller/tcell/v2/terminfo"
|
||||
"github.com/gdamore/tcell/v2/terminfo"
|
||||
)
|
||||
|
||||
var (
|
@ -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)
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
@ -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()) {
|
@ -2,7 +2,7 @@
|
||||
|
||||
package aixterm
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package alacritty
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package alacritty
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package ansi
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package beterm
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -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"
|
||||
)
|
@ -2,7 +2,7 @@
|
||||
|
||||
package cygwin
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package dtterm
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -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"
|
@ -2,7 +2,7 @@
|
||||
|
||||
package emacs
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
58
vendor/github.com/gdamore/tcell/v2/terminfo/extended/extended.go
generated
vendored
Normal file
58
vendor/github.com/gdamore/tcell/v2/terminfo/extended/extended.go
generated
vendored
Normal 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"
|
||||
)
|
@ -2,7 +2,7 @@
|
||||
|
||||
package foot
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package gnome
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/bin/bash
|
||||
while read line
|
||||
do
|
||||
case "$line" in
|
@ -2,7 +2,7 @@
|
||||
|
||||
package hpterm
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package konsole
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package kterm
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package linux
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package pcansi
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package rxvt
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package screen
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package simpleterm
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
package sun
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package termite
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package tmux
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package vt100
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package vt102
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package vt220
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package vt320
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package vt400
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package vt420
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package vt52
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package wy50
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package wy60
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package wy99_ansi
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package xfce
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
package xterm
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package xterm
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package xterm_kitty
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package xterm_termite
|
||||
|
||||
import "github.com/stefanhaller/tcell/v2/terminfo"
|
||||
import "github.com/gdamore/tcell/v2/terminfo"
|
||||
|
||||
func init() {
|
||||
|
@ -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"
|
||||
)
|
@ -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) {
|
@ -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) {
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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()) {
|
@ -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")
|
||||
}
|
2
vendor/github.com/jesseduffield/gocui/attribute.go
generated
vendored
2
vendor/github.com/jesseduffield/gocui/attribute.go
generated
vendored
@ -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
|
||||
|
2
vendor/github.com/jesseduffield/gocui/gui.go
generated
vendored
2
vendor/github.com/jesseduffield/gocui/gui.go
generated
vendored
@ -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
|
||||
|
2
vendor/github.com/jesseduffield/gocui/keybinding.go
generated
vendored
2
vendor/github.com/jesseduffield/gocui/keybinding.go
generated
vendored
@ -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.
|
||||
|
2
vendor/github.com/jesseduffield/gocui/tcell_driver.go
generated
vendored
2
vendor/github.com/jesseduffield/gocui/tcell_driver.go
generated
vendored
@ -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
|
||||
|
2
vendor/github.com/jesseduffield/gocui/view.go
generated
vendored
2
vendor/github.com/jesseduffield/gocui/view.go
generated
vendored
@ -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
|
||||
|
58
vendor/github.com/stefanhaller/tcell/v2/terminfo/extended/extended.go
generated
vendored
58
vendor/github.com/stefanhaller/tcell/v2/terminfo/extended/extended.go
generated
vendored
@ -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
84
vendor/modules.txt
vendored
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user