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

build: bump tcell version

This commit is contained in:
Ryooooooga 2023-02-21 21:53:55 +09:00
parent 526c9dea9b
commit 90772e1eaa
No known key found for this signature in database
GPG Key ID: 07CF200DFCC20C25
18 changed files with 870 additions and 23 deletions

5
go.mod
View File

@ -11,7 +11,7 @@ require (
github.com/creack/pty v1.1.11
github.com/fsmiamoto/git-todo-parser v0.0.2
github.com/fsnotify/fsnotify v1.4.7
github.com/gdamore/tcell/v2 v2.5.4
github.com/gdamore/tcell/v2 v2.6.0
github.com/go-errors/errors v1.4.2
github.com/gookit/color v1.4.2
github.com/imdario/mergo v0.3.11
@ -46,6 +46,7 @@ require (
github.com/emirpasic/gods v1.12.0 // indirect
github.com/fatih/color v1.9.0 // indirect
github.com/gdamore/encoding v1.0.0 // indirect
github.com/gdamore/tcell v1.4.0 // indirect
github.com/go-git/gcfg v1.5.0 // indirect
github.com/go-git/go-billy/v5 v5.0.0 // indirect
github.com/go-logfmt/logfmt v0.5.0 // indirect
@ -62,7 +63,7 @@ require (
github.com/onsi/ginkgo v1.10.3 // indirect
github.com/onsi/gomega v1.7.1 // indirect
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
github.com/rivo/uniseg v0.4.3 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/sergi/go-diff v1.1.0 // indirect
github.com/xanzy/ssh-agent v0.2.1 // indirect
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect

8
go.sum
View File

@ -34,9 +34,13 @@ github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV
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 v1.4.0 h1:vUnHwJRvcPQa3tzi+0QI4U9JINXYJlOz9yiaiPQ2wMU=
github.com/gdamore/tcell v1.4.0/go.mod h1:vxEiSDZdW3L+Uhjii9c3375IlDmR05bzxY404ZVSMo0=
github.com/gdamore/tcell/v2 v2.4.0/go.mod h1:cTTuF84Dlj/RqmaCIV5p4w8uG1zWdk0SF6oBpwHp4fU=
github.com/gdamore/tcell/v2 v2.5.4 h1:TGU4tSjD3sCL788vFNeJnTdzpNKIw1H5dgLnJRQVv/k=
github.com/gdamore/tcell/v2 v2.5.4/go.mod h1:dZgRy5v4iMobMEcWNYBtREnDZAT9DYmfqIkrgEMxLyw=
github.com/gdamore/tcell/v2 v2.6.0 h1:OKbluoP9VYmJwZwq/iLb4BxwKcwGthaa1YNBJIyCySg=
github.com/gdamore/tcell/v2 v2.6.0/go.mod h1:be9omFATkdr0D9qewWW3d+MEvl5dha+Etb5y65J2H8Y=
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=
@ -113,6 +117,7 @@ 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.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
@ -138,6 +143,8 @@ github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw=
github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI=
github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
github.com/samber/lo v1.31.0 h1:Sfa+/064Tdo4SvlohQUQzBhgSer9v/coGvKQI/XLWAM=
@ -196,6 +203,7 @@ golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

61
vendor/github.com/gdamore/tcell/v2/README-wasm.md generated vendored Normal file
View File

@ -0,0 +1,61 @@
# WASM for _Tcell_
You can build _Tcell_ project into a webpage by compiling it slightly differently. This will result in a _Tcell_ project you can embed into another html page, or use as a standalone page.
## Building your project
WASM needs special build flags in order to work. You can build it by executing
```sh
GOOS=js GOARCH=wasm go build -o yourfile.wasm
```
## Additional files
You also need 5 other files in the same directory as the wasm. Four (`tcell.html`, `tcell.js`, `termstyle.css`, and `beep.wav`) are provided in the `webfiles` directory. The last one, `wasm_exec.js`, can be copied from GOROOT into the current directory by executing
```sh
cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" ./
```
In `tcell.js`, you also need to change the constant
```js
const wasmFilePath = "yourfile.wasm"
```
to the file you outputed to when building.
## Displaying your project
### Standalone
You can see the project (with an white background around the terminal) by serving the directory. You can do this using any framework, including another golang project:
```golang
// server.go
package main
import (
"log"
"net/http"
)
func main() {
log.Fatal(http.ListenAndServe(":8080",
http.FileServer(http.Dir("/path/to/dir/to/serve")),
))
}
```
To see the webpage with this example, you can type in `localhost:8080/tcell.html` into your browser while `server.go` is running.
### Embedding
It is recomended to use an iframe if you want to embed the app into a webpage:
```html
<iframe src="tcell.html" title="Tcell app"></iframe>
```
## Other considerations
### Accessing files
`io.Open(filename)` and other related functions for reading file systems do not work; use `http.Get(filename)` instead.

View File

@ -264,7 +264,11 @@ Windows console mode applications are supported.
Modern console applications like ConEmu and the Windows 10 terminal,
support all the good features (resize, mouse tracking, etc.)
### Plan9, WASM, and others
### WASM
WASM is supported, but needs additional setup detailed in [README-wasm](README-wasm.md).
### Plan9 and others
These platforms won't work, but compilation stubs are supplied
for folks that want to include parts of this in software for those

View File

@ -50,6 +50,10 @@ func (cb *CellBuffer) SetContent(x int, y int,
if x >= 0 && y >= 0 && x < cb.w && y < cb.h {
c := &cb.cells[(y*cb.w)+x]
for i := 1; i < c.width; i++ {
cb.SetDirty(x+i, y, true)
}
c.currComb = append([]rune{}, combc...)
if c.currMain != mainc {
@ -178,13 +182,14 @@ func (cb *CellBuffer) Fill(r rune, style Style) {
}
}
var runeConfig *runewidth.Condition;
var runeConfig *runewidth.Condition
func init() {
// The defaults for the runewidth package are poorly chosen for terminal
// applications. We however will honor the setting in the environment if
// it is set.
if os.Getenv("RUNEWIDTH_EASTASIAN") == "" {
runewidth.DefaultCondition.EastAsianWidth = false;
runewidth.DefaultCondition.EastAsianWidth = false
}
// For performance reasons, we create a lookup table. However some users

View File

@ -1002,14 +1002,14 @@ func (c Color) IsRGB() bool {
}
// Hex returns the color's hexadecimal RGB 24-bit value with each component
// consisting of a single byte, ala R << 16 | G << 8 | B. If the color
// consisting of a single byte, R << 16 | G << 8 | B. If the color
// is unknown or unset, -1 is returned.
func (c Color) Hex() int32 {
if !c.Valid() {
return -1
}
if c&ColorIsRGB != 0 {
return int32(c) & 0xffffff
return int32(c & 0xffffff)
}
if v, ok := ColorValues[c]; ok {
return v
@ -1036,7 +1036,7 @@ func (c Color) TrueColor() Color {
return ColorDefault
}
if c&ColorIsRGB != 0 {
return c
return c | ColorValid
}
return Color(c.Hex()) | ColorIsRGB | ColorValid
}

View File

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

View File

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

View File

@ -12,6 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build !(js && wasm)
// +build !js !wasm
package tcell
import (
@ -341,6 +344,11 @@ 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;
}
// More stuff for limits in terminfo. This time we are applying
// the most common OSC (operating system commands). Generally
// terminals that don't understand these will ignore them.

View File

@ -1,5 +1,5 @@
//go:build js || plan9 || windows
// +build js plan9 windows
//go:build plan9 || windows
// +build plan9 windows
// Copyright 2022 The TCell Authors
//

678
vendor/github.com/gdamore/tcell/v2/wscreen.go generated vendored Normal file
View File

@ -0,0 +1,678 @@
// 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.
// 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.
//go:build js && wasm
// +build js,wasm
package tcell
import (
"errors"
"strings"
"sync"
"syscall/js"
"unicode/utf8"
)
func NewTerminfoScreen() (Screen, error) {
t := &wScreen{}
t.fallback = make(map[rune]string)
return t, nil
}
type wScreen struct {
w, h int
style Style
cells CellBuffer
running bool
clear bool
flagsPresent bool
pasteEnabled bool
mouseFlags MouseFlags
cursorStyle CursorStyle
quit chan struct{}
evch chan Event
fallback map[rune]string
sync.Mutex
}
func (t *wScreen) Init() error {
t.w, t.h = 80, 24 // default for html as of now
t.evch = make(chan Event, 10)
t.quit = make(chan struct{})
t.Lock()
t.running = true
t.style = StyleDefault
t.cells.Resize(t.w, t.h)
t.Unlock()
js.Global().Set("onKeyEvent", js.FuncOf(t.onKeyEvent))
return nil
}
func (t *wScreen) Fini() {
close(t.quit)
}
func (t *wScreen) SetStyle(style Style) {
t.Lock()
t.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,
ColorFuchsia: 0xff00ff,
ColorAqua: 0x00ffff,
ColorWhite: 0xffffff,
}
func paletteColor(c Color) int32 {
if (c.IsRGB()) {
return int32(c & 0xffffff);
}
if (c >= ColorBlack && c <= ColorWhite) {
return palette[c]
}
return c.Hex()
}
func (t *wScreen) drawCell(x, y int) int {
mainc, combc, style, width := t.cells.GetContent(x, y)
if !t.cells.Dirty(x, y) {
return width
}
if style == StyleDefault {
style = t.style
}
fg, bg := paletteColor(style.fg), paletteColor(style.bg)
if (fg == -1) {
fg = 0xe5e5e5;
}
if (bg == -1) {
bg = 0x000000;
}
var combcarr []interface{} = make([]interface{}, len(combc))
for i, c := range combc {
combcarr[i] = c
}
t.cells.SetDirty(x, y, false)
js.Global().Call("drawCell", x, y, mainc, combcarr, fg, bg, int(style.attrs))
return width
}
func (t *wScreen) ShowCursor(x, y int) {
t.Lock()
js.Global().Call("showCursor", x, y)
t.Unlock()
}
func (t *wScreen) SetCursorStyle(cs CursorStyle) {
t.Lock()
js.Global().Call("setCursorStyle", curStyleClasses[cs])
t.Unlock()
}
func (t *wScreen) HideCursor() {
t.ShowCursor(-1, -1)
}
func (t *wScreen) Show() {
t.Lock()
t.resize()
t.draw()
t.Unlock()
}
func (t *wScreen) clearScreen() {
js.Global().Call("clearScreen", t.style.fg.Hex(), t.style.bg.Hex())
t.clear = false
}
func (t *wScreen) draw() {
if t.clear {
t.clearScreen()
}
for y := 0; y < t.h; y++ {
for x := 0; x < t.w; x++ {
width := t.drawCell(x, y)
x += width - 1
}
}
js.Global().Call("show")
}
func (t *wScreen) EnableMouse(flags ...MouseFlags) {
var f MouseFlags
flagsPresent := false
for _, flag := range flags {
f |= flag
flagsPresent = true
}
if !flagsPresent {
f = MouseMotionEvents | MouseDragEvents | MouseButtonEvents
}
t.Lock()
t.mouseFlags = f
t.enableMouse(f)
t.Unlock()
}
func (t *wScreen) enableMouse(f MouseFlags) {
if f&MouseButtonEvents != 0 {
js.Global().Set("onMouseClick", js.FuncOf(t.onMouseEvent))
} else {
js.Global().Set("onMouseClick", js.FuncOf(t.unset))
}
if f&MouseDragEvents != 0 || f&MouseMotionEvents != 0 {
js.Global().Set("onMouseMove", js.FuncOf(t.onMouseEvent))
} else {
js.Global().Set("onMouseMove", js.FuncOf(t.unset))
}
}
func (t *wScreen) DisableMouse() {
t.Lock()
t.mouseFlags = 0
t.enableMouse(0)
t.Unlock()
}
func (t *wScreen) EnablePaste() {
t.Lock()
t.pasteEnabled = true
t.enablePasting(true)
t.Unlock()
}
func (t *wScreen) DisablePaste() {
t.Lock()
t.pasteEnabled = false
t.enablePasting(false)
t.Unlock()
}
func (t *wScreen) enablePasting(on bool) {
if on {
js.Global().Set("onPaste", js.FuncOf(t.onPaste))
} else {
js.Global().Set("onPaste", js.FuncOf(t.unset))
}
}
func (t *wScreen) Size() (int, int) {
t.Lock()
w, h := t.w, t.h
t.Unlock()
return w, h
}
// resize does nothing, as asking the web window to resize
// without a specified width or height will cause no change.
func (t *wScreen) resize() {}
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 {
x = 0
}
if y < 0 {
y = 0
}
if x > w-1 {
x = w - 1
}
if y > h-1 {
y = h - 1
}
return x, y
}
func (t *wScreen) onMouseEvent(this js.Value, args []js.Value) interface{} {
mod := ModNone
button := ButtonNone
switch args[2].Int() {
case 0:
if t.mouseFlags&MouseMotionEvents == 0 {
// don't want this event! is a mouse motion event, but user has asked not.
return nil
}
button = ButtonNone
case 1:
button = Button1
case 2:
button = Button3 // Note we prefer to treat right as button 2
case 3:
button = Button2 // And the middle button as button 3
}
if args[3].Bool() { // mod shift
mod |= ModShift
}
if args[4].Bool() { // mod alt
mod |= ModAlt
}
if args[5].Bool() { // mod ctrl
mod |= ModCtrl
}
t.PostEventWait(NewEventMouse(args[0].Int(), args[1].Int(), button, mod))
return nil
}
func (t *wScreen) onKeyEvent(this js.Value, args []js.Value) interface{} {
key := args[0].String()
// don't accept any modifier keys as their own
if key == "Control" || key == "Alt" || key == "Meta" || key == "Shift" {
return nil
}
mod := ModNone
if args[1].Bool() { // mod shift
mod |= ModShift
}
if args[2].Bool() { // mod alt
mod |= ModAlt
}
if args[3].Bool() { // mod ctrl
mod |= ModCtrl
}
if args[4].Bool() { // mod meta
mod |= ModMeta
}
// 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))
return nil
}
}
// next try function keys
if k, ok := WebKeyNames[key]; ok {
t.PostEventWait(NewEventKey(k, 0, mod))
return nil
}
// finally try normal, printable chars
r, _ := utf8.DecodeRuneInString(key)
t.PostEventWait(NewEventKey(KeyRune, r, mod))
return nil
}
func (t *wScreen) onPaste(this js.Value, args []js.Value) interface{} {
t.PostEventWait(NewEventPaste(args[0].Bool()))
return nil
}
// unset is a dummy function for js when we want nothing to
// happen when javascript calls a function (for example, when
// mouse input is disabled, when onMouseEvent() is called from
// js, it redirects here and does nothing).
func (t *wScreen) unset(this js.Value, args []js.Value) interface{} {
return nil
}
func (t *wScreen) Sync() {
t.Lock()
t.resize()
t.clear = true
t.cells.Invalidate()
t.draw()
t.Unlock()
}
func (t *wScreen) CharacterSet() string {
return "UTF-8"
}
func (t *wScreen) RegisterRuneFallback(orig rune, fallback string) {
t.Lock()
t.fallback[orig] = fallback
t.Unlock()
}
func (t *wScreen) UnregisterRuneFallback(orig rune) {
t.Lock()
delete(t.fallback, orig)
t.Unlock()
}
func (t *wScreen) CanDisplay(r rune, checkFallbacks bool) bool {
if utf8.ValidRune(r) {
return true
}
if !checkFallbacks {
return false
}
if _, ok := t.fallback[r]; ok {
return true
}
return false
}
func (t *wScreen) HasMouse() bool {
return true
}
func (t *wScreen) HasKey(k Key) bool {
return true
}
func (t *wScreen) SetSize(w, h int) {
if w == t.w && h == t.h {
return
}
t.cells.Invalidate()
t.cells.Resize(w, h)
js.Global().Call("resize", w, h)
t.w, t.h = w, h
t.PostEvent(NewEventResize(w, h))
}
func (t *wScreen) Resize(int, int, int, int) {}
// Suspend simply pauses all input and output, and clears the screen.
// There isn't a "default terminal" to go back to.
func (t *wScreen) Suspend() error {
t.Lock()
if !t.running {
t.Unlock()
return nil
}
t.running = false
t.clearScreen()
t.enableMouse(0)
t.enablePasting(false)
js.Global().Set("onKeyEvent", js.FuncOf(t.unset)) // stop keypresses
return nil
}
func (t *wScreen) Resume() error {
t.Lock()
if t.running {
return errors.New("already engaged")
}
t.running = true
t.enableMouse(t.mouseFlags)
t.enablePasting(t.pasteEnabled)
js.Global().Set("onKeyEvent", js.FuncOf(t.onKeyEvent))
t.Unlock()
return nil
}
func (t *wScreen) Beep() error {
js.Global().Call("beep")
return nil
}
// WebKeyNames maps string names reported from HTML
// (KeyboardEvent.key) to tcell accepted keys.
var WebKeyNames = map[string]Key{
"Enter": KeyEnter,
"Backspace": KeyBackspace,
"Tab": KeyTab,
"Backtab": KeyBacktab,
"Escape": KeyEsc,
"Backspace2": KeyBackspace2,
"Delete": KeyDelete,
"Insert": KeyInsert,
"ArrowUp": KeyUp,
"ArrowDown": KeyDown,
"ArrowLeft": KeyLeft,
"ArrowRight": KeyRight,
"Home": KeyHome,
"End": KeyEnd,
"UpLeft": KeyUpLeft, // not supported by HTML
"UpRight": KeyUpRight, // not supported by HTML
"DownLeft": KeyDownLeft, // not supported by HTML
"DownRight": KeyDownRight, // not supported by HTML
"Center": KeyCenter,
"PgDn": KeyPgDn,
"PgUp": KeyPgUp,
"Clear": KeyClear,
"Exit": KeyExit,
"Cancel": KeyCancel,
"Pause": KeyPause,
"Print": KeyPrint,
"F1": KeyF1,
"F2": KeyF2,
"F3": KeyF3,
"F4": KeyF4,
"F5": KeyF5,
"F6": KeyF6,
"F7": KeyF7,
"F8": KeyF8,
"F9": KeyF9,
"F10": KeyF10,
"F11": KeyF11,
"F12": KeyF12,
"F13": KeyF13,
"F14": KeyF14,
"F15": KeyF15,
"F16": KeyF16,
"F17": KeyF17,
"F18": KeyF18,
"F19": KeyF19,
"F20": KeyF20,
"F21": KeyF21,
"F22": KeyF22,
"F23": KeyF23,
"F24": KeyF24,
"F25": KeyF25,
"F26": KeyF26,
"F27": KeyF27,
"F28": KeyF28,
"F29": KeyF29,
"F30": KeyF30,
"F31": KeyF31,
"F32": KeyF32,
"F33": KeyF33,
"F34": KeyF34,
"F35": KeyF35,
"F36": KeyF36,
"F37": KeyF37,
"F38": KeyF38,
"F39": KeyF39,
"F40": KeyF40,
"F41": KeyF41,
"F42": KeyF42,
"F43": KeyF43,
"F44": KeyF44,
"F45": KeyF45,
"F46": KeyF46,
"F47": KeyF47,
"F48": KeyF48,
"F49": KeyF49,
"F50": KeyF50,
"F51": KeyF51,
"F52": KeyF52,
"F53": KeyF53,
"F54": KeyF54,
"F55": KeyF55,
"F56": KeyF56,
"F57": KeyF57,
"F58": KeyF58,
"F59": KeyF59,
"F60": KeyF60,
"F61": KeyF61,
"F62": KeyF62,
"F63": KeyF63,
"F64": KeyF64,
"Ctrl-a": KeyCtrlA, // not reported by HTML- need to do special check
"Ctrl-b": KeyCtrlB, // not reported by HTML- need to do special check
"Ctrl-c": KeyCtrlC, // not reported by HTML- need to do special check
"Ctrl-d": KeyCtrlD, // not reported by HTML- need to do special check
"Ctrl-e": KeyCtrlE, // not reported by HTML- need to do special check
"Ctrl-f": KeyCtrlF, // not reported by HTML- need to do special check
"Ctrl-g": KeyCtrlG, // not reported by HTML- need to do special check
"Ctrl-j": KeyCtrlJ, // not reported by HTML- need to do special check
"Ctrl-k": KeyCtrlK, // not reported by HTML- need to do special check
"Ctrl-l": KeyCtrlL, // not reported by HTML- need to do special check
"Ctrl-n": KeyCtrlN, // not reported by HTML- need to do special check
"Ctrl-o": KeyCtrlO, // not reported by HTML- need to do special check
"Ctrl-p": KeyCtrlP, // not reported by HTML- need to do special check
"Ctrl-q": KeyCtrlQ, // not reported by HTML- need to do special check
"Ctrl-r": KeyCtrlR, // not reported by HTML- need to do special check
"Ctrl-s": KeyCtrlS, // not reported by HTML- need to do special check
"Ctrl-t": KeyCtrlT, // not reported by HTML- need to do special check
"Ctrl-u": KeyCtrlU, // not reported by HTML- need to do special check
"Ctrl-v": KeyCtrlV, // not reported by HTML- need to do special check
"Ctrl-w": KeyCtrlW, // not reported by HTML- need to do special check
"Ctrl-x": KeyCtrlX, // not reported by HTML- need to do special check
"Ctrl-y": KeyCtrlY, // not reported by HTML- need to do special check
"Ctrl-z": KeyCtrlZ, // not reported by HTML- need to do special check
"Ctrl- ": KeyCtrlSpace, // not reported by HTML- need to do special check
"Ctrl-_": KeyCtrlUnderscore, // not reported by HTML- need to do special check
"Ctrl-]": KeyCtrlRightSq, // not reported by HTML- need to do special check
"Ctrl-\\": KeyCtrlBackslash, // not reported by HTML- need to do special check
"Ctrl-^": KeyCtrlCarat, // not reported by HTML- need to do special check
}
var curStyleClasses = map[CursorStyle]string{
CursorStyleDefault: "cursor-blinking-block",
CursorStyleBlinkingBlock: "cursor-blinking-block",
CursorStyleSteadyBlock: "cursor-steady-block",
CursorStyleBlinkingUnderline: "cursor-blinking-underline",
CursorStyleSteadyUnderline: "cursor-steady-underline",
CursorStyleBlinkingBar: "cursor-blinking-bar",
CursorStyleSteadyBar: "cursor-steady-bar",
}

View File

@ -187,8 +187,8 @@ func ReverseString(s string) string {
const shiftGraphemePropState = 4
// FirstGraphemeCluster returns the first grapheme cluster found in the given
// byte slice according to the rules of Unicode Standard Annex #29, Grapheme
// Cluster Boundaries. This function can be called continuously to extract all
// byte slice according to the rules of [Unicode Standard Annex #29, Grapheme
// Cluster Boundaries]. This function can be called continuously to extract all
// grapheme clusters from a byte slice, as illustrated in the example below.
//
// If you don't know the current state, for example when calling the function
@ -209,6 +209,8 @@ const shiftGraphemePropState = 4
// While slightly less convenient than using the Graphemes class, this function
// has much better performance and makes no allocations. It lends itself well to
// large byte slices.
//
// [Unicode Standard Annex #29, Grapheme Cluster Boundaries]: http://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries
func FirstGraphemeCluster(b []byte, state int) (cluster, rest []byte, width, newState int) {
// An empty byte slice returns nothing.
if len(b) == 0 {

View File

@ -48,7 +48,7 @@ var grTransitions = map[[2]int][3]int{
{grControlLF, prAny}: {grAny, grBoundary, 40},
// GB3.
{grCR, prLF}: {grAny, grNoBoundary, 30},
{grCR, prLF}: {grControlLF, grNoBoundary, 30},
// GB6.
{grAny, prL}: {grL, grBoundary, 9990},

View File

@ -4,7 +4,7 @@ import "unicode/utf8"
// FirstLineSegment returns the prefix of the given byte slice after which a
// decision to break the string over to the next line can or must be made,
// according to the rules of Unicode Standard Annex #14. This is used to
// according to the rules of [Unicode Standard Annex #14]. This is used to
// implement line breaking.
//
// Line breaking, also known as word wrapping, is the process of breaking a
@ -35,7 +35,7 @@ import "unicode/utf8"
//
// Given an empty byte slice "b", the function returns nil values.
//
// Note that in accordance with UAX #14 LB3, the final segment will end with
// Note that in accordance with [UAX #14 LB3], the final segment will end with
// "mustBreak" set to true. You can choose to ignore this by checking if the
// length of the "rest" slice is 0 and calling [HasTrailingLineBreak] or
// [HasTrailingLineBreakInString] on the last rune.
@ -43,6 +43,9 @@ import "unicode/utf8"
// Note also that this algorithm may break within grapheme clusters. This is
// addressed in Section 8.2 Example 6 of UAX #14. To avoid this, you can use
// the [Step] function instead.
//
// [Unicode Standard Annex #14]: https://www.unicode.org/reports/tr14/
// [UAX #14 LB3]: https://www.unicode.org/reports/tr14/#Algorithm
func FirstLineSegment(b []byte, state int) (segment, rest []byte, mustBreak bool, newState int) {
// An empty byte slice returns nothing.
if len(b) == 0 {

View File

@ -3,7 +3,7 @@ package uniseg
import "unicode/utf8"
// FirstSentence returns the first sentence found in the given byte slice
// according to the rules of Unicode Standard Annex #29, Sentence Boundaries.
// according to the rules of [Unicode Standard Annex #29, Sentence Boundaries].
// This function can be called continuously to extract all sentences from a byte
// slice, as illustrated in the example below.
//
@ -17,6 +17,8 @@ import "unicode/utf8"
// slice is the sub-slice of the input slice containing the identified sentence.
//
// Given an empty byte slice "b", the function returns nil values.
//
// [Unicode Standard Annex #29, Sentence Boundaries]: http://unicode.org/reports/tr29/#Sentence_Boundaries
func FirstSentence(b []byte, state int) (sentence, rest []byte, newState int) {
// An empty byte slice returns nothing.
if len(b) == 0 {

View File

@ -83,10 +83,12 @@ const (
// has much better performance and makes no allocations. It lends itself well to
// large byte slices.
//
// Note that in accordance with UAX #14 LB3, the final segment will end with
// Note that in accordance with [UAX #14 LB3], the final segment will end with
// a mandatory line break (boundaries&MaskLine == LineMustBreak). You can choose
// to ignore this by checking if the length of the "rest" slice is 0 and calling
// [HasTrailingLineBreak] or [HasTrailingLineBreakInString] on the last rune.
//
// [UAX #14 LB3]: https://www.unicode.org/reports/tr14/#Algorithm
func Step(b []byte, state int) (cluster, rest []byte, boundaries int, newState int) {
// An empty byte slice returns nothing.
if len(b) == 0 {

View File

@ -3,7 +3,7 @@ package uniseg
import "unicode/utf8"
// FirstWord returns the first word found in the given byte slice according to
// the rules of Unicode Standard Annex #29, Word Boundaries. This function can
// the rules of [Unicode Standard Annex #29, Word Boundaries]. This function can
// be called continuously to extract all words from a byte slice, as illustrated
// in the example below.
//
@ -17,6 +17,8 @@ import "unicode/utf8"
// the sub-slice of the input slice containing the identified word.
//
// Given an empty byte slice "b", the function returns nil values.
//
// [Unicode Standard Annex #29, Word Boundaries]: http://unicode.org/reports/tr29/#Word_Boundaries
func FirstWord(b []byte, state int) (word, rest []byte, newState int) {
// An empty byte slice returns nothing.
if len(b) == 0 {

6
vendor/modules.txt vendored
View File

@ -39,7 +39,9 @@ github.com/fsnotify/fsnotify
# github.com/gdamore/encoding v1.0.0
## explicit; go 1.9
github.com/gdamore/encoding
# github.com/gdamore/tcell/v2 v2.5.4
# github.com/gdamore/tcell v1.4.0
## explicit; go 1.12
# github.com/gdamore/tcell/v2 v2.6.0
## explicit; go 1.12
github.com/gdamore/tcell/v2
github.com/gdamore/tcell/v2/terminfo
@ -233,7 +235,7 @@ github.com/petermattis/goid
# github.com/pmezard/go-difflib v1.0.0
## explicit
github.com/pmezard/go-difflib/difflib
# github.com/rivo/uniseg v0.4.3
# github.com/rivo/uniseg v0.4.4
## explicit; go 1.18
github.com/rivo/uniseg
# github.com/sahilm/fuzzy v0.1.0