diff options
author | Michael Muré <batolettre@gmail.com> | 2018-07-31 16:43:43 +0200 |
---|---|---|
committer | Michael Muré <batolettre@gmail.com> | 2018-07-31 16:44:23 +0200 |
commit | 87669e0f18f282854d340a676834b939e34e5ed3 (patch) | |
tree | c78eaa155d2939d6647ab814c6710d0d3ed69a6e /termui/termui.go | |
parent | eb39c5c29bc0e9b5e15a940a1b71bdac688b6535 (diff) | |
download | git-bug-87669e0f18f282854d340a676834b939e34e5ed3.tar.gz |
termui: use the editor to create a new bug
Diffstat (limited to 'termui/termui.go')
-rw-r--r-- | termui/termui.go | 153 |
1 files changed, 75 insertions, 78 deletions
diff --git a/termui/termui.go b/termui/termui.go index e2e5ae24..9ac82fd3 100644 --- a/termui/termui.go +++ b/termui/termui.go @@ -2,104 +2,103 @@ package termui import ( "github.com/MichaelMure/git-bug/cache" + "github.com/MichaelMure/git-bug/input" "github.com/MichaelMure/git-bug/repository" "github.com/jroimartin/gocui" + "github.com/pkg/errors" ) +var errTerminateMainloop = errors.New("terminate gocui mainloop") + type termUI struct { - cache cache.RepoCacher + g *gocui.Gui + gError chan error + cache cache.RepoCacher + activeWindow window + bugTable *bugTable } var ui *termUI +type window interface { + keybindings(g *gocui.Gui) error + layout(g *gocui.Gui) error +} + func Run(repo repository.Repo) error { c := cache.NewRepoCache(repo) ui = &termUI{ + gError: make(chan error, 1), cache: c, bugTable: newBugTable(c), } + ui.activeWindow = ui.bugTable + + initGui() + + err := <-ui.gError + + if err != nil && err != gocui.ErrQuit { + return err + } + + return nil +} + +func initGui() { g, err := gocui.NewGui(gocui.OutputNormal) if err != nil { - return err + ui.gError <- err + return } - defer g.Close() + ui.g = g - g.SetManagerFunc(layout) + ui.g.SetManagerFunc(layout) - err = keybindings(g) + err = keybindings(ui.g) if err != nil { - return err + ui.g.Close() + ui.gError <- err + return } err = g.MainLoop() - if err != nil && err != gocui.ErrQuit { - return err + if err != nil && err != errTerminateMainloop { + ui.g.Close() + ui.gError <- err } - return nil + return } func layout(g *gocui.Gui) error { //maxX, maxY := g.Size() - ui.bugTable.layout(g) + g.Cursor = false - v, err := g.View("bugTable") - if err != nil { + if err := ui.activeWindow.layout(g); err != nil { return err } - cursorClamp(v) - return nil } func keybindings(g *gocui.Gui) error { - if err := g.SetKeybinding("", 'q', gocui.ModNone, quit); err != nil { - return err - } - if err := g.SetKeybinding("bugTable", 'j', gocui.ModNone, cursorDown); err != nil { - return err - } - if err := g.SetKeybinding("bugTable", gocui.KeyArrowDown, gocui.ModNone, cursorDown); err != nil { - return err - } - if err := g.SetKeybinding("bugTable", 'k', gocui.ModNone, cursorUp); err != nil { - return err - } - if err := g.SetKeybinding("bugTable", gocui.KeyArrowUp, gocui.ModNone, cursorUp); err != nil { + // Quit + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { return err } - if err := g.SetKeybinding("bugTable", 'h', gocui.ModNone, previousPage); err != nil { + if err := ui.bugTable.keybindings(g); err != nil { return err } - if err := g.SetKeybinding("bugTable", gocui.KeyArrowLeft, gocui.ModNone, previousPage); err != nil { - return err - } - if err := g.SetKeybinding("bugTable", gocui.KeyPgup, gocui.ModNone, previousPage); err != nil { - return err - } - if err := g.SetKeybinding("bugTable", 'l', gocui.ModNone, nextPage); err != nil { - return err - } - if err := g.SetKeybinding("bugTable", gocui.KeyArrowRight, gocui.ModNone, nextPage); err != nil { - return err - } - if err := g.SetKeybinding("bugTable", gocui.KeyPgdn, gocui.ModNone, nextPage); err != nil { - return err - } - - //err = g.SetKeybinding("bugTable", 'p', gocui.ModNone, playSelected) - //err = g.SetKeybinding("bugTable", gocui.KeyEnter, gocui.ModNone, playSelectedAndExit) - //err = g.SetKeybinding("bugTable", 'm', gocui.ModNone, loadNextRecords) return nil } @@ -108,50 +107,48 @@ func quit(g *gocui.Gui, v *gocui.View) error { return gocui.ErrQuit } -func cursorDown(g *gocui.Gui, v *gocui.View) error { - _, y := v.Cursor() - y = minInt(y+1, ui.bugTable.getTableLength()-1) - - err := v.SetCursor(0, y) - if err != nil { - return err - } +func newBugWithEditor(g *gocui.Gui, v *gocui.View) error { + // This is somewhat hacky. + // As there is no way to pause gocui, run the editor, restart gocui, + // we have to stop it entirely and start a new one later. + // + // - an error channel is used to route the returned error of this new + // instance into the original launch function + // - a custom error (errTerminateMainloop) is used to terminate the original + // instance's mainLoop. This error is then filtered. - return nil -} + ui.g.Close() -func cursorUp(g *gocui.Gui, v *gocui.View) error { - _, y := v.Cursor() - y = maxInt(y-1, 0) + title, message, err := input.BugCreateEditorInput(ui.cache.Repository(), "", "") - err := v.SetCursor(0, y) + if err == input.ErrEmptyTitle { + // TODO: display proper error + return err + } if err != nil { return err } - return nil -} - -func cursorClamp(v *gocui.View) error { - _, y := v.Cursor() - - y = minInt(y, ui.bugTable.getTableLength()-1) - y = maxInt(y, 0) - - err := v.SetCursor(0, y) + _, err = ui.cache.NewBug(title, message) if err != nil { return err } - return nil + initGui() + + return errTerminateMainloop } -func nextPage(g *gocui.Gui, v *gocui.View) error { - _, maxY := v.Size() - return ui.bugTable.nextPage(maxY) +func maxInt(a, b int) int { + if a > b { + return a + } + return b } -func previousPage(g *gocui.Gui, v *gocui.View) error { - _, maxY := v.Size() - return ui.bugTable.previousPage(maxY) +func minInt(a, b int) int { + if a > b { + return b + } + return a } |