Merge pull request #130 from winhung/limit-scrolling

scrolling does not go beyond the displayed text #31
pull/155/head
Jesse Duffield 5 years ago committed by GitHub
commit 6ebddea76e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -20,7 +20,7 @@ require (
github.com/imdario/mergo v0.3.7
github.com/integrii/flaggy v0.0.0-20190517180110-07ea7eb77404
github.com/jesseduffield/asciigraph v0.0.0-20190605104717-6d88e39309ee
github.com/jesseduffield/gocui v0.3.1-0.20190706002342-e625df489460
github.com/jesseduffield/gocui v0.3.1-0.20190803023616-ad0cd60f29f9
github.com/jesseduffield/rollrus v0.0.0-20190701125922-dd028cb0bfd7
github.com/jesseduffield/termbox-go v0.0.0-20190630083001-9dd53af7214e // indirect
github.com/jesseduffield/yaml v0.0.0-20190702115811-b900b7e08b56
@ -30,6 +30,7 @@ require (
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
github.com/nsf/termbox-go v0.0.0-20190624072549-eeb6cd0a1762 // indirect
github.com/onsi/ginkgo v1.8.0 // indirect
github.com/onsi/gomega v1.5.0 // indirect
github.com/opencontainers/go-digest v1.0.0-rc1 // indirect

@ -46,8 +46,12 @@ github.com/integrii/flaggy v0.0.0-20190517180110-07ea7eb77404 h1:oRzqLvY7HzDWD9k
github.com/integrii/flaggy v0.0.0-20190517180110-07ea7eb77404/go.mod h1:tnTxHeTJbah0gQ6/K0RW0J7fMUBk9MCF5blhm43LNpI=
github.com/jesseduffield/asciigraph v0.0.0-20190605104717-6d88e39309ee h1:7Zi/OQlGbMz4MT2V1+prN/gv1C64NDyVb/MbJnS0ZfA=
github.com/jesseduffield/asciigraph v0.0.0-20190605104717-6d88e39309ee/go.mod h1:Z9UKHveKXXgyo8ME7R8yxh/BUTFOK+FgfWKlhy8oOAg=
github.com/jesseduffield/gocui v0.3.0 h1:l7wH8MKR2p+ozuZdtdhQiX7szILbv50vkMk1tg2+xow=
github.com/jesseduffield/gocui v0.3.0/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw=
github.com/jesseduffield/gocui v0.3.1-0.20190706002342-e625df489460 h1:ZE/5AVVJV5j7cVFvnQ/YsogDiUh544Qoh4ib/iVyKf8=
github.com/jesseduffield/gocui v0.3.1-0.20190706002342-e625df489460/go.mod h1:2RtZznzYKt8RLRwvFiSkXjU0Ei8WwHdubgnlaYH47dw=
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/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=
@ -72,6 +76,8 @@ github.com/mgutz/str v1.2.0 h1:4IzWSdIz9qPQWLfKZ0rJcV0jcUDpxvP4JVZ4GXQyvSw=
github.com/mgutz/str v1.2.0/go.mod h1:w1v0ofgLaJdoD0HpQ3fycxKD1WtxpjSo151pK/31q6w=
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c h1:nXxl5PrvVm2L/wCy8dQu6DMTwH4oIuGN8GJDAlqDdVE=
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/nsf/termbox-go v0.0.0-20190624072549-eeb6cd0a1762 h1:44Lv0bNi88GweB54TCjB/lEJgp+2Ze5WFpwNu0nh0ag=
github.com/nsf/termbox-go v0.0.0-20190624072549-eeb6cd0a1762/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=

@ -1,7 +1,10 @@
package config
import (
"os"
"testing"
"github.com/jesseduffield/yaml"
)
func TestDockerComposeCommandNoFiles(t *testing.T) {
@ -48,3 +51,50 @@ func TestDockerComposeCommandMultipleFiles(t *testing.T) {
t.Fatalf("Expected %s but got %s", expected, actual)
}
}
func TestWritingToConfigFile(t *testing.T) {
//init the AppConfig
emptyComposeFiles := []string{}
conf, err := NewAppConfig("name", "version", "commit", "date", "buildSource", false, emptyComposeFiles, "projectDir")
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}
testFn := func(ac *AppConfig, newReportingValue string, t *testing.T) {
updateFn := func(uc *UserConfig) error {
uc.Reporting = newReportingValue
return nil
}
err = ac.WriteToUserConfig(updateFn)
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}
file, err := os.OpenFile(ac.ConfigFilename(), os.O_RDONLY, 0660)
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}
sampleUC := UserConfig{}
err = yaml.NewDecoder(file).Decode(&sampleUC)
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}
err = file.Close()
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}
if sampleUC.Reporting != newReportingValue {
t.Fatalf("Got %s, Expected %s\n", sampleUC.Reporting, newReportingValue)
}
}
// insert value into an empty file
testFn(conf, "on", t)
// modifying an existing file that already has 'Reporting'
testFn(conf, "off", t)
}

