From 1d2dab4672e3c9ce6f8c11e551926ebb1f1d49b3 Mon Sep 17 00:00:00 2001 From: elv-gilles Date: Mon, 7 Mar 2022 10:11:52 +0100 Subject: [PATCH 1/5] prettify examples: add main demo screen to select specific examples * encapsulate each example * add README.md --- _examples/README.md | 48 ++++++++ _examples/active.go | 40 ++++--- _examples/bufs.go | 28 +++-- _examples/colors.go | 15 ++- _examples/colors256.go | 21 ++-- _examples/colorstrue.go | 47 ++++---- _examples/custom_frame.go | 67 ++++++----- _examples/demo.go | 73 ++++++------ _examples/demo_screen.png | Bin 0 -> 50834 bytes _examples/dynamic.go | 100 ++++++++-------- _examples/flow_layout.go | 18 ++- _examples/goroutine.go | 72 ++++++------ _examples/hello.go | 19 ++- _examples/keybinds.go | 18 +-- _examples/layout.go | 15 ++- _examples/main.go | 236 ++++++++++++++++++++++++++++++++++++++ _examples/mask.go | 17 +-- _examples/mouse.go | 95 +++++++-------- _examples/ontop.go | 19 +-- _examples/overlap.go | 13 ++- _examples/size.go | 15 ++- _examples/stdin.go | 35 +++--- _examples/table.go | 15 ++- _examples/title.go | 13 ++- _examples/widgets.go | 36 +++--- _examples/wrap.go | 17 +-- 26 files changed, 740 insertions(+), 352 deletions(-) create mode 100644 _examples/README.md create mode 100644 _examples/demo_screen.png create mode 100644 _examples/main.go diff --git a/_examples/README.md b/_examples/README.md new file mode 100644 index 00000000..67fd85a5 --- /dev/null +++ b/_examples/README.md @@ -0,0 +1,48 @@ +## Examples + +Each of the samples in `_examples` demonstrates a specific aspect of the API. + +Each can be run be alone or selected from the 'main' example. + +### Build & run + +``` +gocui $ cd _examples/ +_examples $ go build -o exam ./ + +_examples $ ./exam --help +usage: +./exam : select a demo from the gui and run it +./exam : run the 'demo' argument + + where 'demo' can be one of: + active + bufs + colors + colors-256 + colors-true + custom-frames + demo + dynamic + flow-layout + goroutine + hello + keybinds + layout + mask + mouse + on-top + overlap + size + stdin + table + title + widgets + wrap + +``` + +### Select a demo through the gui + +Demo Screen + diff --git a/_examples/active.go b/_examples/active.go index 2c5ac9f3..4572dd76 100644 --- a/_examples/active.go +++ b/_examples/active.go @@ -12,27 +12,27 @@ import ( "github.com/awesome-gocui/gocui" ) -var ( - viewArr = []string{"v1", "v2", "v3", "v4"} - active = 0 -) +type demoActive struct { + viewArr []string + active int +} -func setCurrentViewOnTop(g *gocui.Gui, name string) (*gocui.View, error) { +func (d *demoActive) setCurrentViewOnTop(g *gocui.Gui, name string) (*gocui.View, error) { if _, err := g.SetCurrentView(name); err != nil { return nil, err } return g.SetViewOnTop(name) } -func nextView(g *gocui.Gui, v *gocui.View) error { - nextIndex := (active + 1) % len(viewArr) - name := viewArr[nextIndex] +func (d *demoActive) nextView(g *gocui.Gui, v *gocui.View) error { + nextIndex := (d.active + 1) % len(d.viewArr) + name := d.viewArr[nextIndex] out, err := g.View("v2") if err != nil { return err } - fmt.Fprintln(out, "Going from view "+v.Name()+" to "+name) + _, _ = fmt.Fprintln(out, "Going from view "+v.Name()+" to "+name) if _, err := setCurrentViewOnTop(g, name); err != nil { return err @@ -44,11 +44,11 @@ func nextView(g *gocui.Gui, v *gocui.View) error { g.Cursor = false } - active = nextIndex + d.active = nextIndex return nil } -func layout(g *gocui.Gui) error { +func (d *demoActive) layout(g *gocui.Gui) error { maxX, maxY := g.Size() if v, err := g.SetView("v1", 0, 0, maxX/2-1, maxY/2-1, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { @@ -78,7 +78,7 @@ func layout(g *gocui.Gui) error { v.Title = "v3" v.Wrap = true v.Autoscroll = true - fmt.Fprint(v, "Press TAB to change current view") + _, _ = fmt.Fprint(v, "Press TAB to change current view") } if v, err := g.SetView("v4", maxX/2, maxY/2, maxX-1, maxY-1, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { @@ -90,11 +90,17 @@ func layout(g *gocui.Gui) error { return nil } -func quit(g *gocui.Gui, v *gocui.View) error { +func (d *demoActive) quit(g *gocui.Gui, v *gocui.View) error { + _ = g + _ = v return gocui.ErrQuit } -func main() { +func mainActive() { + d := &demoActive{ + viewArr: []string{"v1", "v2", "v3", "v4"}, + active: 0, + } g, err := gocui.NewGui(gocui.OutputNormal, true) if err != nil { log.Panicln(err) @@ -105,12 +111,12 @@ func main() { g.Cursor = true g.SelFgColor = gocui.ColorGreen - g.SetManagerFunc(layout) + g.SetManagerFunc(d.layout) - if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, d.quit); err != nil { log.Panicln(err) } - if err := g.SetKeybinding("", gocui.KeyTab, gocui.ModNone, nextView); err != nil { + if err := g.SetKeybinding("", gocui.KeyTab, gocui.ModNone, d.nextView); err != nil { log.Panicln(err) } diff --git a/_examples/bufs.go b/_examples/bufs.go index 2ccb93c3..e320680f 100644 --- a/_examples/bufs.go +++ b/_examples/bufs.go @@ -14,20 +14,22 @@ import ( "github.com/awesome-gocui/gocui" ) -var vbuf, buf string +type demoBufs struct { + vbuf, buf string +} -func quit(g *gocui.Gui, v *gocui.View) error { - vbuf = v.ViewBuffer() - buf = v.Buffer() +func (d *demoBufs) quit(g *gocui.Gui, v *gocui.View) error { + d.vbuf = v.ViewBuffer() + d.buf = v.Buffer() return gocui.ErrQuit } -func overwrite(g *gocui.Gui, v *gocui.View) error { +func (d *demoBufs) overwrite(g *gocui.Gui, v *gocui.View) error { v.Overwrite = !v.Overwrite return nil } -func layout(g *gocui.Gui) error { +func (d *demoBufs) layout(g *gocui.Gui) error { _, maxY := g.Size() if v, err := g.SetView("main", 0, 0, 20, maxY-1, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { @@ -42,21 +44,23 @@ func layout(g *gocui.Gui) error { return nil } -func main() { +func mainBufs() { g, err := gocui.NewGui(gocui.OutputNormal, true) if err != nil { log.Panicln(err) } + d := &demoBufs{} + g.Cursor = true g.Mouse = true - g.SetManagerFunc(layout) + g.SetManagerFunc(d.layout) - if err := g.SetKeybinding("main", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { + if err := g.SetKeybinding("main", gocui.KeyCtrlC, gocui.ModNone, d.quit); err != nil { log.Panicln(err) } - if err := g.SetKeybinding("main", gocui.KeyCtrlI, gocui.ModNone, overwrite); err != nil { + if err := g.SetKeybinding("main", gocui.KeyCtrlI, gocui.ModNone, d.overwrite); err != nil { log.Panicln(err) } @@ -66,6 +70,6 @@ func main() { g.Close() - fmt.Printf("VBUF:\n%s\n", vbuf) - fmt.Printf("BUF:\n%s\n", buf) + fmt.Printf("VBUF:\n%s\n", d.vbuf) + fmt.Printf("BUF:\n%s\n", d.buf) } diff --git a/_examples/colors.go b/_examples/colors.go index 27f8f8ae..f537799c 100644 --- a/_examples/colors.go +++ b/_examples/colors.go @@ -12,16 +12,21 @@ import ( "github.com/awesome-gocui/gocui" ) -func main() { +type demoColors struct { +} + +func mainColors() { g, err := gocui.NewGui(gocui.OutputNormal, true) if err != nil { log.Panicln(err) } defer g.Close() - g.SetManagerFunc(layout) + d := &demoColors{} + + g.SetManagerFunc(d.layout) - if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, d.quit); err != nil { log.Panicln(err) } @@ -30,7 +35,7 @@ func main() { } } -func layout(g *gocui.Gui) error { +func (d *demoColors) layout(g *gocui.Gui) error { maxX, maxY := g.Size() if v, err := g.SetView("colors", maxX/2-7, maxY/2-12, maxX/2+7, maxY/2+13, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { @@ -48,6 +53,6 @@ func layout(g *gocui.Gui) error { return nil } -func quit(g *gocui.Gui, v *gocui.View) error { +func (d *demoColors) quit(g *gocui.Gui, v *gocui.View) error { return gocui.ErrQuit } diff --git a/_examples/colors256.go b/_examples/colors256.go index 931ac660..accb7d3d 100644 --- a/_examples/colors256.go +++ b/_examples/colors256.go @@ -12,7 +12,9 @@ import ( "github.com/awesome-gocui/gocui" ) -func main() { +type demoColors256 struct{} + +func mainColors256() { g, err := gocui.NewGui(gocui.Output256, true) if err != nil { @@ -20,9 +22,10 @@ func main() { } defer g.Close() - g.SetManagerFunc(layout) + d := demoColors256{} + g.SetManagerFunc(d.layout) - if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, d.quit); err != nil { log.Panicln(err) } @@ -31,7 +34,7 @@ func main() { } } -func layout(g *gocui.Gui) error { +func (d *demoColors256) layout(g *gocui.Gui) error { maxX, maxY := g.Size() if v, err := g.SetView("colors", -1, -1, maxX, maxY, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { @@ -47,10 +50,10 @@ func layout(g *gocui.Gui) error { str += "\n" } - fmt.Fprint(v, str) + _, _ = fmt.Fprint(v, str) } - fmt.Fprint(v, "\n\n") + _, _ = fmt.Fprint(v, "\n\n") // 8-colors escape codes ctr := 0 @@ -61,7 +64,7 @@ func layout(g *gocui.Gui) error { str += "\n" } - fmt.Fprint(v, str) + _, _ = fmt.Fprint(v, str) ctr++ } @@ -73,6 +76,8 @@ func layout(g *gocui.Gui) error { return nil } -func quit(g *gocui.Gui, v *gocui.View) error { +func (d *demoColors256) quit(g *gocui.Gui, v *gocui.View) error { + _ = g + _ = v return gocui.ErrQuit } diff --git a/_examples/colorstrue.go b/_examples/colorstrue.go index 060af91e..7de94ba5 100644 --- a/_examples/colorstrue.go +++ b/_examples/colorstrue.go @@ -14,10 +14,12 @@ import ( colorful "github.com/lucasb-eyer/go-colorful" ) -var dark = false +type demoColorsTrue struct { + dark bool +} -func main() { - os.Setenv("COLORTERM", "truecolor") +func mainColorsTrue() { + _ = os.Setenv("COLORTERM", "truecolor") g, err := gocui.NewGui(gocui.OutputTrue, true) if err != nil { @@ -25,19 +27,20 @@ func main() { } defer g.Close() - g.SetManagerFunc(layout) + d := &demoColorsTrue{dark: false} + g.SetManagerFunc(d.layout) - if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, d.quit); err != nil { log.Panicln(err) } if err := g.SetKeybinding("", gocui.KeyCtrlR, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - if dark { - dark = false + if d.dark { + d.dark = false } else { - dark = true + d.dark = true } - displayHsv(v) + d.displayHsv(v) return nil }); err != nil { @@ -49,7 +52,7 @@ func main() { } } -func layout(g *gocui.Gui) error { +func (d *demoColorsTrue) layout(g *gocui.Gui) error { maxX, maxY := g.Size() rows := 33 cols := 182 @@ -66,7 +69,7 @@ func layout(g *gocui.Gui) error { } v.FrameColor = gocui.GetColor("#FFAA55") - displayHsv(v) + d.displayHsv(v) if _, err := g.SetCurrentView("colors"); err != nil { return err @@ -75,29 +78,29 @@ func layout(g *gocui.Gui) error { return nil } -func displayHsv(v *gocui.View) { +func (d *demoColorsTrue) displayHsv(v *gocui.View) { v.Clear() str := "" // HSV color space (lines are value or saturation) for i := 50; i > 0; i -= 2 { // Hue for j := 0; j < 360; j += 2 { - ir, ig, ib := hsv(j, i-1) - ir2, ig2, ib2 := hsv(j, i) + ir, ig, ib := d.hsv(j, i-1) + ir2, ig2, ib2 := d.hsv(j, i) str += fmt.Sprintf("\x1b[48;2;%d;%d;%dm\x1b[38;2;%d;%d;%dm▀\x1b[0m", ir, ig, ib, ir2, ig2, ib2) } str += "\n" - fmt.Fprint(v, str) + _, _ = fmt.Fprint(v, str) str = "" } - fmt.Fprintln(v, "\n\x1b[38;5;245mCtrl + R - Switch light/dark mode") - fmt.Fprintln(v, "\nCtrl + C - Exit\n") - fmt.Fprint(v, "Example should enable true color, but if it doesn't work run this command: \x1b[0mexport COLORTERM=truecolor") + _, _ = fmt.Fprintln(v, "\n\x1b[38;5;245mCtrl + R - Switch light/dark mode") + _, _ = fmt.Fprintln(v, "\nCtrl + C - Exit\n") + _, _ = fmt.Fprint(v, "Example should enable true color, but if it doesn't work run this command: \x1b[0mexport COLORTERM=truecolor") } -func hsv(hue, sv int) (uint32, uint32, uint32) { - if !dark { +func (d *demoColorsTrue) hsv(hue, sv int) (uint32, uint32, uint32) { + if !d.dark { ir, ig, ib, _ := colorful.Hsv(float64(hue), float64(sv)/50, float64(1)).RGBA() return ir >> 8, ig >> 8, ib >> 8 } @@ -105,6 +108,8 @@ func hsv(hue, sv int) (uint32, uint32, uint32) { return ir >> 8, ig >> 8, ib >> 8 } -func quit(g *gocui.Gui, v *gocui.View) error { +func (d *demoColorsTrue) quit(g *gocui.Gui, v *gocui.View) error { + _ = g + _ = v return gocui.ErrQuit } diff --git a/_examples/custom_frame.go b/_examples/custom_frame.go index af34d99b..7ea5b4c1 100644 --- a/_examples/custom_frame.go +++ b/_examples/custom_frame.go @@ -8,10 +8,10 @@ import ( "github.com/awesome-gocui/gocui" ) -var ( - viewArr = []string{"v1", "v2", "v3", "v4"} - active = 0 -) +type demoCustomFrames struct { + viewArr []string + active int +} func setCurrentViewOnTop(g *gocui.Gui, name string) (*gocui.View, error) { if _, err := g.SetCurrentView(name); err != nil { @@ -20,15 +20,15 @@ func setCurrentViewOnTop(g *gocui.Gui, name string) (*gocui.View, error) { return g.SetViewOnTop(name) } -func nextView(g *gocui.Gui, v *gocui.View) error { - nextIndex := (active + 1) % len(viewArr) - name := viewArr[nextIndex] +func (d *demoCustomFrames) nextView(g *gocui.Gui, v *gocui.View) error { + nextIndex := (d.active + 1) % len(d.viewArr) + name := d.viewArr[nextIndex] out, err := g.View("v1") if err != nil { return err } - fmt.Fprintln(out, "Going from view "+v.Name()+" to "+name) + _, _ = fmt.Fprintln(out, "Going from view "+v.Name()+" to "+name) if _, err := setCurrentViewOnTop(g, name); err != nil { return err @@ -40,11 +40,11 @@ func nextView(g *gocui.Gui, v *gocui.View) error { g.Cursor = false } - active = nextIndex + d.active = nextIndex return nil } -func layout(g *gocui.Gui) error { +func (d *demoCustomFrames) layout(g *gocui.Gui) error { maxX, maxY := g.Size() if v, err := g.SetView("v1", 0, 0, maxX/2-1, maxY/2-1, gocui.RIGHT); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { @@ -52,8 +52,8 @@ func layout(g *gocui.Gui) error { } v.Title = "v1" v.Autoscroll = true - fmt.Fprintln(v, "View with default frame color") - fmt.Fprintln(v, "It's connected to v2 with overlay RIGHT.\n") + _, _ = fmt.Fprintln(v, "View with default frame color") + _, _ = fmt.Fprintln(v, "It's connected to v2 with overlay RIGHT.\n") if _, err = setCurrentViewOnTop(g, "v1"); err != nil { return err } @@ -67,12 +67,12 @@ func layout(g *gocui.Gui) error { v.Wrap = true v.FrameColor = gocui.ColorMagenta v.FrameRunes = []rune{'═', '│'} - fmt.Fprintln(v, "View with minimum frame customization and colored frame.") - fmt.Fprintln(v, "It's connected to v1 with overlay LEFT.\n") - fmt.Fprintln(v, "\033[35;1mInstructions:\033[0m") - fmt.Fprintln(v, "Press TAB to change current view") - fmt.Fprintln(v, "Press Ctrl+O to toggle gocui.SupportOverlap\n") - fmt.Fprintln(v, "\033[32;2mSelected frame is highlighted with green color\033[0m") + _, _ = fmt.Fprintln(v, "View with minimum frame customization and colored frame.") + _, _ = fmt.Fprintln(v, "It's connected to v1 with overlay LEFT.\n") + _, _ = fmt.Fprintln(v, "\033[35;1mInstructions:\033[0m") + _, _ = fmt.Fprintln(v, "Press TAB to change current view") + _, _ = fmt.Fprintln(v, "Press Ctrl+O to toggle gocui.SupportOverlap\n") + _, _ = fmt.Fprintln(v, "\033[32;2mSelected frame is highlighted with green color\033[0m") } if v, err := g.SetView("v3", 0, maxY/2, maxX/2-1, maxY-1, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { @@ -84,8 +84,8 @@ func layout(g *gocui.Gui) error { v.FrameColor = gocui.ColorCyan v.TitleColor = gocui.ColorCyan v.FrameRunes = []rune{'═', '║', '╔', '╗', '╚', '╝'} - fmt.Fprintln(v, "View with basic frame customization and colored frame and title") - fmt.Fprintln(v, "It's not connected to any view.") + _, _ = fmt.Fprintln(v, "View with basic frame customization and colored frame and title") + _, _ = fmt.Fprintln(v, "It's not connected to any view.") } if v, err := g.SetView("v4", maxX/2, maxY/2, maxX-1, maxY-1, gocui.LEFT); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { @@ -97,23 +97,26 @@ func layout(g *gocui.Gui) error { v.TitleColor = gocui.ColorYellow v.FrameColor = gocui.ColorRed v.FrameRunes = []rune{'═', '║', '╔', '╗', '╚', '╝', '╠', '╣', '╦', '╩', '╬'} - fmt.Fprintln(v, "View with fully customized frame and colored title differently.") - fmt.Fprintln(v, "It's connected to v3 with overlay LEFT.\n") - v.SetCursor(0, 3) + _, _ = fmt.Fprintln(v, "View with fully customized frame and colored title differently.") + _, _ = fmt.Fprintln(v, "It's connected to v3 with overlay LEFT.\n") + _ = v.SetCursor(0, 3) } return nil } -func quit(g *gocui.Gui, v *gocui.View) error { +func (d *demoCustomFrames) quit(g *gocui.Gui, v *gocui.View) error { + _ = g + _ = v return gocui.ErrQuit } -func toggleOverlap(g *gocui.Gui, v *gocui.View) error { +func (d *demoCustomFrames) toggleOverlap(g *gocui.Gui, v *gocui.View) error { + _ = v g.SupportOverlaps = !g.SupportOverlaps return nil } -func main() { +func mainCustomFrames() { g, err := gocui.NewGui(gocui.OutputNormal, true) if err != nil { log.Panicln(err) @@ -124,15 +127,19 @@ func main() { g.SelFgColor = gocui.ColorGreen g.SelFrameColor = gocui.ColorGreen - g.SetManagerFunc(layout) + d := &demoCustomFrames{ + viewArr: []string{"v1", "v2", "v3", "v4"}, + active: 0, + } + g.SetManagerFunc(d.layout) - if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, d.quit); err != nil { log.Panicln(err) } - if err := g.SetKeybinding("", gocui.KeyCtrlO, gocui.ModNone, toggleOverlap); err != nil { + if err := g.SetKeybinding("", gocui.KeyCtrlO, gocui.ModNone, d.toggleOverlap); err != nil { log.Panicln(err) } - if err := g.SetKeybinding("", gocui.KeyTab, gocui.ModNone, nextView); err != nil { + if err := g.SetKeybinding("", gocui.KeyTab, gocui.ModNone, d.nextView); err != nil { log.Panicln(err) } diff --git a/_examples/demo.go b/_examples/demo.go index d88fe6c0..aa98ceb1 100644 --- a/_examples/demo.go +++ b/_examples/demo.go @@ -15,7 +15,9 @@ import ( "github.com/awesome-gocui/gocui" ) -func nextView(g *gocui.Gui, v *gocui.View) error { +type demo struct{} + +func (d *demo) nextView(g *gocui.Gui, v *gocui.View) error { if v == nil || v.Name() == "side" { _, err := g.SetCurrentView("main") return err @@ -24,7 +26,8 @@ func nextView(g *gocui.Gui, v *gocui.View) error { return err } -func cursorDown(g *gocui.Gui, v *gocui.View) error { +func (d *demo) cursorDown(g *gocui.Gui, v *gocui.View) error { + _ = g if v != nil { cx, cy := v.Cursor() if err := v.SetCursor(cx, cy+1); err != nil { @@ -37,7 +40,8 @@ func cursorDown(g *gocui.Gui, v *gocui.View) error { return nil } -func cursorUp(g *gocui.Gui, v *gocui.View) error { +func (d *demo) cursorUp(g *gocui.Gui, v *gocui.View) error { + _ = g if v != nil { ox, oy := v.Origin() cx, cy := v.Cursor() @@ -50,7 +54,7 @@ func cursorUp(g *gocui.Gui, v *gocui.View) error { return nil } -func getLine(g *gocui.Gui, v *gocui.View) error { +func (d *demo) getLine(g *gocui.Gui, v *gocui.View) error { var l string var err error @@ -64,7 +68,7 @@ func getLine(g *gocui.Gui, v *gocui.View) error { if !errors.Is(err, gocui.ErrUnknownView) { return err } - fmt.Fprintln(v, l) + _, _ = fmt.Fprintln(v, l) if _, err := g.SetCurrentView("msg"); err != nil { return err } @@ -72,7 +76,8 @@ func getLine(g *gocui.Gui, v *gocui.View) error { return nil } -func delMsg(g *gocui.Gui, v *gocui.View) error { +func (d *demo) delMsg(g *gocui.Gui, v *gocui.View) error { + _ = v if err := g.DeleteView("msg"); err != nil { return err } @@ -82,48 +87,51 @@ func delMsg(g *gocui.Gui, v *gocui.View) error { return nil } -func quit(g *gocui.Gui, v *gocui.View) error { +func (d *demo) quit(g *gocui.Gui, v *gocui.View) error { + _ = g + _ = v return gocui.ErrQuit } -func keybindings(g *gocui.Gui) error { - if err := g.SetKeybinding("side", gocui.KeyCtrlSpace, gocui.ModNone, nextView); err != nil { +func (d *demo) keybindings(g *gocui.Gui) error { + if err := g.SetKeybinding("side", gocui.KeyCtrlSpace, gocui.ModNone, d.nextView); err != nil { return err } - if err := g.SetKeybinding("main", gocui.KeyCtrlSpace, gocui.ModNone, nextView); err != nil { + if err := g.SetKeybinding("main", gocui.KeyCtrlSpace, gocui.ModNone, d.nextView); err != nil { return err } - if err := g.SetKeybinding("side", gocui.KeyArrowDown, gocui.ModNone, cursorDown); err != nil { + if err := g.SetKeybinding("side", gocui.KeyArrowDown, gocui.ModNone, d.cursorDown); err != nil { return err } - if err := g.SetKeybinding("side", gocui.KeyArrowUp, gocui.ModNone, cursorUp); err != nil { + if err := g.SetKeybinding("side", gocui.KeyArrowUp, gocui.ModNone, d.cursorUp); err != nil { return err } - if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, d.quit); err != nil { return err } - if err := g.SetKeybinding("side", gocui.KeyEnter, gocui.ModNone, getLine); err != nil { + if err := g.SetKeybinding("side", gocui.KeyEnter, gocui.ModNone, d.getLine); err != nil { return err } - if err := g.SetKeybinding("msg", gocui.KeyEnter, gocui.ModNone, delMsg); err != nil { + if err := g.SetKeybinding("msg", gocui.KeyEnter, gocui.ModNone, d.delMsg); err != nil { return err } - if err := g.SetKeybinding("main", gocui.KeyCtrlS, gocui.ModNone, saveMain); err != nil { + if err := g.SetKeybinding("main", gocui.KeyCtrlS, gocui.ModNone, d.saveMain); err != nil { return err } - if err := g.SetKeybinding("main", gocui.KeyCtrlW, gocui.ModNone, saveVisualMain); err != nil { + if err := g.SetKeybinding("main", gocui.KeyCtrlW, gocui.ModNone, d.saveVisualMain); err != nil { return err } return nil } -func saveMain(g *gocui.Gui, v *gocui.View) error { +func (d *demo) saveMain(g *gocui.Gui, v *gocui.View) error { + _ = g f, err := ioutil.TempFile("", "gocui_demo_") if err != nil { return err } - defer f.Close() + defer func() { _ = f.Close() }() p := make([]byte, 5) v.Rewind() @@ -144,12 +152,13 @@ func saveMain(g *gocui.Gui, v *gocui.View) error { return nil } -func saveVisualMain(g *gocui.Gui, v *gocui.View) error { +func (d *demo) saveVisualMain(g *gocui.Gui, v *gocui.View) error { + _ = g f, err := ioutil.TempFile("", "gocui_demo_") if err != nil { return err } - defer f.Close() + defer func() { _ = f.Close() }() vb := v.ViewBuffer() if _, err := io.Copy(f, strings.NewReader(vb)); err != nil { @@ -158,7 +167,7 @@ func saveVisualMain(g *gocui.Gui, v *gocui.View) error { return nil } -func layout(g *gocui.Gui) error { +func (d *demo) layout(g *gocui.Gui) error { maxX, maxY := g.Size() if v, err := g.SetView("side", -1, -1, 30, maxY, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { @@ -167,11 +176,11 @@ func layout(g *gocui.Gui) error { v.Highlight = true v.SelBgColor = gocui.ColorGreen v.SelFgColor = gocui.ColorBlack - fmt.Fprintln(v, "Item 1") - fmt.Fprintln(v, "Item 2") - fmt.Fprintln(v, "Item 3") - fmt.Fprint(v, "\rWill be") - fmt.Fprint(v, "deleted\rItem 4\nItem 5") + _, _ = fmt.Fprintln(v, "Item 1") + _, _ = fmt.Fprintln(v, "Item 2") + _, _ = fmt.Fprintln(v, "Item 3") + _, _ = fmt.Fprint(v, "\rWill be") + _, _ = fmt.Fprint(v, "deleted\rItem 4\nItem 5") } if v, err := g.SetView("main", 30, -1, maxX, maxY, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { @@ -181,7 +190,7 @@ func layout(g *gocui.Gui) error { if err != nil { panic(err) } - fmt.Fprintf(v, "%s", b) + _, _ = fmt.Fprintf(v, "%s", b) v.Editable = true v.Wrap = true if _, err := g.SetCurrentView("main"); err != nil { @@ -191,18 +200,18 @@ func layout(g *gocui.Gui) error { return nil } -func main() { +func mainDemo() { g, err := gocui.NewGui(gocui.OutputNormal, true) if err != nil { log.Panicln(err) } defer g.Close() - g.Cursor = true - g.SetManagerFunc(layout) + d := &demo{} + g.SetManagerFunc(d.layout) - if err := keybindings(g); err != nil { + if err := d.keybindings(g); err != nil { log.Panicln(err) } diff --git a/_examples/demo_screen.png b/_examples/demo_screen.png new file mode 100644 index 0000000000000000000000000000000000000000..81baee621994c579e0060fb304a2e11eda2b92a5 GIT binary patch literal 50834 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 literal 0 HcmV?d00001 diff --git a/_examples/dynamic.go b/_examples/dynamic.go index 01e6a1a0..c0c2577c 100644 --- a/_examples/dynamic.go +++ b/_examples/dynamic.go @@ -13,15 +13,14 @@ import ( "github.com/awesome-gocui/gocui" ) -const delta = 1 - -var ( - views = []string{} - curView = -1 - idxView = 0 -) +type demoDynamic struct { + views []string + curView int + idxView int + delta int +} -func main() { +func mainDynamic() { g, err := gocui.NewGui(gocui.OutputNormal, true) if err != nil { log.Panicln(err) @@ -32,12 +31,18 @@ func main() { g.SelFgColor = gocui.ColorRed g.SelFrameColor = gocui.ColorRed - g.SetManagerFunc(layout) + d := &demoDynamic{ + views: []string{}, + curView: -1, + idxView: 0, + delta: 1, + } + g.SetManagerFunc(d.layout) - if err := initKeybindings(g); err != nil { + if err := d.initKeybindings(g); err != nil { log.Panicln(err) } - if err := newView(g); err != nil { + if err := d.newView(g); err != nil { log.Panicln(err) } @@ -46,26 +51,26 @@ func main() { } } -func layout(g *gocui.Gui) error { +func (d *demoDynamic) layout(g *gocui.Gui) error { maxX, _ := g.Size() v, err := g.SetView("help", maxX-25, 0, maxX-1, 9, 0) if err != nil { if !errors.Is(err, gocui.ErrUnknownView) { return err } - fmt.Fprintln(v, "KEYBINDINGS") - fmt.Fprintln(v, "Space: New View") - fmt.Fprintln(v, "Tab: Next View") - fmt.Fprintln(v, "← ↑ → ↓: Move View") - fmt.Fprintln(v, "Backspace: Delete View") - fmt.Fprintln(v, "t: Set view on top") - fmt.Fprintln(v, "b: Set view on bottom") - fmt.Fprintln(v, "^C: Exit") + _, _ = fmt.Fprintln(v, "KEYBINDINGS") + _, _ = fmt.Fprintln(v, "Space: New View") + _, _ = fmt.Fprintln(v, "Tab: Next View") + _, _ = fmt.Fprintln(v, "← ↑ → ↓: Move View") + _, _ = fmt.Fprintln(v, "Backspace: Delete View") + _, _ = fmt.Fprintln(v, "t: Set view on top") + _, _ = fmt.Fprintln(v, "b: Set view on bottom") + _, _ = fmt.Fprintln(v, "^C: Exit") } return nil } -func initKeybindings(g *gocui.Gui) error { +func (d *demoDynamic) initKeybindings(g *gocui.Gui) error { if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { return gocui.ErrQuit @@ -74,62 +79,62 @@ func initKeybindings(g *gocui.Gui) error { } if err := g.SetKeybinding("", gocui.KeySpace, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - return newView(g) + return d.newView(g) }); err != nil { return err } if err := g.SetKeybinding("", gocui.KeyBackspace, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - return delView(g) + return d.delView(g) }); err != nil { return err } if err := g.SetKeybinding("", gocui.KeyBackspace2, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - return delView(g) + return d.delView(g) }); err != nil { return err } if err := g.SetKeybinding("", gocui.KeyTab, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - return nextView(g, true) + return d.nextView(g, true) }); err != nil { return err } if err := g.SetKeybinding("", gocui.KeyArrowLeft, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - return moveView(g, v, -delta, 0) + return moveView(g, v, -d.delta, 0) }); err != nil { return err } if err := g.SetKeybinding("", gocui.KeyArrowRight, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - return moveView(g, v, delta, 0) + return moveView(g, v, d.delta, 0) }); err != nil { return err } if err := g.SetKeybinding("", gocui.KeyArrowDown, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - return moveView(g, v, 0, delta) + return moveView(g, v, 0, d.delta) }); err != nil { return err } if err := g.SetKeybinding("", gocui.KeyArrowUp, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - return moveView(g, v, 0, -delta) + return moveView(g, v, 0, -d.delta) }); err != nil { return err } if err := g.SetKeybinding("", 't', gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - _, err := g.SetViewOnTop(views[curView]) + _, err := g.SetViewOnTop(d.views[d.curView]) return err }); err != nil { return err } if err := g.SetKeybinding("", 'b', gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - _, err := g.SetViewOnBottom(views[curView]) + _, err := g.SetViewOnBottom(d.views[d.curView]) return err }); err != nil { return err @@ -137,51 +142,52 @@ func initKeybindings(g *gocui.Gui) error { return nil } -func newView(g *gocui.Gui) error { +func (d *demoDynamic) newView(g *gocui.Gui) error { maxX, maxY := g.Size() - name := fmt.Sprintf("v%v", idxView) + name := fmt.Sprintf("v%v", d.idxView) v, err := g.SetView(name, maxX/2-5, maxY/2-5, maxX/2+5, maxY/2+5, 0) if err != nil { if !errors.Is(err, gocui.ErrUnknownView) { return err } v.Wrap = true - fmt.Fprintln(v, strings.Repeat(name+" ", 30)) + _, _ = fmt.Fprintln(v, strings.Repeat(name+" ", 30)) } if _, err := g.SetCurrentView(name); err != nil { return err } - views = append(views, name) - curView = len(views) - 1 - idxView += 1 + d.views = append(d.views, name) + d.curView = len(d.views) - 1 + d.idxView += 1 return nil } -func delView(g *gocui.Gui) error { - if len(views) <= 1 { +func (d *demoDynamic) delView(g *gocui.Gui) error { + if len(d.views) <= 1 { return nil } - if err := g.DeleteView(views[curView]); err != nil { + if err := g.DeleteView(d.views[d.curView]); err != nil { return err } - views = append(views[:curView], views[curView+1:]...) + d.views = append(d.views[:d.curView], d.views[d.curView+1:]...) - return nextView(g, false) + return d.nextView(g, false) } -func nextView(g *gocui.Gui, disableCurrent bool) error { - next := curView + 1 - if next > len(views)-1 { +func (d *demoDynamic) nextView(g *gocui.Gui, disableCurrent bool) error { + _ = disableCurrent + next := d.curView + 1 + if next > len(d.views)-1 { next = 0 } - if _, err := g.SetCurrentView(views[next]); err != nil { + if _, err := g.SetCurrentView(d.views[next]); err != nil { return err } - curView = next + d.curView = next return nil } diff --git a/_examples/flow_layout.go b/_examples/flow_layout.go index 9795c5b3..5c78469b 100644 --- a/_examples/flow_layout.go +++ b/_examples/flow_layout.go @@ -13,6 +13,8 @@ import ( "github.com/awesome-gocui/gocui" ) +type demoFlowLayout struct{} + type Label struct { name string w, h int @@ -40,7 +42,7 @@ func (w *Label) Layout(g *gocui.Gui) error { if !errors.Is(err, gocui.ErrUnknownView) { return err } - fmt.Fprint(v, w.body) + _, _ = fmt.Fprint(v, w.body) if _, err := g.SetCurrentView(w.name); err != nil { return err } @@ -48,7 +50,7 @@ func (w *Label) Layout(g *gocui.Gui) error { return nil } -func flowLayout(g *gocui.Gui) error { +func (d *demoFlowLayout) flowLayout(g *gocui.Gui) error { views := g.Views() x := 0 for _, v := range views { @@ -62,22 +64,24 @@ func flowLayout(g *gocui.Gui) error { return nil } -func main() { +func mainFlowLayout() { g, err := gocui.NewGui(gocui.OutputNormal, true) if err != nil { log.Panicln(err) } defer g.Close() + d := &demoFlowLayout{} + l1 := NewLabel("l1", "This") l2 := NewLabel("l2", "is") l3 := NewLabel("l3", "a") l4 := NewLabel("l4", "flow\nlayout") l5 := NewLabel("l5", "!") - fl := gocui.ManagerFunc(flowLayout) + fl := gocui.ManagerFunc(d.flowLayout) g.SetManager(l1, l2, l3, l4, l5, fl) - if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, d.quit); err != nil { log.Panicln(err) } @@ -86,6 +90,8 @@ func main() { } } -func quit(g *gocui.Gui, v *gocui.View) error { +func (d *demoFlowLayout) quit(g *gocui.Gui, v *gocui.View) error { + _ = g + _ = v return gocui.ErrQuit } diff --git a/_examples/goroutine.go b/_examples/goroutine.go index ae378917..ccc7b28e 100644 --- a/_examples/goroutine.go +++ b/_examples/goroutine.go @@ -14,43 +14,47 @@ import ( "github.com/awesome-gocui/gocui" ) -const NumGoroutines = 20 - -var ( - done = make(chan struct{}) - wg sync.WaitGroup - - mu sync.Mutex // protects ctr - ctr = 0 -) +type demoGoRoutine struct { + numGoroutines int + done chan struct{} + wg sync.WaitGroup + mu sync.Mutex // protects ctr + ctr int +} -func main() { +func mainGoroutine() { g, err := gocui.NewGui(gocui.OutputNormal, true) if err != nil { log.Panicln(err) } defer g.Close() - g.SetManagerFunc(layout) + d := &demoGoRoutine{ + numGoroutines: 20, + done: make(chan struct{}), + ctr: 0, + } + + g.SetManagerFunc(d.layout) - if err := keybindings(g); err != nil { + if err := d.keybindings(g); err != nil { log.Panicln(err) } - for i := 0; i < NumGoroutines; i++ { - wg.Add(1) - go counter(g) + for i := 0; i < d.numGoroutines; i++ { + d.wg.Add(1) + go d.counter(g) } if err := g.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) { log.Panicln(err) } - wg.Wait() + d.wg.Wait() } -func layout(g *gocui.Gui) error { - if v, err := g.SetView("ctr", 2, 2, 22, 2+NumGoroutines+1, 0); err != nil { +func (d *demoGoRoutine) layout(g *gocui.Gui) error { + if v, err := g.SetView("ctr", 2, 2, 22, 2+d.numGoroutines+1, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { return err } @@ -62,30 +66,32 @@ func layout(g *gocui.Gui) error { return nil } -func keybindings(g *gocui.Gui) error { - if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { +func (d *demoGoRoutine) keybindings(g *gocui.Gui) error { + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, d.quit); err != nil { return err } return nil } -func quit(g *gocui.Gui, v *gocui.View) error { - close(done) +func (d *demoGoRoutine) quit(g *gocui.Gui, v *gocui.View) error { + _ = g + _ = v + close(d.done) return gocui.ErrQuit } -func counter(g *gocui.Gui) { - defer wg.Done() +func (d *demoGoRoutine) counter(g *gocui.Gui) { + defer d.wg.Done() for { select { - case <-done: + case <-d.done: return case <-time.After(500 * time.Millisecond): - mu.Lock() - n := ctr - ctr++ - mu.Unlock() + d.mu.Lock() + n := d.ctr + d.ctr++ + d.mu.Unlock() g.Update(func(g *gocui.Gui) error { v, err := g.View("ctr") @@ -94,13 +100,13 @@ func counter(g *gocui.Gui) { } // use ctr to make it more chaotic // "pseudo-randomly" print in one of two columns (x = 0, and x = 10) - x := (ctr / NumGoroutines) & 1 + x := (d.ctr / d.numGoroutines) & 1 if x != 0 { x = 10 } - y := ctr % NumGoroutines - v.SetWritePos(x, y) - fmt.Fprintln(v, n) + y := d.ctr % d.numGoroutines + _ = v.SetWritePos(x, y) + _, _ = fmt.Fprintln(v, n) return nil }) } diff --git a/_examples/hello.go b/_examples/hello.go index d4851962..3efd85c8 100644 --- a/_examples/hello.go +++ b/_examples/hello.go @@ -12,16 +12,21 @@ import ( "github.com/awesome-gocui/gocui" ) -func main() { +type demoHello struct { +} + +func mainHello() { + g, err := gocui.NewGui(gocui.OutputNormal, true) if err != nil { log.Panicln(err) } defer g.Close() - g.SetManagerFunc(layout) + d := &demoHello{} + g.SetManagerFunc(d.layout) - if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, d.quit); err != nil { log.Panicln(err) } @@ -30,7 +35,7 @@ func main() { } } -func layout(g *gocui.Gui) error { +func (d *demoHello) layout(g *gocui.Gui) error { maxX, maxY := g.Size() if v, err := g.SetView("hello", maxX/2-7, maxY/2, maxX/2+7, maxY/2+2, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { @@ -41,12 +46,14 @@ func layout(g *gocui.Gui) error { return err } - fmt.Fprintln(v, "Hello world!") + _, _ = fmt.Fprintln(v, "Hello world!") } return nil } -func quit(g *gocui.Gui, v *gocui.View) error { +func (d *demoHello) quit(g *gocui.Gui, v *gocui.View) error { + _ = g + _ = v return gocui.ErrQuit } diff --git a/_examples/keybinds.go b/_examples/keybinds.go index c3de5b6f..93c48298 100644 --- a/_examples/keybinds.go +++ b/_examples/keybinds.go @@ -7,15 +7,18 @@ import ( "github.com/awesome-gocui/gocui" ) +type demoKeybinds struct { +} + // layout generates the view -func layout(g *gocui.Gui) error { +func (d *demoKeybinds) layout(g *gocui.Gui) error { maxX, maxY := g.Size() if v, err := g.SetView("hello", maxX/2-7, maxY/2, maxX/2+7, maxY/2+2, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { return err } - v.Write([]byte("Hello")) + _, _ = v.Write([]byte("Hello")) if _, err := g.SetCurrentView("hello"); err != nil { return err @@ -26,11 +29,11 @@ func layout(g *gocui.Gui) error { } // quit stops the gui -func quit(_ *gocui.Gui, _ *gocui.View) error { +func (d *demoKeybinds) quit(_ *gocui.Gui, _ *gocui.View) error { return gocui.ErrQuit } -func main() { +func mainKeybinds() { // Create a gui g, err := gocui.NewGui(gocui.OutputNormal, false) if err != nil { @@ -38,8 +41,9 @@ func main() { } defer g.Close() + d := &demoKeybinds{} // Add a manager function - g.SetManagerFunc(layout) + g.SetManagerFunc(d.layout) // This will set up the recovery for MustParse defer func() { @@ -50,7 +54,7 @@ func main() { // The MustParse can panic, but only returns 2 values instead of 3 keyForced, modForced := gocui.MustParse("q") - if err := g.SetKeybinding("", keyForced, modForced, quit); err != nil { + if err := g.SetKeybinding("", keyForced, modForced, d.quit); err != nil { log.Panicln(err) } @@ -72,7 +76,7 @@ func main() { log.Panicln(err) } - if err = g.SetKeybinding("", keyNormal, modNormal, quit); err != nil { + if err = g.SetKeybinding("", keyNormal, modNormal, d.quit); err != nil { log.Panicln(err) } diff --git a/_examples/layout.go b/_examples/layout.go index 1fe18054..07df0a74 100644 --- a/_examples/layout.go +++ b/_examples/layout.go @@ -11,7 +11,9 @@ import ( "github.com/awesome-gocui/gocui" ) -func layout(g *gocui.Gui) error { +type demoLayout struct{} + +func (d *demoLayout) layout(g *gocui.Gui) error { maxX, maxY := g.Size() if _, err := g.SetView("side", -1, -1, int(0.2*float32(maxX)), maxY-5, 0); err != nil && !errors.Is(err, gocui.ErrUnknownView) { return err @@ -21,7 +23,7 @@ func layout(g *gocui.Gui) error { return err } - g.SetCurrentView("main") + _, _ = g.SetCurrentView("main") } if _, err := g.SetView("cmdline", -1, maxY-5, maxX, maxY, 0); err != nil && !errors.Is(err, gocui.ErrUnknownView) { return err @@ -30,20 +32,21 @@ func layout(g *gocui.Gui) error { return nil } -func quit(g *gocui.Gui, v *gocui.View) error { +func (d *demoLayout) quit(_ *gocui.Gui, _ *gocui.View) error { return gocui.ErrQuit } -func main() { +func mainLayout() { g, err := gocui.NewGui(gocui.OutputNormal, true) if err != nil { log.Panicln(err) } defer g.Close() - g.SetManagerFunc(layout) + d := &demoLayout{} + g.SetManagerFunc(d.layout) - if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, d.quit); err != nil { log.Panicln(err) } diff --git a/_examples/main.go b/_examples/main.go new file mode 100644 index 00000000..7a72b895 --- /dev/null +++ b/_examples/main.go @@ -0,0 +1,236 @@ +package main + +import ( + "errors" + "fmt" + "log" + "os" + "sort" + "strings" + + "github.com/awesome-gocui/gocui" +) + +var demos = map[string]func(){ + "active": mainActive, + "bufs": mainBufs, + "colors": mainColors, + "colors-256": mainColors256, + "colors-true": mainColorsTrue, + "custom-frames": mainCustomFrames, + "demo": mainDemo, + "dynamic": mainDynamic, + "flow-layout": mainFlowLayout, + "goroutine": mainGoroutine, + "hello": mainHello, + "keybinds": mainKeybinds, + "layout": mainLayout, + "mask": mainMask, + "mouse": mainMouse, + "on-top": mainOntop, + "overlap": mainOverlap, + "size": mainSize, + "stdin": mainStdin, + "table": mainTable, + "title": mainTitle, + "widgets": mainWidgets, + "wrap": mainWrap, +} + +func demoNames() []string { + names := make([]string, 0) + for n := range demos { + names = append(names, n) + } + sort.Strings(names) + return names +} + +func usage() string { + sb := strings.Builder{} + sb.WriteString("usage:\n") + sb.WriteString(fmt.Sprintf("%s : select a demo from the gui and run it\n", os.Args[0])) + sb.WriteString(fmt.Sprintf("%s : run the 'demo' argument\n", os.Args[0])) + sb.WriteString("\n") + sb.WriteString(" where 'demo' can be one of: \n") + + names := demoNames() + for _, n := range names { + sb.WriteString(" " + n + "\n") + } + return sb.String() +} + +func main() { + demo := "" + if len(os.Args) > 1 { + demo = os.Args[1] + } + if demo == "-h" || demo == "--help" { + fmt.Println(usage()) + os.Exit(1) + } + if len(demo) > 0 { + demoFn := demos[demo] + if demoFn == nil { + fmt.Println("unknown demo...") + fmt.Println(usage()) + os.Exit(1) + } + demoFn() + return + } + doDemo() +} + +type runDemos struct { + g *gocui.Gui + demos []string + selected int +} + +func doDemo() { + g, err := gocui.NewGui(gocui.OutputNormal, true) + if err != nil { + log.Panicln(err) + } + defer g.Close() + + g.Highlight = true + g.Cursor = false + g.SelFgColor = gocui.ColorGreen + + d := &runDemos{ + g: g, + demos: demoNames(), + } + g.SetManagerFunc(d.layout) + + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, + func(*gocui.Gui, *gocui.View) error { + return gocui.ErrQuit + }); err != nil { + log.Panicln(err) + } + if err := g.SetKeybinding("demos", gocui.KeyArrowDown, gocui.ModNone, d.selectNext); err != nil { + log.Panicln(err) + } + if err := g.SetKeybinding("demos", gocui.KeyArrowUp, gocui.ModNone, d.selectPrev); err != nil { + log.Panicln(err) + } + if err := g.SetKeybinding("demos", gocui.KeyEnter, gocui.ModNone, d.runSelectedDemo); err != nil { + log.Panicln(err) + } + + if err := g.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) { + log.Panicln(err) + } + +} + +func (d *runDemos) moveSelected(v *gocui.View, delta int) { + _ = v.SetHighlight(d.selected, false) + d.selected += delta + if d.selected >= len(d.demos) { + d.selected = 0 + } + if d.selected < 0 { + d.selected = len(d.demos) - 1 + } + _ = v.SetHighlight(d.selected, true) +} + +func (d *runDemos) selectNext(_ *gocui.Gui, v *gocui.View) error { + d.moveSelected(v, +1) + return nil +} + +func (d *runDemos) selectPrev(_ *gocui.Gui, v *gocui.View) error { + d.moveSelected(v, -1) + return nil +} + +func (d *runDemos) layout(g *gocui.Gui) error { + width := 80 + x0 := 0 + x1 := x0 + width + + view, err := g.SetView("help", x0, 5, x1, 9, 0) + if err != nil { + if !errors.Is(err, gocui.ErrUnknownView) { + return err + } + _, _ = fmt.Fprintln(view, "Use the arrow keys to select a demo") + _, _ = fmt.Fprintln(view, "Press [Enter] to run the selected demo (Ctrl-C to exit the demo)") + _, _ = fmt.Fprintln(view, "Ctrl-C to exit") + } + + y0 := 10 + y1 := y0 + len(d.demos) + 1 + view, err = g.SetView("demos", x0, y0, x1, y1, 0) + if err != nil { + if !errors.Is(err, gocui.ErrUnknownView) { + return err + } + //view.Highlight = true + view.SelBgColor = gocui.ColorGreen + view.SelFgColor = gocui.ColorBlack + + for i, demo := range d.demos { + _ = view.SetWritePos(0, i) + view.WriteString(demo) + } + _ = view.SetHighlight(d.selected, true) + _, _ = g.SetCurrentView("demos") + } + return nil +} + +func (d *runDemos) runSelectedDemo(_ *gocui.Gui, _ *gocui.View) error { + name := d.demos[d.selected] + + if name == "stdin" { + lines := []string{ + fmt.Sprintf("This example doesn't work when running `%s stdin`", os.Args[0]), + fmt.Sprintf("you are supposed to pipe something to this like: `/bin/ls | %s stdin`", os.Args[0]), + "Press 'Esc' to close this view", + } + messageBox(d.g, 20, 20, "warning", "stdin", lines, "demos") + return nil + } + demoFn := demos[name] + + gocui.Suspend() + demoFn() + return gocui.Resume() +} + +func messageBox(g *gocui.Gui, x0, y0 int, title, viewName string, lines []string, nextView string) { + w := 20 + for _, l := range lines { + if len(l) > w { + w = len(l) + } + } + x1 := x0 + w + 2 + y1 := y0 + len(lines) + 1 + view, err := g.SetView(viewName, x0, y0, x1, y1, 0) + if err != nil { + if !errors.Is(err, gocui.ErrUnknownView) { + return + } + + view.Title = title + for _, line := range lines { + _, _ = fmt.Fprintln(view, line) + } + _, _ = g.SetViewOnTop(viewName) + _, _ = g.SetCurrentView(viewName) + _ = g.SetKeybinding(viewName, gocui.KeyEsc, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { + view.Visible = false + _ = g.DeleteView(viewName) + _, _ = g.SetCurrentView(nextView) + return nil + }) + } +} diff --git a/_examples/mask.go b/_examples/mask.go index 5bd83f0f..448a76e1 100644 --- a/_examples/mask.go +++ b/_examples/mask.go @@ -12,7 +12,9 @@ import ( "github.com/awesome-gocui/gocui" ) -func main() { +type demoMask struct{} + +func mainMask() { g, err := gocui.NewGui(gocui.OutputNormal, true) if err != nil { log.Fatalln(err) @@ -21,9 +23,10 @@ func main() { g.Cursor = true - g.SetManagerFunc(layout) + d := &demoMask{} + g.SetManagerFunc(d.layout) - if err := initKeybindings(g); err != nil { + if err := d.initKeybindings(g); err != nil { log.Fatalln(err) } @@ -32,7 +35,7 @@ func main() { } } -func layout(g *gocui.Gui) error { +func (d *demoMask) layout(g *gocui.Gui) error { maxX, maxY := g.Size() if v, err := g.SetView("help", maxX-23, 0, maxX-1, 3, 0); err != nil { @@ -40,8 +43,8 @@ func layout(g *gocui.Gui) error { return err } v.Title = "Keybindings" - fmt.Fprintln(v, "^a: Set mask") - fmt.Fprintln(v, "^c: Exit") + _, _ = fmt.Fprintln(v, "^a: Set mask") + _, _ = fmt.Fprintln(v, "^c: Exit") } if v, err := g.SetView("input", 0, 0, maxX-24, maxY-1, 0); err != nil { @@ -58,7 +61,7 @@ func layout(g *gocui.Gui) error { return nil } -func initKeybindings(g *gocui.Gui) error { +func (d *demoMask) initKeybindings(g *gocui.Gui) error { if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { return gocui.ErrQuit diff --git a/_examples/mouse.go b/_examples/mouse.go index 762f8eb8..4f940480 100644 --- a/_examples/mouse.go +++ b/_examples/mouse.go @@ -12,7 +12,12 @@ import ( "github.com/awesome-gocui/gocui" ) -func main() { +type demoMouse struct { + initialMouseX, initialMouseY, xOffset, yOffset int + globalMouseDown, msgMouseDown, movingMsg bool +} + +func mainMouse() { g, err := gocui.NewGui(gocui.OutputNormal, true) if err != nil { log.Panicln(err) @@ -22,9 +27,10 @@ func main() { g.Cursor = false g.Mouse = true - g.SetManagerFunc(layout) + d := demoMouse{} + g.SetManagerFunc(d.layout) - if err := keybindings(g); err != nil { + if err := d.keybindings(g); err != nil { log.Panicln(err) } @@ -33,13 +39,10 @@ func main() { } } -var initialMouseX, initialMouseY, xOffset, yOffset int -var globalMouseDown, msgMouseDown, movingMsg bool - -func layout(g *gocui.Gui) error { +func (d *demoMouse) layout(g *gocui.Gui) error { maxX, maxY := g.Size() - if _, err := g.View("msg"); msgMouseDown && err == nil { - moveMsg(g) + if _, err := g.View("msg"); d.msgMouseDown && err == nil { + d.moveMsg(g) } if v, err := g.SetView("global", -1, -1, maxX, maxY, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { @@ -53,10 +56,10 @@ func layout(g *gocui.Gui) error { } v.SelBgColor = gocui.ColorGreen v.SelFgColor = gocui.ColorBlack - fmt.Fprintln(v, "Button 1 - line 1") - fmt.Fprintln(v, "Button 1 - line 2") - fmt.Fprintln(v, "Button 1 - line 3") - fmt.Fprintln(v, "Button 1 - line 4") + _, _ = fmt.Fprintln(v, "Button 1 - line 1") + _, _ = fmt.Fprintln(v, "Button 1 - line 2") + _, _ = fmt.Fprintln(v, "Button 1 - line 3") + _, _ = fmt.Fprintln(v, "Button 1 - line 4") if _, err := g.SetCurrentView("but1"); err != nil { return err } @@ -67,38 +70,38 @@ func layout(g *gocui.Gui) error { } v.SelBgColor = gocui.ColorGreen v.SelFgColor = gocui.ColorBlack - fmt.Fprintln(v, "Button 2 - line 1") + _, _ = fmt.Fprintln(v, "Button 2 - line 1") } - updateHighlightedView(g) + d.updateHighlightedView(g) return nil } -func keybindings(g *gocui.Gui) error { - if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { +func (d *demoMouse) keybindings(g *gocui.Gui) error { + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, d.quit); err != nil { return err } for _, n := range []string{"but1", "but2"} { - if err := g.SetKeybinding(n, gocui.MouseLeft, gocui.ModNone, showMsg); err != nil { + if err := g.SetKeybinding(n, gocui.MouseLeft, gocui.ModNone, d.showMsg); err != nil { return err } } - if err := g.SetKeybinding("", gocui.MouseRelease, gocui.ModNone, mouseUp); err != nil { + if err := g.SetKeybinding("", gocui.MouseRelease, gocui.ModNone, d.mouseUp); err != nil { return err } - if err := g.SetKeybinding("", gocui.MouseLeft, gocui.ModNone, globalDown); err != nil { + if err := g.SetKeybinding("", gocui.MouseLeft, gocui.ModNone, d.globalDown); err != nil { return err } - if err := g.SetKeybinding("msg", gocui.MouseLeft, gocui.ModNone, msgDown); err != nil { + if err := g.SetKeybinding("msg", gocui.MouseLeft, gocui.ModNone, d.msgDown); err != nil { return err } return nil } -func quit(g *gocui.Gui, v *gocui.View) error { +func (d *demoMouse) quit(_ *gocui.Gui, _ *gocui.View) error { return gocui.ErrQuit } -func showMsg(g *gocui.Gui, v *gocui.View) error { +func (d *demoMouse) showMsg(g *gocui.Gui, v *gocui.View) error { var l string var err error @@ -116,12 +119,12 @@ func showMsg(g *gocui.Gui, v *gocui.View) error { v.Clear() v.SelBgColor = gocui.ColorCyan v.SelFgColor = gocui.ColorBlack - fmt.Fprintln(v, l) + _, _ = fmt.Fprintln(v, l) } return nil } -func updateHighlightedView(g *gocui.Gui) { +func (d *demoMouse) updateHighlightedView(g *gocui.Gui) { mx, my := g.MousePosition() for _, view := range g.Views() { view.Highlight = false @@ -131,32 +134,32 @@ func updateHighlightedView(g *gocui.Gui) { } } -func moveMsg(g *gocui.Gui) { +func (d *demoMouse) moveMsg(g *gocui.Gui) { mx, my := g.MousePosition() - if !movingMsg && (mx != initialMouseX || my != initialMouseY) { - movingMsg = true + if !d.movingMsg && (mx != d.initialMouseX || my != d.initialMouseY) { + d.movingMsg = true } - g.SetView("msg", mx-xOffset, my-yOffset, mx-xOffset+20, my-yOffset+2, 0) + _, _ = g.SetView("msg", mx-d.xOffset, my-d.yOffset, mx-d.xOffset+20, my-d.yOffset+2, 0) } -func msgDown(g *gocui.Gui, v *gocui.View) error { - initialMouseX, initialMouseY = g.MousePosition() +func (d *demoMouse) msgDown(g *gocui.Gui, v *gocui.View) error { + d.initialMouseX, d.initialMouseY = g.MousePosition() if vx, vy, _, _, err := g.ViewPosition("msg"); err == nil { - xOffset = initialMouseX - vx - yOffset = initialMouseY - vy - msgMouseDown = true + d.xOffset = d.initialMouseX - vx + d.yOffset = d.initialMouseY - vy + d.msgMouseDown = true } return nil } -func globalDown(g *gocui.Gui, v *gocui.View) error { +func (d *demoMouse) globalDown(g *gocui.Gui, v *gocui.View) error { mx, my := g.MousePosition() if vx0, vy0, vx1, vy1, err := g.ViewPosition("msg"); err == nil { if mx >= vx0 && mx <= vx1 && my >= vy0 && my <= vy1 { - return msgDown(g, v) + return d.msgDown(g, v) } } - globalMouseDown = true + d.globalMouseDown = true maxX, _ := g.Size() msg := fmt.Sprintf("Mouse down at: %d,%d", mx, my) x := mx - len(msg)/2 @@ -174,18 +177,18 @@ func globalDown(g *gocui.Gui, v *gocui.View) error { return nil } -func mouseUp(g *gocui.Gui, v *gocui.View) error { - if msgMouseDown { - msgMouseDown = false - if movingMsg { - movingMsg = false +func (d *demoMouse) mouseUp(g *gocui.Gui, v *gocui.View) error { + if d.msgMouseDown { + d.msgMouseDown = false + if d.movingMsg { + d.movingMsg = false return nil } else { - g.DeleteView("msg") + _ = g.DeleteView("msg") } - } else if globalMouseDown { - globalMouseDown = false - g.DeleteView("globalDown") + } else if d.globalMouseDown { + d.globalMouseDown = false + _ = g.DeleteView("globalDown") } return nil } diff --git a/_examples/ontop.go b/_examples/ontop.go index a2213626..55b775dd 100644 --- a/_examples/ontop.go +++ b/_examples/ontop.go @@ -12,16 +12,19 @@ import ( "github.com/awesome-gocui/gocui" ) -func main() { +type demoOnTop struct{} + +func mainOntop() { g, err := gocui.NewGui(gocui.OutputNormal, true) if err != nil { log.Panicln(err) } defer g.Close() - g.SetManagerFunc(layout) + d := &demoOnTop{} + g.SetManagerFunc(d.layout) - if err := keybindings(g); err != nil { + if err := d.keybindings(g); err != nil { log.Panicln(err) } @@ -30,24 +33,24 @@ func main() { } } -func layout(g *gocui.Gui) error { +func (d *demoOnTop) layout(g *gocui.Gui) error { if v, err := g.SetView("v1", 10, 2, 30, 6, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { return err } - fmt.Fprintln(v, "View #1") + _, _ = fmt.Fprintln(v, "View #1") } if v, err := g.SetView("v2", 20, 4, 40, 8, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { return err } - fmt.Fprintln(v, "View #2") + _, _ = fmt.Fprintln(v, "View #2") } if v, err := g.SetView("v3", 30, 6, 50, 10, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { return err } - fmt.Fprintln(v, "View #3") + _, _ = fmt.Fprintln(v, "View #3") if _, err := g.SetCurrentView("v3"); err != nil { return err } @@ -56,7 +59,7 @@ func layout(g *gocui.Gui) error { return nil } -func keybindings(g *gocui.Gui) error { +func (d *demoOnTop) keybindings(g *gocui.Gui) error { err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { return gocui.ErrQuit }) diff --git a/_examples/overlap.go b/_examples/overlap.go index 7ecf31b3..1d6ee269 100644 --- a/_examples/overlap.go +++ b/_examples/overlap.go @@ -11,7 +11,9 @@ import ( "github.com/awesome-gocui/gocui" ) -func layout(g *gocui.Gui) error { +type demoOverlap struct{} + +func (d *demoOverlap) layout(g *gocui.Gui) error { maxX, maxY := g.Size() if _, err := g.SetView("v1", -1, -1, 10, 10, 0); err != nil && !errors.Is(err, gocui.ErrUnknownView) { @@ -56,20 +58,21 @@ func layout(g *gocui.Gui) error { return nil } -func quit(g *gocui.Gui, v *gocui.View) error { +func (d *demoOverlap) quit(_ *gocui.Gui, _ *gocui.View) error { return gocui.ErrQuit } -func main() { +func mainOverlap() { g, err := gocui.NewGui(gocui.OutputNormal, true) if err != nil { log.Panicln(err) } defer g.Close() - g.SetManagerFunc(layout) + d := &demoOverlap{} + g.SetManagerFunc(d.layout) - if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, d.quit); err != nil { log.Panicln(err) } diff --git a/_examples/size.go b/_examples/size.go index 8e065fd0..1e197a13 100644 --- a/_examples/size.go +++ b/_examples/size.go @@ -12,16 +12,19 @@ import ( "github.com/awesome-gocui/gocui" ) -func main() { +type demoSize struct{} + +func mainSize() { g, err := gocui.NewGui(gocui.OutputNormal, true) if err != nil { log.Panicln(err) } defer g.Close() - g.SetManagerFunc(layout) + d := &demoSize{} + g.SetManagerFunc(d.layout) - if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, d.quit); err != nil { log.Panicln(err) } @@ -30,7 +33,7 @@ func main() { } } -func layout(g *gocui.Gui) error { +func (d *demoSize) layout(g *gocui.Gui) error { maxX, maxY := g.Size() v, err := g.SetView("size", maxX/2-7, maxY/2, maxX/2+7, maxY/2+2, 0) if err != nil { @@ -42,10 +45,10 @@ func layout(g *gocui.Gui) error { } } v.Clear() - fmt.Fprintf(v, "%d, %d", maxX, maxY) + _, _ = fmt.Fprintf(v, "%d, %d", maxX, maxY) return nil } -func quit(g *gocui.Gui, v *gocui.View) error { +func (d *demoSize) quit(_ *gocui.Gui, _ *gocui.View) error { return gocui.ErrQuit } diff --git a/_examples/stdin.go b/_examples/stdin.go index d93bc02d..d9ec88d0 100644 --- a/_examples/stdin.go +++ b/_examples/stdin.go @@ -17,7 +17,9 @@ import ( "github.com/awesome-gocui/gocui" ) -func main() { +type demoStdin struct{} + +func mainStdin() { g, err := gocui.NewGui(gocui.OutputNormal, true) if err != nil { log.Fatalln(err) @@ -26,9 +28,10 @@ func main() { g.Cursor = true - g.SetManagerFunc(layout) + d := &demoStdin{} + g.SetManagerFunc(d.layout) - if err := initKeybindings(g); err != nil { + if err := d.initKeybindings(g); err != nil { log.Fatalln(err) } @@ -37,17 +40,17 @@ func main() { } } -func layout(g *gocui.Gui) error { +func (d *demoStdin) layout(g *gocui.Gui) error { maxX, _ := g.Size() if v, err := g.SetView("help", maxX-23, 0, maxX-1, 5, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { return err } - fmt.Fprintln(v, "KEYBINDINGS") - fmt.Fprintln(v, "↑ ↓: Seek input") - fmt.Fprintln(v, "a: Enable autoscroll") - fmt.Fprintln(v, "^C: Exit") + _, _ = fmt.Fprintln(v, "KEYBINDINGS") + _, _ = fmt.Fprintln(v, "↑ ↓: Seek input") + _, _ = fmt.Fprintln(v, "a: Enable autoscroll") + _, _ = fmt.Fprintln(v, "^C: Exit") } if v, err := g.SetView("stdin", 0, 0, 80, 35, 0); err != nil { @@ -68,23 +71,23 @@ func layout(g *gocui.Gui) error { return nil } -func initKeybindings(g *gocui.Gui) error { - if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { +func (d *demoStdin) initKeybindings(g *gocui.Gui) error { + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, d.quit); err != nil { return err } - if err := g.SetKeybinding("stdin", 'a', gocui.ModNone, autoscroll); err != nil { + if err := g.SetKeybinding("stdin", 'a', gocui.ModNone, d.autoscroll); err != nil { return err } if err := g.SetKeybinding("stdin", gocui.KeyArrowUp, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - scrollView(v, -1) + _ = d.scrollView(v, -1) return nil }); err != nil { return err } if err := g.SetKeybinding("stdin", gocui.KeyArrowDown, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - scrollView(v, 1) + _ = d.scrollView(v, 1) return nil }); err != nil { return err @@ -92,16 +95,16 @@ func initKeybindings(g *gocui.Gui) error { return nil } -func quit(g *gocui.Gui, v *gocui.View) error { +func (d *demoStdin) quit(_ *gocui.Gui, _ *gocui.View) error { return gocui.ErrQuit } -func autoscroll(g *gocui.Gui, v *gocui.View) error { +func (d *demoStdin) autoscroll(_ *gocui.Gui, v *gocui.View) error { v.Autoscroll = true return nil } -func scrollView(v *gocui.View, dy int) error { +func (d *demoStdin) scrollView(v *gocui.View, dy int) error { if v != nil { v.Autoscroll = false ox, oy := v.Origin() diff --git a/_examples/table.go b/_examples/table.go index 189680a2..1c537122 100644 --- a/_examples/table.go +++ b/_examples/table.go @@ -11,6 +11,8 @@ import ( "github.com/awesome-gocui/gocui" ) +type demoTable struct{} + type Column struct { Title string Size float32 @@ -45,15 +47,15 @@ func (t *Table) Layout(g *gocui.Gui) error { for cid, column := range t.Columns { size := int(float32(width+1) * column.Size) - view.SetWritePos(hOffset, 0) + _ = view.SetWritePos(hOffset, 0) view.WriteString(column.Title) for rid := 0; rid < height; rid++ { if rid < len(t.Data[cid]) { - view.SetWritePos(hOffset, rid+1) + _ = view.SetWritePos(hOffset, rid+1) view.WriteString(t.Data[cid][rid]) } - view.SetWritePos(hOffset+size-1, rid) + _ = view.SetWritePos(hOffset+size-1, rid) view.WriteRunes([]rune{'│'}) } @@ -63,12 +65,13 @@ func (t *Table) Layout(g *gocui.Gui) error { return nil } -func main() { +func mainTable() { g, err := gocui.NewGui(gocui.OutputNormal, false) if err != nil { log.Panicln(err) } defer g.Close() + d := &demoTable{} table := NewTable("t", 0, 2, 80, 10) table.Columns = []Column{ @@ -85,7 +88,7 @@ func main() { } g.SetManager(table) - if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, d.quit); err != nil { log.Panicln(err) } @@ -94,6 +97,6 @@ func main() { } } -func quit(g *gocui.Gui, v *gocui.View) error { +func (d *demoTable) quit(_ *gocui.Gui, _ *gocui.View) error { return gocui.ErrQuit } diff --git a/_examples/title.go b/_examples/title.go index 23be3389..32034eda 100644 --- a/_examples/title.go +++ b/_examples/title.go @@ -11,16 +11,19 @@ import ( "github.com/awesome-gocui/gocui" ) -func main() { +type demoTitle struct{} + +func mainTitle() { g, err := gocui.NewGui(gocui.OutputNormal, true) if err != nil { log.Panicln(err) } defer g.Close() - g.SetManagerFunc(layout) + d := &demoTitle{} + g.SetManagerFunc(d.layout) - if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, d.quit); err != nil { log.Panicln(err) } @@ -29,11 +32,11 @@ func main() { } } -func quit(g *gocui.Gui, v *gocui.View) error { +func (d *demoTitle) quit(_ *gocui.Gui, _ *gocui.View) error { return gocui.ErrQuit } -func layout(g *gocui.Gui) error { +func (d *demoTitle) layout(g *gocui.Gui) error { maxX, maxY := g.Size() // Overlap (front) diff --git a/_examples/widgets.go b/_examples/widgets.go index 2e6c67a9..ee98a8de 100644 --- a/_examples/widgets.go +++ b/_examples/widgets.go @@ -13,7 +13,9 @@ import ( "github.com/awesome-gocui/gocui" ) -const delta = 0.2 +type demoWidgets struct { + delta float64 +} type HelpWidget struct { name string @@ -43,7 +45,7 @@ func (w *HelpWidget) Layout(g *gocui.Gui) error { if !errors.Is(err, gocui.ErrUnknownView) { return err } - fmt.Fprint(v, w.body) + _, _ = fmt.Fprint(v, w.body) } return nil } @@ -79,7 +81,7 @@ func (w *StatusbarWidget) Layout(g *gocui.Gui) error { v.Clear() rep := int(w.val * float64(w.w-1)) - fmt.Fprint(v, strings.Repeat("▒", rep)) + _, _ = fmt.Fprint(v, strings.Repeat("▒", rep)) return nil } @@ -107,31 +109,33 @@ func (w *ButtonWidget) Layout(g *gocui.Gui) error { if err := g.SetKeybinding(w.name, gocui.KeyEnter, gocui.ModNone, w.handler); err != nil { return err } - fmt.Fprint(v, w.label) + _, _ = fmt.Fprint(v, w.label) } return nil } -func main() { +func mainWidgets() { g, err := gocui.NewGui(gocui.OutputNormal, true) if err != nil { log.Panicln(err) } defer g.Close() + d := &demoWidgets{delta: 0.2} + g.Highlight = true g.SelFrameColor = gocui.ColorRed help := NewHelpWidget("help", 1, 1, helpText) status := NewStatusbarWidget("status", 1, 7, 50) - butdown := NewButtonWidget("butdown", 52, 7, "DOWN", statusDown(status)) - butup := NewButtonWidget("butup", 58, 7, "UP", statusUp(status)) + butdown := NewButtonWidget("butdown", 52, 7, "DOWN", d.statusDown(status)) + butup := NewButtonWidget("butup", 58, 7, "UP", d.statusUp(status)) g.SetManager(help, status, butdown, butup) - if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, d.quit); err != nil { log.Panicln(err) } - if err := g.SetKeybinding("", gocui.KeyTab, gocui.ModNone, toggleButton); err != nil { + if err := g.SetKeybinding("", gocui.KeyTab, gocui.ModNone, d.toggleButton); err != nil { log.Panicln(err) } @@ -140,11 +144,11 @@ func main() { } } -func quit(g *gocui.Gui, v *gocui.View) error { +func (d *demoWidgets) quit(_ *gocui.Gui, _ *gocui.View) error { return gocui.ErrQuit } -func toggleButton(g *gocui.Gui, v *gocui.View) error { +func (d *demoWidgets) toggleButton(g *gocui.Gui, v *gocui.View) error { nextview := "butdown" if v != nil && v.Name() == "butdown" { nextview = "butup" @@ -153,19 +157,19 @@ func toggleButton(g *gocui.Gui, v *gocui.View) error { return err } -func statusUp(status *StatusbarWidget) func(g *gocui.Gui, v *gocui.View) error { +func (d *demoWidgets) statusUp(status *StatusbarWidget) func(g *gocui.Gui, v *gocui.View) error { return func(g *gocui.Gui, v *gocui.View) error { - return statusSet(status, delta) + return d.statusSet(status, d.delta) } } -func statusDown(status *StatusbarWidget) func(g *gocui.Gui, v *gocui.View) error { +func (d *demoWidgets) statusDown(status *StatusbarWidget) func(g *gocui.Gui, v *gocui.View) error { return func(g *gocui.Gui, v *gocui.View) error { - return statusSet(status, -delta) + return d.statusSet(status, -d.delta) } } -func statusSet(sw *StatusbarWidget, inc float64) error { +func (d *demoWidgets) statusSet(sw *StatusbarWidget, inc float64) error { val := sw.Val() + inc if val < 0 || val > 1 { return nil diff --git a/_examples/wrap.go b/_examples/wrap.go index 6162ef4e..899ab123 100644 --- a/_examples/wrap.go +++ b/_examples/wrap.go @@ -13,7 +13,9 @@ import ( "github.com/awesome-gocui/gocui" ) -func layout(g *gocui.Gui) error { +type demoWrap struct{} + +func (d *demoWrap) layout(g *gocui.Gui) error { maxX, maxY := g.Size() if v, err := g.SetView("main", 1, 1, maxX-1, maxY-1, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { @@ -22,8 +24,8 @@ func layout(g *gocui.Gui) error { v.Wrap = true line := strings.Repeat("This is a long line -- ", 10) - fmt.Fprintf(v, "%s\n\n", line) - fmt.Fprintln(v, "Short") + _, _ = fmt.Fprintf(v, "%s\n\n", line) + _, _ = fmt.Fprintln(v, "Short") if _, err := g.SetCurrentView("main"); err != nil { return err @@ -32,20 +34,21 @@ func layout(g *gocui.Gui) error { return nil } -func quit(g *gocui.Gui, v *gocui.View) error { +func (d *demoWrap) quit(_ *gocui.Gui, _ *gocui.View) error { return gocui.ErrQuit } -func main() { +func mainWrap() { g, err := gocui.NewGui(gocui.OutputNormal, true) if err != nil { log.Panicln(err) } defer g.Close() - g.SetManagerFunc(layout) + d := &demoWrap{} + g.SetManagerFunc(d.layout) - if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, d.quit); err != nil { log.Panicln(err) } From 17367931df6a8144a67fd4be9707e685fb11e0e1 Mon Sep 17 00:00:00 2001 From: elv-gilles Date: Wed, 9 Mar 2022 14:56:07 +0100 Subject: [PATCH 2/5] address PR comments, fix build * use 'go run .' in usage and text message * make 'main' view sensitive to screen dimensions --- _examples/active.go | 4 +-- _examples/custom_frame.go | 6 ++-- _examples/dynamic.go | 10 +++--- _examples/main.go | 71 +++++++++++++++++++++++++++++++-------- 4 files changed, 67 insertions(+), 24 deletions(-) diff --git a/_examples/active.go b/_examples/active.go index 4572dd76..87ec03ba 100644 --- a/_examples/active.go +++ b/_examples/active.go @@ -34,7 +34,7 @@ func (d *demoActive) nextView(g *gocui.Gui, v *gocui.View) error { } _, _ = fmt.Fprintln(out, "Going from view "+v.Name()+" to "+name) - if _, err := setCurrentViewOnTop(g, name); err != nil { + if _, err := d.setCurrentViewOnTop(g, name); err != nil { return err } @@ -58,7 +58,7 @@ func (d *demoActive) layout(g *gocui.Gui) error { v.Editable = true v.Wrap = true - if _, err = setCurrentViewOnTop(g, "v1"); err != nil { + if _, err = d.setCurrentViewOnTop(g, "v1"); err != nil { return err } } diff --git a/_examples/custom_frame.go b/_examples/custom_frame.go index 7ea5b4c1..0dc33c61 100644 --- a/_examples/custom_frame.go +++ b/_examples/custom_frame.go @@ -13,7 +13,7 @@ type demoCustomFrames struct { active int } -func setCurrentViewOnTop(g *gocui.Gui, name string) (*gocui.View, error) { +func (d *demoCustomFrames) setCurrentViewOnTop(g *gocui.Gui, name string) (*gocui.View, error) { if _, err := g.SetCurrentView(name); err != nil { return nil, err } @@ -30,7 +30,7 @@ func (d *demoCustomFrames) nextView(g *gocui.Gui, v *gocui.View) error { } _, _ = fmt.Fprintln(out, "Going from view "+v.Name()+" to "+name) - if _, err := setCurrentViewOnTop(g, name); err != nil { + if _, err := d.setCurrentViewOnTop(g, name); err != nil { return err } @@ -54,7 +54,7 @@ func (d *demoCustomFrames) layout(g *gocui.Gui) error { v.Autoscroll = true _, _ = fmt.Fprintln(v, "View with default frame color") _, _ = fmt.Fprintln(v, "It's connected to v2 with overlay RIGHT.\n") - if _, err = setCurrentViewOnTop(g, "v1"); err != nil { + if _, err = d.setCurrentViewOnTop(g, "v1"); err != nil { return err } } diff --git a/_examples/dynamic.go b/_examples/dynamic.go index c0c2577c..6c3c22ec 100644 --- a/_examples/dynamic.go +++ b/_examples/dynamic.go @@ -103,25 +103,25 @@ func (d *demoDynamic) initKeybindings(g *gocui.Gui) error { } if err := g.SetKeybinding("", gocui.KeyArrowLeft, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - return moveView(g, v, -d.delta, 0) + return d.moveView(g, v, -d.delta, 0) }); err != nil { return err } if err := g.SetKeybinding("", gocui.KeyArrowRight, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - return moveView(g, v, d.delta, 0) + return d.moveView(g, v, d.delta, 0) }); err != nil { return err } if err := g.SetKeybinding("", gocui.KeyArrowDown, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - return moveView(g, v, 0, d.delta) + return d.moveView(g, v, 0, d.delta) }); err != nil { return err } if err := g.SetKeybinding("", gocui.KeyArrowUp, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - return moveView(g, v, 0, -d.delta) + return d.moveView(g, v, 0, -d.delta) }); err != nil { return err } @@ -191,7 +191,7 @@ func (d *demoDynamic) nextView(g *gocui.Gui, disableCurrent bool) error { return nil } -func moveView(g *gocui.Gui, v *gocui.View, dx, dy int) error { +func (d *demoDynamic) moveView(g *gocui.Gui, v *gocui.View, dx, dy int) error { name := v.Name() x0, y0, x1, y1, err := g.ViewPosition(name) if err != nil { diff --git a/_examples/main.go b/_examples/main.go index 7a72b895..79d44001 100644 --- a/_examples/main.go +++ b/_examples/main.go @@ -49,8 +49,8 @@ func demoNames() []string { func usage() string { sb := strings.Builder{} sb.WriteString("usage:\n") - sb.WriteString(fmt.Sprintf("%s : select a demo from the gui and run it\n", os.Args[0])) - sb.WriteString(fmt.Sprintf("%s : run the 'demo' argument\n", os.Args[0])) + sb.WriteString("go run . : select a demo from the gui and run it\n") + sb.WriteString("go run . : run the 'demo' argument\n") sb.WriteString("\n") sb.WriteString(" where 'demo' can be one of: \n") @@ -137,6 +137,21 @@ func (d *runDemos) moveSelected(v *gocui.View, delta int) { if d.selected < 0 { d.selected = len(d.demos) - 1 } + + x0, y0 := v.Origin() + _, _, _, y1 := v.Dimensions() + lcount := y1 - 1 + + for d.selected < y0+lcount { + y0-- + _ = v.SetOrigin(x0, y0) + _ = v.SetCursor(x0, y0) + } + for d.selected >= y0+lcount { + y0++ + _ = v.SetOrigin(x0, y0) + _ = v.SetCursor(x0, y0) + } _ = v.SetHighlight(d.selected, true) } @@ -150,23 +165,48 @@ func (d *runDemos) selectPrev(_ *gocui.Gui, v *gocui.View) error { return nil } +func (d *runDemos) adjustDim(max, minDim, pos, dim int) (p0 int, p1 int) { + p0 = pos + p1 = p0 + dim + for p1 > max { + for p0 > 0 { + p0-- + p1 = p0 + dim + if p1 < max { + return + } + } + for dim > minDim { + dim-- + p1 = p0 + dim + if p1 < max { + return + } + } + p1 = max + } + return +} + func (d *runDemos) layout(g *gocui.Gui) error { - width := 80 - x0 := 0 - x1 := x0 + width + maxX, maxY := g.Size() - view, err := g.SetView("help", x0, 5, x1, 9, 0) + x0, x1 := d.adjustDim(maxX, 20, 5, 80) + y0 := 0 + y1 := y0 + 4 + + view, err := g.SetView("help", x0, y0, x1, y1, 0) if err != nil { if !errors.Is(err, gocui.ErrUnknownView) { return err } + view.Wrap = true _, _ = fmt.Fprintln(view, "Use the arrow keys to select a demo") _, _ = fmt.Fprintln(view, "Press [Enter] to run the selected demo (Ctrl-C to exit the demo)") _, _ = fmt.Fprintln(view, "Ctrl-C to exit") } - y0 := 10 - y1 := y0 + len(d.demos) + 1 + y0, y1 = d.adjustDim(maxY, 5, y1+1, len(d.demos)+1) view, err = g.SetView("demos", x0, y0, x1, y1, 0) if err != nil { if !errors.Is(err, gocui.ErrUnknownView) { @@ -191,11 +231,11 @@ func (d *runDemos) runSelectedDemo(_ *gocui.Gui, _ *gocui.View) error { if name == "stdin" { lines := []string{ - fmt.Sprintf("This example doesn't work when running `%s stdin`", os.Args[0]), - fmt.Sprintf("you are supposed to pipe something to this like: `/bin/ls | %s stdin`", os.Args[0]), + "This example doesn't work when running `go run . stdin`", + "you are supposed to pipe something to this like: `/bin/ls | go run . stdin`", "Press 'Esc' to close this view", } - messageBox(d.g, 20, 20, "warning", "stdin", lines, "demos") + d.messageBox(d.g, 20, 20, "warning", "stdin", lines, "demos") return nil } demoFn := demos[name] @@ -205,15 +245,17 @@ func (d *runDemos) runSelectedDemo(_ *gocui.Gui, _ *gocui.View) error { return gocui.Resume() } -func messageBox(g *gocui.Gui, x0, y0 int, title, viewName string, lines []string, nextView string) { +func (d *runDemos) messageBox(g *gocui.Gui, x0, y0 int, title, viewName string, lines []string, nextView string) { w := 20 for _, l := range lines { if len(l) > w { w = len(l) } } - x1 := x0 + w + 2 - y1 := y0 + len(lines) + 1 + maxX, maxY := g.Size() + x0, x1 := d.adjustDim(maxX, 20, x0, w+2) + y0, y1 := d.adjustDim(maxY, 5, y0, len(lines)+1) + view, err := g.SetView(viewName, x0, y0, x1, y1, 0) if err != nil { if !errors.Is(err, gocui.ErrUnknownView) { @@ -221,6 +263,7 @@ func messageBox(g *gocui.Gui, x0, y0 int, title, viewName string, lines []string } view.Title = title + view.Wrap = true for _, line := range lines { _, _ = fmt.Fprintln(view, line) } From d0da6aade704fb40cf3c7e0d645b9e88dacaaf0c Mon Sep 17 00:00:00 2001 From: elv-gilles Date: Wed, 9 Mar 2022 15:00:54 +0100 Subject: [PATCH 3/5] * use 'go run .' in README.md --- _examples/README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/_examples/README.md b/_examples/README.md index 67fd85a5..b7074177 100644 --- a/_examples/README.md +++ b/_examples/README.md @@ -8,12 +8,11 @@ Each can be run be alone or selected from the 'main' example. ``` gocui $ cd _examples/ -_examples $ go build -o exam ./ -_examples $ ./exam --help +_examples $ go run . --help usage: -./exam : select a demo from the gui and run it -./exam : run the 'demo' argument +go run . : select a demo from the gui and run it +go run . : run the 'demo' argument where 'demo' can be one of: active From 654352d4f8e8a115ca670f45d9c7e1a1368205ca Mon Sep 17 00:00:00 2001 From: elv-gilles Date: Wed, 9 Mar 2022 18:30:15 +0100 Subject: [PATCH 4/5] * fix github workflow --- .github/workflows/go.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index a29431f0..d1bf6cf1 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -30,7 +30,4 @@ jobs: - name: Build run: | cd _examples/ - for file in *.go - do - go build $file - done + go build . From 57d213235fd63937e6963e9f823e368880b12a8b Mon Sep 17 00:00:00 2001 From: elv-gilles Date: Fri, 11 Mar 2022 15:38:41 +0100 Subject: [PATCH 5/5] PR comment: remove assignments to _ --- _examples/active.go | 8 +++----- _examples/bufs.go | 2 +- _examples/colors.go | 2 +- _examples/colors256.go | 10 ++++------ _examples/colorstrue.go | 14 ++++++-------- _examples/custom_frame.go | 33 +++++++++++++++------------------ _examples/demo.go | 27 ++++++++++----------------- _examples/dynamic.go | 19 +++++++++---------- _examples/flow_layout.go | 6 ++---- _examples/goroutine.go | 8 +++----- _examples/hello.go | 6 ++---- _examples/keybinds.go | 4 ++-- _examples/layout.go | 4 ++-- _examples/mask.go | 4 ++-- _examples/mouse.go | 16 ++++++++-------- _examples/ontop.go | 6 +++--- _examples/overlap.go | 2 +- _examples/size.go | 4 ++-- _examples/stdin.go | 14 +++++++------- _examples/table.go | 8 ++++---- _examples/title.go | 2 +- _examples/widgets.go | 8 ++++---- _examples/wrap.go | 6 +++--- 23 files changed, 95 insertions(+), 118 deletions(-) diff --git a/_examples/active.go b/_examples/active.go index 87ec03ba..e322dce0 100644 --- a/_examples/active.go +++ b/_examples/active.go @@ -32,7 +32,7 @@ func (d *demoActive) nextView(g *gocui.Gui, v *gocui.View) error { if err != nil { return err } - _, _ = fmt.Fprintln(out, "Going from view "+v.Name()+" to "+name) + fmt.Fprintln(out, "Going from view "+v.Name()+" to "+name) if _, err := d.setCurrentViewOnTop(g, name); err != nil { return err @@ -78,7 +78,7 @@ func (d *demoActive) layout(g *gocui.Gui) error { v.Title = "v3" v.Wrap = true v.Autoscroll = true - _, _ = fmt.Fprint(v, "Press TAB to change current view") + fmt.Fprint(v, "Press TAB to change current view") } if v, err := g.SetView("v4", maxX/2, maxY/2, maxX-1, maxY-1, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { @@ -90,9 +90,7 @@ func (d *demoActive) layout(g *gocui.Gui) error { return nil } -func (d *demoActive) quit(g *gocui.Gui, v *gocui.View) error { - _ = g - _ = v +func (d *demoActive) quit(*gocui.Gui, *gocui.View) error { return gocui.ErrQuit } diff --git a/_examples/bufs.go b/_examples/bufs.go index e320680f..5b0d420f 100644 --- a/_examples/bufs.go +++ b/_examples/bufs.go @@ -18,7 +18,7 @@ type demoBufs struct { vbuf, buf string } -func (d *demoBufs) quit(g *gocui.Gui, v *gocui.View) error { +func (d *demoBufs) quit(_ *gocui.Gui, v *gocui.View) error { d.vbuf = v.ViewBuffer() d.buf = v.Buffer() return gocui.ErrQuit diff --git a/_examples/colors.go b/_examples/colors.go index f537799c..25a562da 100644 --- a/_examples/colors.go +++ b/_examples/colors.go @@ -53,6 +53,6 @@ func (d *demoColors) layout(g *gocui.Gui) error { return nil } -func (d *demoColors) quit(g *gocui.Gui, v *gocui.View) error { +func (d *demoColors) quit(*gocui.Gui, *gocui.View) error { return gocui.ErrQuit } diff --git a/_examples/colors256.go b/_examples/colors256.go index accb7d3d..188571d0 100644 --- a/_examples/colors256.go +++ b/_examples/colors256.go @@ -50,10 +50,10 @@ func (d *demoColors256) layout(g *gocui.Gui) error { str += "\n" } - _, _ = fmt.Fprint(v, str) + fmt.Fprint(v, str) } - _, _ = fmt.Fprint(v, "\n\n") + fmt.Fprint(v, "\n\n") // 8-colors escape codes ctr := 0 @@ -64,7 +64,7 @@ func (d *demoColors256) layout(g *gocui.Gui) error { str += "\n" } - _, _ = fmt.Fprint(v, str) + fmt.Fprint(v, str) ctr++ } @@ -76,8 +76,6 @@ func (d *demoColors256) layout(g *gocui.Gui) error { return nil } -func (d *demoColors256) quit(g *gocui.Gui, v *gocui.View) error { - _ = g - _ = v +func (d *demoColors256) quit(*gocui.Gui, *gocui.View) error { return gocui.ErrQuit } diff --git a/_examples/colorstrue.go b/_examples/colorstrue.go index 7de94ba5..55e127ea 100644 --- a/_examples/colorstrue.go +++ b/_examples/colorstrue.go @@ -19,7 +19,7 @@ type demoColorsTrue struct { } func mainColorsTrue() { - _ = os.Setenv("COLORTERM", "truecolor") + os.Setenv("COLORTERM", "truecolor") g, err := gocui.NewGui(gocui.OutputTrue, true) if err != nil { @@ -90,13 +90,13 @@ func (d *demoColorsTrue) displayHsv(v *gocui.View) { str += fmt.Sprintf("\x1b[48;2;%d;%d;%dm\x1b[38;2;%d;%d;%dm▀\x1b[0m", ir, ig, ib, ir2, ig2, ib2) } str += "\n" - _, _ = fmt.Fprint(v, str) + fmt.Fprint(v, str) str = "" } - _, _ = fmt.Fprintln(v, "\n\x1b[38;5;245mCtrl + R - Switch light/dark mode") - _, _ = fmt.Fprintln(v, "\nCtrl + C - Exit\n") - _, _ = fmt.Fprint(v, "Example should enable true color, but if it doesn't work run this command: \x1b[0mexport COLORTERM=truecolor") + fmt.Fprintln(v, "\n\x1b[38;5;245mCtrl + R - Switch light/dark mode") + fmt.Fprintln(v, "\nCtrl + C - Exit\n") + fmt.Fprint(v, "Example should enable true color, but if it doesn't work run this command: \x1b[0mexport COLORTERM=truecolor") } func (d *demoColorsTrue) hsv(hue, sv int) (uint32, uint32, uint32) { @@ -108,8 +108,6 @@ func (d *demoColorsTrue) hsv(hue, sv int) (uint32, uint32, uint32) { return ir >> 8, ig >> 8, ib >> 8 } -func (d *demoColorsTrue) quit(g *gocui.Gui, v *gocui.View) error { - _ = g - _ = v +func (d *demoColorsTrue) quit(*gocui.Gui, *gocui.View) error { return gocui.ErrQuit } diff --git a/_examples/custom_frame.go b/_examples/custom_frame.go index 0dc33c61..c972f430 100644 --- a/_examples/custom_frame.go +++ b/_examples/custom_frame.go @@ -28,7 +28,7 @@ func (d *demoCustomFrames) nextView(g *gocui.Gui, v *gocui.View) error { if err != nil { return err } - _, _ = fmt.Fprintln(out, "Going from view "+v.Name()+" to "+name) + fmt.Fprintln(out, "Going from view "+v.Name()+" to "+name) if _, err := d.setCurrentViewOnTop(g, name); err != nil { return err @@ -52,8 +52,8 @@ func (d *demoCustomFrames) layout(g *gocui.Gui) error { } v.Title = "v1" v.Autoscroll = true - _, _ = fmt.Fprintln(v, "View with default frame color") - _, _ = fmt.Fprintln(v, "It's connected to v2 with overlay RIGHT.\n") + fmt.Fprintln(v, "View with default frame color") + fmt.Fprintln(v, "It's connected to v2 with overlay RIGHT.\n") if _, err = d.setCurrentViewOnTop(g, "v1"); err != nil { return err } @@ -67,12 +67,12 @@ func (d *demoCustomFrames) layout(g *gocui.Gui) error { v.Wrap = true v.FrameColor = gocui.ColorMagenta v.FrameRunes = []rune{'═', '│'} - _, _ = fmt.Fprintln(v, "View with minimum frame customization and colored frame.") - _, _ = fmt.Fprintln(v, "It's connected to v1 with overlay LEFT.\n") - _, _ = fmt.Fprintln(v, "\033[35;1mInstructions:\033[0m") - _, _ = fmt.Fprintln(v, "Press TAB to change current view") - _, _ = fmt.Fprintln(v, "Press Ctrl+O to toggle gocui.SupportOverlap\n") - _, _ = fmt.Fprintln(v, "\033[32;2mSelected frame is highlighted with green color\033[0m") + fmt.Fprintln(v, "View with minimum frame customization and colored frame.") + fmt.Fprintln(v, "It's connected to v1 with overlay LEFT.\n") + fmt.Fprintln(v, "\033[35;1mInstructions:\033[0m") + fmt.Fprintln(v, "Press TAB to change current view") + fmt.Fprintln(v, "Press Ctrl+O to toggle gocui.SupportOverlap\n") + fmt.Fprintln(v, "\033[32;2mSelected frame is highlighted with green color\033[0m") } if v, err := g.SetView("v3", 0, maxY/2, maxX/2-1, maxY-1, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { @@ -84,8 +84,8 @@ func (d *demoCustomFrames) layout(g *gocui.Gui) error { v.FrameColor = gocui.ColorCyan v.TitleColor = gocui.ColorCyan v.FrameRunes = []rune{'═', '║', '╔', '╗', '╚', '╝'} - _, _ = fmt.Fprintln(v, "View with basic frame customization and colored frame and title") - _, _ = fmt.Fprintln(v, "It's not connected to any view.") + fmt.Fprintln(v, "View with basic frame customization and colored frame and title") + fmt.Fprintln(v, "It's not connected to any view.") } if v, err := g.SetView("v4", maxX/2, maxY/2, maxX-1, maxY-1, gocui.LEFT); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { @@ -97,21 +97,18 @@ func (d *demoCustomFrames) layout(g *gocui.Gui) error { v.TitleColor = gocui.ColorYellow v.FrameColor = gocui.ColorRed v.FrameRunes = []rune{'═', '║', '╔', '╗', '╚', '╝', '╠', '╣', '╦', '╩', '╬'} - _, _ = fmt.Fprintln(v, "View with fully customized frame and colored title differently.") - _, _ = fmt.Fprintln(v, "It's connected to v3 with overlay LEFT.\n") - _ = v.SetCursor(0, 3) + fmt.Fprintln(v, "View with fully customized frame and colored title differently.") + fmt.Fprintln(v, "It's connected to v3 with overlay LEFT.\n") + v.SetCursor(0, 3) } return nil } -func (d *demoCustomFrames) quit(g *gocui.Gui, v *gocui.View) error { - _ = g - _ = v +func (d *demoCustomFrames) quit(*gocui.Gui, *gocui.View) error { return gocui.ErrQuit } func (d *demoCustomFrames) toggleOverlap(g *gocui.Gui, v *gocui.View) error { - _ = v g.SupportOverlaps = !g.SupportOverlaps return nil } diff --git a/_examples/demo.go b/_examples/demo.go index aa98ceb1..f12b1c62 100644 --- a/_examples/demo.go +++ b/_examples/demo.go @@ -27,7 +27,6 @@ func (d *demo) nextView(g *gocui.Gui, v *gocui.View) error { } func (d *demo) cursorDown(g *gocui.Gui, v *gocui.View) error { - _ = g if v != nil { cx, cy := v.Cursor() if err := v.SetCursor(cx, cy+1); err != nil { @@ -41,7 +40,6 @@ func (d *demo) cursorDown(g *gocui.Gui, v *gocui.View) error { } func (d *demo) cursorUp(g *gocui.Gui, v *gocui.View) error { - _ = g if v != nil { ox, oy := v.Origin() cx, cy := v.Cursor() @@ -68,7 +66,7 @@ func (d *demo) getLine(g *gocui.Gui, v *gocui.View) error { if !errors.Is(err, gocui.ErrUnknownView) { return err } - _, _ = fmt.Fprintln(v, l) + fmt.Fprintln(v, l) if _, err := g.SetCurrentView("msg"); err != nil { return err } @@ -77,7 +75,6 @@ func (d *demo) getLine(g *gocui.Gui, v *gocui.View) error { } func (d *demo) delMsg(g *gocui.Gui, v *gocui.View) error { - _ = v if err := g.DeleteView("msg"); err != nil { return err } @@ -87,9 +84,7 @@ func (d *demo) delMsg(g *gocui.Gui, v *gocui.View) error { return nil } -func (d *demo) quit(g *gocui.Gui, v *gocui.View) error { - _ = g - _ = v +func (d *demo) quit(*gocui.Gui, *gocui.View) error { return gocui.ErrQuit } @@ -126,12 +121,11 @@ func (d *demo) keybindings(g *gocui.Gui) error { } func (d *demo) saveMain(g *gocui.Gui, v *gocui.View) error { - _ = g f, err := ioutil.TempFile("", "gocui_demo_") if err != nil { return err } - defer func() { _ = f.Close() }() + defer f.Close() p := make([]byte, 5) v.Rewind() @@ -153,12 +147,11 @@ func (d *demo) saveMain(g *gocui.Gui, v *gocui.View) error { } func (d *demo) saveVisualMain(g *gocui.Gui, v *gocui.View) error { - _ = g f, err := ioutil.TempFile("", "gocui_demo_") if err != nil { return err } - defer func() { _ = f.Close() }() + defer f.Close() vb := v.ViewBuffer() if _, err := io.Copy(f, strings.NewReader(vb)); err != nil { @@ -176,11 +169,11 @@ func (d *demo) layout(g *gocui.Gui) error { v.Highlight = true v.SelBgColor = gocui.ColorGreen v.SelFgColor = gocui.ColorBlack - _, _ = fmt.Fprintln(v, "Item 1") - _, _ = fmt.Fprintln(v, "Item 2") - _, _ = fmt.Fprintln(v, "Item 3") - _, _ = fmt.Fprint(v, "\rWill be") - _, _ = fmt.Fprint(v, "deleted\rItem 4\nItem 5") + fmt.Fprintln(v, "Item 1") + fmt.Fprintln(v, "Item 2") + fmt.Fprintln(v, "Item 3") + fmt.Fprint(v, "\rWill be") + fmt.Fprint(v, "deleted\rItem 4\nItem 5") } if v, err := g.SetView("main", 30, -1, maxX, maxY, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { @@ -190,7 +183,7 @@ func (d *demo) layout(g *gocui.Gui) error { if err != nil { panic(err) } - _, _ = fmt.Fprintf(v, "%s", b) + fmt.Fprintf(v, "%s", b) v.Editable = true v.Wrap = true if _, err := g.SetCurrentView("main"); err != nil { diff --git a/_examples/dynamic.go b/_examples/dynamic.go index 6c3c22ec..3ef6e6da 100644 --- a/_examples/dynamic.go +++ b/_examples/dynamic.go @@ -58,14 +58,14 @@ func (d *demoDynamic) layout(g *gocui.Gui) error { if !errors.Is(err, gocui.ErrUnknownView) { return err } - _, _ = fmt.Fprintln(v, "KEYBINDINGS") - _, _ = fmt.Fprintln(v, "Space: New View") - _, _ = fmt.Fprintln(v, "Tab: Next View") - _, _ = fmt.Fprintln(v, "← ↑ → ↓: Move View") - _, _ = fmt.Fprintln(v, "Backspace: Delete View") - _, _ = fmt.Fprintln(v, "t: Set view on top") - _, _ = fmt.Fprintln(v, "b: Set view on bottom") - _, _ = fmt.Fprintln(v, "^C: Exit") + fmt.Fprintln(v, "KEYBINDINGS") + fmt.Fprintln(v, "Space: New View") + fmt.Fprintln(v, "Tab: Next View") + fmt.Fprintln(v, "← ↑ → ↓: Move View") + fmt.Fprintln(v, "Backspace: Delete View") + fmt.Fprintln(v, "t: Set view on top") + fmt.Fprintln(v, "b: Set view on bottom") + fmt.Fprintln(v, "^C: Exit") } return nil } @@ -151,7 +151,7 @@ func (d *demoDynamic) newView(g *gocui.Gui) error { return err } v.Wrap = true - _, _ = fmt.Fprintln(v, strings.Repeat(name+" ", 30)) + fmt.Fprintln(v, strings.Repeat(name+" ", 30)) } if _, err := g.SetCurrentView(name); err != nil { return err @@ -177,7 +177,6 @@ func (d *demoDynamic) delView(g *gocui.Gui) error { } func (d *demoDynamic) nextView(g *gocui.Gui, disableCurrent bool) error { - _ = disableCurrent next := d.curView + 1 if next > len(d.views)-1 { next = 0 diff --git a/_examples/flow_layout.go b/_examples/flow_layout.go index 5c78469b..948bfd0d 100644 --- a/_examples/flow_layout.go +++ b/_examples/flow_layout.go @@ -42,7 +42,7 @@ func (w *Label) Layout(g *gocui.Gui) error { if !errors.Is(err, gocui.ErrUnknownView) { return err } - _, _ = fmt.Fprint(v, w.body) + fmt.Fprint(v, w.body) if _, err := g.SetCurrentView(w.name); err != nil { return err } @@ -90,8 +90,6 @@ func mainFlowLayout() { } } -func (d *demoFlowLayout) quit(g *gocui.Gui, v *gocui.View) error { - _ = g - _ = v +func (d *demoFlowLayout) quit(*gocui.Gui, *gocui.View) error { return gocui.ErrQuit } diff --git a/_examples/goroutine.go b/_examples/goroutine.go index ccc7b28e..3e3327d7 100644 --- a/_examples/goroutine.go +++ b/_examples/goroutine.go @@ -73,9 +73,7 @@ func (d *demoGoRoutine) keybindings(g *gocui.Gui) error { return nil } -func (d *demoGoRoutine) quit(g *gocui.Gui, v *gocui.View) error { - _ = g - _ = v +func (d *demoGoRoutine) quit(*gocui.Gui, *gocui.View) error { close(d.done) return gocui.ErrQuit } @@ -105,8 +103,8 @@ func (d *demoGoRoutine) counter(g *gocui.Gui) { x = 10 } y := d.ctr % d.numGoroutines - _ = v.SetWritePos(x, y) - _, _ = fmt.Fprintln(v, n) + v.SetWritePos(x, y) + fmt.Fprintln(v, n) return nil }) } diff --git a/_examples/hello.go b/_examples/hello.go index 3efd85c8..c68002b6 100644 --- a/_examples/hello.go +++ b/_examples/hello.go @@ -46,14 +46,12 @@ func (d *demoHello) layout(g *gocui.Gui) error { return err } - _, _ = fmt.Fprintln(v, "Hello world!") + fmt.Fprintln(v, "Hello world!") } return nil } -func (d *demoHello) quit(g *gocui.Gui, v *gocui.View) error { - _ = g - _ = v +func (d *demoHello) quit(*gocui.Gui, *gocui.View) error { return gocui.ErrQuit } diff --git a/_examples/keybinds.go b/_examples/keybinds.go index 93c48298..b65344eb 100644 --- a/_examples/keybinds.go +++ b/_examples/keybinds.go @@ -18,7 +18,7 @@ func (d *demoKeybinds) layout(g *gocui.Gui) error { return err } - _, _ = v.Write([]byte("Hello")) + v.Write([]byte("Hello")) if _, err := g.SetCurrentView("hello"); err != nil { return err @@ -29,7 +29,7 @@ func (d *demoKeybinds) layout(g *gocui.Gui) error { } // quit stops the gui -func (d *demoKeybinds) quit(_ *gocui.Gui, _ *gocui.View) error { +func (d *demoKeybinds) quit(*gocui.Gui, *gocui.View) error { return gocui.ErrQuit } diff --git a/_examples/layout.go b/_examples/layout.go index 07df0a74..1b607114 100644 --- a/_examples/layout.go +++ b/_examples/layout.go @@ -23,7 +23,7 @@ func (d *demoLayout) layout(g *gocui.Gui) error { return err } - _, _ = g.SetCurrentView("main") + g.SetCurrentView("main") } if _, err := g.SetView("cmdline", -1, maxY-5, maxX, maxY, 0); err != nil && !errors.Is(err, gocui.ErrUnknownView) { return err @@ -32,7 +32,7 @@ func (d *demoLayout) layout(g *gocui.Gui) error { return nil } -func (d *demoLayout) quit(_ *gocui.Gui, _ *gocui.View) error { +func (d *demoLayout) quit(*gocui.Gui, *gocui.View) error { return gocui.ErrQuit } diff --git a/_examples/mask.go b/_examples/mask.go index 448a76e1..d490d447 100644 --- a/_examples/mask.go +++ b/_examples/mask.go @@ -43,8 +43,8 @@ func (d *demoMask) layout(g *gocui.Gui) error { return err } v.Title = "Keybindings" - _, _ = fmt.Fprintln(v, "^a: Set mask") - _, _ = fmt.Fprintln(v, "^c: Exit") + fmt.Fprintln(v, "^a: Set mask") + fmt.Fprintln(v, "^c: Exit") } if v, err := g.SetView("input", 0, 0, maxX-24, maxY-1, 0); err != nil { diff --git a/_examples/mouse.go b/_examples/mouse.go index 4f940480..840c55d1 100644 --- a/_examples/mouse.go +++ b/_examples/mouse.go @@ -56,10 +56,10 @@ func (d *demoMouse) layout(g *gocui.Gui) error { } v.SelBgColor = gocui.ColorGreen v.SelFgColor = gocui.ColorBlack - _, _ = fmt.Fprintln(v, "Button 1 - line 1") - _, _ = fmt.Fprintln(v, "Button 1 - line 2") - _, _ = fmt.Fprintln(v, "Button 1 - line 3") - _, _ = fmt.Fprintln(v, "Button 1 - line 4") + fmt.Fprintln(v, "Button 1 - line 1") + fmt.Fprintln(v, "Button 1 - line 2") + fmt.Fprintln(v, "Button 1 - line 3") + fmt.Fprintln(v, "Button 1 - line 4") if _, err := g.SetCurrentView("but1"); err != nil { return err } @@ -70,7 +70,7 @@ func (d *demoMouse) layout(g *gocui.Gui) error { } v.SelBgColor = gocui.ColorGreen v.SelFgColor = gocui.ColorBlack - _, _ = fmt.Fprintln(v, "Button 2 - line 1") + fmt.Fprintln(v, "Button 2 - line 1") } d.updateHighlightedView(g) return nil @@ -97,7 +97,7 @@ func (d *demoMouse) keybindings(g *gocui.Gui) error { return nil } -func (d *demoMouse) quit(_ *gocui.Gui, _ *gocui.View) error { +func (d *demoMouse) quit(*gocui.Gui, *gocui.View) error { return gocui.ErrQuit } @@ -119,7 +119,7 @@ func (d *demoMouse) showMsg(g *gocui.Gui, v *gocui.View) error { v.Clear() v.SelBgColor = gocui.ColorCyan v.SelFgColor = gocui.ColorBlack - _, _ = fmt.Fprintln(v, l) + fmt.Fprintln(v, l) } return nil } @@ -139,7 +139,7 @@ func (d *demoMouse) moveMsg(g *gocui.Gui) { if !d.movingMsg && (mx != d.initialMouseX || my != d.initialMouseY) { d.movingMsg = true } - _, _ = g.SetView("msg", mx-d.xOffset, my-d.yOffset, mx-d.xOffset+20, my-d.yOffset+2, 0) + g.SetView("msg", mx-d.xOffset, my-d.yOffset, mx-d.xOffset+20, my-d.yOffset+2, 0) } func (d *demoMouse) msgDown(g *gocui.Gui, v *gocui.View) error { diff --git a/_examples/ontop.go b/_examples/ontop.go index 55b775dd..a4ff6d7c 100644 --- a/_examples/ontop.go +++ b/_examples/ontop.go @@ -38,19 +38,19 @@ func (d *demoOnTop) layout(g *gocui.Gui) error { if !errors.Is(err, gocui.ErrUnknownView) { return err } - _, _ = fmt.Fprintln(v, "View #1") + fmt.Fprintln(v, "View #1") } if v, err := g.SetView("v2", 20, 4, 40, 8, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { return err } - _, _ = fmt.Fprintln(v, "View #2") + fmt.Fprintln(v, "View #2") } if v, err := g.SetView("v3", 30, 6, 50, 10, 0); err != nil { if !errors.Is(err, gocui.ErrUnknownView) { return err } - _, _ = fmt.Fprintln(v, "View #3") + fmt.Fprintln(v, "View #3") if _, err := g.SetCurrentView("v3"); err != nil { return err } diff --git a/_examples/overlap.go b/_examples/overlap.go index 1d6ee269..61652dfc 100644 --- a/_examples/overlap.go +++ b/_examples/overlap.go @@ -58,7 +58,7 @@ func (d *demoOverlap) layout(g *gocui.Gui) error { return nil } -func (d *demoOverlap) quit(_ *gocui.Gui, _ *gocui.View) error { +func (d *demoOverlap) quit(*gocui.Gui, *gocui.View) error { return gocui.ErrQuit } diff --git a/_examples/size.go b/_examples/size.go index 1e197a13..3b03cdaa 100644 --- a/_examples/size.go +++ b/_examples/size.go @@ -45,10 +45,10 @@ func (d *demoSize) layout(g *gocui.Gui) error { } } v.Clear() - _, _ = fmt.Fprintf(v, "%d, %d", maxX, maxY) + fmt.Fprintf(v, "%d, %d", maxX, maxY) return nil } -func (d *demoSize) quit(_ *gocui.Gui, _ *gocui.View) error { +func (d *demoSize) quit(*gocui.Gui, *gocui.View) error { return gocui.ErrQuit } diff --git a/_examples/stdin.go b/_examples/stdin.go index d9ec88d0..4a5beca6 100644 --- a/_examples/stdin.go +++ b/_examples/stdin.go @@ -47,10 +47,10 @@ func (d *demoStdin) layout(g *gocui.Gui) error { if !errors.Is(err, gocui.ErrUnknownView) { return err } - _, _ = fmt.Fprintln(v, "KEYBINDINGS") - _, _ = fmt.Fprintln(v, "↑ ↓: Seek input") - _, _ = fmt.Fprintln(v, "a: Enable autoscroll") - _, _ = fmt.Fprintln(v, "^C: Exit") + fmt.Fprintln(v, "KEYBINDINGS") + fmt.Fprintln(v, "↑ ↓: Seek input") + fmt.Fprintln(v, "a: Enable autoscroll") + fmt.Fprintln(v, "^C: Exit") } if v, err := g.SetView("stdin", 0, 0, 80, 35, 0); err != nil { @@ -80,14 +80,14 @@ func (d *demoStdin) initKeybindings(g *gocui.Gui) error { } if err := g.SetKeybinding("stdin", gocui.KeyArrowUp, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - _ = d.scrollView(v, -1) + d.scrollView(v, -1) return nil }); err != nil { return err } if err := g.SetKeybinding("stdin", gocui.KeyArrowDown, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { - _ = d.scrollView(v, 1) + d.scrollView(v, 1) return nil }); err != nil { return err @@ -95,7 +95,7 @@ func (d *demoStdin) initKeybindings(g *gocui.Gui) error { return nil } -func (d *demoStdin) quit(_ *gocui.Gui, _ *gocui.View) error { +func (d *demoStdin) quit(*gocui.Gui, *gocui.View) error { return gocui.ErrQuit } diff --git a/_examples/table.go b/_examples/table.go index 1c537122..89460520 100644 --- a/_examples/table.go +++ b/_examples/table.go @@ -47,15 +47,15 @@ func (t *Table) Layout(g *gocui.Gui) error { for cid, column := range t.Columns { size := int(float32(width+1) * column.Size) - _ = view.SetWritePos(hOffset, 0) + view.SetWritePos(hOffset, 0) view.WriteString(column.Title) for rid := 0; rid < height; rid++ { if rid < len(t.Data[cid]) { - _ = view.SetWritePos(hOffset, rid+1) + view.SetWritePos(hOffset, rid+1) view.WriteString(t.Data[cid][rid]) } - _ = view.SetWritePos(hOffset+size-1, rid) + view.SetWritePos(hOffset+size-1, rid) view.WriteRunes([]rune{'│'}) } @@ -97,6 +97,6 @@ func mainTable() { } } -func (d *demoTable) quit(_ *gocui.Gui, _ *gocui.View) error { +func (d *demoTable) quit(*gocui.Gui, *gocui.View) error { return gocui.ErrQuit } diff --git a/_examples/title.go b/_examples/title.go index 32034eda..803e5223 100644 --- a/_examples/title.go +++ b/_examples/title.go @@ -32,7 +32,7 @@ func mainTitle() { } } -func (d *demoTitle) quit(_ *gocui.Gui, _ *gocui.View) error { +func (d *demoTitle) quit(*gocui.Gui, *gocui.View) error { return gocui.ErrQuit } diff --git a/_examples/widgets.go b/_examples/widgets.go index ee98a8de..e38b5b0f 100644 --- a/_examples/widgets.go +++ b/_examples/widgets.go @@ -45,7 +45,7 @@ func (w *HelpWidget) Layout(g *gocui.Gui) error { if !errors.Is(err, gocui.ErrUnknownView) { return err } - _, _ = fmt.Fprint(v, w.body) + fmt.Fprint(v, w.body) } return nil } @@ -81,7 +81,7 @@ func (w *StatusbarWidget) Layout(g *gocui.Gui) error { v.Clear() rep := int(w.val * float64(w.w-1)) - _, _ = fmt.Fprint(v, strings.Repeat("▒", rep)) + fmt.Fprint(v, strings.Repeat("▒", rep)) return nil } @@ -109,7 +109,7 @@ func (w *ButtonWidget) Layout(g *gocui.Gui) error { if err := g.SetKeybinding(w.name, gocui.KeyEnter, gocui.ModNone, w.handler); err != nil { return err } - _, _ = fmt.Fprint(v, w.label) + fmt.Fprint(v, w.label) } return nil } @@ -144,7 +144,7 @@ func mainWidgets() { } } -func (d *demoWidgets) quit(_ *gocui.Gui, _ *gocui.View) error { +func (d *demoWidgets) quit(*gocui.Gui, *gocui.View) error { return gocui.ErrQuit } diff --git a/_examples/wrap.go b/_examples/wrap.go index 899ab123..817cceff 100644 --- a/_examples/wrap.go +++ b/_examples/wrap.go @@ -24,8 +24,8 @@ func (d *demoWrap) layout(g *gocui.Gui) error { v.Wrap = true line := strings.Repeat("This is a long line -- ", 10) - _, _ = fmt.Fprintf(v, "%s\n\n", line) - _, _ = fmt.Fprintln(v, "Short") + fmt.Fprintf(v, "%s\n\n", line) + fmt.Fprintln(v, "Short") if _, err := g.SetCurrentView("main"); err != nil { return err @@ -34,7 +34,7 @@ func (d *demoWrap) layout(g *gocui.Gui) error { return nil } -func (d *demoWrap) quit(_ *gocui.Gui, _ *gocui.View) error { +func (d *demoWrap) quit(*gocui.Gui, *gocui.View) error { return gocui.ErrQuit }