issues

Github, Jira, Gitlab issues from Plan 9's acme
Log | Files | Refs | README | LICENSE

commit ca38aec71144ec417a2c5a950237ffb3bc6b256c
parent d90b33e0b7c880ce92dbbf9d986f28d6c84bb1c1
Author: Russ Cox <rsc@golang.org>
Date:   Fri,  9 Jan 2015 22:20:23 -0500

issue: add Sort command to acme mode

Diffstat:
Missue/acme.go | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Missue/issue.go | 5++++-
2 files changed, 89 insertions(+), 13 deletions(-)

diff --git a/issue/acme.go b/issue/acme.go @@ -13,6 +13,7 @@ import ( "log" "os" "regexp" + "sort" "strconv" "strings" "sync" @@ -47,15 +48,16 @@ const ( type awin struct { *acme.Win - prefix string - mode int - query string - id int - github *github.Issue - tab int - font *draw.Font - fontName string - title string + prefix string + mode int + query string + id int + github *github.Issue + tab int + font *draw.Font + fontName string + title string + sortByNumber bool // otherwise sort by title } var all struct { @@ -279,7 +281,7 @@ func (w *awin) newMilestoneList() { w.mode = modeMilestone w.query = "" w.Ctl("cleartag") - w.Fprintf("tag", " New Get Search ") + w.Fprintf("tag", " New Get Sort Search ") w.Write("body", []byte("Loading...")) go w.load() go w.loop() @@ -290,7 +292,7 @@ func (w *awin) newSearch(title, query string) { w.mode = modeQuery w.query = query w.Ctl("cleartag") - w.Fprintf("tag", " New Get Search ") + w.Fprintf("tag", " New Get Sort Search ") w.Write("body", []byte("Loading...")) go w.load() go w.loop() @@ -299,7 +301,7 @@ func (w *awin) newSearch(title, query string) { func (w *awin) blinker() func() { c := make(chan struct{}) go func() { - t := time.NewTicker(300 * time.Millisecond) + t := time.NewTicker(1000 * time.Millisecond) defer t.Stop() dirty := false for { @@ -600,6 +602,68 @@ func (w *awin) selection() string { return string(data) } +func (w *awin) sort() { + if err := w.Addr("0/^[0-9]/,"); err != nil { + w.err("nothing to sort") + } + data, err := w.ReadAll("xdata") + if err != nil { + w.err(err.Error()) + return + } + suffix := "" + lines := strings.Split(string(data), "\n") + if lines[len(lines)-1] == "" { + suffix = "\n" + lines = lines[:len(lines)-1] + } + if w.sortByNumber { + sort.Stable(byNumber(lines)) + } else { + sort.Stable(bySecondField(lines)) + } + w.Addr("0/^[0-9]/,") + w.Write("data", []byte(strings.Join(lines, "\n")+suffix)) + w.Addr("0") + w.Ctl("dot=addr") + w.Ctl("show") +} + +type byNumber []string + +func (x byNumber) Len() int { return len(x) } +func (x byNumber) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x byNumber) Less(i, j int) bool { + return lineNumber(x[i]) > lineNumber(x[j]) +} + +func lineNumber(s string) int { + n := 0 + for j := 0; j < len(s) && '0' <= s[j] && s[j] <= '9'; j++ { + n = n*10 + int(s[j]-'0') + } + return n +} + +type bySecondField []string + +func (x bySecondField) Len() int { return len(x) } +func (x bySecondField) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x bySecondField) Less(i, j int) bool { + return skipField(x[i]) < skipField(x[j]) +} + +func skipField(s string) string { + i := strings.Index(s, "\t") + if i < 0 { + return s + } + for i < len(s) && s[i+1] == '\t' { + i++ + } + return s[i:] +} + func (w *awin) loop() { defer w.exit() for e := range w.EventChan() { @@ -622,6 +686,15 @@ func (w *awin) loop() { w.createIssue() break } + if cmd == "Sort" { + if w.mode != modeQuery { + w.err("can only sort issue list windows") + break + } + w.sortByNumber = !w.sortByNumber + w.sort() + break + } if strings.HasPrefix(cmd, "Search ") { w.newSearch("search", strings.TrimSpace(strings.TrimPrefix(cmd, "Search"))) break diff --git a/issue/issue.go b/issue/issue.go @@ -120,7 +120,7 @@ // A search result window, opened by executing "Search <query>", displays a list of issues // matching a search query. It shows the query in a header line. For example: // -// Search: author:rsc +// Search author:rsc // // 9131 bench: no documentation // 599 cmd/5c, 5g, 8c, 8g: make 64-bit fields 64-bit aligned @@ -128,6 +128,9 @@ // 4997 cmd/6a, cmd/8a: MOVL $x-8(SP) and LEAL x-8(SP) are different // ... // +// Executing "Sort" in a search result window toggles between sorting by title +// and sorting by decreasing issue number. +// // Milestone List Window // // The milestone list window, opened by loading any of the names