bump gocui

pull/203/head
Jesse Duffield 4 years ago
parent 69f32d52d1
commit 012f8d6e08

@ -21,14 +21,14 @@ require (
github.com/imdario/mergo v0.3.8
github.com/integrii/flaggy v1.4.0
github.com/jesseduffield/asciigraph v0.0.0-20190605104717-6d88e39309ee
github.com/jesseduffield/gocui v0.3.1-0.20190803023616-ad0cd60f29f9
github.com/jesseduffield/gocui v0.3.1-0.20200201013258-57fdcf23edc5
github.com/jesseduffield/rollrus v0.0.0-20190701125922-dd028cb0bfd7
github.com/jesseduffield/termbox-go v0.0.0-20190630083001-9dd53af7214e // indirect
github.com/jesseduffield/termbox-go v0.0.0-20200130214842-1d31d1faa3c9 // indirect
github.com/jesseduffield/yaml v0.0.0-20190702115811-b900b7e08b56
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
github.com/mattn/go-colorable v0.1.4 // indirect
github.com/mattn/go-isatty v0.0.11 // indirect
github.com/mattn/go-runewidth v0.0.7 // indirect
github.com/mattn/go-runewidth v0.0.8 // indirect
github.com/mcuadros/go-lookup v0.0.0-20171110082742-5650f26be767
github.com/mgutz/str v1.2.0
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c // indirect

@ -50,12 +50,16 @@ github.com/jesseduffield/asciigraph v0.0.0-20190605104717-6d88e39309ee h1:7Zi/OQ
github.com/jesseduffield/asciigraph v0.0.0-20190605104717-6d88e39309ee/go.mod h1:Z9UKHveKXXgyo8ME7R8yxh/BUTFOK+FgfWKlhy8oOAg=
github.com/jesseduffield/gocui v0.3.1-0.20190803023616-ad0cd60f29f9 h1:v2Pf3RaIN+MlFfSDnJw2d9Qksr4Tw08+pjL4LEY+JLM=
github.com/jesseduffield/gocui v0.3.1-0.20190803023616-ad0cd60f29f9/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw=
github.com/jesseduffield/gocui v0.3.1-0.20200201013258-57fdcf23edc5 h1:tE0w3tuL/bj1o5VMhjjE0ep6i7Fva+RYjKcMFcniJEY=
github.com/jesseduffield/gocui v0.3.1-0.20200201013258-57fdcf23edc5/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw=
github.com/jesseduffield/roll v0.0.0-20190629104057-695be2e62b00 h1:+JaOkfBNYQYlGD7dgru8mCwYNEc5tRRI8mThlVANhSM=
github.com/jesseduffield/roll v0.0.0-20190629104057-695be2e62b00/go.mod h1:cWNQljQAWYBp4wchyGfql4q2jRNZXxiE1KhVQgz+JaM=
github.com/jesseduffield/rollrus v0.0.0-20190701125922-dd028cb0bfd7 h1:CRD7bVjlGIiV+M0jlsa+XWpneW0KY0e7Y4z3GWb5S4o=
github.com/jesseduffield/rollrus v0.0.0-20190701125922-dd028cb0bfd7/go.mod h1:VspA3aTkEo0Q7TPCLmX1uHNP+Wb4iSDX09hmTRo1QYc=
github.com/jesseduffield/termbox-go v0.0.0-20190630083001-9dd53af7214e h1:tth7wr6+sfSbdpRWWrwvLYyS56HyIRVfq0Qcl2h28wM=
github.com/jesseduffield/termbox-go v0.0.0-20190630083001-9dd53af7214e/go.mod h1:anMibpZtqNxjDbxrcDEAwSdaJ37vyUeM1f/M4uekib4=
github.com/jesseduffield/termbox-go v0.0.0-20200130214842-1d31d1faa3c9 h1:iBBk1lhFwjwJw//J2m1yyz9S368GeXQTpMVACTyQMh0=
github.com/jesseduffield/termbox-go v0.0.0-20200130214842-1d31d1faa3c9/go.mod h1:anMibpZtqNxjDbxrcDEAwSdaJ37vyUeM1f/M4uekib4=
github.com/jesseduffield/yaml v0.0.0-20190702115811-b900b7e08b56 h1:33wSxJWU/f2TAozHYtJ8zqBxEnEVYM+22moLoiAkxvg=
github.com/jesseduffield/yaml v0.0.0-20190702115811-b900b7e08b56/go.mod h1:FZJBwOhE+RXz8EVZfY+xnbCw2cVOwxlK3/aIi581z/s=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
@ -71,6 +75,8 @@ github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGe
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.8 h1:3tS41NlGYSmhhe/8fhGRzc+z3AYCw1Fe1WAyLuujKs0=
github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mcuadros/go-lookup v0.0.0-20171110082742-5650f26be767 h1:BrhJNdEFWGuiJk/3/SwsG5Rex3zjFxYsDi2bpd7382Y=
github.com/mcuadros/go-lookup v0.0.0-20171110082742-5650f26be767/go.mod h1:ct+byCpkFokm4J0tiuAvB8cf2ttm6GcCe89Yr25nGKg=
github.com/mgutz/str v1.2.0 h1:4IzWSdIz9qPQWLfKZ0rJcV0jcUDpxvP4JVZ4GXQyvSw=

@ -127,17 +127,17 @@ func (gui *Gui) createPopupPanel(g *gocui.Gui, currentView *gocui.View, title, p
func (gui *Gui) setKeyBindings(g *gocui.Gui, handleConfirm, handleClose func(*gocui.Gui, *gocui.View) error) error {
// would use a loop here but because the function takes an interface{} and slices of interfaces require even more boilerplate
if err := g.SetKeybinding("confirmation", gocui.KeyEnter, gocui.ModNone, gui.wrappedConfirmationFunction(handleConfirm)); err != nil {
if err := g.SetKeybinding("confirmation", nil, gocui.KeyEnter, gocui.ModNone, gui.wrappedConfirmationFunction(handleConfirm)); err != nil {
return err
}
if err := g.SetKeybinding("confirmation", 'y', gocui.ModNone, gui.wrappedConfirmationFunction(handleConfirm)); err != nil {
if err := g.SetKeybinding("confirmation", nil, 'y', gocui.ModNone, gui.wrappedConfirmationFunction(handleConfirm)); err != nil {
return err
}
if err := g.SetKeybinding("confirmation", gocui.KeyEsc, gocui.ModNone, gui.wrappedConfirmationFunction(handleClose)); err != nil {
if err := g.SetKeybinding("confirmation", nil, gocui.KeyEsc, gocui.ModNone, gui.wrappedConfirmationFunction(handleClose)); err != nil {
return err
}
if err := g.SetKeybinding("confirmation", 'n', gocui.ModNone, gui.wrappedConfirmationFunction(handleClose)); err != nil {
if err := g.SetKeybinding("confirmation", nil, 'n', gocui.ModNone, gui.wrappedConfirmationFunction(handleClose)); err != nil {
return err
}

@ -509,7 +509,7 @@ func (gui *Gui) keybindings(g *gocui.Gui) error {
bindings := gui.GetInitialKeybindings()
for _, binding := range bindings {
if err := g.SetKeybinding(binding.ViewName, binding.Key, binding.Modifier, binding.Handler); err != nil {
if err := g.SetKeybinding(binding.ViewName, nil, binding.Key, binding.Modifier, binding.Handler); err != nil {
return err
}
}

@ -98,7 +98,7 @@ func (gui *Gui) createMenu(title string, items interface{}, itemCount int, handl
for _, key := range []gocui.Key{gocui.KeySpace, gocui.KeyEnter, 'y'} {
_ = gui.g.DeleteKeybinding("menu", key, gocui.ModNone)
if err := gui.g.SetKeybinding("menu", key, gocui.ModNone, wrappedHandlePress); err != nil {
if err := gui.g.SetKeybinding("menu", nil, key, gocui.ModNone, wrappedHandlePress); err != nil {
return err
}
}

@ -5,8 +5,10 @@
package gocui
import (
"github.com/go-errors/errors"
"strconv"
"sync"
"github.com/go-errors/errors"
)
type escapeInterpreter struct {
@ -15,6 +17,7 @@ type escapeInterpreter struct {
csiParam []string
curFgColor, curBgColor Attribute
mode OutputMode
mutex sync.Mutex
}
type escapeState int
@ -34,6 +37,9 @@ var (
// runes in case of error will output the non-parsed runes as a string.
func (ei *escapeInterpreter) runes() []rune {
ei.mutex.Lock()
defer ei.mutex.Unlock()
switch ei.state {
case stateNone:
return []rune{0x1b}
@ -66,6 +72,9 @@ func newEscapeInterpreter(mode OutputMode) *escapeInterpreter {
// reset sets the escapeInterpreter in initial state.
func (ei *escapeInterpreter) reset() {
ei.mutex.Lock()
defer ei.mutex.Unlock()
ei.state = stateNone
ei.curFgColor = ColorDefault
ei.curBgColor = ColorDefault
@ -76,6 +85,9 @@ func (ei *escapeInterpreter) reset() {
// of an escape sequence, and as such should not be printed verbatim. Otherwise,
// it's not an escape sequence.
func (ei *escapeInterpreter) parseOne(ch rune) (isEscape bool, err error) {
ei.mutex.Lock()
defer ei.mutex.Unlock()
// Sanity checks
if len(ei.csiParam) > 20 {
return false, errCSITooLong
@ -179,6 +191,9 @@ func (ei *escapeInterpreter) outputNormal() error {
// 0x11 - 0xe8: 216 different colors
// 0xe9 - 0x1ff: 24 different shades of grey
func (ei *escapeInterpreter) output256() error {
ei.mutex.Lock()
defer ei.mutex.Unlock()
if len(ei.csiParam) < 3 {
return ei.outputNormal()
}

@ -7,6 +7,7 @@ package gocui
import (
standardErrors "errors"
"strings"
"sync"
"time"
"github.com/go-errors/errors"
@ -89,6 +90,10 @@ type Gui struct {
// SupportOverlaps is true when we allow for view edges to overlap with other
// view edges
SupportOverlaps bool
// tickingMutex ensures we don't have two loops ticking. The point of 'ticking'
// is to refresh the gui rapidly so that loader characters can be animated.
tickingMutex sync.Mutex
}
// NewGui returns a new Gui object with a given output mode.
@ -125,9 +130,7 @@ func NewGui(mode OutputMode, supportOverlaps bool) (*Gui, error) {
// Close finalizes the library. It should be called after a successful
// initialization and when gocui is not needed anymore.
func (g *Gui) Close() {
go func() {
g.stop <- struct{}{}
}()
close(g.stop)
termbox.Close()
}
@ -141,7 +144,8 @@ func (g *Gui) Size() (x, y int) {
// the given colors.
func (g *Gui) SetRune(x, y int, ch rune, fgColor, bgColor Attribute) error {
if x < 0 || y < 0 || x >= g.maxX || y >= g.maxY {
return errors.New("invalid point")
// swallowing error because it's not that big of a deal
return nil
}
termbox.SetCell(x, y, ch, termbox.Attribute(fgColor), termbox.Attribute(bgColor))
return nil
@ -163,9 +167,6 @@ func (g *Gui) Rune(x, y int) (rune, error) {
// ErrUnknownView is returned, which allows to assert if the View must
// be initialized. It checks if the position is valid.
func (g *Gui) SetView(name string, x0, y0, x1, y1 int, overlaps byte) (*View, error) {
if x0 >= x1 {
return nil, errors.New("invalid dimensions")
}
if name == "" {
return nil, errors.New("invalid name")
}
@ -297,14 +298,14 @@ func (g *Gui) CurrentView() *View {
// SetKeybinding creates a new keybinding. If viewname equals to ""
// (empty string) then the keybinding will apply to all views. key must
// be a rune or a Key.
func (g *Gui) SetKeybinding(viewname string, key interface{}, mod Modifier, handler func(*Gui, *View) error) error {
func (g *Gui) SetKeybinding(viewname string, contexts []string, key interface{}, mod Modifier, handler func(*Gui, *View) error) error {
var kb *keybinding
k, ch, err := getKey(key)
if err != nil {
return err
}
kb = newKeybinding(viewname, k, ch, mod, handler)
kb = newKeybinding(viewname, contexts, k, ch, mod, handler)
g.keybindings = append(g.keybindings, kb)
return nil
}
@ -411,7 +412,6 @@ func (g *Gui) SetManagerFunc(manager func(*Gui) error) {
// MainLoop runs the main loop until an error is returned. A successful
// finish should return ErrQuit.
func (g *Gui) MainLoop() error {
g.loaderTick()
if err := g.flush(); err != nil {
return err
}
@ -837,14 +837,25 @@ func (g *Gui) execKeybinding(v *View, kb *keybinding) (bool, error) {
return true, nil
}
func (g *Gui) loaderTick() {
func (g *Gui) StartTicking() {
go func() {
for range time.Tick(time.Millisecond * 50) {
for _, view := range g.Views() {
if view.HasLoader {
g.userEvents <- userEvent{func(g *Gui) error { return nil }}
break
g.tickingMutex.Lock()
defer g.tickingMutex.Unlock()
ticker := time.NewTicker(time.Millisecond * 50)
defer ticker.Stop()
outer:
for {
select {
case <-ticker.C:
for _, view := range g.Views() {
if view.HasLoader {
g.userEvents <- userEvent{func(g *Gui) error { return nil }}
continue outer
}
}
return
case <-g.stop:
return
}
}
}()

@ -9,6 +9,7 @@ import "github.com/jesseduffield/termbox-go"
// Keybidings are used to link a given key-press event with a handler.
type keybinding struct {
viewName string
contexts []string
key Key
ch rune
mod Modifier
@ -16,9 +17,10 @@ type keybinding struct {
}
// newKeybinding returns a new Keybinding object.
func newKeybinding(viewname string, key Key, ch rune, mod Modifier, handler func(*Gui, *View) error) (kb *keybinding) {
func newKeybinding(viewname string, contexts []string, key Key, ch rune, mod Modifier, handler func(*Gui, *View) error) (kb *keybinding) {
kb = &keybinding{
viewName: viewname,
contexts: contexts,
key: key,
ch: ch,
mod: mod,
@ -32,7 +34,7 @@ func (kb *keybinding) matchKeypress(key Key, ch rune, mod Modifier) bool {
return kb.key == key && kb.ch == ch && kb.mod == mod
}
// matchView returns if the keybinding matches the current view.
// matchView returns if the keybinding matches the current view (and the view's context)
func (kb *keybinding) matchView(v *View) bool {
// if the user is typing in a field, ignore char keys
if v == nil {
@ -41,7 +43,19 @@ func (kb *keybinding) matchView(v *View) bool {
if v.Editable == true && kb.ch != 0 {
return false
}
return kb.viewName == v.name
if kb.viewName != v.name {
return false
}
// if the keybinding doesn't specify contexts, it applies for all contexts
if len(kb.contexts) == 0 {
return true
}
for _, context := range kb.contexts {
if context == v.Context {
return true
}
}
return false
}
// Key represents special keys or keys combinations.
@ -136,6 +150,7 @@ type Modifier termbox.Modifier
// Modifiers.
const (
ModNone Modifier = Modifier(0)
ModAlt = Modifier(termbox.ModAlt)
ModNone Modifier = Modifier(0)
ModAlt = Modifier(termbox.ModAlt)
ModMotion = Modifier(termbox.ModMotion)
)

@ -103,6 +103,8 @@ type View struct {
// ParentView is the view which catches events bubbled up from the given view if there's no matching handler
ParentView *View
Context string // this is for assigning keybindings to a view only in certain contexts
}
type viewLine struct {
@ -217,9 +219,6 @@ func (v *View) Cursor() (x, y int) {
// implement Horizontal and Vertical scrolling with just incrementing
// or decrementing ox and oy.
func (v *View) SetOrigin(x, y int) error {
if x < 0 || y < 0 {
return errors.New("invalid point")
}
v.ox = x
v.oy = y
return nil
@ -459,6 +458,8 @@ func (v *View) clearRunes() {
// BufferLines returns the lines in the view's internal
// buffer.
func (v *View) BufferLines() []string {
v.writeMutex.Lock()
defer v.writeMutex.Unlock()
lines := make([]string, len(v.lines))
for i, l := range v.lines {
str := lineType(l).String()
@ -477,6 +478,8 @@ func (v *View) Buffer() string {
// ViewBufferLines returns the lines in the view's internal
// buffer that is shown to the user.
func (v *View) ViewBufferLines() []string {
v.writeMutex.Lock()
defer v.writeMutex.Unlock()
lines := make([]string, len(v.viewLines))
for i, l := range v.viewLines {
str := lineType(l.line).String()
@ -653,3 +656,14 @@ func (v *View) GetClickedTabIndex(x int) int {
return 0
}
func (v *View) SelectedLineIdx() int {
_, seletedLineIdx := v.SelectedPoint()
return seletedLineIdx
}
func (v *View) SelectedPoint() (int, int) {
cx, cy := v.Cursor()
ox, oy := v.Origin()
return cx + ox, cy + oy
}

@ -2,13 +2,16 @@
package termbox
import "github.com/mattn/go-runewidth"
import "fmt"
import "os"
import "os/signal"
import "syscall"
import "runtime"
import "time"
import (
"fmt"
"os"
"os/signal"
"runtime"
"syscall"
"time"
"github.com/mattn/go-runewidth"
)
// public API
@ -26,13 +29,21 @@ func Init() error {
var err error
out, err = os.OpenFile("/dev/tty", syscall.O_WRONLY, 0)
if err != nil {
return err
}
in, err = syscall.Open("/dev/tty", syscall.O_RDONLY, 0)
if err != nil {
return err
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()

@ -1,8 +1,16 @@
language: go
sudo: false
go:
- 1.13.x
- tip
before_install:
- go get github.com/mattn/goveralls
- go get golang.org/x/tools/cmd/cover
- go get -t -v ./...
script:
- $HOME/gopath/bin/goveralls -repotoken lAKAWPzcGsD3A8yBX3BGGtRUdJ6CaGERL
- go generate
- git diff --cached --exit-code
- ./go.test.sh
after_success:
- bash <(curl -s https://codecov.io/bash)

@ -2,7 +2,7 @@ go-runewidth
============
[![Build Status](https://travis-ci.org/mattn/go-runewidth.png?branch=master)](https://travis-ci.org/mattn/go-runewidth)
[![Coverage Status](https://coveralls.io/repos/mattn/go-runewidth/badge.png?branch=HEAD)](https://coveralls.io/r/mattn/go-runewidth?branch=HEAD)
[![Codecov](https://codecov.io/gh/mattn/go-runewidth/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-runewidth)
[![GoDoc](https://godoc.org/github.com/mattn/go-runewidth?status.svg)](http://godoc.org/github.com/mattn/go-runewidth)
[![Go Report Card](https://goreportcard.com/badge/github.com/mattn/go-runewidth)](https://goreportcard.com/report/github.com/mattn/go-runewidth)

@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -e
echo "" > coverage.txt
for d in $(go list ./... | grep -v vendor); do
go test -race -coverprofile=profile.out -covermode=atomic "$d"
if [ -f profile.out ]; then
cat profile.out >> coverage.txt
rm profile.out
fi
done

@ -50,7 +50,6 @@ func inTables(r rune, ts ...table) bool {
}
func inTable(r rune, t table) bool {
// func (t table) IncludesRune(r rune) bool {
if r < t[0].first {
return false
}

@ -1,3 +1,5 @@
// Code generated by script/generate.go. DO NOT EDIT.
package runewidth
var combining = table{

@ -51,13 +51,13 @@ github.com/imdario/mergo
github.com/integrii/flaggy
# github.com/jesseduffield/asciigraph v0.0.0-20190605104717-6d88e39309ee
github.com/jesseduffield/asciigraph
# github.com/jesseduffield/gocui v0.3.1-0.20190803023616-ad0cd60f29f9
# github.com/jesseduffield/gocui v0.3.1-0.20200201013258-57fdcf23edc5
github.com/jesseduffield/gocui
# github.com/jesseduffield/roll v0.0.0-20190629104057-695be2e62b00
github.com/jesseduffield/roll
# github.com/jesseduffield/rollrus v0.0.0-20190701125922-dd028cb0bfd7
github.com/jesseduffield/rollrus
# github.com/jesseduffield/termbox-go v0.0.0-20190630083001-9dd53af7214e
# github.com/jesseduffield/termbox-go v0.0.0-20200130214842-1d31d1faa3c9
github.com/jesseduffield/termbox-go
# github.com/jesseduffield/yaml v0.0.0-20190702115811-b900b7e08b56
github.com/jesseduffield/yaml
@ -67,7 +67,7 @@ github.com/konsorten/go-windows-terminal-sequences
github.com/mattn/go-colorable
# github.com/mattn/go-isatty v0.0.11
github.com/mattn/go-isatty
# github.com/mattn/go-runewidth v0.0.7
# github.com/mattn/go-runewidth v0.0.8
github.com/mattn/go-runewidth
# github.com/mcuadros/go-lookup v0.0.0-20171110082742-5650f26be767
github.com/mcuadros/go-lookup

Loading…
Cancel
Save