diff --git a/eventBindings.go b/eventBindings.go index b59c78f..e3f1994 100644 --- a/eventBindings.go +++ b/eventBindings.go @@ -20,9 +20,11 @@ import ( func registerHandlers(g *gocui.Gui) { // mouse handlers - g.SetKeybinding("", gocui.MouseLeft, gocui.ModNone, mouseDown) // normal left mouse down - g.SetKeybinding("", gocui.MouseLeft, gocui.ModMouseCtrl, ctrlDown) // mouse with the ctrl key held down - g.SetKeybinding("", gocui.MouseRelease, gocui.ModNone, mouseUp) // mouse button release + g.SetKeybinding("", gocui.MouseLeft, gocui.ModNone, mouseDown) // normal left mouse down + g.SetKeybinding("", gocui.MouseLeft, gocui.ModMouseCtrl, ctrlDown) // mouse with the ctrl key held down + g.SetKeybinding("", gocui.MouseRelease, gocui.ModNone, mouseUp) // mouse button release + g.SetKeybinding("", gocui.MouseWheelUp, gocui.ModNone, wheelsUp) // mouse button release + g.SetKeybinding("", gocui.MouseWheelDown, gocui.ModNone, wheelsDown) // mouse button release // Ctrl key handlers g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, doExit) // CTRL-C : exits the application @@ -36,6 +38,8 @@ func registerHandlers(g *gocui.Gui) { g.SetKeybinding("", 'O', gocui.ModNone, theStdout) // 'o' toggle the STDOUT window g.SetKeybinding("", 'q', gocui.ModNone, doExit) // 'q' exit g.SetKeybinding("", gocui.KeyTab, gocui.ModNone, tabCycleWindows) // '2' use this to test new ideas + g.SetKeybinding("", gocui.KeyPgup, gocui.ModNone, stdoutPgup) // Pgup scroll up the Stdout buffer + g.SetKeybinding("", gocui.KeyPgdn, gocui.ModNone, stdoutPgdn) // Pgdn scroll down the Stdout buffer // debugging g.SetKeybinding("", '2', gocui.ModNone, theNotsure) // '2' use this to test new ideas @@ -95,7 +99,26 @@ func addDropdown() *tree.Node { // use this to test code ideas // put whatever you want here and hit '2' to activate it func theNotsure(g *gocui.Gui, v *gocui.View) error { log.Info("got keypress 2. now what?") - log.Info("try to switch windows here") + return nil +} + +func stdoutPgup(g *gocui.Gui, v *gocui.View) error { + log.Info("try to page up in the stdout buffer here") + return nil +} + +func stdoutPgdn(g *gocui.Gui, v *gocui.View) error { + log.Info("try to page down in the stdout buffer here") + return nil +} + +func wheelsUp(g *gocui.Gui, v *gocui.View) error { + log.Info("private wheels up") + return nil +} + +func wheelsDown(g *gocui.Gui, v *gocui.View) error { + log.Info("you've landed") return nil } diff --git a/log.go b/log.go index ec2723e..dd99ebf 100644 --- a/log.go +++ b/log.go @@ -11,8 +11,6 @@ import ( "go.wit.com/log" ) -var outputS []string - var NOW *log.LogFlag var INFO *log.LogFlag var GOCUI *log.LogFlag diff --git a/stdoutShow.go b/stdoutShow.go index 94c7a1f..61f2246 100644 --- a/stdoutShow.go +++ b/stdoutShow.go @@ -6,6 +6,8 @@ package main import ( "errors" "fmt" + "slices" + "strings" "github.com/awesome-gocui/gocui" @@ -126,3 +128,50 @@ func (tk *guiWidget) relocateStdout(w int, h int) { me.baseGui.SetView("msg", w0, h0, w1, h1, 0) // me.baseGui.SetViewOnBottom("msg") } + +// from the gocui devs: +// Write appends a byte slice into the view's internal buffer. Because +// View implements the io.Writer interface, it can be passed as parameter +// of functions like fmt.Fprintf, fmt.Fprintln, io.Copy, etc. Clear must +// be called to clear the view's buffer. + +func (w *guiWidget) Write(p []byte) (n int, err error) { + w.tainted = true + me.writeMutex.Lock() + defer me.writeMutex.Unlock() + + tk := me.stdout.tk + + if tk.v == nil { + // optionally write the output to /tmp + s := fmt.Sprint(string(p)) + s = strings.TrimSuffix(s, "\n") + fmt.Fprintln(outf, s) + v, _ := me.baseGui.View("msg") + if v != nil { + // fmt.Fprintln(outf, "found msg") + tk.v = v + } + } else { + // display the output in the gocui window + lines := strings.Split(strings.TrimSpace(string(p)), "\n") + me.stdout.outputS = append(me.stdout.outputS, lines...) + + var cur []string + // chop off the last lines in the buffer + chop := len(me.stdout.outputS) - (me.stdout.h - 1) + if chop < 0 { + chop = 0 + } + if len(me.stdout.outputS) > chop { + cur = append(cur, me.stdout.outputS[chop:]...) + } else { + cur = append(cur, me.stdout.outputS...) + } + slices.Reverse(cur) + tk.v.Clear() + fmt.Fprintln(tk.v, strings.Join(cur, "\n")) + } + + return len(p), nil +} diff --git a/structs.go b/structs.go index f444e65..b4d1aef 100644 --- a/structs.go +++ b/structs.go @@ -12,7 +12,6 @@ import ( "fmt" "reflect" "strconv" - "strings" "sync" "github.com/awesome-gocui/gocui" @@ -88,6 +87,8 @@ type stdout struct { mouseOffsetH int // the current 'h' offset init bool // moves the window offscreen on startup resize bool // user is resizing the window + outputS []string // the buffer of all the output + } // settings for the dropdown window @@ -166,49 +167,6 @@ type guiWidget struct { isBG bool // means this is the background widget. There is only one of these } -// from the gocui devs: -// Write appends a byte slice into the view's internal buffer. Because -// View implements the io.Writer interface, it can be passed as parameter -// of functions like fmt.Fprintf, fmt.Fprintln, io.Copy, etc. Clear must -// be called to clear the view's buffer. - -func (w *guiWidget) Write(p []byte) (n int, err error) { - w.tainted = true - me.writeMutex.Lock() - defer me.writeMutex.Unlock() - - // _, outputH := w.Size() - outputH := 33 // special output length for "msg" window until I figure things out - - tk := me.stdout.tk - if tk.v == nil { - // optionally write the output to /tmp - s := fmt.Sprint(string(p)) - s = strings.TrimSuffix(s, "\n") - fmt.Fprintln(outf, s) - v, _ := me.baseGui.View("msg") - if v != nil { - // fmt.Fprintln(outf, "found msg") - tk.v = v - } - } else { - // display the output in the gocui window - tk.v.Clear() - - s := fmt.Sprint(string(p)) - s = strings.TrimSuffix(s, "\n") - tmp := strings.Split(s, "\n") - outputS = append(outputS, tmp...) - if len(outputS) > outputH { - l := len(outputS) - outputH - outputS = outputS[l:] - } - fmt.Fprintln(tk.v, strings.Join(outputS, "\n")) - } - - return len(p), nil -} - // THIS IS GO COMPILER MAGIC // this sets the `default` in the structs above on init() // this is cool code. thank the GO devs for this code and Alex Flint for explaining it to me