diff --git a/vendor/github.com/nsf/termbox-go/README.md b/vendor/github.com/nsf/termbox-go/README.md index 5174435..35dcf1b 100644 --- a/vendor/github.com/nsf/termbox-go/README.md +++ b/vendor/github.com/nsf/termbox-go/README.md @@ -14,7 +14,7 @@ There are also some interesting projects using termbox-go: - [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/michaeldv/mop) is stock market tracker for hackers. + - [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. @@ -27,6 +27,13 @@ There are also some interesting projects using termbox-go: - [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/ ### API reference [godoc.org/github.com/nsf/termbox-go](http://godoc.org/github.com/nsf/termbox-go) diff --git a/vendor/github.com/nsf/termbox-go/api.go b/vendor/github.com/nsf/termbox-go/api.go index b242ddc..d530ab5 100644 --- a/vendor/github.com/nsf/termbox-go/api.go +++ b/vendor/github.com/nsf/termbox-go/api.go @@ -8,6 +8,7 @@ import "os" import "os/signal" import "syscall" import "runtime" +import "time" // public API @@ -253,8 +254,8 @@ func CellBuffer() []Cell { // NOTE: This API is experimental and may change in future. func ParseEvent(data []byte) Event { event := Event{Type: EventKey} - ok := extract_event(data, &event) - if !ok { + status := extract_event(data, &event, false) + if status != event_extracted { return Event{Type: EventNone, N: event.N} } return event @@ -303,34 +304,65 @@ func PollRawEvent(data []byte) 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 - ok := extract_event(inbuf, &event) + status := extract_event(inbuf, &event, true) if event.N != 0 { copy(inbuf, inbuf[event.N:]) inbuf = inbuf[:len(inbuf)-event.N] } - if ok { + 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 - ok := extract_event(inbuf, &event) + status := extract_event(inbuf, &event, true) if event.N != 0 { copy(inbuf, inbuf[event.N:]) inbuf = inbuf[:len(inbuf)-event.N] } - if ok { + 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 { + copy(inbuf, inbuf[event.N:]) + inbuf = inbuf[:len(inbuf)-event.N] + } + if status == event_extracted { return event } case <-interrupt_comm: @@ -418,12 +450,12 @@ func SetInputMode(mode InputMode) InputMode { // // 3. Output216 => [1..216] // This mode supports the 3rd range of the 256 mode only. -// But you dont need to provide an offset. +// 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 dont need to provide an offset. +// But you don't need to provide an offset. // // In all modes, 0x00 represents the default color. // diff --git a/vendor/github.com/nsf/termbox-go/api_common.go b/vendor/github.com/nsf/termbox-go/api_common.go index 9f23661..5ca1371 100644 --- a/vendor/github.com/nsf/termbox-go/api_common.go +++ b/vendor/github.com/nsf/termbox-go/api_common.go @@ -148,7 +148,7 @@ const ( // 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 attibutes. +// 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. diff --git a/vendor/github.com/nsf/termbox-go/escwait.go b/vendor/github.com/nsf/termbox-go/escwait.go new file mode 100644 index 0000000..b7bbb89 --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/escwait.go @@ -0,0 +1,11 @@ +// +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 +} diff --git a/vendor/github.com/nsf/termbox-go/escwait_darwin.go b/vendor/github.com/nsf/termbox-go/escwait_darwin.go new file mode 100644 index 0000000..dde69b6 --- /dev/null +++ b/vendor/github.com/nsf/termbox-go/escwait_darwin.go @@ -0,0 +1,9 @@ +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 +} diff --git a/vendor/github.com/nsf/termbox-go/termbox.go b/vendor/github.com/nsf/termbox-go/termbox.go index c2d86c6..fbe4c3d 100644 --- a/vendor/github.com/nsf/termbox-go/termbox.go +++ b/vendor/github.com/nsf/termbox-go/termbox.go @@ -41,6 +41,14 @@ type input_event struct { 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 @@ -417,7 +425,7 @@ func parse_escape_sequence(event *Event, buf []byte) (int, bool) { } } - // if none of the keys match, let's try mouse seqences + // if none of the keys match, let's try mouse sequences return parse_mouse_event(event, bufstr) } @@ -440,17 +448,27 @@ func extract_raw_event(data []byte, event *Event) bool { return true } -func extract_event(inbuf []byte, event *Event) bool { +func extract_event(inbuf []byte, event *Event, allow_esc_wait bool) extract_event_res { if len(inbuf) == 0 { event.N = 0 - return false + return event_not_extracted } if inbuf[0] == '\033' { // possible escape sequence if n, ok := parse_escape_sequence(event, inbuf); n != 0 { event.N = n - return ok + 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 @@ -461,17 +479,17 @@ func extract_event(inbuf []byte, event *Event) bool { event.Key = KeyEsc event.Mod = 0 event.N = 1 - return true + 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 - ok := extract_event(inbuf[1:], event) - if ok { + status := extract_event(inbuf[1:], event, false) + if status == event_extracted { event.N++ } else { event.N = 0 } - return ok + return status default: panic("unreachable") } @@ -486,7 +504,7 @@ func extract_event(inbuf []byte, event *Event) bool { event.Ch = 0 event.Key = Key(inbuf[0]) event.N = 1 - return true + return event_extracted } // the only possible option is utf8 rune @@ -494,10 +512,10 @@ func extract_event(inbuf []byte, event *Event) bool { event.Ch = r event.Key = 0 event.N = n - return true + return event_extracted } - return false + return event_not_extracted } func fcntl(fd int, cmd int, arg int) (val int, err error) { diff --git a/vendor/github.com/nsf/termbox-go/termbox_windows.go b/vendor/github.com/nsf/termbox-go/termbox_windows.go index f7dad7b..738847c 100644 --- a/vendor/github.com/nsf/termbox-go/termbox_windows.go +++ b/vendor/github.com/nsf/termbox-go/termbox_windows.go @@ -63,6 +63,8 @@ const ( mouse_lmb = 0x1 mouse_rmb = 0x2 mouse_mmb = 0x4 | 0x8 | 0x10 + SM_CXMIN = 28 + SM_CYMIN = 29 ) func (this coord) uintptr() uintptr { @@ -70,6 +72,7 @@ func (this coord) uintptr() uintptr { } var kernel32 = syscall.NewLazyDLL("kernel32.dll") +var moduser32 = syscall.NewLazyDLL("user32.dll") var is_cjk = runewidth.IsEastAsian() var ( @@ -91,6 +94,7 @@ var ( proc_create_event = kernel32.NewProc("CreateEventW") proc_wait_for_multiple_objects = kernel32.NewProc("WaitForMultipleObjects") proc_set_event = kernel32.NewProc("SetEvent") + get_system_metrics = moduser32.NewProc("GetSystemMetrics") ) func set_console_active_screen_buffer(h syscall.Handle) (err error) { @@ -397,15 +401,44 @@ func get_term_size(out syscall.Handle) coord { 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) + } + } + + return coord{ + x: short(x), + y: short(y), + } +} + func get_win_size(out syscall.Handle) coord { err := get_console_screen_buffer_info(out, &tmp_info) if err != nil { panic(err) } - return coord{ + + 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() {