From 9cbd5b4ee113c660377ffe9c01ca374d6addfef4 Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Tue, 11 Sep 2018 19:28:32 +0200 Subject: termui: allow to change the bug query --- termui/bug_table.go | 37 ++++++++++++++++++++++++++----------- termui/input_popup.go | 14 +++++++++++--- termui/termui.go | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 14 deletions(-) (limited to 'termui') diff --git a/termui/bug_table.go b/termui/bug_table.go index 6ee44b42..59252b48 100644 --- a/termui/bug_table.go +++ b/termui/bug_table.go @@ -16,10 +16,12 @@ const bugTableHeaderView = "bugTableHeaderView" const bugTableFooterView = "bugTableFooterView" const bugTableInstructionView = "bugTableInstructionView" -const remote = "origin" +const defaultRemote = "origin" +const defaultQuery = "status:open" type bugTable struct { repo *cache.RepoCache + queryStr string query *cache.Query allIds []string bugs []*cache.BugCache @@ -28,12 +30,15 @@ type bugTable struct { } func newBugTable(c *cache.RepoCache) *bugTable { + query, err := cache.ParseQuery(defaultQuery) + if err != nil { + panic(err) + } + return &bugTable{ - repo: c, - query: &cache.Query{ - OrderBy: cache.OrderByCreation, - OrderDirection: cache.OrderAscending, - }, + repo: c, + query: query, + queryStr: defaultQuery, pageCursor: 0, selectCursor: 0, } @@ -197,6 +202,12 @@ func (bt *bugTable) keybindings(g *gocui.Gui) error { return err } + // Query + if err := g.SetKeybinding(bugTableView, 'q', gocui.ModNone, + bt.changeQuery); err != nil { + return err + } + return nil } @@ -390,10 +401,10 @@ func (bt *bugTable) openBug(g *gocui.Gui, v *gocui.View) error { func (bt *bugTable) pull(g *gocui.Gui, v *gocui.View) error { // Note: this is very hacky - ui.msgPopup.Activate("Pull from remote "+remote, "...") + ui.msgPopup.Activate("Pull from remote "+defaultRemote, "...") go func() { - stdout, err := bt.repo.Fetch(remote) + stdout, err := bt.repo.Fetch(defaultRemote) if err != nil { g.Update(func(gui *gocui.Gui) error { @@ -410,7 +421,7 @@ func (bt *bugTable) pull(g *gocui.Gui, v *gocui.View) error { var buffer bytes.Buffer beginLine := "" - for merge := range bt.repo.MergeAll(remote) { + for merge := range bt.repo.MergeAll(defaultRemote) { if merge.Status == bug.MsgMergeNothing { continue } @@ -447,11 +458,11 @@ func (bt *bugTable) pull(g *gocui.Gui, v *gocui.View) error { } func (bt *bugTable) push(g *gocui.Gui, v *gocui.View) error { - ui.msgPopup.Activate("Push to remote "+remote, "...") + ui.msgPopup.Activate("Push to remote "+defaultRemote, "...") go func() { // TODO: make the remote configurable - stdout, err := bt.repo.Push(remote) + stdout, err := bt.repo.Push(defaultRemote) if err != nil { g.Update(func(gui *gocui.Gui) error { @@ -468,3 +479,7 @@ func (bt *bugTable) push(g *gocui.Gui, v *gocui.View) error { return nil } + +func (bt *bugTable) changeQuery(g *gocui.Gui, v *gocui.View) error { + return editQueryWithEditor(bt) +} diff --git a/termui/input_popup.go b/termui/input_popup.go index 00e602e5..c8299d2a 100644 --- a/termui/input_popup.go +++ b/termui/input_popup.go @@ -8,10 +8,12 @@ import ( const inputPopupView = "inputPopupView" +// inputPopup is a simple popup with an input field type inputPopup struct { - active bool - title string - c chan string + active bool + title string + preload string + c chan string } func newInputPopup() *inputPopup { @@ -53,6 +55,7 @@ func (ip *inputPopup) layout(g *gocui.Gui) error { v.Frame = true v.Title = ip.title v.Editable = true + v.Write([]byte(ip.preload)) } if _, err := g.SetCurrentView(inputPopupView); err != nil { @@ -88,6 +91,11 @@ func (ip *inputPopup) validate(g *gocui.Gui, v *gocui.View) error { return nil } +func (ip *inputPopup) ActivateWithContent(title string, content string) <-chan string { + ip.preload = content + return ip.Activate(title) +} + func (ip *inputPopup) Activate(title string) <-chan string { ip.title = title ip.active = true diff --git a/termui/termui.go b/termui/termui.go index 879ec2ea..54324c61 100644 --- a/termui/termui.go +++ b/termui/termui.go @@ -262,6 +262,40 @@ func setTitleWithEditor(bug *cache.BugCache) error { return errTerminateMainloop } +func editQueryWithEditor(bt *bugTable) error { + // This is somewhat hacky. + // As there is no way to pause gocui, run the editor and 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. + + ui.g.Close() + ui.g = nil + + queryStr, err := input.QueryEditorInput(bt.repo.Repository(), bt.queryStr) + + if err != nil { + return err + } + + bt.queryStr = queryStr + + query, err := cache.ParseQuery(queryStr) + + if err != nil { + ui.msgPopup.Activate(msgPopupErrorTitle, err.Error()) + } else { + bt.query = query + } + + initGui(nil) + + return errTerminateMainloop +} + func maxInt(a, b int) int { if a > b { return a -- cgit