mirror of
https://github.com/jesseduffield/lazygit.git
synced 2024-11-30 09:16:47 +02:00
no more termbox
This commit is contained in:
parent
1149dea4b2
commit
c0cad91cb6
4
vendor/github.com/jesseduffield/termbox-go/AUTHORS
generated
vendored
4
vendor/github.com/jesseduffield/termbox-go/AUTHORS
generated
vendored
@ -1,4 +0,0 @@
|
||||
# Please keep this file sorted.
|
||||
|
||||
Georg Reinke <guelfey@googlemail.com>
|
||||
nsf <no.smile.face@gmail.com>
|
19
vendor/github.com/jesseduffield/termbox-go/LICENSE
generated
vendored
19
vendor/github.com/jesseduffield/termbox-go/LICENSE
generated
vendored
@ -1,19 +0,0 @@
|
||||
Copyright (C) 2012 termbox-go authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
44
vendor/github.com/jesseduffield/termbox-go/README.md
generated
vendored
44
vendor/github.com/jesseduffield/termbox-go/README.md
generated
vendored
@ -1,44 +0,0 @@
|
||||
[![GoDoc](https://godoc.org/github.com/nsf/termbox-go?status.svg)](http://godoc.org/github.com/nsf/termbox-go)
|
||||
|
||||
## Termbox
|
||||
Termbox is a library that provides a minimalistic API which allows the programmer to write text-based user interfaces. The library is crossplatform and has both terminal-based implementations on *nix operating systems and a winapi console based implementation for windows operating systems. The basic idea is an abstraction of the greatest common subset of features available on all major terminals and other terminal-like APIs in a minimalistic fashion. Small API means it is easy to implement, test, maintain and learn it, that's what makes the termbox a distinct library in its area.
|
||||
|
||||
### Installation
|
||||
Install and update this go package with `go get -u github.com/nsf/termbox-go`
|
||||
|
||||
### Examples
|
||||
For examples of what can be done take a look at demos in the _demos directory. You can try them with go run: `go run _demos/keyboard.go`
|
||||
|
||||
There are also some interesting projects using termbox-go:
|
||||
- [godit](https://github.com/nsf/godit) is an emacsish lightweight text editor written using termbox.
|
||||
- [gotetris](https://github.com/jjinux/gotetris) is an implementation of Tetris.
|
||||
- [sokoban-go](https://github.com/rn2dy/sokoban-go) is an implementation of sokoban game.
|
||||
- [hecate](https://github.com/evanmiller/hecate) is a hex editor designed by Satan.
|
||||
- [httopd](https://github.com/verdverm/httopd) is top for httpd logs.
|
||||
- [mop](https://github.com/mop-tracker/mop) is stock market tracker for hackers.
|
||||
- [termui](https://github.com/gizak/termui) is a terminal dashboard.
|
||||
- [termloop](https://github.com/JoelOtter/termloop) is a terminal game engine.
|
||||
- [xterm-color-chart](https://github.com/kutuluk/xterm-color-chart) is a XTerm 256 color chart.
|
||||
- [gocui](https://github.com/jroimartin/gocui) is a minimalist Go library aimed at creating console user interfaces.
|
||||
- [dry](https://github.com/moncho/dry) is an interactive cli to manage Docker containers.
|
||||
- [pxl](https://github.com/ichinaski/pxl) displays images in the terminal.
|
||||
- [snake-game](https://github.com/DyegoCosta/snake-game) is an implementation of the Snake game.
|
||||
- [gone](https://github.com/guillaumebreton/gone) is a CLI pomodoro® timer.
|
||||
- [Spoof.go](https://github.com/sabey/spoofgo) controllable movement spoofing from the cli
|
||||
- [lf](https://github.com/gokcehan/lf) is a terminal file manager
|
||||
- [rat](https://github.com/ericfreese/rat) lets you compose shell commands to build terminal applications.
|
||||
- [httplab](https://github.com/gchaincl/httplab) An interactive web server.
|
||||
- [tetris](https://github.com/MichaelS11/tetris) Go Tetris with AI option
|
||||
- [wot](https://github.com/kyu-suke/wot) Wait time during command is completed.
|
||||
- [2048-go](https://github.com/1984weed/2048-go) is 2048 in Go
|
||||
- [jv](https://github.com/maxzender/jv) helps you view JSON on the command-line.
|
||||
- [pinger](https://github.com/hirose31/pinger) helps you to monitor numerous hosts using ICMP ECHO_REQUEST.
|
||||
- [vixl44](https://github.com/sebashwa/vixl44) lets you create pixel art inside your terminal using vim movements
|
||||
- [zterm](https://github.com/varunrau/zterm) is a typing game inspired by http://zty.pe/
|
||||
- [gotypist](https://github.com/pb-/gotypist) is a fun touch-typing tutor following Steve Yegge's method.
|
||||
- [cointop](https://github.com/miguelmota/cointop) is an interactive terminal based UI application for tracking cryptocurrencies.
|
||||
- [pexpo](https://github.com/nnao45/pexpo) is a terminal sending ping tool written in Go.
|
||||
- [jid](https://github.com/simeji/jid) is an interactive JSON drill down tool using filtering queries like jq.
|
||||
|
||||
### API reference
|
||||
[godoc.org/github.com/nsf/termbox-go](http://godoc.org/github.com/nsf/termbox-go)
|
517
vendor/github.com/jesseduffield/termbox-go/api.go
generated
vendored
517
vendor/github.com/jesseduffield/termbox-go/api.go
generated
vendored
@ -1,517 +0,0 @@
|
||||
// +build !windows
|
||||
|
||||
package termbox
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/mattn/go-runewidth"
|
||||
)
|
||||
|
||||
// public API
|
||||
|
||||
// Initializes termbox library. This function should be called before any other functions.
|
||||
// After successful initialization, the library must be finalized using 'Close' function.
|
||||
//
|
||||
// Example usage:
|
||||
// err := termbox.Init()
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// defer termbox.Close()
|
||||
func Init() error {
|
||||
quitPolling = make(chan int)
|
||||
|
||||
var err error
|
||||
|
||||
if runtime.GOOS == "openbsd" || runtime.GOOS == "freebsd" {
|
||||
out, err = os.OpenFile("/dev/tty", os.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
in = int(out.Fd())
|
||||
} else {
|
||||
out, err = os.OpenFile("/dev/tty", os.O_WRONLY, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
in, err = syscall.Open("/dev/tty", syscall.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = setup_term()
|
||||
if err != nil {
|
||||
return fmt.Errorf("termbox: error while reading terminfo data: %v", err)
|
||||
}
|
||||
|
||||
signal.Notify(sigwinch, syscall.SIGWINCH)
|
||||
signal.Notify(sigio, syscall.SIGIO)
|
||||
|
||||
_, err = fcntl(in, syscall.F_SETFL, syscall.O_ASYNC|syscall.O_NONBLOCK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = fcntl(in, syscall.F_SETOWN, syscall.Getpid())
|
||||
if runtime.GOOS != "darwin" && err != nil {
|
||||
return err
|
||||
}
|
||||
err = tcgetattr(out.Fd(), &orig_tios)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tios := orig_tios
|
||||
tios.Iflag &^= syscall_IGNBRK | syscall_BRKINT | syscall_PARMRK |
|
||||
syscall_ISTRIP | syscall_INLCR | syscall_IGNCR |
|
||||
syscall_ICRNL | syscall_IXON
|
||||
tios.Lflag &^= syscall_ECHO | syscall_ECHONL | syscall_ICANON |
|
||||
syscall_ISIG | syscall_IEXTEN
|
||||
tios.Cflag &^= syscall_CSIZE | syscall_PARENB
|
||||
tios.Cflag |= syscall_CS8
|
||||
tios.Cc[syscall_VMIN] = 1
|
||||
tios.Cc[syscall_VTIME] = 0
|
||||
|
||||
err = tcsetattr(out.Fd(), &tios)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
out.WriteString(funcs[t_enter_ca])
|
||||
out.WriteString(funcs[t_enter_keypad])
|
||||
out.WriteString(funcs[t_hide_cursor])
|
||||
out.WriteString(funcs[t_clear_screen])
|
||||
|
||||
termw, termh = get_term_size(out.Fd())
|
||||
back_buffer.init(termw, termh)
|
||||
front_buffer.init(termw, termh)
|
||||
back_buffer.clear()
|
||||
front_buffer.clear()
|
||||
|
||||
go func() {
|
||||
buf := make([]byte, 128)
|
||||
for {
|
||||
select {
|
||||
case <-sigio:
|
||||
for {
|
||||
n, err := syscall.Read(in, buf)
|
||||
if err == syscall.EAGAIN || err == syscall.EWOULDBLOCK {
|
||||
break
|
||||
}
|
||||
select {
|
||||
case input_comm <- input_event{buf[:n], err}:
|
||||
ie := <-input_comm
|
||||
buf = ie.data[:128]
|
||||
case <-quit:
|
||||
return
|
||||
}
|
||||
}
|
||||
case <-quit:
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
IsInit = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// Interrupt an in-progress call to PollEvent by causing it to return
|
||||
// EventInterrupt. Note that this function will block until the PollEvent
|
||||
// function has successfully been interrupted.
|
||||
func Interrupt() {
|
||||
interrupt_comm <- struct{}{}
|
||||
}
|
||||
|
||||
// Finalizes termbox library, should be called after successful initialization
|
||||
// when termbox's functionality isn't required anymore.
|
||||
func Close() {
|
||||
quit <- 1
|
||||
close(quitPolling)
|
||||
out.WriteString(funcs[t_show_cursor])
|
||||
out.WriteString(funcs[t_sgr0])
|
||||
out.WriteString(funcs[t_clear_screen])
|
||||
out.WriteString(funcs[t_exit_ca])
|
||||
out.WriteString(funcs[t_exit_keypad])
|
||||
out.WriteString(funcs[t_exit_mouse])
|
||||
tcsetattr(out.Fd(), &orig_tios)
|
||||
|
||||
out.Close()
|
||||
syscall.Close(in)
|
||||
|
||||
// reset the state, so that on next Init() it will work again
|
||||
termw = 0
|
||||
termh = 0
|
||||
input_mode = InputEsc
|
||||
out = nil
|
||||
in = 0
|
||||
lastfg = attr_invalid
|
||||
lastbg = attr_invalid
|
||||
lastx = coord_invalid
|
||||
lasty = coord_invalid
|
||||
cursor_x = cursor_hidden
|
||||
cursor_y = cursor_hidden
|
||||
foreground = ColorDefault
|
||||
background = ColorDefault
|
||||
IsInit = false
|
||||
}
|
||||
|
||||
// Synchronizes the internal back buffer with the terminal.
|
||||
func Flush() error {
|
||||
// invalidate cursor position
|
||||
lastx = coord_invalid
|
||||
lasty = coord_invalid
|
||||
|
||||
update_size_maybe()
|
||||
|
||||
for y := 0; y < front_buffer.height; y++ {
|
||||
line_offset := y * front_buffer.width
|
||||
for x := 0; x < front_buffer.width; {
|
||||
cell_offset := line_offset + x
|
||||
back := &back_buffer.cells[cell_offset]
|
||||
front := &front_buffer.cells[cell_offset]
|
||||
if back.Ch < ' ' {
|
||||
back.Ch = ' '
|
||||
}
|
||||
w := runewidth.RuneWidth(back.Ch)
|
||||
if w == 0 || w == 2 && runewidth.IsAmbiguousWidth(back.Ch) {
|
||||
w = 1
|
||||
}
|
||||
if *back == *front {
|
||||
x += w
|
||||
continue
|
||||
}
|
||||
*front = *back
|
||||
send_attr(back.Fg, back.Bg)
|
||||
|
||||
if w == 2 && x == front_buffer.width-1 {
|
||||
// there's not enough space for 2-cells rune,
|
||||
// let's just put a space in there
|
||||
send_char(x, y, ' ')
|
||||
} else {
|
||||
send_char(x, y, back.Ch)
|
||||
if w == 2 {
|
||||
next := cell_offset + 1
|
||||
front_buffer.cells[next] = Cell{
|
||||
Ch: 0,
|
||||
Fg: back.Fg,
|
||||
Bg: back.Bg,
|
||||
}
|
||||
}
|
||||
}
|
||||
x += w
|
||||
}
|
||||
}
|
||||
if !is_cursor_hidden(cursor_x, cursor_y) {
|
||||
write_cursor(cursor_x, cursor_y)
|
||||
}
|
||||
return flush()
|
||||
}
|
||||
|
||||
// Sets the position of the cursor. See also HideCursor().
|
||||
func SetCursor(x, y int) {
|
||||
if is_cursor_hidden(cursor_x, cursor_y) && !is_cursor_hidden(x, y) {
|
||||
outbuf.WriteString(funcs[t_show_cursor])
|
||||
}
|
||||
|
||||
if !is_cursor_hidden(cursor_x, cursor_y) && is_cursor_hidden(x, y) {
|
||||
outbuf.WriteString(funcs[t_hide_cursor])
|
||||
}
|
||||
|
||||
cursor_x, cursor_y = x, y
|
||||
if !is_cursor_hidden(cursor_x, cursor_y) {
|
||||
write_cursor(cursor_x, cursor_y)
|
||||
}
|
||||
}
|
||||
|
||||
// The shortcut for SetCursor(-1, -1).
|
||||
func HideCursor() {
|
||||
SetCursor(cursor_hidden, cursor_hidden)
|
||||
}
|
||||
|
||||
// Changes cell's parameters in the internal back buffer at the specified
|
||||
// position.
|
||||
func SetCell(x, y int, ch rune, fg, bg Attribute) {
|
||||
if x < 0 || x >= back_buffer.width {
|
||||
return
|
||||
}
|
||||
if y < 0 || y >= back_buffer.height {
|
||||
return
|
||||
}
|
||||
|
||||
back_buffer.cells[y*back_buffer.width+x] = Cell{ch, fg, bg}
|
||||
}
|
||||
|
||||
// Returns a slice into the termbox's back buffer. You can get its dimensions
|
||||
// using 'Size' function. The slice remains valid as long as no 'Clear' or
|
||||
// 'Flush' function calls were made after call to this function.
|
||||
func CellBuffer() []Cell {
|
||||
return back_buffer.cells
|
||||
}
|
||||
|
||||
// After getting a raw event from PollRawEvent function call, you can parse it
|
||||
// again into an ordinary one using termbox logic. That is parse an event as
|
||||
// termbox would do it. Returned event in addition to usual Event struct fields
|
||||
// sets N field to the amount of bytes used within 'data' slice. If the length
|
||||
// of 'data' slice is zero or event cannot be parsed for some other reason, the
|
||||
// function will return a special event type: EventNone.
|
||||
//
|
||||
// IMPORTANT: EventNone may contain a non-zero N, which means you should skip
|
||||
// these bytes, because termbox cannot recognize them.
|
||||
//
|
||||
// NOTE: This API is experimental and may change in future.
|
||||
func ParseEvent(data []byte) Event {
|
||||
event := Event{Type: EventKey}
|
||||
status := extract_event(data, &event, false)
|
||||
if status != event_extracted {
|
||||
return Event{Type: EventNone, N: event.N}
|
||||
}
|
||||
return event
|
||||
}
|
||||
|
||||
// Wait for an event and return it. This is a blocking function call. Instead
|
||||
// of EventKey and EventMouse it returns EventRaw events. Raw event is written
|
||||
// into `data` slice and Event's N field is set to the amount of bytes written.
|
||||
// The minimum required length of the 'data' slice is 1. This requirement may
|
||||
// vary on different platforms.
|
||||
//
|
||||
// NOTE: This API is experimental and may change in future.
|
||||
func PollRawEvent(data []byte) Event {
|
||||
if len(data) == 0 {
|
||||
panic("len(data) >= 1 is a requirement")
|
||||
}
|
||||
|
||||
var event Event
|
||||
if extract_raw_event(data, &event) {
|
||||
return event
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case ev := <-input_comm:
|
||||
if ev.err != nil {
|
||||
return Event{Type: EventError, Err: ev.err}
|
||||
}
|
||||
|
||||
inbuf = append(inbuf, ev.data...)
|
||||
input_comm <- ev
|
||||
if extract_raw_event(data, &event) {
|
||||
return event
|
||||
}
|
||||
case <-interrupt_comm:
|
||||
event.Type = EventInterrupt
|
||||
return event
|
||||
|
||||
case <-sigwinch:
|
||||
event.Type = EventResize
|
||||
event.Width, event.Height = get_term_size(out.Fd())
|
||||
return event
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for an event and return it. This is a blocking function call.
|
||||
func PollEvent() Event {
|
||||
// Constant governing macOS specific behavior. See https://github.com/nsf/termbox-go/issues/132
|
||||
// This is an arbitrary delay which hopefully will be enough time for any lagging
|
||||
// partial escape sequences to come through.
|
||||
const esc_wait_delay = 100 * time.Millisecond
|
||||
|
||||
var event Event
|
||||
var esc_wait_timer *time.Timer
|
||||
var esc_timeout <-chan time.Time
|
||||
|
||||
// try to extract event from input buffer, return on success
|
||||
event.Type = EventKey
|
||||
status := extract_event(inbuf, &event, true)
|
||||
if event.N != 0 {
|
||||
if event.N > len(inbuf) {
|
||||
event.N = len(inbuf)
|
||||
}
|
||||
copy(inbuf, inbuf[event.N:])
|
||||
event.Bytes = append(event.Bytes, inbuf[:event.N]...)
|
||||
inbuf = inbuf[:len(inbuf)-event.N]
|
||||
}
|
||||
if status == event_extracted {
|
||||
return event
|
||||
} else if status == esc_wait {
|
||||
esc_wait_timer = time.NewTimer(esc_wait_delay)
|
||||
esc_timeout = esc_wait_timer.C
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case ev := <-input_comm:
|
||||
if esc_wait_timer != nil {
|
||||
if !esc_wait_timer.Stop() {
|
||||
<-esc_wait_timer.C
|
||||
}
|
||||
esc_wait_timer = nil
|
||||
}
|
||||
|
||||
if ev.err != nil {
|
||||
return Event{Type: EventError, Err: ev.err}
|
||||
}
|
||||
|
||||
inbuf = append(inbuf, ev.data...)
|
||||
input_comm <- ev
|
||||
status := extract_event(inbuf, &event, true)
|
||||
if event.N != 0 {
|
||||
if event.N > len(inbuf) {
|
||||
event.N = len(inbuf)
|
||||
}
|
||||
copy(inbuf, inbuf[event.N:])
|
||||
event.Bytes = append(event.Bytes, inbuf[:event.N]...)
|
||||
inbuf = inbuf[:len(inbuf)-event.N]
|
||||
}
|
||||
if status == event_extracted {
|
||||
return event
|
||||
} else if status == esc_wait {
|
||||
esc_wait_timer = time.NewTimer(esc_wait_delay)
|
||||
esc_timeout = esc_wait_timer.C
|
||||
}
|
||||
case <-esc_timeout:
|
||||
esc_wait_timer = nil
|
||||
|
||||
status := extract_event(inbuf, &event, false)
|
||||
if event.N != 0 {
|
||||
if event.N > len(inbuf) {
|
||||
event.N = len(inbuf)
|
||||
}
|
||||
copy(inbuf, inbuf[event.N:])
|
||||
event.Bytes = append(event.Bytes, inbuf[:event.N]...)
|
||||
inbuf = inbuf[:len(inbuf)-event.N]
|
||||
}
|
||||
if status == event_extracted {
|
||||
return event
|
||||
}
|
||||
case <-interrupt_comm:
|
||||
event.Type = EventInterrupt
|
||||
return event
|
||||
|
||||
case <-sigwinch:
|
||||
event.Type = EventResize
|
||||
event.Width, event.Height = get_term_size(out.Fd())
|
||||
return event
|
||||
case <-quitPolling:
|
||||
return Event{Type: EventStop}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the size of the internal back buffer (which is mostly the same as
|
||||
// terminal's window size in characters). But it doesn't always match the size
|
||||
// of the terminal window, after the terminal size has changed, the internal
|
||||
// back buffer will get in sync only after Clear or Flush function calls.
|
||||
func Size() (width int, height int) {
|
||||
return termw, termh
|
||||
}
|
||||
|
||||
// Clears the internal back buffer.
|
||||
func Clear(fg, bg Attribute) error {
|
||||
foreground, background = fg, bg
|
||||
err := update_size_maybe()
|
||||
back_buffer.clear()
|
||||
return err
|
||||
}
|
||||
|
||||
// Sets termbox input mode. Termbox has two input modes:
|
||||
//
|
||||
// 1. Esc input mode. When ESC sequence is in the buffer and it doesn't match
|
||||
// any known sequence. ESC means KeyEsc. This is the default input mode.
|
||||
//
|
||||
// 2. Alt input mode. When ESC sequence is in the buffer and it doesn't match
|
||||
// any known sequence. ESC enables ModAlt modifier for the next keyboard event.
|
||||
//
|
||||
// Both input modes can be OR'ed with Mouse mode. Setting Mouse mode bit up will
|
||||
// enable mouse button press/release and drag events.
|
||||
//
|
||||
// If 'mode' is InputCurrent, returns the current input mode. See also Input*
|
||||
// constants.
|
||||
func SetInputMode(mode InputMode) InputMode {
|
||||
if mode == InputCurrent {
|
||||
return input_mode
|
||||
}
|
||||
if mode&(InputEsc|InputAlt) == 0 {
|
||||
mode |= InputEsc
|
||||
}
|
||||
if mode&(InputEsc|InputAlt) == InputEsc|InputAlt {
|
||||
mode &^= InputAlt
|
||||
}
|
||||
if mode&InputMouse != 0 {
|
||||
out.WriteString(funcs[t_enter_mouse])
|
||||
} else {
|
||||
out.WriteString(funcs[t_exit_mouse])
|
||||
}
|
||||
|
||||
input_mode = mode
|
||||
return input_mode
|
||||
}
|
||||
|
||||
// Sets the termbox output mode. Termbox has four output options:
|
||||
//
|
||||
// 1. OutputNormal => [1..8]
|
||||
// This mode provides 8 different colors:
|
||||
// black, red, green, yellow, blue, magenta, cyan, white
|
||||
// Shortcut: ColorBlack, ColorRed, ...
|
||||
// Attributes: AttrBold, AttrUnderline, AttrReverse
|
||||
//
|
||||
// Example usage:
|
||||
// SetCell(x, y, '@', ColorBlack | AttrBold, ColorRed);
|
||||
//
|
||||
// 2. Output256 => [1..256]
|
||||
// In this mode you can leverage the 256 terminal mode:
|
||||
// 0x01 - 0x08: the 8 colors as in OutputNormal
|
||||
// 0x09 - 0x10: Color* | AttrBold
|
||||
// 0x11 - 0xe8: 216 different colors
|
||||
// 0xe9 - 0x1ff: 24 different shades of grey
|
||||
//
|
||||
// Example usage:
|
||||
// SetCell(x, y, '@', 184, 240);
|
||||
// SetCell(x, y, '@', 0xb8, 0xf0);
|
||||
//
|
||||
// 3. Output216 => [1..216]
|
||||
// This mode supports the 3rd range of the 256 mode only.
|
||||
// But you don't need to provide an offset.
|
||||
//
|
||||
// 4. OutputGrayscale => [1..26]
|
||||
// This mode supports the 4th range of the 256 mode
|
||||
// and black and white colors from 3th range of the 256 mode
|
||||
// But you don't need to provide an offset.
|
||||
//
|
||||
// In all modes, 0x00 represents the default color.
|
||||
//
|
||||
// `go run _demos/output.go` to see its impact on your terminal.
|
||||
//
|
||||
// If 'mode' is OutputCurrent, it returns the current output mode.
|
||||
//
|
||||
// Note that this may return a different OutputMode than the one requested,
|
||||
// as the requested mode may not be available on the target platform.
|
||||
func SetOutputMode(mode OutputMode) OutputMode {
|
||||
if mode == OutputCurrent {
|
||||
return output_mode
|
||||
}
|
||||
|
||||
output_mode = mode
|
||||
return output_mode
|
||||
}
|
||||
|
||||
// Sync comes handy when something causes desync between termbox's understanding
|
||||
// of a terminal buffer and the reality. Such as a third party process. Sync
|
||||
// forces a complete resync between the termbox and a terminal, it may not be
|
||||
// visually pretty though.
|
||||
func Sync() error {
|
||||
front_buffer.clear()
|
||||
err := send_clear()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return Flush()
|
||||
}
|
189
vendor/github.com/jesseduffield/termbox-go/api_common.go
generated
vendored
189
vendor/github.com/jesseduffield/termbox-go/api_common.go
generated
vendored
@ -1,189 +0,0 @@
|
||||
// termbox is a library for creating cross-platform text-based interfaces
|
||||
package termbox
|
||||
|
||||
// public API, common OS agnostic part
|
||||
|
||||
type (
|
||||
InputMode int
|
||||
OutputMode int
|
||||
EventType uint8
|
||||
Modifier uint8
|
||||
Key uint16
|
||||
Attribute uint16
|
||||
)
|
||||
|
||||
// This type represents a termbox event. The 'Mod', 'Key' and 'Ch' fields are
|
||||
// valid if 'Type' is EventKey. The 'Width' and 'Height' fields are valid if
|
||||
// 'Type' is EventResize. The 'Err' field is valid if 'Type' is EventError.
|
||||
type Event struct {
|
||||
Type EventType // one of Event* constants
|
||||
Mod Modifier // one of Mod* constants or 0
|
||||
Key Key // one of Key* constants, invalid if 'Ch' is not 0
|
||||
Ch rune // a unicode character
|
||||
Width int // width of the screen
|
||||
Height int // height of the screen
|
||||
Err error // error in case if input failed
|
||||
MouseX int // x coord of mouse
|
||||
MouseY int // y coord of mouse
|
||||
N int // number of bytes written when getting a raw event
|
||||
Bytes []byte // byte array that triggered the event
|
||||
}
|
||||
|
||||
// A cell, single conceptual entity on the screen. The screen is basically a 2d
|
||||
// array of cells. 'Ch' is a unicode character, 'Fg' and 'Bg' are foreground
|
||||
// and background attributes respectively.
|
||||
type Cell struct {
|
||||
Ch rune
|
||||
Fg Attribute
|
||||
Bg Attribute
|
||||
}
|
||||
|
||||
// To know if termbox has been initialized or not
|
||||
var (
|
||||
IsInit bool = false
|
||||
)
|
||||
|
||||
// Key constants, see Event.Key field.
|
||||
const (
|
||||
KeyF1 Key = 0xFFFF - iota
|
||||
KeyF2
|
||||
KeyF3
|
||||
KeyF4
|
||||
KeyF5
|
||||
KeyF6
|
||||
KeyF7
|
||||
KeyF8
|
||||
KeyF9
|
||||
KeyF10
|
||||
KeyF11
|
||||
KeyF12
|
||||
KeyInsert
|
||||
KeyDelete
|
||||
KeyHome
|
||||
KeyEnd
|
||||
KeyPgup
|
||||
KeyPgdn
|
||||
KeyArrowUp
|
||||
KeyArrowDown
|
||||
KeyArrowLeft
|
||||
KeyArrowRight
|
||||
key_min // see terminfo
|
||||
MouseLeft
|
||||
MouseMiddle
|
||||
MouseRight
|
||||
MouseRelease
|
||||
MouseWheelUp
|
||||
MouseWheelDown
|
||||
)
|
||||
|
||||
const (
|
||||
KeyCtrlTilde Key = 0x00
|
||||
KeyCtrl2 Key = 0x00
|
||||
KeyCtrlSpace Key = 0x00
|
||||
KeyCtrlA Key = 0x01
|
||||
KeyCtrlB Key = 0x02
|
||||
KeyCtrlC Key = 0x03
|
||||
KeyCtrlD Key = 0x04
|
||||
KeyCtrlE Key = 0x05
|
||||
KeyCtrlF Key = 0x06
|
||||
KeyCtrlG Key = 0x07
|
||||
KeyBackspace Key = 0x08
|
||||
KeyCtrlH Key = 0x08
|
||||
KeyTab Key = 0x09
|
||||
KeyCtrlI Key = 0x09
|
||||
KeyCtrlJ Key = 0x0A
|
||||
KeyCtrlK Key = 0x0B
|
||||
KeyCtrlL Key = 0x0C
|
||||
KeyEnter Key = 0x0D
|
||||
KeyCtrlM Key = 0x0D
|
||||
KeyCtrlN Key = 0x0E
|
||||
KeyCtrlO Key = 0x0F
|
||||
KeyCtrlP Key = 0x10
|
||||
KeyCtrlQ Key = 0x11
|
||||
KeyCtrlR Key = 0x12
|
||||
KeyCtrlS Key = 0x13
|
||||
KeyCtrlT Key = 0x14
|
||||
KeyCtrlU Key = 0x15
|
||||
KeyCtrlV Key = 0x16
|
||||
KeyCtrlW Key = 0x17
|
||||
KeyCtrlX Key = 0x18
|
||||
KeyCtrlY Key = 0x19
|
||||
KeyCtrlZ Key = 0x1A
|
||||
KeyEsc Key = 0x1B
|
||||
KeyCtrlLsqBracket Key = 0x1B
|
||||
KeyCtrl3 Key = 0x1B
|
||||
KeyCtrl4 Key = 0x1C
|
||||
KeyCtrlBackslash Key = 0x1C
|
||||
KeyCtrl5 Key = 0x1D
|
||||
KeyCtrlRsqBracket Key = 0x1D
|
||||
KeyCtrl6 Key = 0x1E
|
||||
KeyCtrl7 Key = 0x1F
|
||||
KeyCtrlSlash Key = 0x1F
|
||||
KeyCtrlUnderscore Key = 0x1F
|
||||
KeySpace Key = 0x20
|
||||
KeyBackspace2 Key = 0x7F
|
||||
KeyCtrl8 Key = 0x7F
|
||||
)
|
||||
|
||||
// Alt modifier constant, see Event.Mod field and SetInputMode function.
|
||||
const (
|
||||
ModAlt Modifier = 1 << iota
|
||||
ModMotion
|
||||
)
|
||||
|
||||
// Cell colors, you can combine a color with multiple attributes using bitwise
|
||||
// OR ('|').
|
||||
const (
|
||||
ColorDefault Attribute = iota
|
||||
ColorBlack
|
||||
ColorRed
|
||||
ColorGreen
|
||||
ColorYellow
|
||||
ColorBlue
|
||||
ColorMagenta
|
||||
ColorCyan
|
||||
ColorWhite
|
||||
)
|
||||
|
||||
// Cell attributes, it is possible to use multiple attributes by combining them
|
||||
// using bitwise OR ('|'). Although, colors cannot be combined. But you can
|
||||
// combine attributes and a single color.
|
||||
//
|
||||
// It's worth mentioning that some platforms don't support certain attributes.
|
||||
// For example windows console doesn't support AttrUnderline. And on some
|
||||
// terminals applying AttrBold to background may result in blinking text. Use
|
||||
// them with caution and test your code on various terminals.
|
||||
const (
|
||||
AttrBold Attribute = 1 << (iota + 9)
|
||||
AttrUnderline
|
||||
AttrReverse
|
||||
)
|
||||
|
||||
// Input mode. See SetInputMode function.
|
||||
const (
|
||||
InputEsc InputMode = 1 << iota
|
||||
InputAlt
|
||||
InputMouse
|
||||
InputCurrent InputMode = 0
|
||||
)
|
||||
|
||||
// Output mode. See SetOutputMode function.
|
||||
const (
|
||||
OutputCurrent OutputMode = iota
|
||||
OutputNormal
|
||||
Output256
|
||||
Output216
|
||||
OutputGrayscale
|
||||
)
|
||||
|
||||
// Event type. See Event.Type field.
|
||||
const (
|
||||
EventKey EventType = iota
|
||||
EventResize
|
||||
EventMouse
|
||||
EventError
|
||||
EventInterrupt
|
||||
EventRaw
|
||||
EventNone
|
||||
EventStop
|
||||
)
|
239
vendor/github.com/jesseduffield/termbox-go/api_windows.go
generated
vendored
239
vendor/github.com/jesseduffield/termbox-go/api_windows.go
generated
vendored
@ -1,239 +0,0 @@
|
||||
package termbox
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// public API
|
||||
|
||||
// Initializes termbox library. This function should be called before any other functions.
|
||||
// After successful initialization, the library must be finalized using 'Close' function.
|
||||
//
|
||||
// Example usage:
|
||||
// err := termbox.Init()
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// defer termbox.Close()
|
||||
func Init() error {
|
||||
var err error
|
||||
|
||||
interrupt, err = create_event()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
in, err = syscall.Open("CONIN$", syscall.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out, err = syscall.Open("CONOUT$", syscall.O_RDWR, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = get_console_mode(in, &orig_mode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = set_console_mode(in, enable_window_input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
orig_size = get_term_size(out)
|
||||
win_size := get_win_size(out)
|
||||
|
||||
err = set_console_screen_buffer_size(out, win_size)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = get_console_cursor_info(out, &orig_cursor_info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
show_cursor(false)
|
||||
term_size = get_term_size(out)
|
||||
back_buffer.init(int(term_size.x), int(term_size.y))
|
||||
front_buffer.init(int(term_size.x), int(term_size.y))
|
||||
back_buffer.clear()
|
||||
front_buffer.clear()
|
||||
clear()
|
||||
|
||||
diffbuf = make([]diff_msg, 0, 32)
|
||||
|
||||
go input_event_producer()
|
||||
IsInit = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// Finalizes termbox library, should be called after successful initialization
|
||||
// when termbox's functionality isn't required anymore.
|
||||
func Close() {
|
||||
// we ignore errors here, because we can't really do anything about them
|
||||
Clear(0, 0)
|
||||
Flush()
|
||||
|
||||
// stop event producer
|
||||
cancel_comm <- true
|
||||
set_event(interrupt)
|
||||
select {
|
||||
case <-input_comm:
|
||||
default:
|
||||
}
|
||||
<-cancel_done_comm
|
||||
|
||||
set_console_cursor_info(out, &orig_cursor_info)
|
||||
set_console_cursor_position(out, coord{})
|
||||
set_console_screen_buffer_size(out, orig_size)
|
||||
set_console_mode(in, orig_mode)
|
||||
syscall.Close(in)
|
||||
syscall.Close(out)
|
||||
syscall.Close(interrupt)
|
||||
IsInit = false
|
||||
}
|
||||
|
||||
// Interrupt an in-progress call to PollEvent by causing it to return
|
||||
// EventInterrupt. Note that this function will block until the PollEvent
|
||||
// function has successfully been interrupted.
|
||||
func Interrupt() {
|
||||
interrupt_comm <- struct{}{}
|
||||
}
|
||||
|
||||
// Synchronizes the internal back buffer with the terminal.
|
||||
func Flush() error {
|
||||
update_size_maybe()
|
||||
prepare_diff_messages()
|
||||
for _, diff := range diffbuf {
|
||||
r := small_rect{
|
||||
left: 0,
|
||||
top: diff.pos,
|
||||
right: term_size.x - 1,
|
||||
bottom: diff.pos + diff.lines - 1,
|
||||
}
|
||||
write_console_output(out, diff.chars, r)
|
||||
}
|
||||
if !is_cursor_hidden(cursor_x, cursor_y) {
|
||||
move_cursor(cursor_x, cursor_y)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Sets the position of the cursor. See also HideCursor().
|
||||
func SetCursor(x, y int) {
|
||||
if is_cursor_hidden(cursor_x, cursor_y) && !is_cursor_hidden(x, y) {
|
||||
show_cursor(true)
|
||||
}
|
||||
|
||||
if !is_cursor_hidden(cursor_x, cursor_y) && is_cursor_hidden(x, y) {
|
||||
show_cursor(false)
|
||||
}
|
||||
|
||||
cursor_x, cursor_y = x, y
|
||||
if !is_cursor_hidden(cursor_x, cursor_y) {
|
||||
move_cursor(cursor_x, cursor_y)
|
||||
}
|
||||
}
|
||||
|
||||
// The shortcut for SetCursor(-1, -1).
|
||||
func HideCursor() {
|
||||
SetCursor(cursor_hidden, cursor_hidden)
|
||||
}
|
||||
|
||||
// Changes cell's parameters in the internal back buffer at the specified
|
||||
// position.
|
||||
func SetCell(x, y int, ch rune, fg, bg Attribute) {
|
||||
if x < 0 || x >= back_buffer.width {
|
||||
return
|
||||
}
|
||||
if y < 0 || y >= back_buffer.height {
|
||||
return
|
||||
}
|
||||
|
||||
back_buffer.cells[y*back_buffer.width+x] = Cell{ch, fg, bg}
|
||||
}
|
||||
|
||||
// Returns a slice into the termbox's back buffer. You can get its dimensions
|
||||
// using 'Size' function. The slice remains valid as long as no 'Clear' or
|
||||
// 'Flush' function calls were made after call to this function.
|
||||
func CellBuffer() []Cell {
|
||||
return back_buffer.cells
|
||||
}
|
||||
|
||||
// Wait for an event and return it. This is a blocking function call.
|
||||
func PollEvent() Event {
|
||||
select {
|
||||
case ev := <-input_comm:
|
||||
return ev
|
||||
case <-interrupt_comm:
|
||||
return Event{Type: EventInterrupt}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the size of the internal back buffer (which is mostly the same as
|
||||
// console's window size in characters). But it doesn't always match the size
|
||||
// of the console window, after the console size has changed, the internal back
|
||||
// buffer will get in sync only after Clear or Flush function calls.
|
||||
func Size() (int, int) {
|
||||
return int(term_size.x), int(term_size.y)
|
||||
}
|
||||
|
||||
// Clears the internal back buffer.
|
||||
func Clear(fg, bg Attribute) error {
|
||||
foreground, background = fg, bg
|
||||
update_size_maybe()
|
||||
back_buffer.clear()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Sets termbox input mode. Termbox has two input modes:
|
||||
//
|
||||
// 1. Esc input mode. When ESC sequence is in the buffer and it doesn't match
|
||||
// any known sequence. ESC means KeyEsc. This is the default input mode.
|
||||
//
|
||||
// 2. Alt input mode. When ESC sequence is in the buffer and it doesn't match
|
||||
// any known sequence. ESC enables ModAlt modifier for the next keyboard event.
|
||||
//
|
||||
// Both input modes can be OR'ed with Mouse mode. Setting Mouse mode bit up will
|
||||
// enable mouse button press/release and drag events.
|
||||
//
|
||||
// If 'mode' is InputCurrent, returns the current input mode. See also Input*
|
||||
// constants.
|
||||
func SetInputMode(mode InputMode) InputMode {
|
||||
if mode == InputCurrent {
|
||||
return input_mode
|
||||
}
|
||||
if mode&InputMouse != 0 {
|
||||
err := set_console_mode(in, enable_window_input|enable_mouse_input|enable_extended_flags)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
err := set_console_mode(in, enable_window_input)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
input_mode = mode
|
||||
return input_mode
|
||||
}
|
||||
|
||||
// Sets the termbox output mode.
|
||||
//
|
||||
// Windows console does not support extra colour modes,
|
||||
// so this will always set and return OutputNormal.
|
||||
func SetOutputMode(mode OutputMode) OutputMode {
|
||||
return OutputNormal
|
||||
}
|
||||
|
||||
// Sync comes handy when something causes desync between termbox's understanding
|
||||
// of a terminal buffer and the reality. Such as a third party process. Sync
|
||||
// forces a complete resync between the termbox and a terminal, it may not be
|
||||
// visually pretty though. At the moment on Windows it does nothing.
|
||||
func Sync() error {
|
||||
return nil
|
||||
}
|
110
vendor/github.com/jesseduffield/termbox-go/collect_terminfo.py
generated
vendored
110
vendor/github.com/jesseduffield/termbox-go/collect_terminfo.py
generated
vendored
@ -1,110 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, subprocess
|
||||
|
||||
def escaped(s):
|
||||
return repr(s)[1:-1]
|
||||
|
||||
def tput(term, name):
|
||||
try:
|
||||
return subprocess.check_output(['tput', '-T%s' % term, name]).decode()
|
||||
except subprocess.CalledProcessError as e:
|
||||
return e.output.decode()
|
||||
|
||||
|
||||
def w(s):
|
||||
if s == None:
|
||||
return
|
||||
sys.stdout.write(s)
|
||||
|
||||
terminals = {
|
||||
'xterm' : 'xterm',
|
||||
'rxvt-256color' : 'rxvt_256color',
|
||||
'rxvt-unicode' : 'rxvt_unicode',
|
||||
'linux' : 'linux',
|
||||
'Eterm' : 'eterm',
|
||||
'screen' : 'screen'
|
||||
}
|
||||
|
||||
keys = [
|
||||
"F1", "kf1",
|
||||
"F2", "kf2",
|
||||
"F3", "kf3",
|
||||
"F4", "kf4",
|
||||
"F5", "kf5",
|
||||
"F6", "kf6",
|
||||
"F7", "kf7",
|
||||
"F8", "kf8",
|
||||
"F9", "kf9",
|
||||
"F10", "kf10",
|
||||
"F11", "kf11",
|
||||
"F12", "kf12",
|
||||
"INSERT", "kich1",
|
||||
"DELETE", "kdch1",
|
||||
"HOME", "khome",
|
||||
"END", "kend",
|
||||
"PGUP", "kpp",
|
||||
"PGDN", "knp",
|
||||
"KEY_UP", "kcuu1",
|
||||
"KEY_DOWN", "kcud1",
|
||||
"KEY_LEFT", "kcub1",
|
||||
"KEY_RIGHT", "kcuf1"
|
||||
]
|
||||
|
||||
funcs = [
|
||||
"T_ENTER_CA", "smcup",
|
||||
"T_EXIT_CA", "rmcup",
|
||||
"T_SHOW_CURSOR", "cnorm",
|
||||
"T_HIDE_CURSOR", "civis",
|
||||
"T_CLEAR_SCREEN", "clear",
|
||||
"T_SGR0", "sgr0",
|
||||
"T_UNDERLINE", "smul",
|
||||
"T_BOLD", "bold",
|
||||
"T_BLINK", "blink",
|
||||
"T_REVERSE", "rev",
|
||||
"T_ENTER_KEYPAD", "smkx",
|
||||
"T_EXIT_KEYPAD", "rmkx"
|
||||
]
|
||||
|
||||
def iter_pairs(iterable):
|
||||
iterable = iter(iterable)
|
||||
while True:
|
||||
yield (next(iterable), next(iterable))
|
||||
|
||||
def do_term(term, nick):
|
||||
w("// %s\n" % term)
|
||||
w("var %s_keys = []string{\n\t" % nick)
|
||||
for k, v in iter_pairs(keys):
|
||||
w('"')
|
||||
w(escaped(tput(term, v)))
|
||||
w('",')
|
||||
w("\n}\n")
|
||||
w("var %s_funcs = []string{\n\t" % nick)
|
||||
for k,v in iter_pairs(funcs):
|
||||
w('"')
|
||||
if v == "sgr":
|
||||
w("\\033[3%d;4%dm")
|
||||
elif v == "cup":
|
||||
w("\\033[%d;%dH")
|
||||
else:
|
||||
w(escaped(tput(term, v)))
|
||||
w('", ')
|
||||
w("\n}\n\n")
|
||||
|
||||
def do_terms(d):
|
||||
w("var terms = []struct {\n")
|
||||
w("\tname string\n")
|
||||
w("\tkeys []string\n")
|
||||
w("\tfuncs []string\n")
|
||||
w("}{\n")
|
||||
for k, v in d.items():
|
||||
w('\t{"%s", %s_keys, %s_funcs},\n' % (k, v, v))
|
||||
w("}\n\n")
|
||||
|
||||
w("// +build !windows\n\npackage termbox\n\n")
|
||||
|
||||
for k,v in terminals.items():
|
||||
do_term(k, v)
|
||||
|
||||
do_terms(terminals)
|
||||
|
11
vendor/github.com/jesseduffield/termbox-go/escwait.go
generated
vendored
11
vendor/github.com/jesseduffield/termbox-go/escwait.go
generated
vendored
@ -1,11 +0,0 @@
|
||||
// +build !darwin
|
||||
|
||||
package termbox
|
||||
|
||||
// On all systems other than macOS, disable behavior which will wait before
|
||||
// deciding that the escape key was pressed, to account for partially send
|
||||
// escape sequences, especially with regard to lengthy mouse sequences.
|
||||
// See https://github.com/nsf/termbox-go/issues/132
|
||||
func enable_wait_for_escape_sequence() bool {
|
||||
return false
|
||||
}
|
9
vendor/github.com/jesseduffield/termbox-go/escwait_darwin.go
generated
vendored
9
vendor/github.com/jesseduffield/termbox-go/escwait_darwin.go
generated
vendored
@ -1,9 +0,0 @@
|
||||
package termbox
|
||||
|
||||
// On macOS, enable behavior which will wait before deciding that the escape
|
||||
// key was pressed, to account for partially send escape sequences, especially
|
||||
// with regard to lengthy mouse sequences.
|
||||
// See https://github.com/nsf/termbox-go/issues/132
|
||||
func enable_wait_for_escape_sequence() bool {
|
||||
return true
|
||||
}
|
41
vendor/github.com/jesseduffield/termbox-go/syscalls_darwin.go
generated
vendored
41
vendor/github.com/jesseduffield/termbox-go/syscalls_darwin.go
generated
vendored
@ -1,41 +0,0 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs syscalls.go
|
||||
|
||||
// +build !amd64
|
||||
|
||||
package termbox
|
||||
|
||||
type syscall_Termios struct {
|
||||
Iflag uint32
|
||||
Oflag uint32
|
||||
Cflag uint32
|
||||
Lflag uint32
|
||||
Cc [20]uint8
|
||||
Ispeed uint32
|
||||
Ospeed uint32
|
||||
}
|
||||
|
||||
const (
|
||||
syscall_IGNBRK = 0x1
|
||||
syscall_BRKINT = 0x2
|
||||
syscall_PARMRK = 0x8
|
||||
syscall_ISTRIP = 0x20
|
||||
syscall_INLCR = 0x40
|
||||
syscall_IGNCR = 0x80
|
||||
syscall_ICRNL = 0x100
|
||||
syscall_IXON = 0x200
|
||||
syscall_OPOST = 0x1
|
||||
syscall_ECHO = 0x8
|
||||
syscall_ECHONL = 0x10
|
||||
syscall_ICANON = 0x100
|
||||
syscall_ISIG = 0x80
|
||||
syscall_IEXTEN = 0x400
|
||||
syscall_CSIZE = 0x300
|
||||
syscall_PARENB = 0x1000
|
||||
syscall_CS8 = 0x300
|
||||
syscall_VMIN = 0x10
|
||||
syscall_VTIME = 0x11
|
||||
|
||||
syscall_TCGETS = 0x402c7413
|
||||
syscall_TCSETS = 0x802c7414
|
||||
)
|
40
vendor/github.com/jesseduffield/termbox-go/syscalls_darwin_amd64.go
generated
vendored
40
vendor/github.com/jesseduffield/termbox-go/syscalls_darwin_amd64.go
generated
vendored
@ -1,40 +0,0 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs syscalls.go
|
||||
|
||||
package termbox
|
||||
|
||||
type syscall_Termios struct {
|
||||
Iflag uint64
|
||||
Oflag uint64
|
||||
Cflag uint64
|
||||
Lflag uint64
|
||||
Cc [20]uint8
|
||||
Pad_cgo_0 [4]byte
|
||||
Ispeed uint64
|
||||
Ospeed uint64
|
||||
}
|
||||
|
||||
const (
|
||||
syscall_IGNBRK = 0x1
|
||||
syscall_BRKINT = 0x2
|
||||
syscall_PARMRK = 0x8
|
||||
syscall_ISTRIP = 0x20
|
||||
syscall_INLCR = 0x40
|
||||
syscall_IGNCR = 0x80
|
||||
syscall_ICRNL = 0x100
|
||||
syscall_IXON = 0x200
|
||||
syscall_OPOST = 0x1
|
||||
syscall_ECHO = 0x8
|
||||
syscall_ECHONL = 0x10
|
||||
syscall_ICANON = 0x100
|
||||
syscall_ISIG = 0x80
|
||||
syscall_IEXTEN = 0x400
|
||||
syscall_CSIZE = 0x300
|
||||
syscall_PARENB = 0x1000
|
||||
syscall_CS8 = 0x300
|
||||
syscall_VMIN = 0x10
|
||||
syscall_VTIME = 0x11
|
||||
|
||||
syscall_TCGETS = 0x40487413
|
||||
syscall_TCSETS = 0x80487414
|
||||
)
|
39
vendor/github.com/jesseduffield/termbox-go/syscalls_dragonfly.go
generated
vendored
39
vendor/github.com/jesseduffield/termbox-go/syscalls_dragonfly.go
generated
vendored
@ -1,39 +0,0 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs syscalls.go
|
||||
|
||||
package termbox
|
||||
|
||||
type syscall_Termios struct {
|
||||
Iflag uint32
|
||||
Oflag uint32
|
||||
Cflag uint32
|
||||
Lflag uint32
|
||||
Cc [20]uint8
|
||||
Ispeed uint32
|
||||
Ospeed uint32
|
||||
}
|
||||
|
||||
const (
|
||||
syscall_IGNBRK = 0x1
|
||||
syscall_BRKINT = 0x2
|
||||
syscall_PARMRK = 0x8
|
||||
syscall_ISTRIP = 0x20
|
||||
syscall_INLCR = 0x40
|
||||
syscall_IGNCR = 0x80
|
||||
syscall_ICRNL = 0x100
|
||||
syscall_IXON = 0x200
|
||||
syscall_OPOST = 0x1
|
||||
syscall_ECHO = 0x8
|
||||
syscall_ECHONL = 0x10
|
||||
syscall_ICANON = 0x100
|
||||
syscall_ISIG = 0x80
|
||||
syscall_IEXTEN = 0x400
|
||||
syscall_CSIZE = 0x300
|
||||
syscall_PARENB = 0x1000
|
||||
syscall_CS8 = 0x300
|
||||
syscall_VMIN = 0x10
|
||||
syscall_VTIME = 0x11
|
||||
|
||||
syscall_TCGETS = 0x402c7413
|
||||
syscall_TCSETS = 0x802c7414
|
||||
)
|
39
vendor/github.com/jesseduffield/termbox-go/syscalls_freebsd.go
generated
vendored
39
vendor/github.com/jesseduffield/termbox-go/syscalls_freebsd.go
generated
vendored
@ -1,39 +0,0 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs syscalls.go
|
||||
|
||||
package termbox
|
||||
|
||||
type syscall_Termios struct {
|
||||
Iflag uint32
|
||||
Oflag uint32
|
||||
Cflag uint32
|
||||
Lflag uint32
|
||||
Cc [20]uint8
|
||||
Ispeed uint32
|
||||
Ospeed uint32
|
||||
}
|
||||
|
||||
const (
|
||||
syscall_IGNBRK = 0x1
|
||||
syscall_BRKINT = 0x2
|
||||
syscall_PARMRK = 0x8
|
||||
syscall_ISTRIP = 0x20
|
||||
syscall_INLCR = 0x40
|
||||
syscall_IGNCR = 0x80
|
||||
syscall_ICRNL = 0x100
|
||||
syscall_IXON = 0x200
|
||||
syscall_OPOST = 0x1
|
||||
syscall_ECHO = 0x8
|
||||
syscall_ECHONL = 0x10
|
||||
syscall_ICANON = 0x100
|
||||
syscall_ISIG = 0x80
|
||||
syscall_IEXTEN = 0x400
|
||||
syscall_CSIZE = 0x300
|
||||
syscall_PARENB = 0x1000
|
||||
syscall_CS8 = 0x300
|
||||
syscall_VMIN = 0x10
|
||||
syscall_VTIME = 0x11
|
||||
|
||||
syscall_TCGETS = 0x402c7413
|
||||
syscall_TCSETS = 0x802c7414
|
||||
)
|
33
vendor/github.com/jesseduffield/termbox-go/syscalls_linux.go
generated
vendored
33
vendor/github.com/jesseduffield/termbox-go/syscalls_linux.go
generated
vendored
@ -1,33 +0,0 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs syscalls.go
|
||||
|
||||
package termbox
|
||||
|
||||
import "syscall"
|
||||
|
||||
type syscall_Termios syscall.Termios
|
||||
|
||||
const (
|
||||
syscall_IGNBRK = syscall.IGNBRK
|
||||
syscall_BRKINT = syscall.BRKINT
|
||||
syscall_PARMRK = syscall.PARMRK
|
||||
syscall_ISTRIP = syscall.ISTRIP
|
||||
syscall_INLCR = syscall.INLCR
|
||||
syscall_IGNCR = syscall.IGNCR
|
||||
syscall_ICRNL = syscall.ICRNL
|
||||
syscall_IXON = syscall.IXON
|
||||
syscall_OPOST = syscall.OPOST
|
||||
syscall_ECHO = syscall.ECHO
|
||||
syscall_ECHONL = syscall.ECHONL
|
||||
syscall_ICANON = syscall.ICANON
|
||||
syscall_ISIG = syscall.ISIG
|
||||
syscall_IEXTEN = syscall.IEXTEN
|
||||
syscall_CSIZE = syscall.CSIZE
|
||||
syscall_PARENB = syscall.PARENB
|
||||
syscall_CS8 = syscall.CS8
|
||||
syscall_VMIN = syscall.VMIN
|
||||
syscall_VTIME = syscall.VTIME
|
||||
|
||||
syscall_TCGETS = syscall.TCGETS
|
||||
syscall_TCSETS = syscall.TCSETS
|
||||
)
|
39
vendor/github.com/jesseduffield/termbox-go/syscalls_netbsd.go
generated
vendored
39
vendor/github.com/jesseduffield/termbox-go/syscalls_netbsd.go
generated
vendored
@ -1,39 +0,0 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs syscalls.go
|
||||
|
||||
package termbox
|
||||
|
||||
type syscall_Termios struct {
|
||||
Iflag uint32
|
||||
Oflag uint32
|
||||
Cflag uint32
|
||||
Lflag uint32
|
||||
Cc [20]uint8
|
||||
Ispeed int32
|
||||
Ospeed int32
|
||||
}
|
||||
|
||||
const (
|
||||
syscall_IGNBRK = 0x1
|
||||
syscall_BRKINT = 0x2
|
||||
syscall_PARMRK = 0x8
|
||||
syscall_ISTRIP = 0x20
|
||||
syscall_INLCR = 0x40
|
||||
syscall_IGNCR = 0x80
|
||||
syscall_ICRNL = 0x100
|
||||
syscall_IXON = 0x200
|
||||
syscall_OPOST = 0x1
|
||||
syscall_ECHO = 0x8
|
||||
syscall_ECHONL = 0x10
|
||||
syscall_ICANON = 0x100
|
||||
syscall_ISIG = 0x80
|
||||
syscall_IEXTEN = 0x400
|
||||
syscall_CSIZE = 0x300
|
||||
syscall_PARENB = 0x1000
|
||||
syscall_CS8 = 0x300
|
||||
syscall_VMIN = 0x10
|
||||
syscall_VTIME = 0x11
|
||||
|
||||
syscall_TCGETS = 0x402c7413
|
||||
syscall_TCSETS = 0x802c7414
|
||||
)
|
39
vendor/github.com/jesseduffield/termbox-go/syscalls_openbsd.go
generated
vendored
39
vendor/github.com/jesseduffield/termbox-go/syscalls_openbsd.go
generated
vendored
@ -1,39 +0,0 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs syscalls.go
|
||||
|
||||
package termbox
|
||||
|
||||
type syscall_Termios struct {
|
||||
Iflag uint32
|
||||
Oflag uint32
|
||||
Cflag uint32
|
||||
Lflag uint32
|
||||
Cc [20]uint8
|
||||
Ispeed int32
|
||||
Ospeed int32
|
||||
}
|
||||
|
||||
const (
|
||||
syscall_IGNBRK = 0x1
|
||||
syscall_BRKINT = 0x2
|
||||
syscall_PARMRK = 0x8
|
||||
syscall_ISTRIP = 0x20
|
||||
syscall_INLCR = 0x40
|
||||
syscall_IGNCR = 0x80
|
||||
syscall_ICRNL = 0x100
|
||||
syscall_IXON = 0x200
|
||||
syscall_OPOST = 0x1
|
||||
syscall_ECHO = 0x8
|
||||
syscall_ECHONL = 0x10
|
||||
syscall_ICANON = 0x100
|
||||
syscall_ISIG = 0x80
|
||||
syscall_IEXTEN = 0x400
|
||||
syscall_CSIZE = 0x300
|
||||
syscall_PARENB = 0x1000
|
||||
syscall_CS8 = 0x300
|
||||
syscall_VMIN = 0x10
|
||||
syscall_VTIME = 0x11
|
||||
|
||||
syscall_TCGETS = 0x402c7413
|
||||
syscall_TCSETS = 0x802c7414
|
||||
)
|
61
vendor/github.com/jesseduffield/termbox-go/syscalls_windows.go
generated
vendored
61
vendor/github.com/jesseduffield/termbox-go/syscalls_windows.go
generated
vendored
@ -1,61 +0,0 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs -- -DUNICODE syscalls.go
|
||||
|
||||
package termbox
|
||||
|
||||
const (
|
||||
foreground_blue = 0x1
|
||||
foreground_green = 0x2
|
||||
foreground_red = 0x4
|
||||
foreground_intensity = 0x8
|
||||
background_blue = 0x10
|
||||
background_green = 0x20
|
||||
background_red = 0x40
|
||||
background_intensity = 0x80
|
||||
std_input_handle = -0xa
|
||||
std_output_handle = -0xb
|
||||
key_event = 0x1
|
||||
mouse_event = 0x2
|
||||
window_buffer_size_event = 0x4
|
||||
enable_window_input = 0x8
|
||||
enable_mouse_input = 0x10
|
||||
enable_extended_flags = 0x80
|
||||
|
||||
vk_f1 = 0x70
|
||||
vk_f2 = 0x71
|
||||
vk_f3 = 0x72
|
||||
vk_f4 = 0x73
|
||||
vk_f5 = 0x74
|
||||
vk_f6 = 0x75
|
||||
vk_f7 = 0x76
|
||||
vk_f8 = 0x77
|
||||
vk_f9 = 0x78
|
||||
vk_f10 = 0x79
|
||||
vk_f11 = 0x7a
|
||||
vk_f12 = 0x7b
|
||||
vk_insert = 0x2d
|
||||
vk_delete = 0x2e
|
||||
vk_home = 0x24
|
||||
vk_end = 0x23
|
||||
vk_pgup = 0x21
|
||||
vk_pgdn = 0x22
|
||||
vk_arrow_up = 0x26
|
||||
vk_arrow_down = 0x28
|
||||
vk_arrow_left = 0x25
|
||||
vk_arrow_right = 0x27
|
||||
vk_backspace = 0x8
|
||||
vk_tab = 0x9
|
||||
vk_enter = 0xd
|
||||
vk_esc = 0x1b
|
||||
vk_space = 0x20
|
||||
|
||||
left_alt_pressed = 0x2
|
||||
left_ctrl_pressed = 0x8
|
||||
right_alt_pressed = 0x1
|
||||
right_ctrl_pressed = 0x4
|
||||
shift_pressed = 0x10
|
||||
|
||||
generic_read = 0x80000000
|
||||
generic_write = 0x40000000
|
||||
console_textmode_buffer = 0x1
|
||||
)
|
532
vendor/github.com/jesseduffield/termbox-go/termbox.go
generated
vendored
532
vendor/github.com/jesseduffield/termbox-go/termbox.go
generated
vendored
@ -1,532 +0,0 @@
|
||||
// +build !windows
|
||||
|
||||
package termbox
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unicode/utf8"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// private API
|
||||
|
||||
const (
|
||||
t_enter_ca = iota
|
||||
t_exit_ca
|
||||
t_show_cursor
|
||||
t_hide_cursor
|
||||
t_clear_screen
|
||||
t_sgr0
|
||||
t_underline
|
||||
t_bold
|
||||
t_blink
|
||||
t_reverse
|
||||
t_enter_keypad
|
||||
t_exit_keypad
|
||||
t_enter_mouse
|
||||
t_exit_mouse
|
||||
t_max_funcs
|
||||
)
|
||||
|
||||
const (
|
||||
coord_invalid = -2
|
||||
attr_invalid = Attribute(0xFFFF)
|
||||
)
|
||||
|
||||
type input_event struct {
|
||||
data []byte
|
||||
err error
|
||||
}
|
||||
|
||||
type extract_event_res int
|
||||
|
||||
const (
|
||||
event_not_extracted extract_event_res = iota
|
||||
event_extracted
|
||||
esc_wait
|
||||
)
|
||||
|
||||
var (
|
||||
// term specific sequences
|
||||
keys []string
|
||||
funcs []string
|
||||
|
||||
// termbox inner state
|
||||
orig_tios syscall_Termios
|
||||
back_buffer cellbuf
|
||||
front_buffer cellbuf
|
||||
termw int
|
||||
termh int
|
||||
input_mode = InputEsc
|
||||
output_mode = OutputNormal
|
||||
out *os.File
|
||||
in int
|
||||
lastfg = attr_invalid
|
||||
lastbg = attr_invalid
|
||||
lastx = coord_invalid
|
||||
lasty = coord_invalid
|
||||
cursor_x = cursor_hidden
|
||||
cursor_y = cursor_hidden
|
||||
foreground = ColorDefault
|
||||
background = ColorDefault
|
||||
inbuf = make([]byte, 0, 64)
|
||||
outbuf bytes.Buffer
|
||||
sigwinch = make(chan os.Signal, 1)
|
||||
sigio = make(chan os.Signal, 1)
|
||||
quit = make(chan int)
|
||||
quitPolling chan int // get set on each initialize
|
||||
input_comm = make(chan input_event)
|
||||
interrupt_comm = make(chan struct{})
|
||||
intbuf = make([]byte, 0, 16)
|
||||
|
||||
// grayscale indexes
|
||||
grayscale = []Attribute{
|
||||
0, 17, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,
|
||||
245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 232,
|
||||
}
|
||||
)
|
||||
|
||||
func write_cursor(x, y int) {
|
||||
outbuf.WriteString("\033[")
|
||||
outbuf.Write(strconv.AppendUint(intbuf, uint64(y+1), 10))
|
||||
outbuf.WriteString(";")
|
||||
outbuf.Write(strconv.AppendUint(intbuf, uint64(x+1), 10))
|
||||
outbuf.WriteString("H")
|
||||
}
|
||||
|
||||
func write_sgr_fg(a Attribute) {
|
||||
switch output_mode {
|
||||
case Output256, Output216, OutputGrayscale:
|
||||
outbuf.WriteString("\033[38;5;")
|
||||
outbuf.Write(strconv.AppendUint(intbuf, uint64(a-1), 10))
|
||||
outbuf.WriteString("m")
|
||||
default:
|
||||
outbuf.WriteString("\033[3")
|
||||
outbuf.Write(strconv.AppendUint(intbuf, uint64(a-1), 10))
|
||||
outbuf.WriteString("m")
|
||||
}
|
||||
}
|
||||
|
||||
func write_sgr_bg(a Attribute) {
|
||||
switch output_mode {
|
||||
case Output256, Output216, OutputGrayscale:
|
||||
outbuf.WriteString("\033[48;5;")
|
||||
outbuf.Write(strconv.AppendUint(intbuf, uint64(a-1), 10))
|
||||
outbuf.WriteString("m")
|
||||
default:
|
||||
outbuf.WriteString("\033[4")
|
||||
outbuf.Write(strconv.AppendUint(intbuf, uint64(a-1), 10))
|
||||
outbuf.WriteString("m")
|
||||
}
|
||||
}
|
||||
|
||||
func write_sgr(fg, bg Attribute) {
|
||||
switch output_mode {
|
||||
case Output256, Output216, OutputGrayscale:
|
||||
outbuf.WriteString("\033[38;5;")
|
||||
outbuf.Write(strconv.AppendUint(intbuf, uint64(fg-1), 10))
|
||||
outbuf.WriteString("m")
|
||||
outbuf.WriteString("\033[48;5;")
|
||||
outbuf.Write(strconv.AppendUint(intbuf, uint64(bg-1), 10))
|
||||
outbuf.WriteString("m")
|
||||
default:
|
||||
outbuf.WriteString("\033[3")
|
||||
outbuf.Write(strconv.AppendUint(intbuf, uint64(fg-1), 10))
|
||||
outbuf.WriteString(";4")
|
||||
outbuf.Write(strconv.AppendUint(intbuf, uint64(bg-1), 10))
|
||||
outbuf.WriteString("m")
|
||||
}
|
||||
}
|
||||
|
||||
type winsize struct {
|
||||
rows uint16
|
||||
cols uint16
|
||||
xpixels uint16
|
||||
ypixels uint16
|
||||
}
|
||||
|
||||
func get_term_size(fd uintptr) (int, int) {
|
||||
var sz winsize
|
||||
_, _, _ = syscall.Syscall(syscall.SYS_IOCTL,
|
||||
fd, uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&sz)))
|
||||
return int(sz.cols), int(sz.rows)
|
||||
}
|
||||
|
||||
func send_attr(fg, bg Attribute) {
|
||||
if fg == lastfg && bg == lastbg {
|
||||
return
|
||||
}
|
||||
|
||||
outbuf.WriteString(funcs[t_sgr0])
|
||||
|
||||
var fgcol, bgcol Attribute
|
||||
|
||||
switch output_mode {
|
||||
case Output256:
|
||||
fgcol = fg & 0x1FF
|
||||
bgcol = bg & 0x1FF
|
||||
case Output216:
|
||||
fgcol = fg & 0xFF
|
||||
bgcol = bg & 0xFF
|
||||
if fgcol > 216 {
|
||||
fgcol = ColorDefault
|
||||
}
|
||||
if bgcol > 216 {
|
||||
bgcol = ColorDefault
|
||||
}
|
||||
if fgcol != ColorDefault {
|
||||
fgcol += 0x10
|
||||
}
|
||||
if bgcol != ColorDefault {
|
||||
bgcol += 0x10
|
||||
}
|
||||
case OutputGrayscale:
|
||||
fgcol = fg & 0x1F
|
||||
bgcol = bg & 0x1F
|
||||
if fgcol > 26 {
|
||||
fgcol = ColorDefault
|
||||
}
|
||||
if bgcol > 26 {
|
||||
bgcol = ColorDefault
|
||||
}
|
||||
if fgcol != ColorDefault {
|
||||
fgcol = grayscale[fgcol]
|
||||
}
|
||||
if bgcol != ColorDefault {
|
||||
bgcol = grayscale[bgcol]
|
||||
}
|
||||
default:
|
||||
fgcol = fg & 0x0F
|
||||
bgcol = bg & 0x0F
|
||||
}
|
||||
|
||||
if fgcol != ColorDefault {
|
||||
if bgcol != ColorDefault {
|
||||
write_sgr(fgcol, bgcol)
|
||||
} else {
|
||||
write_sgr_fg(fgcol)
|
||||
}
|
||||
} else if bgcol != ColorDefault {
|
||||
write_sgr_bg(bgcol)
|
||||
}
|
||||
|
||||
if fg&AttrBold != 0 {
|
||||
outbuf.WriteString(funcs[t_bold])
|
||||
}
|
||||
if bg&AttrBold != 0 {
|
||||
outbuf.WriteString(funcs[t_blink])
|
||||
}
|
||||
if fg&AttrUnderline != 0 {
|
||||
outbuf.WriteString(funcs[t_underline])
|
||||
}
|
||||
if fg&AttrReverse|bg&AttrReverse != 0 {
|
||||
outbuf.WriteString(funcs[t_reverse])
|
||||
}
|
||||
|
||||
lastfg, lastbg = fg, bg
|
||||
}
|
||||
|
||||
func send_char(x, y int, ch rune) {
|
||||
var buf [8]byte
|
||||
n := utf8.EncodeRune(buf[:], ch)
|
||||
if x-1 != lastx || y != lasty {
|
||||
write_cursor(x, y)
|
||||
}
|
||||
lastx, lasty = x, y
|
||||
outbuf.Write(buf[:n])
|
||||
}
|
||||
|
||||
func flush() error {
|
||||
_, err := io.Copy(out, &outbuf)
|
||||
outbuf.Reset()
|
||||
return err
|
||||
}
|
||||
|
||||
func send_clear() error {
|
||||
send_attr(foreground, background)
|
||||
outbuf.WriteString(funcs[t_clear_screen])
|
||||
if !is_cursor_hidden(cursor_x, cursor_y) {
|
||||
write_cursor(cursor_x, cursor_y)
|
||||
}
|
||||
|
||||
// we need to invalidate cursor position too and these two vars are
|
||||
// used only for simple cursor positioning optimization, cursor
|
||||
// actually may be in the correct place, but we simply discard
|
||||
// optimization once and it gives us simple solution for the case when
|
||||
// cursor moved
|
||||
lastx = coord_invalid
|
||||
lasty = coord_invalid
|
||||
|
||||
return flush()
|
||||
}
|
||||
|
||||
func update_size_maybe() error {
|
||||
w, h := get_term_size(out.Fd())
|
||||
if w != termw || h != termh {
|
||||
termw, termh = w, h
|
||||
back_buffer.resize(termw, termh)
|
||||
front_buffer.resize(termw, termh)
|
||||
front_buffer.clear()
|
||||
return send_clear()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func tcsetattr(fd uintptr, termios *syscall_Termios) error {
|
||||
r, _, e := syscall.Syscall(syscall.SYS_IOCTL,
|
||||
fd, uintptr(syscall_TCSETS), uintptr(unsafe.Pointer(termios)))
|
||||
if r != 0 {
|
||||
return os.NewSyscallError("SYS_IOCTL", e)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func tcgetattr(fd uintptr, termios *syscall_Termios) error {
|
||||
r, _, e := syscall.Syscall(syscall.SYS_IOCTL,
|
||||
fd, uintptr(syscall_TCGETS), uintptr(unsafe.Pointer(termios)))
|
||||
if r != 0 {
|
||||
return os.NewSyscallError("SYS_IOCTL", e)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parse_mouse_event(event *Event, buf string) (int, bool) {
|
||||
if strings.HasPrefix(buf, "\033[M") && len(buf) >= 6 {
|
||||
// X10 mouse encoding, the simplest one
|
||||
// \033 [ M Cb Cx Cy
|
||||
b := buf[3] - 32
|
||||
switch b & 3 {
|
||||
case 0:
|
||||
if b&64 != 0 {
|
||||
event.Key = MouseWheelUp
|
||||
} else {
|
||||
event.Key = MouseLeft
|
||||
}
|
||||
case 1:
|
||||
if b&64 != 0 {
|
||||
event.Key = MouseWheelDown
|
||||
} else {
|
||||
event.Key = MouseMiddle
|
||||
}
|
||||
case 2:
|
||||
event.Key = MouseRight
|
||||
case 3:
|
||||
event.Key = MouseRelease
|
||||
default:
|
||||
return 6, false
|
||||
}
|
||||
event.Type = EventMouse // KeyEvent by default
|
||||
if b&32 != 0 {
|
||||
event.Mod |= ModMotion
|
||||
}
|
||||
|
||||
// the coord is 1,1 for upper left
|
||||
event.MouseX = int(buf[4]) - 1 - 32
|
||||
event.MouseY = int(buf[5]) - 1 - 32
|
||||
return 6, true
|
||||
} else if strings.HasPrefix(buf, "\033[<") || strings.HasPrefix(buf, "\033[") {
|
||||
// xterm 1006 extended mode or urxvt 1015 extended mode
|
||||
// xterm: \033 [ < Cb ; Cx ; Cy (M or m)
|
||||
// urxvt: \033 [ Cb ; Cx ; Cy M
|
||||
|
||||
// find the first M or m, that's where we stop
|
||||
mi := strings.IndexAny(buf, "Mm")
|
||||
if mi == -1 {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// whether it's a capital M or not
|
||||
isM := buf[mi] == 'M'
|
||||
|
||||
// whether it's urxvt or not
|
||||
isU := false
|
||||
|
||||
// buf[2] is safe here, because having M or m found means we have at
|
||||
// least 3 bytes in a string
|
||||
if buf[2] == '<' {
|
||||
buf = buf[3:mi]
|
||||
} else {
|
||||
isU = true
|
||||
buf = buf[2:mi]
|
||||
}
|
||||
|
||||
s1 := strings.Index(buf, ";")
|
||||
s2 := strings.LastIndex(buf, ";")
|
||||
// not found or only one ';'
|
||||
if s1 == -1 || s2 == -1 || s1 == s2 {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
n1, err := strconv.ParseInt(buf[0:s1], 10, 64)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
n2, err := strconv.ParseInt(buf[s1+1:s2], 10, 64)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
n3, err := strconv.ParseInt(buf[s2+1:], 10, 64)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// on urxvt, first number is encoded exactly as in X10, but we need to
|
||||
// make it zero-based, on xterm it is zero-based already
|
||||
if isU {
|
||||
n1 -= 32
|
||||
}
|
||||
switch n1 & 3 {
|
||||
case 0:
|
||||
if n1&64 != 0 {
|
||||
event.Key = MouseWheelUp
|
||||
} else {
|
||||
event.Key = MouseLeft
|
||||
}
|
||||
case 1:
|
||||
if n1&64 != 0 {
|
||||
event.Key = MouseWheelDown
|
||||
} else {
|
||||
event.Key = MouseMiddle
|
||||
}
|
||||
case 2:
|
||||
event.Key = MouseRight
|
||||
case 3:
|
||||
event.Key = MouseRelease
|
||||
default:
|
||||
return mi + 1, false
|
||||
}
|
||||
if !isM {
|
||||
// on xterm mouse release is signaled by lowercase m
|
||||
event.Key = MouseRelease
|
||||
}
|
||||
|
||||
event.Type = EventMouse // KeyEvent by default
|
||||
if n1&32 != 0 {
|
||||
event.Mod |= ModMotion
|
||||
}
|
||||
|
||||
event.MouseX = int(n2) - 1
|
||||
event.MouseY = int(n3) - 1
|
||||
return mi + 1, true
|
||||
}
|
||||
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func parse_escape_sequence(event *Event, buf []byte) (int, bool) {
|
||||
bufstr := string(buf)
|
||||
for i, key := range keys {
|
||||
if strings.HasPrefix(bufstr, key) {
|
||||
event.Ch = 0
|
||||
event.Key = Key(0xFFFF - i)
|
||||
return len(key), true
|
||||
}
|
||||
}
|
||||
|
||||
// if none of the keys match, let's try mouse sequences
|
||||
return parse_mouse_event(event, bufstr)
|
||||
}
|
||||
|
||||
func extract_raw_event(data []byte, event *Event) bool {
|
||||
if len(inbuf) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
n := len(data)
|
||||
if n == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
n = copy(data, inbuf)
|
||||
copy(inbuf, inbuf[n:])
|
||||
inbuf = inbuf[:len(inbuf)-n]
|
||||
|
||||
event.N = n
|
||||
event.Type = EventRaw
|
||||
return true
|
||||
}
|
||||
|
||||
func extract_event(inbuf []byte, event *Event, allow_esc_wait bool) extract_event_res {
|
||||
if len(inbuf) == 0 {
|
||||
event.N = 0
|
||||
return event_not_extracted
|
||||
}
|
||||
|
||||
if inbuf[0] == '\033' {
|
||||
// possible escape sequence
|
||||
if n, ok := parse_escape_sequence(event, inbuf); n != 0 {
|
||||
event.N = n
|
||||
if ok {
|
||||
return event_extracted
|
||||
} else {
|
||||
return event_not_extracted
|
||||
}
|
||||
}
|
||||
|
||||
// possible partially read escape sequence; trigger a wait if appropriate
|
||||
if enable_wait_for_escape_sequence() && allow_esc_wait {
|
||||
event.N = 0
|
||||
return esc_wait
|
||||
}
|
||||
|
||||
// it's not escape sequence, then it's Alt or Esc, check input_mode
|
||||
switch {
|
||||
case input_mode&InputEsc != 0:
|
||||
// if we're in escape mode, fill Esc event, pop buffer, return success
|
||||
event.Ch = 0
|
||||
event.Key = KeyEsc
|
||||
event.Mod = 0
|
||||
event.N = 1
|
||||
return event_extracted
|
||||
case input_mode&InputAlt != 0:
|
||||
// if we're in alt mode, set Alt modifier to event and redo parsing
|
||||
event.Mod = ModAlt
|
||||
status := extract_event(inbuf[1:], event, false)
|
||||
if status == event_extracted {
|
||||
event.N++
|
||||
} else {
|
||||
event.N = 0
|
||||
}
|
||||
return status
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
||||
|
||||
// if we're here, this is not an escape sequence and not an alt sequence
|
||||
// so, it's a FUNCTIONAL KEY or a UNICODE character
|
||||
|
||||
// first of all check if it's a functional key
|
||||
if Key(inbuf[0]) <= KeySpace || Key(inbuf[0]) == KeyBackspace2 {
|
||||
// fill event, pop buffer, return success
|
||||
event.Ch = 0
|
||||
event.Key = Key(inbuf[0])
|
||||
event.N = 1
|
||||
return event_extracted
|
||||
}
|
||||
|
||||
// the only possible option is utf8 rune
|
||||
if r, n := utf8.DecodeRune(inbuf); r != utf8.RuneError {
|
||||
event.Ch = r
|
||||
event.Key = 0
|
||||
event.N = n
|
||||
return event_extracted
|
||||
}
|
||||
|
||||
return event_not_extracted
|
||||
}
|
||||
|
||||
func fcntl(fd int, cmd int, arg int) (val int, err error) {
|
||||
r, _, e := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), uintptr(cmd),
|
||||
uintptr(arg))
|
||||
val = int(r)
|
||||
if e != 0 {
|
||||
err = e
|
||||
}
|
||||
return
|
||||
}
|
59
vendor/github.com/jesseduffield/termbox-go/termbox_common.go
generated
vendored
59
vendor/github.com/jesseduffield/termbox-go/termbox_common.go
generated
vendored
@ -1,59 +0,0 @@
|
||||
package termbox
|
||||
|
||||
// private API, common OS agnostic part
|
||||
|
||||
type cellbuf struct {
|
||||
width int
|
||||
height int
|
||||
cells []Cell
|
||||
}
|
||||
|
||||
func (this *cellbuf) init(width, height int) {
|
||||
this.width = width
|
||||
this.height = height
|
||||
this.cells = make([]Cell, width*height)
|
||||
}
|
||||
|
||||
func (this *cellbuf) resize(width, height int) {
|
||||
if this.width == width && this.height == height {
|
||||
return
|
||||
}
|
||||
|
||||
oldw := this.width
|
||||
oldh := this.height
|
||||
oldcells := this.cells
|
||||
|
||||
this.init(width, height)
|
||||
this.clear()
|
||||
|
||||
minw, minh := oldw, oldh
|
||||
|
||||
if width < minw {
|
||||
minw = width
|
||||
}
|
||||
if height < minh {
|
||||
minh = height
|
||||
}
|
||||
|
||||
for i := 0; i < minh; i++ {
|
||||
srco, dsto := i*oldw, i*width
|
||||
src := oldcells[srco : srco+minw]
|
||||
dst := this.cells[dsto : dsto+minw]
|
||||
copy(dst, src)
|
||||
}
|
||||
}
|
||||
|
||||
func (this *cellbuf) clear() {
|
||||
for i := range this.cells {
|
||||
c := &this.cells[i]
|
||||
c.Ch = ' '
|
||||
c.Fg = foreground
|
||||
c.Bg = background
|
||||
}
|
||||
}
|
||||
|
||||
const cursor_hidden = -1
|
||||
|
||||
func is_cursor_hidden(x, y int) bool {
|
||||
return x == cursor_hidden || y == cursor_hidden
|
||||
}
|
915
vendor/github.com/jesseduffield/termbox-go/termbox_windows.go
generated
vendored
915
vendor/github.com/jesseduffield/termbox-go/termbox_windows.go
generated
vendored
@ -1,915 +0,0 @@
|
||||
package termbox
|
||||
|
||||
import "math"
|
||||
import "syscall"
|
||||
import "unsafe"
|
||||
import "unicode/utf16"
|
||||
import "github.com/mattn/go-runewidth"
|
||||
|
||||
type (
|
||||
wchar uint16
|
||||
short int16
|
||||
dword uint32
|
||||
word uint16
|
||||
char_info struct {
|
||||
char wchar
|
||||
attr word
|
||||
}
|
||||
coord struct {
|
||||
x short
|
||||
y short
|
||||
}
|
||||
small_rect struct {
|
||||
left short
|
||||
top short
|
||||
right short
|
||||
bottom short
|
||||
}
|
||||
console_screen_buffer_info struct {
|
||||
size coord
|
||||
cursor_position coord
|
||||
attributes word
|
||||
window small_rect
|
||||
maximum_window_size coord
|
||||
}
|
||||
console_cursor_info struct {
|
||||
size dword
|
||||
visible int32
|
||||
}
|
||||
input_record struct {
|
||||
event_type word
|
||||
_ [2]byte
|
||||
event [16]byte
|
||||
}
|
||||
key_event_record struct {
|
||||
key_down int32
|
||||
repeat_count word
|
||||
virtual_key_code word
|
||||
virtual_scan_code word
|
||||
unicode_char wchar
|
||||
control_key_state dword
|
||||
}
|
||||
window_buffer_size_record struct {
|
||||
size coord
|
||||
}
|
||||
mouse_event_record struct {
|
||||
mouse_pos coord
|
||||
button_state dword
|
||||
control_key_state dword
|
||||
event_flags dword
|
||||
}
|
||||
console_font_info struct {
|
||||
font uint32
|
||||
font_size coord
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
mouse_lmb = 0x1
|
||||
mouse_rmb = 0x2
|
||||
mouse_mmb = 0x4 | 0x8 | 0x10
|
||||
SM_CXMIN = 28
|
||||
SM_CYMIN = 29
|
||||
)
|
||||
|
||||
func (this coord) uintptr() uintptr {
|
||||
return uintptr(*(*int32)(unsafe.Pointer(&this)))
|
||||
}
|
||||
|
||||
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
var moduser32 = syscall.NewLazyDLL("user32.dll")
|
||||
var is_cjk = runewidth.IsEastAsian()
|
||||
|
||||
var (
|
||||
proc_set_console_active_screen_buffer = kernel32.NewProc("SetConsoleActiveScreenBuffer")
|
||||
proc_set_console_screen_buffer_size = kernel32.NewProc("SetConsoleScreenBufferSize")
|
||||
proc_create_console_screen_buffer = kernel32.NewProc("CreateConsoleScreenBuffer")
|
||||
proc_get_console_screen_buffer_info = kernel32.NewProc("GetConsoleScreenBufferInfo")
|
||||
proc_write_console_output = kernel32.NewProc("WriteConsoleOutputW")
|
||||
proc_write_console_output_character = kernel32.NewProc("WriteConsoleOutputCharacterW")
|
||||
proc_write_console_output_attribute = kernel32.NewProc("WriteConsoleOutputAttribute")
|
||||
proc_set_console_cursor_info = kernel32.NewProc("SetConsoleCursorInfo")
|
||||
proc_set_console_cursor_position = kernel32.NewProc("SetConsoleCursorPosition")
|
||||
proc_get_console_cursor_info = kernel32.NewProc("GetConsoleCursorInfo")
|
||||
proc_read_console_input = kernel32.NewProc("ReadConsoleInputW")
|
||||
proc_get_console_mode = kernel32.NewProc("GetConsoleMode")
|
||||
proc_set_console_mode = kernel32.NewProc("SetConsoleMode")
|
||||
proc_fill_console_output_character = kernel32.NewProc("FillConsoleOutputCharacterW")
|
||||
proc_fill_console_output_attribute = kernel32.NewProc("FillConsoleOutputAttribute")
|
||||
proc_create_event = kernel32.NewProc("CreateEventW")
|
||||
proc_wait_for_multiple_objects = kernel32.NewProc("WaitForMultipleObjects")
|
||||
proc_set_event = kernel32.NewProc("SetEvent")
|
||||
proc_get_current_console_font = kernel32.NewProc("GetCurrentConsoleFont")
|
||||
get_system_metrics = moduser32.NewProc("GetSystemMetrics")
|
||||
)
|
||||
|
||||
func set_console_active_screen_buffer(h syscall.Handle) (err error) {
|
||||
r0, _, e1 := syscall.Syscall(proc_set_console_active_screen_buffer.Addr(),
|
||||
1, uintptr(h), 0, 0)
|
||||
if int(r0) == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func set_console_screen_buffer_size(h syscall.Handle, size coord) (err error) {
|
||||
r0, _, e1 := syscall.Syscall(proc_set_console_screen_buffer_size.Addr(),
|
||||
2, uintptr(h), size.uintptr(), 0)
|
||||
if int(r0) == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func create_console_screen_buffer() (h syscall.Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall6(proc_create_console_screen_buffer.Addr(),
|
||||
5, uintptr(generic_read|generic_write), 0, 0, console_textmode_buffer, 0, 0)
|
||||
if int(r0) == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return syscall.Handle(r0), err
|
||||
}
|
||||
|
||||
func get_console_screen_buffer_info(h syscall.Handle, info *console_screen_buffer_info) (err error) {
|
||||
r0, _, e1 := syscall.Syscall(proc_get_console_screen_buffer_info.Addr(),
|
||||
2, uintptr(h), uintptr(unsafe.Pointer(info)), 0)
|
||||
if int(r0) == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func write_console_output(h syscall.Handle, chars []char_info, dst small_rect) (err error) {
|
||||
tmp_coord = coord{dst.right - dst.left + 1, dst.bottom - dst.top + 1}
|
||||
tmp_rect = dst
|
||||
r0, _, e1 := syscall.Syscall6(proc_write_console_output.Addr(),
|
||||
5, uintptr(h), uintptr(unsafe.Pointer(&chars[0])), tmp_coord.uintptr(),
|
||||
tmp_coord0.uintptr(), uintptr(unsafe.Pointer(&tmp_rect)), 0)
|
||||
if int(r0) == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func write_console_output_character(h syscall.Handle, chars []wchar, pos coord) (err error) {
|
||||
r0, _, e1 := syscall.Syscall6(proc_write_console_output_character.Addr(),
|
||||
5, uintptr(h), uintptr(unsafe.Pointer(&chars[0])), uintptr(len(chars)),
|
||||
pos.uintptr(), uintptr(unsafe.Pointer(&tmp_arg)), 0)
|
||||
if int(r0) == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func write_console_output_attribute(h syscall.Handle, attrs []word, pos coord) (err error) {
|
||||
r0, _, e1 := syscall.Syscall6(proc_write_console_output_attribute.Addr(),
|
||||
5, uintptr(h), uintptr(unsafe.Pointer(&attrs[0])), uintptr(len(attrs)),
|
||||
pos.uintptr(), uintptr(unsafe.Pointer(&tmp_arg)), 0)
|
||||
if int(r0) == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func set_console_cursor_info(h syscall.Handle, info *console_cursor_info) (err error) {
|
||||
r0, _, e1 := syscall.Syscall(proc_set_console_cursor_info.Addr(),
|
||||
2, uintptr(h), uintptr(unsafe.Pointer(info)), 0)
|
||||
if int(r0) == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func get_console_cursor_info(h syscall.Handle, info *console_cursor_info) (err error) {
|
||||
r0, _, e1 := syscall.Syscall(proc_get_console_cursor_info.Addr(),
|
||||
2, uintptr(h), uintptr(unsafe.Pointer(info)), 0)
|
||||
if int(r0) == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func set_console_cursor_position(h syscall.Handle, pos coord) (err error) {
|
||||
r0, _, e1 := syscall.Syscall(proc_set_console_cursor_position.Addr(),
|
||||
2, uintptr(h), pos.uintptr(), 0)
|
||||
if int(r0) == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func read_console_input(h syscall.Handle, record *input_record) (err error) {
|
||||
r0, _, e1 := syscall.Syscall6(proc_read_console_input.Addr(),
|
||||
4, uintptr(h), uintptr(unsafe.Pointer(record)), 1, uintptr(unsafe.Pointer(&tmp_arg)), 0, 0)
|
||||
if int(r0) == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func get_console_mode(h syscall.Handle, mode *dword) (err error) {
|
||||
r0, _, e1 := syscall.Syscall(proc_get_console_mode.Addr(),
|
||||
2, uintptr(h), uintptr(unsafe.Pointer(mode)), 0)
|
||||
if int(r0) == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func set_console_mode(h syscall.Handle, mode dword) (err error) {
|
||||
r0, _, e1 := syscall.Syscall(proc_set_console_mode.Addr(),
|
||||
2, uintptr(h), uintptr(mode), 0)
|
||||
if int(r0) == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func fill_console_output_character(h syscall.Handle, char wchar, n int) (err error) {
|
||||
r0, _, e1 := syscall.Syscall6(proc_fill_console_output_character.Addr(),
|
||||
5, uintptr(h), uintptr(char), uintptr(n), tmp_coord.uintptr(),
|
||||
uintptr(unsafe.Pointer(&tmp_arg)), 0)
|
||||
if int(r0) == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func fill_console_output_attribute(h syscall.Handle, attr word, n int) (err error) {
|
||||
r0, _, e1 := syscall.Syscall6(proc_fill_console_output_attribute.Addr(),
|
||||
5, uintptr(h), uintptr(attr), uintptr(n), tmp_coord.uintptr(),
|
||||
uintptr(unsafe.Pointer(&tmp_arg)), 0)
|
||||
if int(r0) == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func create_event() (out syscall.Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall6(proc_create_event.Addr(),
|
||||
4, 0, 0, 0, 0, 0, 0)
|
||||
if int(r0) == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return syscall.Handle(r0), err
|
||||
}
|
||||
|
||||
func wait_for_multiple_objects(objects []syscall.Handle) (err error) {
|
||||
r0, _, e1 := syscall.Syscall6(proc_wait_for_multiple_objects.Addr(),
|
||||
4, uintptr(len(objects)), uintptr(unsafe.Pointer(&objects[0])),
|
||||
0, 0xFFFFFFFF, 0, 0)
|
||||
if uint32(r0) == 0xFFFFFFFF {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func set_event(ev syscall.Handle) (err error) {
|
||||
r0, _, e1 := syscall.Syscall(proc_set_event.Addr(),
|
||||
1, uintptr(ev), 0, 0)
|
||||
if int(r0) == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func get_current_console_font(h syscall.Handle, info *console_font_info) (err error) {
|
||||
r0, _, e1 := syscall.Syscall(proc_get_current_console_font.Addr(),
|
||||
3, uintptr(h), 0, uintptr(unsafe.Pointer(info)))
|
||||
if int(r0) == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
} else {
|
||||
err = syscall.EINVAL
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type diff_msg struct {
|
||||
pos short
|
||||
lines short
|
||||
chars []char_info
|
||||
}
|
||||
|
||||
type input_event struct {
|
||||
event Event
|
||||
err error
|
||||
}
|
||||
|
||||
var (
|
||||
orig_cursor_info console_cursor_info
|
||||
orig_size coord
|
||||
orig_mode dword
|
||||
orig_screen syscall.Handle
|
||||
back_buffer cellbuf
|
||||
front_buffer cellbuf
|
||||
term_size coord
|
||||
input_mode = InputEsc
|
||||
cursor_x = cursor_hidden
|
||||
cursor_y = cursor_hidden
|
||||
foreground = ColorDefault
|
||||
background = ColorDefault
|
||||
in syscall.Handle
|
||||
out syscall.Handle
|
||||
interrupt syscall.Handle
|
||||
charbuf []char_info
|
||||
diffbuf []diff_msg
|
||||
beg_x = -1
|
||||
beg_y = -1
|
||||
beg_i = -1
|
||||
input_comm = make(chan Event)
|
||||
interrupt_comm = make(chan struct{})
|
||||
cancel_comm = make(chan bool, 1)
|
||||
cancel_done_comm = make(chan bool)
|
||||
alt_mode_esc = false
|
||||
|
||||
// these ones just to prevent heap allocs at all costs
|
||||
tmp_info console_screen_buffer_info
|
||||
tmp_arg dword
|
||||
tmp_coord0 = coord{0, 0}
|
||||
tmp_coord = coord{0, 0}
|
||||
tmp_rect = small_rect{0, 0, 0, 0}
|
||||
tmp_finfo console_font_info
|
||||
)
|
||||
|
||||
func get_cursor_position(out syscall.Handle) coord {
|
||||
err := get_console_screen_buffer_info(out, &tmp_info)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return tmp_info.cursor_position
|
||||
}
|
||||
|
||||
func get_term_size(out syscall.Handle) coord {
|
||||
err := get_console_screen_buffer_info(out, &tmp_info)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return tmp_info.size
|
||||
}
|
||||
|
||||
func get_win_min_size(out syscall.Handle) coord {
|
||||
x, _, err := get_system_metrics.Call(SM_CXMIN)
|
||||
y, _, err := get_system_metrics.Call(SM_CYMIN)
|
||||
|
||||
if x == 0 || y == 0 {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
err1 := get_current_console_font(out, &tmp_finfo)
|
||||
if err1 != nil {
|
||||
panic(err1)
|
||||
}
|
||||
|
||||
return coord{
|
||||
x: short(math.Ceil(float64(x) / float64(tmp_finfo.font_size.x))),
|
||||
y: short(math.Ceil(float64(y) / float64(tmp_finfo.font_size.y))),
|
||||
}
|
||||
}
|
||||
|
||||
func get_win_size(out syscall.Handle) coord {
|
||||
err := get_console_screen_buffer_info(out, &tmp_info)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
min_size := get_win_min_size(out)
|
||||
|
||||
size := coord{
|
||||
x: tmp_info.window.right - tmp_info.window.left + 1,
|
||||
y: tmp_info.window.bottom - tmp_info.window.top + 1,
|
||||
}
|
||||
|
||||
if size.x < min_size.x {
|
||||
size.x = min_size.x
|
||||
}
|
||||
|
||||
if size.y < min_size.y {
|
||||
size.y = min_size.y
|
||||
}
|
||||
|
||||
return size
|
||||
}
|
||||
|
||||
func update_size_maybe() {
|
||||
size := get_win_size(out)
|
||||
if size.x != term_size.x || size.y != term_size.y {
|
||||
set_console_screen_buffer_size(out, size)
|
||||
term_size = size
|
||||
back_buffer.resize(int(size.x), int(size.y))
|
||||
front_buffer.resize(int(size.x), int(size.y))
|
||||
front_buffer.clear()
|
||||
clear()
|
||||
|
||||
area := int(size.x) * int(size.y)
|
||||
if cap(charbuf) < area {
|
||||
charbuf = make([]char_info, 0, area)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var color_table_bg = []word{
|
||||
0, // default (black)
|
||||
0, // black
|
||||
background_red,
|
||||
background_green,
|
||||
background_red | background_green, // yellow
|
||||
background_blue,
|
||||
background_red | background_blue, // magenta
|
||||
background_green | background_blue, // cyan
|
||||
background_red | background_blue | background_green, // white
|
||||
}
|
||||
|
||||
var color_table_fg = []word{
|
||||
foreground_red | foreground_blue | foreground_green, // default (white)
|
||||
0,
|
||||
foreground_red,
|
||||
foreground_green,
|
||||
foreground_red | foreground_green, // yellow
|
||||
foreground_blue,
|
||||
foreground_red | foreground_blue, // magenta
|
||||
foreground_green | foreground_blue, // cyan
|
||||
foreground_red | foreground_blue | foreground_green, // white
|
||||
}
|
||||
|
||||
const (
|
||||
replacement_char = '\uFFFD'
|
||||
max_rune = '\U0010FFFF'
|
||||
surr1 = 0xd800
|
||||
surr2 = 0xdc00
|
||||
surr3 = 0xe000
|
||||
surr_self = 0x10000
|
||||
)
|
||||
|
||||
func append_diff_line(y int) int {
|
||||
n := 0
|
||||
for x := 0; x < front_buffer.width; {
|
||||
cell_offset := y*front_buffer.width + x
|
||||
back := &back_buffer.cells[cell_offset]
|
||||
front := &front_buffer.cells[cell_offset]
|
||||
attr, char := cell_to_char_info(*back)
|
||||
charbuf = append(charbuf, char_info{attr: attr, char: char[0]})
|
||||
*front = *back
|
||||
n++
|
||||
w := runewidth.RuneWidth(back.Ch)
|
||||
if w == 0 || w == 2 && runewidth.IsAmbiguousWidth(back.Ch) {
|
||||
w = 1
|
||||
}
|
||||
x += w
|
||||
// If not CJK, fill trailing space with whitespace
|
||||
if !is_cjk && w == 2 {
|
||||
charbuf = append(charbuf, char_info{attr: attr, char: ' '})
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// compares 'back_buffer' with 'front_buffer' and prepares all changes in the form of
|
||||
// 'diff_msg's in the 'diff_buf'
|
||||
func prepare_diff_messages() {
|
||||
// clear buffers
|
||||
diffbuf = diffbuf[:0]
|
||||
charbuf = charbuf[:0]
|
||||
|
||||
var diff diff_msg
|
||||
gbeg := 0
|
||||
for y := 0; y < front_buffer.height; y++ {
|
||||
same := true
|
||||
line_offset := y * front_buffer.width
|
||||
for x := 0; x < front_buffer.width; x++ {
|
||||
cell_offset := line_offset + x
|
||||
back := &back_buffer.cells[cell_offset]
|
||||
front := &front_buffer.cells[cell_offset]
|
||||
if *back != *front {
|
||||
same = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if same && diff.lines > 0 {
|
||||
diffbuf = append(diffbuf, diff)
|
||||
diff = diff_msg{}
|
||||
}
|
||||
if !same {
|
||||
beg := len(charbuf)
|
||||
end := beg + append_diff_line(y)
|
||||
if diff.lines == 0 {
|
||||
diff.pos = short(y)
|
||||
gbeg = beg
|
||||
}
|
||||
diff.lines++
|
||||
diff.chars = charbuf[gbeg:end]
|
||||
}
|
||||
}
|
||||
if diff.lines > 0 {
|
||||
diffbuf = append(diffbuf, diff)
|
||||
diff = diff_msg{}
|
||||
}
|
||||
}
|
||||
|
||||
func get_ct(table []word, idx int) word {
|
||||
idx = idx & 0x0F
|
||||
if idx >= len(table) {
|
||||
idx = len(table) - 1
|
||||
}
|
||||
return table[idx]
|
||||
}
|
||||
|
||||
func cell_to_char_info(c Cell) (attr word, wc [2]wchar) {
|
||||
attr = get_ct(color_table_fg, int(c.Fg)) | get_ct(color_table_bg, int(c.Bg))
|
||||
if c.Fg&AttrReverse|c.Bg&AttrReverse != 0 {
|
||||
attr = (attr&0xF0)>>4 | (attr&0x0F)<<4
|
||||
}
|
||||
if c.Fg&AttrBold != 0 {
|
||||
attr |= foreground_intensity
|
||||
}
|
||||
if c.Bg&AttrBold != 0 {
|
||||
attr |= background_intensity
|
||||
}
|
||||
|
||||
r0, r1 := utf16.EncodeRune(c.Ch)
|
||||
if r0 == 0xFFFD {
|
||||
wc[0] = wchar(c.Ch)
|
||||
wc[1] = ' '
|
||||
} else {
|
||||
wc[0] = wchar(r0)
|
||||
wc[1] = wchar(r1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func move_cursor(x, y int) {
|
||||
err := set_console_cursor_position(out, coord{short(x), short(y)})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func show_cursor(visible bool) {
|
||||
var v int32
|
||||
if visible {
|
||||
v = 1
|
||||
}
|
||||
|
||||
var info console_cursor_info
|
||||
info.size = 100
|
||||
info.visible = v
|
||||
err := set_console_cursor_info(out, &info)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func clear() {
|
||||
var err error
|
||||
attr, char := cell_to_char_info(Cell{
|
||||
' ',
|
||||
foreground,
|
||||
background,
|
||||
})
|
||||
|
||||
area := int(term_size.x) * int(term_size.y)
|
||||
err = fill_console_output_attribute(out, attr, area)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = fill_console_output_character(out, char[0], area)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !is_cursor_hidden(cursor_x, cursor_y) {
|
||||
move_cursor(cursor_x, cursor_y)
|
||||
}
|
||||
}
|
||||
|
||||
func key_event_record_to_event(r *key_event_record) (Event, bool) {
|
||||
if r.key_down == 0 {
|
||||
return Event{}, false
|
||||
}
|
||||
|
||||
e := Event{Type: EventKey}
|
||||
if input_mode&InputAlt != 0 {
|
||||
if alt_mode_esc {
|
||||
e.Mod = ModAlt
|
||||
alt_mode_esc = false
|
||||
}
|
||||
if r.control_key_state&(left_alt_pressed|right_alt_pressed) != 0 {
|
||||
e.Mod = ModAlt
|
||||
}
|
||||
}
|
||||
|
||||
ctrlpressed := r.control_key_state&(left_ctrl_pressed|right_ctrl_pressed) != 0
|
||||
|
||||
if r.virtual_key_code >= vk_f1 && r.virtual_key_code <= vk_f12 {
|
||||
switch r.virtual_key_code {
|
||||
case vk_f1:
|
||||
e.Key = KeyF1
|
||||
case vk_f2:
|
||||
e.Key = KeyF2
|
||||
case vk_f3:
|
||||
e.Key = KeyF3
|
||||
case vk_f4:
|
||||
e.Key = KeyF4
|
||||
case vk_f5:
|
||||
e.Key = KeyF5
|
||||
case vk_f6:
|
||||
e.Key = KeyF6
|
||||
case vk_f7:
|
||||
e.Key = KeyF7
|
||||
case vk_f8:
|
||||
e.Key = KeyF8
|
||||
case vk_f9:
|
||||
e.Key = KeyF9
|
||||
case vk_f10:
|
||||
e.Key = KeyF10
|
||||
case vk_f11:
|
||||
e.Key = KeyF11
|
||||
case vk_f12:
|
||||
e.Key = KeyF12
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
return e, true
|
||||
}
|
||||
|
||||
if r.virtual_key_code <= vk_delete {
|
||||
switch r.virtual_key_code {
|
||||
case vk_insert:
|
||||
e.Key = KeyInsert
|
||||
case vk_delete:
|
||||
e.Key = KeyDelete
|
||||
case vk_home:
|
||||
e.Key = KeyHome
|
||||
case vk_end:
|
||||
e.Key = KeyEnd
|
||||
case vk_pgup:
|
||||
e.Key = KeyPgup
|
||||
case vk_pgdn:
|
||||
e.Key = KeyPgdn
|
||||
case vk_arrow_up:
|
||||
e.Key = KeyArrowUp
|
||||
case vk_arrow_down:
|
||||
e.Key = KeyArrowDown
|
||||
case vk_arrow_left:
|
||||
e.Key = KeyArrowLeft
|
||||
case vk_arrow_right:
|
||||
e.Key = KeyArrowRight
|
||||
case vk_backspace:
|
||||
if ctrlpressed {
|
||||
e.Key = KeyBackspace2
|
||||
} else {
|
||||
e.Key = KeyBackspace
|
||||
}
|
||||
case vk_tab:
|
||||
e.Key = KeyTab
|
||||
case vk_enter:
|
||||
e.Key = KeyEnter
|
||||
case vk_esc:
|
||||
switch {
|
||||
case input_mode&InputEsc != 0:
|
||||
e.Key = KeyEsc
|
||||
case input_mode&InputAlt != 0:
|
||||
alt_mode_esc = true
|
||||
return Event{}, false
|
||||
}
|
||||
case vk_space:
|
||||
if ctrlpressed {
|
||||
// manual return here, because KeyCtrlSpace is zero
|
||||
e.Key = KeyCtrlSpace
|
||||
return e, true
|
||||
} else {
|
||||
e.Key = KeySpace
|
||||
}
|
||||
}
|
||||
|
||||
if e.Key != 0 {
|
||||
return e, true
|
||||
}
|
||||
}
|
||||
|
||||
if ctrlpressed {
|
||||
if Key(r.unicode_char) >= KeyCtrlA && Key(r.unicode_char) <= KeyCtrlRsqBracket {
|
||||
e.Key = Key(r.unicode_char)
|
||||
if input_mode&InputAlt != 0 && e.Key == KeyEsc {
|
||||
alt_mode_esc = true
|
||||
return Event{}, false
|
||||
}
|
||||
return e, true
|
||||
}
|
||||
switch r.virtual_key_code {
|
||||
case 192, 50:
|
||||
// manual return here, because KeyCtrl2 is zero
|
||||
e.Key = KeyCtrl2
|
||||
return e, true
|
||||
case 51:
|
||||
if input_mode&InputAlt != 0 {
|
||||
alt_mode_esc = true
|
||||
return Event{}, false
|
||||
}
|
||||
e.Key = KeyCtrl3
|
||||
case 52:
|
||||
e.Key = KeyCtrl4
|
||||
case 53:
|
||||
e.Key = KeyCtrl5
|
||||
case 54:
|
||||
e.Key = KeyCtrl6
|
||||
case 189, 191, 55:
|
||||
e.Key = KeyCtrl7
|
||||
case 8, 56:
|
||||
e.Key = KeyCtrl8
|
||||
}
|
||||
|
||||
if e.Key != 0 {
|
||||
return e, true
|
||||
}
|
||||
}
|
||||
|
||||
if r.unicode_char != 0 {
|
||||
e.Ch = rune(r.unicode_char)
|
||||
return e, true
|
||||
}
|
||||
|
||||
return Event{}, false
|
||||
}
|
||||
|
||||
func input_event_producer() {
|
||||
var r input_record
|
||||
var err error
|
||||
var last_button Key
|
||||
var last_button_pressed Key
|
||||
var last_state = dword(0)
|
||||
var last_x, last_y = -1, -1
|
||||
handles := []syscall.Handle{in, interrupt}
|
||||
for {
|
||||
err = wait_for_multiple_objects(handles)
|
||||
if err != nil {
|
||||
input_comm <- Event{Type: EventError, Err: err}
|
||||
}
|
||||
|
||||
select {
|
||||
case <-cancel_comm:
|
||||
cancel_done_comm <- true
|
||||
return
|
||||
default:
|
||||
}
|
||||
|
||||
err = read_console_input(in, &r)
|
||||
if err != nil {
|
||||
input_comm <- Event{Type: EventError, Err: err}
|
||||
}
|
||||
|
||||
switch r.event_type {
|
||||
case key_event:
|
||||
kr := (*key_event_record)(unsafe.Pointer(&r.event))
|
||||
ev, ok := key_event_record_to_event(kr)
|
||||
if ok {
|
||||
for i := 0; i < int(kr.repeat_count); i++ {
|
||||
input_comm <- ev
|
||||
}
|
||||
}
|
||||
case window_buffer_size_event:
|
||||
sr := *(*window_buffer_size_record)(unsafe.Pointer(&r.event))
|
||||
input_comm <- Event{
|
||||
Type: EventResize,
|
||||
Width: int(sr.size.x),
|
||||
Height: int(sr.size.y),
|
||||
}
|
||||
case mouse_event:
|
||||
mr := *(*mouse_event_record)(unsafe.Pointer(&r.event))
|
||||
ev := Event{Type: EventMouse}
|
||||
switch mr.event_flags {
|
||||
case 0, 2:
|
||||
// single or double click
|
||||
cur_state := mr.button_state
|
||||
switch {
|
||||
case last_state&mouse_lmb == 0 && cur_state&mouse_lmb != 0:
|
||||
last_button = MouseLeft
|
||||
last_button_pressed = last_button
|
||||
case last_state&mouse_rmb == 0 && cur_state&mouse_rmb != 0:
|
||||
last_button = MouseRight
|
||||
last_button_pressed = last_button
|
||||
case last_state&mouse_mmb == 0 && cur_state&mouse_mmb != 0:
|
||||
last_button = MouseMiddle
|
||||
last_button_pressed = last_button
|
||||
case last_state&mouse_lmb != 0 && cur_state&mouse_lmb == 0:
|
||||
last_button = MouseRelease
|
||||
case last_state&mouse_rmb != 0 && cur_state&mouse_rmb == 0:
|
||||
last_button = MouseRelease
|
||||
case last_state&mouse_mmb != 0 && cur_state&mouse_mmb == 0:
|
||||
last_button = MouseRelease
|
||||
default:
|
||||
last_state = cur_state
|
||||
continue
|
||||
}
|
||||
last_state = cur_state
|
||||
ev.Key = last_button
|
||||
last_x, last_y = int(mr.mouse_pos.x), int(mr.mouse_pos.y)
|
||||
ev.MouseX = last_x
|
||||
ev.MouseY = last_y
|
||||
case 1:
|
||||
// mouse motion
|
||||
x, y := int(mr.mouse_pos.x), int(mr.mouse_pos.y)
|
||||
if last_state != 0 && (last_x != x || last_y != y) {
|
||||
ev.Key = last_button_pressed
|
||||
ev.Mod = ModMotion
|
||||
ev.MouseX = x
|
||||
ev.MouseY = y
|
||||
last_x, last_y = x, y
|
||||
} else {
|
||||
ev.Type = EventNone
|
||||
}
|
||||
case 4:
|
||||
// mouse wheel
|
||||
n := int16(mr.button_state >> 16)
|
||||
if n > 0 {
|
||||
ev.Key = MouseWheelUp
|
||||
} else {
|
||||
ev.Key = MouseWheelDown
|
||||
}
|
||||
last_x, last_y = int(mr.mouse_pos.x), int(mr.mouse_pos.y)
|
||||
ev.MouseX = last_x
|
||||
ev.MouseY = last_y
|
||||
default:
|
||||
ev.Type = EventNone
|
||||
}
|
||||
if ev.Type != EventNone {
|
||||
input_comm <- ev
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
233
vendor/github.com/jesseduffield/termbox-go/terminfo.go
generated
vendored
233
vendor/github.com/jesseduffield/termbox-go/terminfo.go
generated
vendored
@ -1,233 +0,0 @@
|
||||
// +build !windows
|
||||
// This file contains a simple and incomplete implementation of the terminfo
|
||||
// database. Information was taken from the ncurses manpages term(5) and
|
||||
// terminfo(5). Currently, only the string capabilities for special keys and for
|
||||
// functions without parameters are actually used. Colors are still done with
|
||||
// ANSI escape sequences. Other special features that are not (yet?) supported
|
||||
// are reading from ~/.terminfo, the TERMINFO_DIRS variable, Berkeley database
|
||||
// format and extended capabilities.
|
||||
|
||||
package termbox
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
ti_magic = 0432
|
||||
ti_header_length = 12
|
||||
ti_mouse_enter = "\x1b[?1000h\x1b[?1002h\x1b[?1015h\x1b[?1006h"
|
||||
ti_mouse_leave = "\x1b[?1006l\x1b[?1015l\x1b[?1002l\x1b[?1000l"
|
||||
)
|
||||
|
||||
func load_terminfo() ([]byte, error) {
|
||||
var data []byte
|
||||
var err error
|
||||
|
||||
term := os.Getenv("TERM")
|
||||
if term == "" {
|
||||
return nil, fmt.Errorf("termbox: TERM not set")
|
||||
}
|
||||
|
||||
// The following behaviour follows the one described in terminfo(5) as
|
||||
// distributed by ncurses.
|
||||
|
||||
terminfo := os.Getenv("TERMINFO")
|
||||
if terminfo != "" {
|
||||
// if TERMINFO is set, no other directory should be searched
|
||||
return ti_try_path(terminfo)
|
||||
}
|
||||
|
||||
// next, consider ~/.terminfo
|
||||
home := os.Getenv("HOME")
|
||||
if home != "" {
|
||||
data, err = ti_try_path(home + "/.terminfo")
|
||||
if err == nil {
|
||||
return data, nil
|
||||
}
|
||||
}
|
||||
|
||||
// next, TERMINFO_DIRS
|
||||
dirs := os.Getenv("TERMINFO_DIRS")
|
||||
if dirs != "" {
|
||||
for _, dir := range strings.Split(dirs, ":") {
|
||||
if dir == "" {
|
||||
// "" -> "/usr/share/terminfo"
|
||||
dir = "/usr/share/terminfo"
|
||||
}
|
||||
data, err = ti_try_path(dir)
|
||||
if err == nil {
|
||||
return data, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// next, /lib/terminfo
|
||||
data, err = ti_try_path("/lib/terminfo")
|
||||
if err == nil {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// fall back to /usr/share/terminfo
|
||||
return ti_try_path("/usr/share/terminfo")
|
||||
}
|
||||
|
||||
func ti_try_path(path string) (data []byte, err error) {
|
||||
// load_terminfo already made sure it is set
|
||||
term := os.Getenv("TERM")
|
||||
|
||||
// first try, the typical *nix path
|
||||
terminfo := path + "/" + term[0:1] + "/" + term
|
||||
data, err = ioutil.ReadFile(terminfo)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// fallback to darwin specific dirs structure
|
||||
terminfo = path + "/" + hex.EncodeToString([]byte(term[:1])) + "/" + term
|
||||
data, err = ioutil.ReadFile(terminfo)
|
||||
return
|
||||
}
|
||||
|
||||
func setup_term_builtin() error {
|
||||
name := os.Getenv("TERM")
|
||||
if name == "" {
|
||||
return errors.New("termbox: TERM environment variable not set")
|
||||
}
|
||||
|
||||
for _, t := range terms {
|
||||
if t.name == name {
|
||||
keys = t.keys
|
||||
funcs = t.funcs
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
compat_table := []struct {
|
||||
partial string
|
||||
keys []string
|
||||
funcs []string
|
||||
}{
|
||||
{"xterm", xterm_keys, xterm_funcs},
|
||||
{"rxvt", rxvt_unicode_keys, rxvt_unicode_funcs},
|
||||
{"linux", linux_keys, linux_funcs},
|
||||
{"Eterm", eterm_keys, eterm_funcs},
|
||||
{"screen", screen_keys, screen_funcs},
|
||||
// let's assume that 'cygwin' is xterm compatible
|
||||
{"cygwin", xterm_keys, xterm_funcs},
|
||||
{"st", xterm_keys, xterm_funcs},
|
||||
{"alacritty", xterm_keys, xterm_funcs},
|
||||
}
|
||||
|
||||
// try compatibility variants
|
||||
for _, it := range compat_table {
|
||||
if strings.Contains(name, it.partial) {
|
||||
keys = it.keys
|
||||
funcs = it.funcs
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return errors.New("termbox: unsupported terminal")
|
||||
}
|
||||
|
||||
func setup_term() (err error) {
|
||||
var data []byte
|
||||
var header [6]int16
|
||||
var str_offset, table_offset int16
|
||||
|
||||
data, err = load_terminfo()
|
||||
if err != nil {
|
||||
return setup_term_builtin()
|
||||
}
|
||||
|
||||
rd := bytes.NewReader(data)
|
||||
// 0: magic number, 1: size of names section, 2: size of boolean section, 3:
|
||||
// size of numbers section (in integers), 4: size of the strings section (in
|
||||
// integers), 5: size of the string table
|
||||
|
||||
err = binary.Read(rd, binary.LittleEndian, header[:])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
number_sec_len := int16(2)
|
||||
if header[0] == 542 { // doc says it should be octal 0542, but what I see it terminfo files is 542, learn to program please... thank you..
|
||||
number_sec_len = 4
|
||||
}
|
||||
|
||||
if (header[1]+header[2])%2 != 0 {
|
||||
// old quirk to align everything on word boundaries
|
||||
header[2] += 1
|
||||
}
|
||||
str_offset = ti_header_length + header[1] + header[2] + number_sec_len*header[3]
|
||||
table_offset = str_offset + 2*header[4]
|
||||
|
||||
keys = make([]string, 0xFFFF-key_min)
|
||||
for i, _ := range keys {
|
||||
keys[i], err = ti_read_string(rd, str_offset+2*ti_keys[i], table_offset)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
funcs = make([]string, t_max_funcs)
|
||||
// the last two entries are reserved for mouse. because the table offset is
|
||||
// not there, the two entries have to fill in manually
|
||||
for i, _ := range funcs[:len(funcs)-2] {
|
||||
funcs[i], err = ti_read_string(rd, str_offset+2*ti_funcs[i], table_offset)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
funcs[t_max_funcs-2] = ti_mouse_enter
|
||||
funcs[t_max_funcs-1] = ti_mouse_leave
|
||||
return nil
|
||||
}
|
||||
|
||||
func ti_read_string(rd *bytes.Reader, str_off, table int16) (string, error) {
|
||||
var off int16
|
||||
|
||||
_, err := rd.Seek(int64(str_off), 0)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = binary.Read(rd, binary.LittleEndian, &off)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
_, err = rd.Seek(int64(table+off), 0)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var bs []byte
|
||||
for {
|
||||
b, err := rd.ReadByte()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if b == byte(0x00) {
|
||||
break
|
||||
}
|
||||
bs = append(bs, b)
|
||||
}
|
||||
return string(bs), nil
|
||||
}
|
||||
|
||||
// "Maps" the function constants from termbox.go to the number of the respective
|
||||
// string capability in the terminfo file. Taken from (ncurses) term.h.
|
||||
var ti_funcs = []int16{
|
||||
28, 40, 16, 13, 5, 39, 36, 27, 26, 34, 89, 88,
|
||||
}
|
||||
|
||||
// Same as above for the special keys.
|
||||
var ti_keys = []int16{
|
||||
66, 68 /* apparently not a typo; 67 is F10 for whatever reason */, 69, 70,
|
||||
71, 72, 73, 74, 75, 67, 216, 217, 77, 59, 76, 164, 82, 81, 87, 61, 79, 83,
|
||||
}
|
65
vendor/github.com/jesseduffield/termbox-go/terminfo_builtin.go
generated
vendored
65
vendor/github.com/jesseduffield/termbox-go/terminfo_builtin.go
generated
vendored
@ -1,65 +0,0 @@
|
||||
// +build !windows
|
||||
|
||||
package termbox
|
||||
|
||||
// Eterm
|
||||
var eterm_keys = []string{
|
||||
"\x1b[11~", "\x1b[12~", "\x1b[13~", "\x1b[14~", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[7~", "\x1b[8~", "\x1b[5~", "\x1b[6~", "\x1b[A", "\x1b[B", "\x1b[D", "\x1b[C",
|
||||
}
|
||||
var eterm_funcs = []string{
|
||||
"\x1b7\x1b[?47h", "\x1b[2J\x1b[?47l\x1b8", "\x1b[?25h", "\x1b[?25l", "\x1b[H\x1b[2J", "\x1b[m\x0f", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "", "", "", "",
|
||||
}
|
||||
|
||||
// screen
|
||||
var screen_keys = []string{
|
||||
"\x1bOP", "\x1bOQ", "\x1bOR", "\x1bOS", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[1~", "\x1b[4~", "\x1b[5~", "\x1b[6~", "\x1bOA", "\x1bOB", "\x1bOD", "\x1bOC",
|
||||
}
|
||||
var screen_funcs = []string{
|
||||
"\x1b[?1049h", "\x1b[?1049l", "\x1b[34h\x1b[?25h", "\x1b[?25l", "\x1b[H\x1b[J", "\x1b[m\x0f", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "\x1b[?1h\x1b=", "\x1b[?1l\x1b>", ti_mouse_enter, ti_mouse_leave,
|
||||
}
|
||||
|
||||
// xterm
|
||||
var xterm_keys = []string{
|
||||
"\x1bOP", "\x1bOQ", "\x1bOR", "\x1bOS", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1bOH", "\x1bOF", "\x1b[5~", "\x1b[6~", "\x1bOA", "\x1bOB", "\x1bOD", "\x1bOC",
|
||||
}
|
||||
var xterm_funcs = []string{
|
||||
"\x1b[?1049h", "\x1b[?1049l", "\x1b[?12l\x1b[?25h", "\x1b[?25l", "\x1b[H\x1b[2J", "\x1b(B\x1b[m", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "\x1b[?1h\x1b=", "\x1b[?1l\x1b>", ti_mouse_enter, ti_mouse_leave,
|
||||
}
|
||||
|
||||
// rxvt-unicode
|
||||
var rxvt_unicode_keys = []string{
|
||||
"\x1b[11~", "\x1b[12~", "\x1b[13~", "\x1b[14~", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[7~", "\x1b[8~", "\x1b[5~", "\x1b[6~", "\x1b[A", "\x1b[B", "\x1b[D", "\x1b[C",
|
||||
}
|
||||
var rxvt_unicode_funcs = []string{
|
||||
"\x1b[?1049h", "\x1b[r\x1b[?1049l", "\x1b[?25h", "\x1b[?25l", "\x1b[H\x1b[2J", "\x1b[m\x1b(B", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "\x1b=", "\x1b>", ti_mouse_enter, ti_mouse_leave,
|
||||
}
|
||||
|
||||
// linux
|
||||
var linux_keys = []string{
|
||||
"\x1b[[A", "\x1b[[B", "\x1b[[C", "\x1b[[D", "\x1b[[E", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[1~", "\x1b[4~", "\x1b[5~", "\x1b[6~", "\x1b[A", "\x1b[B", "\x1b[D", "\x1b[C",
|
||||
}
|
||||
var linux_funcs = []string{
|
||||
"", "", "\x1b[?25h\x1b[?0c", "\x1b[?25l\x1b[?1c", "\x1b[H\x1b[J", "\x1b[0;10m", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "", "", "", "",
|
||||
}
|
||||
|
||||
// rxvt-256color
|
||||
var rxvt_256color_keys = []string{
|
||||
"\x1b[11~", "\x1b[12~", "\x1b[13~", "\x1b[14~", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[7~", "\x1b[8~", "\x1b[5~", "\x1b[6~", "\x1b[A", "\x1b[B", "\x1b[D", "\x1b[C",
|
||||
}
|
||||
var rxvt_256color_funcs = []string{
|
||||
"\x1b7\x1b[?47h", "\x1b[2J\x1b[?47l\x1b8", "\x1b[?25h", "\x1b[?25l", "\x1b[H\x1b[2J", "\x1b[m\x0f", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "\x1b=", "\x1b>", ti_mouse_enter, ti_mouse_leave,
|
||||
}
|
||||
|
||||
var terms = []struct {
|
||||
name string
|
||||
keys []string
|
||||
funcs []string
|
||||
}{
|
||||
{"Eterm", eterm_keys, eterm_funcs},
|
||||
{"screen", screen_keys, screen_funcs},
|
||||
{"xterm", xterm_keys, xterm_funcs},
|
||||
{"rxvt-unicode", rxvt_unicode_keys, rxvt_unicode_funcs},
|
||||
{"linux", linux_keys, linux_funcs},
|
||||
{"rxvt-256color", rxvt_256color_keys, rxvt_256color_funcs},
|
||||
{"alacritty", xterm_keys, xterm_funcs},
|
||||
}
|
1
vendor/modules.txt
vendored
1
vendor/modules.txt
vendored
@ -154,7 +154,6 @@ github.com/jesseduffield/go-git/v5/utils/merkletrie/noder
|
||||
github.com/jesseduffield/gocui
|
||||
# github.com/jesseduffield/termbox-go v0.0.0-20200823212418-a2289ed6aafe
|
||||
## explicit
|
||||
github.com/jesseduffield/termbox-go
|
||||
# github.com/jesseduffield/yaml v2.1.0+incompatible
|
||||
## explicit
|
||||
github.com/jesseduffield/yaml
|
||||
|
Loading…
Reference in New Issue
Block a user