mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-07-31 14:24:25 +03:00
refactor to only have one context per view
This commit is contained in:
7
vendor/github.com/gdamore/tcell/v2/README.md
generated
vendored
7
vendor/github.com/gdamore/tcell/v2/README.md
generated
vendored
@ -1,8 +1,13 @@
|
||||
<a href="https://stand-with-ukraine.pp.ua">
|
||||
<img src="https://upload.wikimedia.org/wikipedia/commons/d/d2/Flag_of_Ukraine.png" height="20px" width="100%"/>
|
||||
</a>
|
||||
|
||||
# 
|
||||
<img src="logos/tcell.png" style="float: right"/>
|
||||
|
||||
Please see [here](UKRAINE.md) for an important message for the people of Russia.
|
||||
|
||||
# Tcell
|
||||
|
||||
_Tcell_ is a _Go_ package that provides a cell based view for text terminals, like _XTerm_.
|
||||
It was inspired by _termbox_, but includes many additional improvements.
|
||||
|
||||
|
187
vendor/github.com/gdamore/tcell/v2/console_win.go
generated
vendored
187
vendor/github.com/gdamore/tcell/v2/console_win.go
generated
vendored
@ -1,6 +1,7 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
// Copyright 2021 The TCell Authors
|
||||
// Copyright 2022 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
@ -114,22 +115,23 @@ var (
|
||||
// characters (Unicode) are in use. The documentation refers to them
|
||||
// without this suffix, as the resolution is made via preprocessor.
|
||||
var (
|
||||
procReadConsoleInput = k32.NewProc("ReadConsoleInputW")
|
||||
procWaitForMultipleObjects = k32.NewProc("WaitForMultipleObjects")
|
||||
procCreateEvent = k32.NewProc("CreateEventW")
|
||||
procSetEvent = k32.NewProc("SetEvent")
|
||||
procGetConsoleCursorInfo = k32.NewProc("GetConsoleCursorInfo")
|
||||
procSetConsoleCursorInfo = k32.NewProc("SetConsoleCursorInfo")
|
||||
procSetConsoleCursorPosition = k32.NewProc("SetConsoleCursorPosition")
|
||||
procSetConsoleMode = k32.NewProc("SetConsoleMode")
|
||||
procGetConsoleMode = k32.NewProc("GetConsoleMode")
|
||||
procGetConsoleScreenBufferInfo = k32.NewProc("GetConsoleScreenBufferInfo")
|
||||
procFillConsoleOutputAttribute = k32.NewProc("FillConsoleOutputAttribute")
|
||||
procFillConsoleOutputCharacter = k32.NewProc("FillConsoleOutputCharacterW")
|
||||
procSetConsoleWindowInfo = k32.NewProc("SetConsoleWindowInfo")
|
||||
procSetConsoleScreenBufferSize = k32.NewProc("SetConsoleScreenBufferSize")
|
||||
procSetConsoleTextAttribute = k32.NewProc("SetConsoleTextAttribute")
|
||||
procMessageBeep = u32.NewProc("MessageBeep")
|
||||
procReadConsoleInput = k32.NewProc("ReadConsoleInputW")
|
||||
procWaitForMultipleObjects = k32.NewProc("WaitForMultipleObjects")
|
||||
procCreateEvent = k32.NewProc("CreateEventW")
|
||||
procSetEvent = k32.NewProc("SetEvent")
|
||||
procGetConsoleCursorInfo = k32.NewProc("GetConsoleCursorInfo")
|
||||
procSetConsoleCursorInfo = k32.NewProc("SetConsoleCursorInfo")
|
||||
procSetConsoleCursorPosition = k32.NewProc("SetConsoleCursorPosition")
|
||||
procSetConsoleMode = k32.NewProc("SetConsoleMode")
|
||||
procGetConsoleMode = k32.NewProc("GetConsoleMode")
|
||||
procGetConsoleScreenBufferInfo = k32.NewProc("GetConsoleScreenBufferInfo")
|
||||
procFillConsoleOutputAttribute = k32.NewProc("FillConsoleOutputAttribute")
|
||||
procFillConsoleOutputCharacter = k32.NewProc("FillConsoleOutputCharacterW")
|
||||
procSetConsoleWindowInfo = k32.NewProc("SetConsoleWindowInfo")
|
||||
procSetConsoleScreenBufferSize = k32.NewProc("SetConsoleScreenBufferSize")
|
||||
procSetConsoleTextAttribute = k32.NewProc("SetConsoleTextAttribute")
|
||||
procGetLargestConsoleWindowSize = k32.NewProc("GetLargestConsoleWindowSize")
|
||||
procMessageBeep = u32.NewProc("MessageBeep")
|
||||
)
|
||||
|
||||
const (
|
||||
@ -189,7 +191,7 @@ func (s *cScreen) Init() error {
|
||||
s.in = in
|
||||
out, e := syscall.Open("CONOUT$", syscall.O_RDWR, 0)
|
||||
if e != nil {
|
||||
syscall.Close(s.in)
|
||||
_ = syscall.Close(s.in)
|
||||
return e
|
||||
}
|
||||
s.out = out
|
||||
@ -224,15 +226,15 @@ func (s *cScreen) Init() error {
|
||||
s.resize()
|
||||
|
||||
s.fini = false
|
||||
s.setInMode(modeResizeEn | modeExtndFlg)
|
||||
s.setInMode(modeResizeEn | modeExtendFlg)
|
||||
|
||||
// 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)
|
||||
var omode uint32
|
||||
s.getOutMode(&omode)
|
||||
if omode&modeVtOutput == modeVtOutput {
|
||||
var om uint32
|
||||
s.getOutMode(&om)
|
||||
if om&modeVtOutput == modeVtOutput {
|
||||
s.vten = true
|
||||
} else {
|
||||
s.truecolor = false
|
||||
@ -268,9 +270,9 @@ func (s *cScreen) DisableMouse() {
|
||||
|
||||
func (s *cScreen) enableMouse(on bool) {
|
||||
if on {
|
||||
s.setInMode(modeResizeEn | modeMouseEn | modeExtndFlg)
|
||||
s.setInMode(modeResizeEn | modeMouseEn | modeExtendFlg)
|
||||
} else {
|
||||
s.setInMode(modeResizeEn | modeExtndFlg)
|
||||
s.setInMode(modeResizeEn | modeExtendFlg)
|
||||
}
|
||||
}
|
||||
|
||||
@ -292,7 +294,7 @@ func (s *cScreen) disengage() {
|
||||
}
|
||||
s.running = false
|
||||
stopQ := s.stopQ
|
||||
procSetEvent.Call(uintptr(s.cancelflag))
|
||||
_, _, _ = procSetEvent.Call(uintptr(s.cancelflag))
|
||||
close(stopQ)
|
||||
s.Unlock()
|
||||
|
||||
@ -307,7 +309,7 @@ func (s *cScreen) disengage() {
|
||||
s.clearScreen(StyleDefault, false)
|
||||
s.setCursorPos(0, 0, false)
|
||||
s.setCursorInfo(&s.ocursor)
|
||||
procSetConsoleTextAttribute.Call(
|
||||
_, _, _ = procSetConsoleTextAttribute.Call(
|
||||
uintptr(s.out),
|
||||
uintptr(s.mapStyle(StyleDefault)))
|
||||
}
|
||||
@ -421,7 +423,7 @@ type rect struct {
|
||||
|
||||
func (s *cScreen) emitVtString(vs string) {
|
||||
esc := utf16.Encode([]rune(vs))
|
||||
syscall.WriteConsole(s.out, &esc[0], uint32(len(esc)), nil, nil)
|
||||
_ = syscall.WriteConsole(s.out, &esc[0], uint32(len(esc)), nil, nil)
|
||||
}
|
||||
|
||||
func (s *cScreen) showCursor() {
|
||||
@ -487,8 +489,8 @@ const (
|
||||
keyEvent uint16 = 1
|
||||
mouseEvent uint16 = 2
|
||||
resizeEvent uint16 = 4
|
||||
menuEvent uint16 = 8 // don't use
|
||||
focusEvent uint16 = 16 // don't use
|
||||
// menuEvent uint16 = 8 // don't use
|
||||
// focusEvent uint16 = 16 // don't use
|
||||
)
|
||||
|
||||
type mouseRecord struct {
|
||||
@ -500,10 +502,10 @@ type mouseRecord struct {
|
||||
}
|
||||
|
||||
const (
|
||||
mouseDoubleClick uint32 = 0x2
|
||||
mouseHWheeled uint32 = 0x8
|
||||
mouseVWheeled uint32 = 0x4
|
||||
mouseMoved uint32 = 0x1
|
||||
mouseHWheeled uint32 = 0x8
|
||||
mouseVWheeled uint32 = 0x4
|
||||
// mouseDoubleClick uint32 = 0x2
|
||||
// mouseMoved uint32 = 0x1
|
||||
)
|
||||
|
||||
type resizeRecord struct {
|
||||
@ -590,6 +592,8 @@ var vkKeys = map[uint16]Key{
|
||||
vkInsert: KeyInsert,
|
||||
vkDelete: KeyDelete,
|
||||
vkHelp: KeyHelp,
|
||||
vkEscape: KeyEscape,
|
||||
vkSpace: ' ',
|
||||
vkF1: KeyF1,
|
||||
vkF2: KeyF2,
|
||||
vkF3: KeyF3,
|
||||
@ -806,11 +810,11 @@ func (s *cScreen) scanInput(stopQ chan struct{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// Windows console can display 8 characters, in either low or high intensity
|
||||
func (s *cScreen) Colors() int {
|
||||
if s.vten {
|
||||
return 1 << 24
|
||||
}
|
||||
// Windows console can display 8 colors, in either low or high intensity
|
||||
return 16
|
||||
}
|
||||
|
||||
@ -868,10 +872,10 @@ func (s *cScreen) mapStyle(style Style) uint16 {
|
||||
// views.
|
||||
if a&AttrReverse != 0 {
|
||||
attr = ba
|
||||
attr |= (fa << 4)
|
||||
attr |= fa << 4
|
||||
} else {
|
||||
attr = fa
|
||||
attr |= (ba << 4)
|
||||
attr |= ba << 4
|
||||
}
|
||||
if a&AttrBold != 0 {
|
||||
attr |= 0x8
|
||||
@ -895,19 +899,19 @@ func (s *cScreen) SetCell(x, y int, style Style, ch ...rune) {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *cScreen) SetContent(x, y int, mainc rune, combc []rune, style Style) {
|
||||
func (s *cScreen) SetContent(x, y int, primary rune, combining []rune, style Style) {
|
||||
s.Lock()
|
||||
if !s.fini {
|
||||
s.cells.SetContent(x, y, mainc, combc, style)
|
||||
s.cells.SetContent(x, y, primary, combining, style)
|
||||
}
|
||||
s.Unlock()
|
||||
}
|
||||
|
||||
func (s *cScreen) GetContent(x, y int) (rune, []rune, Style, int) {
|
||||
s.Lock()
|
||||
mainc, combc, style, width := s.cells.GetContent(x, y)
|
||||
primary, combining, style, width := s.cells.GetContent(x, y)
|
||||
s.Unlock()
|
||||
return mainc, combc, style, width
|
||||
return primary, combining, style, width
|
||||
}
|
||||
|
||||
func (s *cScreen) sendVtStyle(style Style) {
|
||||
@ -931,15 +935,15 @@ func (s *cScreen) sendVtStyle(style Style) {
|
||||
}
|
||||
if fg.IsRGB() {
|
||||
r, g, b := fg.RGB()
|
||||
fmt.Fprintf(esc, vtSetFgRGB, r, g, b)
|
||||
_, _ = fmt.Fprintf(esc, vtSetFgRGB, r, g, b)
|
||||
} else if fg.Valid() {
|
||||
fmt.Fprintf(esc, vtSetFg, fg&0xff)
|
||||
_, _ = fmt.Fprintf(esc, vtSetFg, fg&0xff)
|
||||
}
|
||||
if bg.IsRGB() {
|
||||
r, g, b := bg.RGB()
|
||||
fmt.Fprintf(esc, vtSetBgRGB, r, g, b)
|
||||
_, _ = fmt.Fprintf(esc, vtSetBgRGB, r, g, b)
|
||||
} else if bg.Valid() {
|
||||
fmt.Fprintf(esc, vtSetBg, bg&0xff)
|
||||
_, _ = fmt.Fprintf(esc, vtSetBg, bg&0xff)
|
||||
}
|
||||
s.emitVtString(esc.String())
|
||||
}
|
||||
@ -954,16 +958,16 @@ func (s *cScreen) writeString(x, y int, style Style, ch []uint16) {
|
||||
if s.vten {
|
||||
s.sendVtStyle(style)
|
||||
} else {
|
||||
procSetConsoleTextAttribute.Call(
|
||||
_, _, _ = procSetConsoleTextAttribute.Call(
|
||||
uintptr(s.out),
|
||||
uintptr(s.mapStyle(style)))
|
||||
}
|
||||
syscall.WriteConsole(s.out, &ch[0], uint32(len(ch)), nil, nil)
|
||||
_ = syscall.WriteConsole(s.out, &ch[0], uint32(len(ch)), nil, nil)
|
||||
}
|
||||
|
||||
func (s *cScreen) draw() {
|
||||
// allocate a scratch line bit enough for no combining chars.
|
||||
// if you have combining characters, you may pay for extra allocs.
|
||||
// if you have combining characters, you may pay for extra allocations.
|
||||
if s.clear {
|
||||
s.clearScreen(s.style, s.vten)
|
||||
s.clear = false
|
||||
@ -1053,19 +1057,19 @@ type consoleInfo struct {
|
||||
}
|
||||
|
||||
func (s *cScreen) getConsoleInfo(info *consoleInfo) {
|
||||
procGetConsoleScreenBufferInfo.Call(
|
||||
_, _, _ = procGetConsoleScreenBufferInfo.Call(
|
||||
uintptr(s.out),
|
||||
uintptr(unsafe.Pointer(info)))
|
||||
}
|
||||
|
||||
func (s *cScreen) getCursorInfo(info *cursorInfo) {
|
||||
procGetConsoleCursorInfo.Call(
|
||||
_, _, _ = procGetConsoleCursorInfo.Call(
|
||||
uintptr(s.out),
|
||||
uintptr(unsafe.Pointer(info)))
|
||||
}
|
||||
|
||||
func (s *cScreen) setCursorInfo(info *cursorInfo) {
|
||||
procSetConsoleCursorInfo.Call(
|
||||
_, _, _ = procSetConsoleCursorInfo.Call(
|
||||
uintptr(s.out),
|
||||
uintptr(unsafe.Pointer(info)))
|
||||
|
||||
@ -1076,14 +1080,14 @@ func (s *cScreen) setCursorPos(x, y int, vtEnable bool) {
|
||||
// Note that the string is Y first. Origin is 1,1.
|
||||
s.emitVtString(fmt.Sprintf(vtCursorPos, y+1, x+1))
|
||||
} else {
|
||||
procSetConsoleCursorPosition.Call(
|
||||
_, _, _ = procSetConsoleCursorPosition.Call(
|
||||
uintptr(s.out),
|
||||
coord{int16(x), int16(y)}.uintptr())
|
||||
}
|
||||
}
|
||||
|
||||
func (s *cScreen) setBufferSize(x, y int) {
|
||||
procSetConsoleScreenBufferSize.Call(
|
||||
_, _, _ = procSetConsoleScreenBufferSize.Call(
|
||||
uintptr(s.out),
|
||||
coord{int16(x), int16(y)}.uintptr())
|
||||
}
|
||||
@ -1096,6 +1100,37 @@ func (s *cScreen) Size() (int, int) {
|
||||
return w, h
|
||||
}
|
||||
|
||||
func (s *cScreen) SetSize(w, h int) {
|
||||
xy, _, _ := procGetLargestConsoleWindowSize.Call(uintptr(s.out))
|
||||
|
||||
// xy is little endian packed
|
||||
y := int(xy >> 16)
|
||||
x := int(xy & 0xffff)
|
||||
|
||||
if x == 0 || y == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// This is a hacky workaround for Windows Terminal.
|
||||
// Essentially Windows Terminal (Windows 11) does not support application
|
||||
// initiated resizing. To detect this, we look for an extremely large size
|
||||
// for the maximum width. If it is > 500, then this is almost certainly
|
||||
// Windows Terminal, and won't support this. (Note that the legacy console
|
||||
// does support application resizing.)
|
||||
if x >= 500 {
|
||||
return
|
||||
}
|
||||
|
||||
s.setBufferSize(x, y)
|
||||
r := rect{0, 0, int16(w - 1), int16(h - 1)}
|
||||
_, _, _ = procSetConsoleWindowInfo.Call(
|
||||
uintptr(s.out),
|
||||
uintptr(1),
|
||||
uintptr(unsafe.Pointer(&r)))
|
||||
|
||||
s.resize()
|
||||
}
|
||||
|
||||
func (s *cScreen) resize() {
|
||||
info := consoleInfo{}
|
||||
s.getConsoleInfo(&info)
|
||||
@ -1114,11 +1149,11 @@ func (s *cScreen) resize() {
|
||||
s.setBufferSize(w, h)
|
||||
|
||||
r := rect{0, 0, int16(w - 1), int16(h - 1)}
|
||||
procSetConsoleWindowInfo.Call(
|
||||
_, _, _ = procSetConsoleWindowInfo.Call(
|
||||
uintptr(s.out),
|
||||
uintptr(1),
|
||||
uintptr(unsafe.Pointer(&r)))
|
||||
s.PostEvent(NewEventResize(w, h))
|
||||
_ = s.PostEvent(NewEventResize(w, h))
|
||||
}
|
||||
|
||||
func (s *cScreen) Clear() {
|
||||
@ -1151,13 +1186,13 @@ func (s *cScreen) clearScreen(style Style, vtEnable bool) {
|
||||
scratch := uint32(0)
|
||||
count := uint32(x * y)
|
||||
|
||||
procFillConsoleOutputAttribute.Call(
|
||||
_, _, _ = procFillConsoleOutputAttribute.Call(
|
||||
uintptr(s.out),
|
||||
uintptr(attr),
|
||||
uintptr(count),
|
||||
pos.uintptr(),
|
||||
uintptr(unsafe.Pointer(&scratch)))
|
||||
procFillConsoleOutputCharacter.Call(
|
||||
_, _, _ = procFillConsoleOutputCharacter.Call(
|
||||
uintptr(s.out),
|
||||
uintptr(' '),
|
||||
uintptr(count),
|
||||
@ -1168,47 +1203,39 @@ func (s *cScreen) clearScreen(style Style, vtEnable bool) {
|
||||
|
||||
const (
|
||||
// Input modes
|
||||
modeExtndFlg uint32 = 0x0080
|
||||
modeMouseEn = 0x0010
|
||||
modeResizeEn = 0x0008
|
||||
modeCooked = 0x0001
|
||||
modeVtInput = 0x0200
|
||||
modeExtendFlg uint32 = 0x0080
|
||||
modeMouseEn = 0x0010
|
||||
modeResizeEn = 0x0008
|
||||
// modeCooked = 0x0001
|
||||
// modeVtInput = 0x0200
|
||||
|
||||
// Output modes
|
||||
modeCookedOut uint32 = 0x0001
|
||||
modeWrapEOL = 0x0002
|
||||
modeVtOutput = 0x0004
|
||||
modeNoAutoNL = 0x0008
|
||||
// modeWrapEOL = 0x0002
|
||||
)
|
||||
|
||||
func (s *cScreen) setInMode(mode uint32) error {
|
||||
rv, _, err := procSetConsoleMode.Call(
|
||||
func (s *cScreen) setInMode(mode uint32) {
|
||||
_, _, _ = procSetConsoleMode.Call(
|
||||
uintptr(s.in),
|
||||
uintptr(mode))
|
||||
if rv == 0 {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *cScreen) setOutMode(mode uint32) error {
|
||||
rv, _, err := procSetConsoleMode.Call(
|
||||
func (s *cScreen) setOutMode(mode uint32) {
|
||||
_, _, _ = procSetConsoleMode.Call(
|
||||
uintptr(s.out),
|
||||
uintptr(mode))
|
||||
if rv == 0 {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *cScreen) getInMode(v *uint32) {
|
||||
procGetConsoleMode.Call(
|
||||
_, _, _ = procGetConsoleMode.Call(
|
||||
uintptr(s.in),
|
||||
uintptr(unsafe.Pointer(v)))
|
||||
}
|
||||
|
||||
func (s *cScreen) getOutMode(v *uint32) {
|
||||
procGetConsoleMode.Call(
|
||||
_, _, _ = procGetConsoleMode.Call(
|
||||
uintptr(s.out),
|
||||
uintptr(unsafe.Pointer(v)))
|
||||
}
|
||||
@ -1221,15 +1248,15 @@ func (s *cScreen) SetStyle(style Style) {
|
||||
|
||||
// No fallback rune support, since we have Unicode. Yay!
|
||||
|
||||
func (s *cScreen) RegisterRuneFallback(r rune, subst string) {
|
||||
func (s *cScreen) RegisterRuneFallback(_ rune, _ string) {
|
||||
}
|
||||
|
||||
func (s *cScreen) UnregisterRuneFallback(r rune) {
|
||||
func (s *cScreen) UnregisterRuneFallback(_ rune) {
|
||||
}
|
||||
|
||||
func (s *cScreen) CanDisplay(r rune, checkFallbacks bool) bool {
|
||||
func (s *cScreen) CanDisplay(_ rune, _ bool) bool {
|
||||
// We presume we can display anything -- we're Unicode.
|
||||
// (Sadly this not precisely true. Combinings are especially
|
||||
// (Sadly this not precisely true. Combining characters are especially
|
||||
// poorly supported under Windows.)
|
||||
return true
|
||||
}
|
||||
|
2
vendor/github.com/gdamore/tcell/v2/paste.go
generated
vendored
2
vendor/github.com/gdamore/tcell/v2/paste.go
generated
vendored
@ -27,7 +27,7 @@ type EventPaste struct {
|
||||
t time.Time
|
||||
}
|
||||
|
||||
// When returns the time when this EventMouse was created.
|
||||
// When returns the time when this EventPaste was created.
|
||||
func (ev *EventPaste) When() time.Time {
|
||||
return ev.t
|
||||
}
|
||||
|
41
vendor/github.com/gdamore/tcell/v2/screen.go
generated
vendored
41
vendor/github.com/gdamore/tcell/v2/screen.go
generated
vendored
@ -1,4 +1,4 @@
|
||||
// Copyright 2021 The TCell Authors
|
||||
// Copyright 2022 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
@ -43,7 +43,7 @@ type Screen interface {
|
||||
// be displayed if Show() or Sync() is called. The width is the width
|
||||
// in screen cells; most often this will be 1, but some East Asian
|
||||
// characters require two cells.
|
||||
GetContent(x, y int) (mainc rune, combc []rune, style Style, width int)
|
||||
GetContent(x, y int) (primary rune, combining []rune, style Style, width int)
|
||||
|
||||
// SetContent sets the contents of the given cell location. If
|
||||
// the coordinates are out of range, then the operation is ignored.
|
||||
@ -52,13 +52,13 @@ type Screen interface {
|
||||
// that follows is a possible list of combining characters to append,
|
||||
// and will usually be nil (no combining characters.)
|
||||
//
|
||||
// The results are not displayd until Show() or Sync() is called.
|
||||
// The results are not displayed until Show() or Sync() is called.
|
||||
//
|
||||
// Note that wide (East Asian full width) runes occupy two cells,
|
||||
// and attempts to place character at next cell to the right will have
|
||||
// undefined effects. Wide runes that are printed in the
|
||||
// last column will be replaced with a single width space on output.
|
||||
SetContent(x int, y int, mainc rune, combc []rune, style Style)
|
||||
SetContent(x int, y int, primary rune, combining []rune, style Style)
|
||||
|
||||
// SetStyle sets the default style to use when clearing the screen
|
||||
// or when StyleDefault is specified. If it is also StyleDefault,
|
||||
@ -70,7 +70,7 @@ type Screen interface {
|
||||
// dimensions of the screen, the cursor will be hidden.
|
||||
ShowCursor(x int, y int)
|
||||
|
||||
// HideCursor is used to hide the cursor. Its an alias for
|
||||
// HideCursor is used to hide the cursor. It's an alias for
|
||||
// ShowCursor(-1, -1).sim
|
||||
HideCursor()
|
||||
|
||||
@ -139,7 +139,7 @@ type Screen interface {
|
||||
DisablePaste()
|
||||
|
||||
// HasMouse returns true if the terminal (apparently) supports a
|
||||
// mouse. Note that the a return value of true doesn't guarantee that
|
||||
// mouse. Note that the return value of true doesn't guarantee that
|
||||
// a mouse/pointing device is present; a false return definitely
|
||||
// indicates no mouse support is available.
|
||||
HasMouse() bool
|
||||
@ -161,8 +161,8 @@ type Screen interface {
|
||||
// internal model. This may be both expensive and visually jarring,
|
||||
// so it should only be used when believed to actually be necessary.
|
||||
//
|
||||
// Typically this is called as a result of a user-requested redraw
|
||||
// (e.g. to clear up on screen corruption caused by some other program),
|
||||
// Typically, this is called as a result of a user-requested redraw
|
||||
// (e.g. to clear up on-screen corruption caused by some other program),
|
||||
// or during a resize event.
|
||||
Sync()
|
||||
|
||||
@ -178,13 +178,13 @@ type Screen interface {
|
||||
// o as a fallback for ø. This should be done cautiously for
|
||||
// characters that might be displayed ordinarily in language
|
||||
// specific text -- characters that could change the meaning of
|
||||
// of written text would be dangerous. The intention here is to
|
||||
// written text would be dangerous. The intention here is to
|
||||
// facilitate fallback characters in pseudo-graphical applications.
|
||||
//
|
||||
// If the terminal has fallbacks already in place via an alternate
|
||||
// character set, those are used in preference. Also, standard
|
||||
// fallbacks for graphical characters in the ACSC terminfo string
|
||||
// are registered implicitly.
|
||||
// fallbacks for graphical characters in the alternate character set
|
||||
// terminfo string are registered implicitly.
|
||||
//
|
||||
// The display string should be the same width as original rune.
|
||||
// This makes it possible to register two character replacements
|
||||
@ -203,7 +203,7 @@ type Screen interface {
|
||||
UnregisterRuneFallback(r rune)
|
||||
|
||||
// CanDisplay returns true if the given rune can be displayed on
|
||||
// this screen. Note that this is a best guess effort -- whether
|
||||
// this screen. Note that this is a best-guess effort -- whether
|
||||
// your fonts support the character or not may be questionable.
|
||||
// Mostly this is for folks who work outside of Unicode.
|
||||
//
|
||||
@ -213,7 +213,7 @@ type Screen interface {
|
||||
// one that is visually indistinguishable from the one requested.
|
||||
CanDisplay(r rune, checkFallbacks bool) bool
|
||||
|
||||
// Resize does nothing, since its generally not possible to
|
||||
// Resize does nothing, since it's generally not possible to
|
||||
// ask a screen to resize, but it allows the Screen to implement
|
||||
// the View interface.
|
||||
Resize(int, int, int, int)
|
||||
@ -239,6 +239,15 @@ type Screen interface {
|
||||
// Beep attempts to sound an OS-dependent audible alert and returns an error
|
||||
// when unsuccessful.
|
||||
Beep() error
|
||||
|
||||
// SetSize attempts to resize the window. It also invalidates the cells and
|
||||
// calls the resize function. Note that if the window size is changed, it will
|
||||
// not be restored upon application exit.
|
||||
//
|
||||
// Many terminals cannot support this. Perversely, the "modern" Windows Terminal
|
||||
// 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)
|
||||
}
|
||||
|
||||
// NewScreen returns a default Screen suitable for the user's terminal
|
||||
@ -255,7 +264,7 @@ func NewScreen() (Screen, error) {
|
||||
}
|
||||
|
||||
// MouseFlags are options to modify the handling of mouse events.
|
||||
// Actual events can be or'd together.
|
||||
// Actual events can be ORed together.
|
||||
type MouseFlags int
|
||||
|
||||
const (
|
||||
@ -265,7 +274,7 @@ const (
|
||||
)
|
||||
|
||||
// CursorStyle represents a given cursor style, which can include the shape and
|
||||
// whether the cursor blinks or is solid. Support for changing these is not universal.
|
||||
// whether the cursor blinks or is solid. Support for changing this is not universal.
|
||||
type CursorStyle int
|
||||
|
||||
const (
|
||||
@ -276,4 +285,4 @@ const (
|
||||
CursorStyleSteadyUnderline
|
||||
CursorStyleBlinkingBar
|
||||
CursorStyleSteadyBar
|
||||
)
|
||||
)
|
||||
|
9
vendor/github.com/gdamore/tcell/v2/simulation.go
generated
vendored
9
vendor/github.com/gdamore/tcell/v2/simulation.go
generated
vendored
@ -1,4 +1,4 @@
|
||||
// Copyright 2021 The TCell Authors
|
||||
// Copyright 2022 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
@ -49,13 +49,6 @@ type SimulationScreen interface {
|
||||
// InjectMouse injects a mouse event.
|
||||
InjectMouse(x, y int, buttons ButtonMask, mod ModMask)
|
||||
|
||||
// SetSize resizes the underlying physical screen. It also causes
|
||||
// a resize event to be injected during the next Show() or Sync().
|
||||
// A new physical contents array will be allocated (with data from
|
||||
// the old copied), so any prior value obtained with GetContents
|
||||
// won't be used anymore
|
||||
SetSize(width, height int)
|
||||
|
||||
// GetContents returns screen contents as an array of
|
||||
// cells, along with the physical width & height. Note that the
|
||||
// physical contents will be used until the next time SetSize()
|
||||
|
22
vendor/github.com/gdamore/tcell/v2/style.go
generated
vendored
22
vendor/github.com/gdamore/tcell/v2/style.go
generated
vendored
@ -1,4 +1,4 @@
|
||||
// Copyright 2020 The TCell Authors
|
||||
// Copyright 2022 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
@ -26,6 +26,7 @@ type Style struct {
|
||||
fg Color
|
||||
bg Color
|
||||
attrs AttrMask
|
||||
url string
|
||||
}
|
||||
|
||||
// StyleDefault represents a default style, based upon the context.
|
||||
@ -42,6 +43,7 @@ func (s Style) Foreground(c Color) Style {
|
||||
fg: c,
|
||||
bg: s.bg,
|
||||
attrs: s.attrs,
|
||||
url: s.url,
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,11 +54,12 @@ func (s Style) Background(c Color) Style {
|
||||
fg: s.fg,
|
||||
bg: c,
|
||||
attrs: s.attrs,
|
||||
url: s.url,
|
||||
}
|
||||
}
|
||||
|
||||
// Decompose breaks a style up, returning the foreground, background,
|
||||
// and other attributes.
|
||||
// and other attributes. The URL if set is not included.
|
||||
func (s Style) Decompose() (fg Color, bg Color, attr AttrMask) {
|
||||
return s.fg, s.bg, s.attrs
|
||||
}
|
||||
@ -67,12 +70,14 @@ func (s Style) setAttrs(attrs AttrMask, on bool) Style {
|
||||
fg: s.fg,
|
||||
bg: s.bg,
|
||||
attrs: s.attrs | attrs,
|
||||
url: s.url,
|
||||
}
|
||||
}
|
||||
return Style{
|
||||
fg: s.fg,
|
||||
bg: s.bg,
|
||||
attrs: s.attrs &^ attrs,
|
||||
url: s.url,
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,5 +138,18 @@ func (s Style) Attributes(attrs AttrMask) Style {
|
||||
fg: s.fg,
|
||||
bg: s.bg,
|
||||
attrs: attrs,
|
||||
url: s.url,
|
||||
}
|
||||
}
|
||||
|
||||
// Url returns a style with the Url set. If the provided Url is not empty,
|
||||
// and the terminal supports it, text will typically be marked up as a clickable
|
||||
// link to that Url. If the Url is empty, then this mode is turned off.
|
||||
func (s Style) Url(url string) Style {
|
||||
return Style{
|
||||
fg: s.fg,
|
||||
bg: s.bg,
|
||||
attrs: s.attrs,
|
||||
url: url,
|
||||
}
|
||||
}
|
||||
|
188
vendor/github.com/gdamore/tcell/v2/terminfo/terminfo.go
generated
vendored
188
vendor/github.com/gdamore/tcell/v2/terminfo/terminfo.go
generated
vendored
@ -1,4 +1,4 @@
|
||||
// Copyright 2021 The TCell Authors
|
||||
// Copyright 2022 The TCell Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use file except in compliance with the License.
|
||||
@ -227,6 +227,9 @@ type Terminfo struct {
|
||||
CursorSteadyUnderline string
|
||||
CursorBlinkingBar string
|
||||
CursorSteadyBar string
|
||||
EnterUrl string
|
||||
ExitUrl string
|
||||
SetWindowSize string
|
||||
}
|
||||
|
||||
const (
|
||||
@ -234,93 +237,75 @@ const (
|
||||
ModifiersXTerm = 1
|
||||
)
|
||||
|
||||
type stackElem struct {
|
||||
s string
|
||||
i int
|
||||
isStr bool
|
||||
isInt bool
|
||||
type stack []interface{}
|
||||
|
||||
func (st stack) Push(v interface{}) stack {
|
||||
return append(st, v)
|
||||
}
|
||||
|
||||
type stack []stackElem
|
||||
|
||||
func (st stack) Push(v string) stack {
|
||||
e := stackElem{
|
||||
s: v,
|
||||
isStr: true,
|
||||
}
|
||||
return append(st, e)
|
||||
}
|
||||
|
||||
func (st stack) Pop() (string, stack) {
|
||||
v := ""
|
||||
func (st stack) Pop() (interface{}, stack) {
|
||||
if len(st) > 0 {
|
||||
e := st[len(st)-1]
|
||||
st = st[:len(st)-1]
|
||||
if e.isStr {
|
||||
v = e.s
|
||||
} else {
|
||||
v = strconv.Itoa(e.i)
|
||||
}
|
||||
return e, st[:len(st)-1]
|
||||
}
|
||||
return v, st
|
||||
return 0, st
|
||||
}
|
||||
|
||||
func (st stack) PopString() (string, stack) {
|
||||
if len(st) > 0 {
|
||||
e := st[len(st)-1]
|
||||
var s string
|
||||
switch v := e.(type) {
|
||||
case int:
|
||||
s = strconv.Itoa(v)
|
||||
case bool:
|
||||
s = strconv.FormatBool(v)
|
||||
case string:
|
||||
s = v
|
||||
}
|
||||
return s, st[:len(st)-1]
|
||||
}
|
||||
return "", st
|
||||
|
||||
}
|
||||
func (st stack) PopInt() (int, stack) {
|
||||
if len(st) > 0 {
|
||||
e := st[len(st)-1]
|
||||
st = st[:len(st)-1]
|
||||
if e.isInt {
|
||||
return e.i, st
|
||||
} else if e.isStr {
|
||||
// If the string that was pushed was the representation
|
||||
// of a number e.g. '123', then return the number. If the
|
||||
// conversion doesn't work, assume the string pushed was
|
||||
// intended to return, as an int, the ascii representation
|
||||
// of the (one and only) character.
|
||||
i, err := strconv.Atoi(e.s)
|
||||
if err == nil {
|
||||
return i, st
|
||||
} else if len(e.s) >= 1 {
|
||||
return int(e.s[0]), st
|
||||
var i int
|
||||
switch v := e.(type) {
|
||||
case int:
|
||||
i = v
|
||||
case bool:
|
||||
if v {
|
||||
i = 1
|
||||
} else {
|
||||
i = 0
|
||||
}
|
||||
case string:
|
||||
i, _ = strconv.Atoi(v)
|
||||
}
|
||||
return i, st[:len(st)-1]
|
||||
}
|
||||
return 0, st
|
||||
}
|
||||
|
||||
func (st stack) PopBool() (bool, stack) {
|
||||
var b bool
|
||||
if len(st) > 0 {
|
||||
e := st[len(st)-1]
|
||||
st = st[:len(st)-1]
|
||||
if e.isStr {
|
||||
if e.s == "1" {
|
||||
return true, st
|
||||
}
|
||||
return false, st
|
||||
} else if e.i == 1 {
|
||||
return true, st
|
||||
} else {
|
||||
return false, st
|
||||
switch v := e.(type) {
|
||||
case int:
|
||||
b = v != 0
|
||||
case bool:
|
||||
b = v
|
||||
case string:
|
||||
b = v != "" && v != "false"
|
||||
}
|
||||
return b, st[:len(st)-1]
|
||||
}
|
||||
return false, st
|
||||
}
|
||||
|
||||
func (st stack) PushInt(i int) stack {
|
||||
e := stackElem{
|
||||
i: i,
|
||||
isInt: true,
|
||||
}
|
||||
return append(st, e)
|
||||
}
|
||||
|
||||
func (st stack) PushBool(i bool) stack {
|
||||
if i {
|
||||
return st.PushInt(1)
|
||||
}
|
||||
return st.PushInt(0)
|
||||
}
|
||||
|
||||
// static vars
|
||||
var svars [26]string
|
||||
|
||||
@ -372,13 +357,13 @@ var pb = ¶msBuffer{}
|
||||
// TParm takes a terminfo parameterized string, such as setaf or cup, and
|
||||
// evaluates the string, and returns the result with the parameter
|
||||
// applied.
|
||||
func (t *Terminfo) TParm(s string, p ...int) string {
|
||||
func (t *Terminfo) TParm(s string, p ...interface{}) string {
|
||||
var stk stack
|
||||
var a, b string
|
||||
var ai, bi int
|
||||
var ab bool
|
||||
var dvars [26]string
|
||||
var params [9]int
|
||||
var params [9]interface{}
|
||||
|
||||
pb.Start(s)
|
||||
|
||||
@ -413,14 +398,18 @@ func (t *Terminfo) TParm(s string, p ...int) string {
|
||||
pb.PutCh(ch)
|
||||
|
||||
case 'i': // increment both parameters (ANSI cup support)
|
||||
params[0]++
|
||||
params[1]++
|
||||
if i, ok := params[0].(int); ok {
|
||||
params[0] = i + 1
|
||||
}
|
||||
if i, ok := params[1].(int); ok {
|
||||
params[1] = i + 1
|
||||
}
|
||||
|
||||
case 'c', 's':
|
||||
// NB: these, and 'd' below are special cased for
|
||||
// efficiency. They could be handled by the richer
|
||||
// format support below, less efficiently.
|
||||
a, stk = stk.Pop()
|
||||
a, stk = stk.PopString()
|
||||
pb.PutString(a)
|
||||
|
||||
case 'd':
|
||||
@ -431,7 +420,7 @@ func (t *Terminfo) TParm(s string, p ...int) string {
|
||||
// This is pretty suboptimal, but this is rarely used.
|
||||
// None of the mainstream terminals use any of this,
|
||||
// and it would surprise me if this code is ever
|
||||
// executed outside of test cases.
|
||||
// executed outside test cases.
|
||||
f := "%"
|
||||
if ch == ':' {
|
||||
ch, _ = pb.NextCh()
|
||||
@ -450,7 +439,7 @@ func (t *Terminfo) TParm(s string, p ...int) string {
|
||||
ai, stk = stk.PopInt()
|
||||
pb.PutString(fmt.Sprintf(f, ai))
|
||||
case 'c', 's':
|
||||
a, stk = stk.Pop()
|
||||
a, stk = stk.PopString()
|
||||
pb.PutString(fmt.Sprintf(f, a))
|
||||
}
|
||||
|
||||
@ -458,17 +447,17 @@ func (t *Terminfo) TParm(s string, p ...int) string {
|
||||
ch, _ = pb.NextCh()
|
||||
ai = int(ch - '1')
|
||||
if ai >= 0 && ai < len(params) {
|
||||
stk = stk.PushInt(params[ai])
|
||||
stk = stk.Push(params[ai])
|
||||
} else {
|
||||
stk = stk.PushInt(0)
|
||||
stk = stk.Push(0)
|
||||
}
|
||||
|
||||
case 'P': // pop & store variable
|
||||
ch, _ = pb.NextCh()
|
||||
if ch >= 'A' && ch <= 'Z' {
|
||||
svars[int(ch-'A')], stk = stk.Pop()
|
||||
svars[int(ch-'A')], stk = stk.PopString()
|
||||
} else if ch >= 'a' && ch <= 'z' {
|
||||
dvars[int(ch-'a')], stk = stk.Pop()
|
||||
dvars[int(ch-'a')], stk = stk.PopString()
|
||||
}
|
||||
|
||||
case 'g': // recall & push variable
|
||||
@ -481,7 +470,7 @@ func (t *Terminfo) TParm(s string, p ...int) string {
|
||||
|
||||
case '\'': // push(char)
|
||||
ch, _ = pb.NextCh()
|
||||
pb.NextCh() // must be ' but we don't check
|
||||
_, _ = pb.NextCh() // must be ' but we don't check
|
||||
stk = stk.Push(string(ch))
|
||||
|
||||
case '{': // push(int)
|
||||
@ -493,82 +482,82 @@ func (t *Terminfo) TParm(s string, p ...int) string {
|
||||
ch, _ = pb.NextCh()
|
||||
}
|
||||
// ch must be '}' but no verification
|
||||
stk = stk.PushInt(ai)
|
||||
stk = stk.Push(ai)
|
||||
|
||||
case 'l': // push(strlen(pop))
|
||||
a, stk = stk.Pop()
|
||||
stk = stk.PushInt(len(a))
|
||||
a, stk = stk.PopString()
|
||||
stk = stk.Push(len(a))
|
||||
|
||||
case '+':
|
||||
bi, stk = stk.PopInt()
|
||||
ai, stk = stk.PopInt()
|
||||
stk = stk.PushInt(ai + bi)
|
||||
stk = stk.Push(ai + bi)
|
||||
|
||||
case '-':
|
||||
bi, stk = stk.PopInt()
|
||||
ai, stk = stk.PopInt()
|
||||
stk = stk.PushInt(ai - bi)
|
||||
stk = stk.Push(ai - bi)
|
||||
|
||||
case '*':
|
||||
bi, stk = stk.PopInt()
|
||||
ai, stk = stk.PopInt()
|
||||
stk = stk.PushInt(ai * bi)
|
||||
stk = stk.Push(ai * bi)
|
||||
|
||||
case '/':
|
||||
bi, stk = stk.PopInt()
|
||||
ai, stk = stk.PopInt()
|
||||
if bi != 0 {
|
||||
stk = stk.PushInt(ai / bi)
|
||||
stk = stk.Push(ai / bi)
|
||||
} else {
|
||||
stk = stk.PushInt(0)
|
||||
stk = stk.Push(0)
|
||||
}
|
||||
|
||||
case 'm': // push(pop mod pop)
|
||||
bi, stk = stk.PopInt()
|
||||
ai, stk = stk.PopInt()
|
||||
if bi != 0 {
|
||||
stk = stk.PushInt(ai % bi)
|
||||
stk = stk.Push(ai % bi)
|
||||
} else {
|
||||
stk = stk.PushInt(0)
|
||||
stk = stk.Push(0)
|
||||
}
|
||||
|
||||
case '&': // AND
|
||||
bi, stk = stk.PopInt()
|
||||
ai, stk = stk.PopInt()
|
||||
stk = stk.PushInt(ai & bi)
|
||||
stk = stk.Push(ai & bi)
|
||||
|
||||
case '|': // OR
|
||||
bi, stk = stk.PopInt()
|
||||
ai, stk = stk.PopInt()
|
||||
stk = stk.PushInt(ai | bi)
|
||||
stk = stk.Push(ai | bi)
|
||||
|
||||
case '^': // XOR
|
||||
bi, stk = stk.PopInt()
|
||||
ai, stk = stk.PopInt()
|
||||
stk = stk.PushInt(ai ^ bi)
|
||||
stk = stk.Push(ai ^ bi)
|
||||
|
||||
case '~': // bit complement
|
||||
ai, stk = stk.PopInt()
|
||||
stk = stk.PushInt(ai ^ -1)
|
||||
stk = stk.Push(ai ^ -1)
|
||||
|
||||
case '!': // logical NOT
|
||||
ai, stk = stk.PopInt()
|
||||
stk = stk.PushBool(ai != 0)
|
||||
stk = stk.Push(ai != 0)
|
||||
|
||||
case '=': // numeric compare or string compare
|
||||
b, stk = stk.Pop()
|
||||
a, stk = stk.Pop()
|
||||
stk = stk.PushBool(a == b)
|
||||
b, stk = stk.PopString()
|
||||
a, stk = stk.PopString()
|
||||
stk = stk.Push(a == b)
|
||||
|
||||
case '>': // greater than, numeric
|
||||
bi, stk = stk.PopInt()
|
||||
ai, stk = stk.PopInt()
|
||||
stk = stk.PushBool(ai > bi)
|
||||
stk = stk.Push(ai > bi)
|
||||
|
||||
case '<': // less than, numeric
|
||||
bi, stk = stk.PopInt()
|
||||
ai, stk = stk.PopInt()
|
||||
stk = stk.PushBool(ai < bi)
|
||||
stk = stk.Push(ai < bi)
|
||||
|
||||
case '?': // start conditional
|
||||
|
||||
@ -650,15 +639,15 @@ func (t *Terminfo) TPuts(w io.Writer, s string) {
|
||||
beg := strings.Index(s, "$<")
|
||||
if beg < 0 {
|
||||
// Most strings don't need padding, which is good news!
|
||||
io.WriteString(w, s)
|
||||
_, _ = io.WriteString(w, s)
|
||||
return
|
||||
}
|
||||
io.WriteString(w, s[:beg])
|
||||
_, _ = io.WriteString(w, s[:beg])
|
||||
s = s[beg+2:]
|
||||
end := strings.Index(s, ">")
|
||||
if end < 0 {
|
||||
// unterminated.. just emit bytes unadulterated
|
||||
io.WriteString(w, "$<"+s)
|
||||
_, _ = io.WriteString(w, "$<"+s)
|
||||
return
|
||||
}
|
||||
val := s[:end]
|
||||
@ -729,7 +718,6 @@ func (t *Terminfo) TColor(fi, bi int) string {
|
||||
var (
|
||||
dblock sync.Mutex
|
||||
terminfos = make(map[string]*Terminfo)
|
||||
aliases = make(map[string]string)
|
||||
)
|
||||
|
||||
// AddTerminfo can be called to register a new Terminfo entry.
|
||||
|
71
vendor/github.com/gdamore/tcell/v2/tscreen.go
generated
vendored
71
vendor/github.com/gdamore/tcell/v2/tscreen.go
generated
vendored
@ -148,6 +148,9 @@ type tScreen struct {
|
||||
finiOnce sync.Once
|
||||
enablePaste string
|
||||
disablePaste string
|
||||
enterUrl string
|
||||
exitUrl string
|
||||
setWinSize string
|
||||
cursorStyles map[CursorStyle]string
|
||||
cursorStyle CursorStyle
|
||||
saved *term.State
|
||||
@ -334,6 +337,26 @@ func (t *tScreen) prepareBracketedPaste() {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *tScreen) prepareExtendedOSC() {
|
||||
// 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.
|
||||
// Again, we condition this based on mouse capabilities.
|
||||
if t.ti.EnterUrl != "" {
|
||||
t.enterUrl = t.ti.EnterUrl
|
||||
t.exitUrl = t.ti.ExitUrl
|
||||
} else if t.ti.Mouse != "" {
|
||||
t.enterUrl = "\x1b]8;;%p1%s\x1b\\"
|
||||
t.exitUrl = "\x1b]8;;\x1b\\"
|
||||
}
|
||||
|
||||
if t.ti.SetWindowSize != "" {
|
||||
t.setWinSize = t.ti.SetWindowSize
|
||||
} else if t.ti.Mouse != "" {
|
||||
t.setWinSize = "\x1b[8;%p1%p2%d;%dt"
|
||||
}
|
||||
}
|
||||
|
||||
func (t *tScreen) prepareCursorStyles() {
|
||||
// Another workaround for lack of reporting in terminfo.
|
||||
// We assume if the terminal has a mouse entry, that it
|
||||
@ -502,6 +525,7 @@ func (t *tScreen) prepareKeys() {
|
||||
t.prepareXtermModifiers()
|
||||
t.prepareBracketedPaste()
|
||||
t.prepareCursorStyles()
|
||||
t.prepareExtendedOSC()
|
||||
|
||||
outer:
|
||||
// Add key mappings for control keys.
|
||||
@ -623,11 +647,27 @@ func (t *tScreen) encodeRune(r rune, buf []byte) []byte {
|
||||
return buf
|
||||
}
|
||||
|
||||
func (t *tScreen) sendFgBg(fg Color, bg Color) {
|
||||
func (t *tScreen) sendFgBg(fg Color, bg Color, attr AttrMask) AttrMask {
|
||||
ti := t.ti
|
||||
if ti.Colors == 0 {
|
||||
return
|
||||
// foreground vs background, we calculate luminance
|
||||
// and possibly do a reverse video
|
||||
if !fg.Valid() {
|
||||
return attr
|
||||
}
|
||||
v, ok := t.colors[fg]
|
||||
if !ok {
|
||||
v = FindColor(fg, []Color{ColorBlack, ColorWhite})
|
||||
t.colors[fg] = v
|
||||
}
|
||||
switch v {
|
||||
case ColorWhite:
|
||||
return attr
|
||||
case ColorBlack:
|
||||
return attr ^ AttrReverse
|
||||
}
|
||||
}
|
||||
|
||||
if fg == ColorReset || bg == ColorReset {
|
||||
t.TPuts(ti.ResetFgBg)
|
||||
}
|
||||
@ -638,7 +678,7 @@ func (t *tScreen) sendFgBg(fg Color, bg Color) {
|
||||
t.TPuts(ti.TParm(ti.SetFgBgRGB,
|
||||
int(r1), int(g1), int(b1),
|
||||
int(r2), int(g2), int(b2)))
|
||||
return
|
||||
return attr
|
||||
}
|
||||
|
||||
if fg.IsRGB() && ti.SetFgRGB != "" {
|
||||
@ -685,6 +725,7 @@ func (t *tScreen) sendFgBg(fg Color, bg Color) {
|
||||
t.TPuts(ti.TParm(ti.SetBg, int(bg&0xff)))
|
||||
}
|
||||
}
|
||||
return attr
|
||||
}
|
||||
|
||||
func (t *tScreen) drawCell(x, y int) int {
|
||||
@ -727,7 +768,7 @@ func (t *tScreen) drawCell(x, y int) int {
|
||||
|
||||
t.TPuts(ti.AttrOff)
|
||||
|
||||
t.sendFgBg(fg, bg)
|
||||
attrs = t.sendFgBg(fg, bg, attrs)
|
||||
if attrs&AttrBold != 0 {
|
||||
t.TPuts(ti.Bold)
|
||||
}
|
||||
@ -749,8 +790,19 @@ func (t *tScreen) drawCell(x, y int) int {
|
||||
if attrs&AttrStrikeThrough != 0 {
|
||||
t.TPuts(ti.StrikeThrough)
|
||||
}
|
||||
|
||||
// URL string can be long, so don't send it unless we really need to
|
||||
if t.enterUrl != "" && t.curstyle != style {
|
||||
if style.url != "" {
|
||||
t.TPuts(ti.TParm(t.enterUrl, style.url))
|
||||
} else {
|
||||
t.TPuts(t.exitUrl)
|
||||
}
|
||||
}
|
||||
|
||||
t.curstyle = style
|
||||
}
|
||||
|
||||
// now emit runes - taking care to not overrun width with a
|
||||
// wide character, and to ensure that we emit exactly one regular
|
||||
// character followed up by any residual combing characters
|
||||
@ -859,8 +911,9 @@ func (t *tScreen) Show() {
|
||||
|
||||
func (t *tScreen) clearScreen() {
|
||||
t.TPuts(t.ti.AttrOff)
|
||||
t.TPuts(t.exitUrl)
|
||||
fg, bg, _ := t.style.Decompose()
|
||||
t.sendFgBg(fg, bg)
|
||||
_ = t.sendFgBg(fg, bg, AttrNone)
|
||||
t.TPuts(t.ti.Clear)
|
||||
t.clear = false
|
||||
}
|
||||
@ -1716,6 +1769,14 @@ func (t *tScreen) HasKey(k Key) bool {
|
||||
return t.keyexist[k]
|
||||
}
|
||||
|
||||
func (t *tScreen) SetSize(w, h int) {
|
||||
if t.setWinSize != "" {
|
||||
t.TPuts(t.ti.TParm(t.setWinSize, w, h))
|
||||
}
|
||||
t.cells.Invalidate()
|
||||
t.resize()
|
||||
}
|
||||
|
||||
func (t *tScreen) Resize(int, int, int, int) {}
|
||||
|
||||
func (t *tScreen) Suspend() error {
|
||||
|
Reference in New Issue
Block a user