@ -16,14 +16,20 @@ func (gui *Gui) scrollUpMain(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) scrollDownMain(g *gocui.Gui, v *gocui.View) error {
mainView := gui.getMainView()
mainView.Autoscroll = false
ox, oy := mainView.Origin()
y := oy
reservedLines := 0
if !gui.Config.UserConfig.Gui.ScrollPastBottom {
_, sy := mainView.Size()
y += sy
_, sizeY := mainView.Size()
reservedLines = sizeY
}
totalLines := mainView.ViewLinesHeight()
if oy+reservedLines >= totalLines {
return nil
}
// for some reason we can't work out whether we've hit the bottomq
// there is a large discrepancy in the origin's y value and the length of BufferLines
return mainView.SetOrigin(ox, oy+gui.Config.UserConfig.Gui.ScrollHeight)
}
@ -39,6 +45,19 @@ func (gui *Gui) scrollRightMain(g *gocui.Gui, v *gocui.View) error {
mainView := gui.getMainView()
ox, oy := mainView.Origin()
content := mainView.ViewBufferLines()
var largestNumberOfCharacters int
for _, txt := range content {
if len(txt) > largestNumberOfCharacters {
largestNumberOfCharacters = len(txt)
}
}
sizeX, _ := mainView.Size()
if ox+sizeX >= largestNumberOfCharacters {
return nil
}
return mainView.SetOrigin(ox+gui.Config.UserConfig.Gui.ScrollHeight, oy)
}

@ -6,13 +6,8 @@ package gocui
import (
standardErrors "errors"
"os"
"os/signal"
"runtime"
"strings"
"syscall"
"time"
"unsafe"
"github.com/go-errors/errors"
@ -100,13 +95,9 @@ type Gui struct {
func NewGui(mode OutputMode, supportOverlaps bool) (*Gui, error) {
g := &Gui{}
if runtime.GOOS != "windows" {
var err error
if g.maxX, g.maxY, err = g.getTermWindowSize(); err != nil {
return nil, err
}
} else {
g.maxX, g.maxY = termbox.Size()
var err error
if g.maxX, g.maxY, err = g.getTermWindowSize(); err != nil {
return nil, err
}
if err := termbox.Init(); err != nil {
@ -858,52 +849,3 @@ func (g *Gui) loaderTick() {
}
}()
}
type windowSize struct {
rows uint16
cols uint16
xpixels uint16
ypixels uint16
}
// getTermWindowSize is get terminal window size on linux or unix.
// When gocui run inside the docker contaienr need to check and get the window size.
func (g *Gui) getTermWindowSize() (int, int, error) {
out, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
if err != nil {
return 0, 0, err
}
defer out.Close()
signalCh := make(chan os.Signal, 1)
signal.Notify(signalCh, syscall.SIGWINCH, syscall.SIGINT)
defer signal.Stop(signalCh)
var sz windowSize
for {
_, _, err = syscall.Syscall(
syscall.SYS_IOCTL,
out.Fd(),
uintptr(syscall.TIOCGWINSZ),
uintptr(unsafe.Pointer(&sz)),
)
// check terminal window size
if sz.cols > 0 && sz.rows > 0 {
return int(sz.cols), int(sz.rows), nil
}
select {
case signal := <-signalCh:
switch signal {
// when the terminal window size is changed
case syscall.SIGWINCH:
continue
// ctrl + c to cancel
case syscall.SIGINT:
return 0, 0, errors.New("There was not enough window space to start the application")
}
}
}
}

@ -0,0 +1,61 @@
// +build !windows
package gocui
import (
"os"
"os/signal"
"syscall"
"unsafe"
"github.com/go-errors/errors"
)
type windowSize struct {
rows uint16
cols uint16
xpixels uint16
ypixels uint16
}
// getTermWindowSize is get terminal window size on linux or unix.
// When gocui run inside the docker contaienr need to check and get the window size.
func (g *Gui) getTermWindowSize() (int, int, error) {
out, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
if err != nil {
return 0, 0, err
}
defer out.Close()
signalCh := make(chan os.Signal, 1)
signal.Notify(signalCh, syscall.SIGWINCH, syscall.SIGINT)
defer signal.Stop(signalCh)
var sz windowSize
for {
_, _, err = syscall.Syscall(
syscall.SYS_IOCTL,
out.Fd(),
uintptr(syscall.TIOCGWINSZ),
uintptr(unsafe.Pointer(&sz)),
)
// check terminal window size
if sz.cols > 0 && sz.rows > 0 {
return int(sz.cols), int(sz.rows), nil
}
select {
case signal := <-signalCh:
switch signal {
// when the terminal window size is changed
case syscall.SIGWINCH:
continue
// ctrl + c to cancel
case syscall.SIGINT:
return 0, 0, errors.New("There was not enough window space to start the application")
}
}
}
}

@ -0,0 +1,10 @@
// +build windows
package gocui
import "github.com/jesseduffield/termbox-go"
func (g *Gui) getTermWindowSize() (int, int, error) {
x, y := termbox.Size()
return x, y, nil
}

@ -486,10 +486,16 @@ func (v *View) ViewBufferLines() []string {
return lines
}
// LinesHeight is the count of view lines (i.e. lines excluding wrapping)
func (v *View) LinesHeight() int {
return len(v.lines)
}
// ViewLinesHeight is the count of view lines (i.e. lines including wrapping)
func (v *View) ViewLinesHeight() int {
return len(v.viewLines)
}
// ViewBuffer returns a string with the contents of the view's buffer that is
// shown to the user.
func (v *View) ViewBuffer() string {

@ -48,7 +48,7 @@ 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.20190706002342-e625df489460
# github.com/jesseduffield/gocui v0.3.1-0.20190803023616-ad0cd60f29f9
github.com/jesseduffield/gocui
# github.com/jesseduffield/roll v0.0.0-20190629104057-695be2e62b00
github.com/jesseduffield/roll

Loading…
Cancel
Save