func main() { err := ui.Init() if err != nil { panic(err) } defer ui.Close() p := ui.NewPar("Press q to QUIT THE DEMO. [There](fg-blue) are other things [that](fg-red) are going to fit in here I think. What do you think? Now is the time for all good [men to](bg-blue) come to the aid of their country. [This is going to be one really really really long line](fg-green) that is going to go together and stuffs and things. Let's see how this thing renders out.\n Here is a new paragraph and stuffs and things. There should be a tab indent at the beginning of the paragraph. Let's see if that worked as well.") p.WrapLength = 48 // this should be at least p.Width - 2 p.Height = 20 p.Width = 50 p.Y = 2 p.X = 20 p.TextFgColor = ui.ColorWhite p.BorderLabel = "Text Box with Wrapping" p.BorderFg = ui.ColorCyan //p.Border = false ui.Render(p) ui.Handle("/sys/kbd/q", func(ui.Event) { ui.StopLoop() }) ui.Loop() }
func (m *Monitor) Start(conn *net.Conn) { if err := ui.Init(); err != nil { panic(err) } defer ui.Close() help := ui.NewPar(":PRESS q TO QUIT") help.Height = 3 help.Width = 50 help.TextFgColor = ui.ColorWhite help.BorderLabel = "Help" help.BorderFg = ui.ColorCyan // build ui.Body.AddRows( ui.NewRow( ui.NewCol(6, 0, help), ), ) draw := func(t int) { ui.Body.Align() ui.Render(ui.Body) } draw(0) ui.Handle("/sys/kbd/q", func(ui.Event) { ui.StopLoop() }) ui.Handle("/timer/1s", func(e ui.Event) { t := e.Data.(ui.EvtTimer) draw(int(t.Count)) }) ui.Loop() }
func main() { if err := termui.Init(); err != nil { panic(err) } defer termui.Close() bc := termui.NewBarChart() data := []int{3, 2, 5, 3, 9, 5, 3, 2, 5, 8, 3, 2, 4, 5, 3, 2, 5, 7, 5, 3, 2, 6, 7, 4, 6, 3, 6, 7, 8, 3, 6, 4, 5, 3, 2, 4, 6, 4, 8, 5, 9, 4, 3, 6, 5, 3, 6} bclabels := []string{"S0", "S1", "S2", "S3", "S4", "S5"} bc.BorderLabel = "Bar Chart" bc.Data = data bc.Width = 26 bc.Height = 10 bc.DataLabels = bclabels bc.TextColor = termui.ColorGreen bc.BarColor = termui.ColorRed bc.NumColor = termui.ColorYellow termui.Render(bc) termui.Handle("/sys/kbd/q", func(termui.Event) { termui.StopLoop() }) termui.Loop() }
func main() { err := termui.Init() if err != nil { panic(err) } defer termui.Close() //termui.UseTheme("helloworld") strs := []string{ "[0] github.com/gizak/termui", "[1] [你好,世界](fg-blue)", "[2] [こんにちは世界](fg-red)", "[3] [color output](fg-white,bg-green)", "[4] output.go", "[5] random_out.go", "[6] dashboard.go", "[7] nsf/termbox-go"} ls := termui.NewList() ls.Items = strs ls.ItemFgColor = termui.ColorYellow ls.BorderLabel = "List" ls.Height = 7 ls.Width = 25 ls.Y = 0 termui.Render(ls) termui.Handle("/sys/kbd/q", func(termui.Event) { termui.StopLoop() }) termui.Loop() }
func BuildUI() { ui.Init() defer ui.Close() receiveBox := CreateReceiveBox() sendBox := CreateSendBox() ui.Body.AddRows( ui.NewRow(ui.NewCol(12, 0, receiveBox)), ui.NewRow(ui.NewCol(12, 0, sendBox)), ) ui.Body.Align() ui.Render(ui.Body) ui.Handle("/sys/kbd/C-x", func(e ui.Event) { ui.StopLoop() }) ui.Handle("/timer/1s", func(e ui.Event) { ReceiveBoxHeight = ui.TermHeight() - SendBoxHeight receiveBox.Height = ReceiveBoxHeight ui.Body.Align() ui.Render(ui.Body) }) // Leaving this commented out for now // I'd like to get this method of screen refreshing working instead of the 1s method, // but this crashes on resize. // ui.Handle("/sys/wnd/resize", func(e ui.Event) { // ui.Body.Align() // ui.Render(ui.Body) // }) ui.Loop() }
func main() { flag.Parse() if err := termui.Init(); err != nil { panic(err) } defer termui.Close() ticker := time.NewTicker(15 * time.Second) go func() { for { mstats, err := fetch.FetchMemStats(*target) if err != nil { termui.StopLoop() log.Fatal(err) } render(*mstats) <-ticker.C } }() termui.Handle("/sys/kbd/q", func(termui.Event) { // press q to quit termui.StopLoop() }) termui.Loop() }
func main() { err := termui.Init() if err != nil { panic(err) } defer termui.Close() //termui.UseTheme("helloworld") data := []int{4, 2, 1, 6, 3, 9, 1, 4, 2, 15, 14, 9, 8, 6, 10, 13, 15, 12, 10, 5, 3, 6, 1, 7, 10, 10, 14, 13, 6} spl0 := termui.NewSparkline() spl0.Data = data[3:] spl0.Title = "Sparkline 0" spl0.LineColor = termui.ColorGreen // single spls0 := termui.NewSparklines(spl0) spls0.Height = 2 spls0.Width = 20 spls0.Border = false spl1 := termui.NewSparkline() spl1.Data = data spl1.Title = "Sparkline 1" spl1.LineColor = termui.ColorRed spl2 := termui.NewSparkline() spl2.Data = data[5:] spl2.Title = "Sparkline 2" spl2.LineColor = termui.ColorMagenta // group spls1 := termui.NewSparklines(spl0, spl1, spl2) spls1.Height = 8 spls1.Width = 20 spls1.Y = 3 spls1.BorderLabel = "Group Sparklines" spl3 := termui.NewSparkline() spl3.Data = data spl3.Title = "Enlarged Sparkline" spl3.Height = 8 spl3.LineColor = termui.ColorYellow spls2 := termui.NewSparklines(spl3) spls2.Height = 11 spls2.Width = 30 spls2.BorderFg = termui.ColorCyan spls2.X = 21 spls2.BorderLabel = "Tweeked Sparkline" termui.Render(spls0, spls1, spls2) termui.Handle("/sys/kbd/q", func(termui.Event) { termui.StopLoop() }) termui.Loop() }
func runUI(args []string) { ui := &tatui{} ui.init(args) ui.draw(0) defer termui.Close() termui.Loop() }
func main() { err := termui.Init() if err != nil { panic(err) } defer termui.Close() //termui.UseTheme("helloworld") sinps := (func() []float64 { n := 220 ps := make([]float64, n) for i := range ps { ps[i] = 1 + math.Sin(float64(i)/5) } return ps })() lc0 := termui.NewLineChart() lc0.BorderLabel = "braille-mode Line Chart" lc0.Data = sinps lc0.Width = 50 lc0.Height = 12 lc0.X = 0 lc0.Y = 0 lc0.AxesColor = termui.ColorWhite lc0.LineColor = termui.ColorGreen | termui.AttrBold lc1 := termui.NewLineChart() lc1.BorderLabel = "dot-mode Line Chart" lc1.Mode = "dot" lc1.Data = sinps lc1.Width = 26 lc1.Height = 12 lc1.X = 51 lc1.DotStyle = '+' lc1.AxesColor = termui.ColorWhite lc1.LineColor = termui.ColorYellow | termui.AttrBold lc2 := termui.NewLineChart() lc2.BorderLabel = "dot-mode Line Chart" lc2.Mode = "dot" lc2.Data = sinps[4:] lc2.Width = 77 lc2.Height = 16 lc2.X = 0 lc2.Y = 12 lc2.AxesColor = termui.ColorWhite lc2.LineColor = termui.ColorCyan | termui.AttrBold termui.Render(lc0, lc1, lc2) termui.Handle("/sys/kbd/q", func(termui.Event) { termui.StopLoop() }) termui.Loop() }
func main() { err := termui.Init() if err != nil { panic(err) } defer termui.Close() sinps := (func() []float64 { n := 220 ps := make([]float64, n) for i := range ps { ps[i] = 1 + math.Sin(float64(i)/5) } return ps })() p := termui.NewPar(":PRESS q or Esc TO QUIT DEMO Hello World") p.Height = 3 p.Width = 50 p.TextFgColor = termui.ColorWhite p.BorderLabel = "Hello-World" p.BorderFg = termui.ColorCyan lc1 := termui.NewLineChart() lc1.BorderLabel = "dot-mode Line Chart" lc1.Mode = "dot" lc1.Data = sinps lc1.Width = 26 lc1.Height = 12 lc1.X = 51 lc1.DotStyle = '+' lc1.AxesColor = termui.ColorWhite lc1.LineColor = termui.ColorYellow | termui.AttrBold g0 := termui.NewGauge() g0.Percent = 40 g0.Width = 50 g0.Height = 3 g0.Y = 3 g0.BorderLabel = "Slim Gauge" g0.BarColor = termui.ColorRed g0.BorderFg = termui.ColorWhite g0.BorderLabelFg = termui.ColorCyan termui.Render(p, g0, lc1) termui.Handle("/sys", func(e termui.Event) { k, ok := e.Data.(termui.EvtKbd) if ok && (k.KeyStr == "q" || k.KeyStr == "<escape>") { termui.StopLoop() } }) termui.Loop() }
//doLiveGraph builds a graph in the terminal window that //updates every graphUpdate seconds //It will build up to maxGraphs graphs with one time-series //per graph func doLiveGraph(res *wavefront.QueryResponse, query *wavefront.Querying, period int64) { err := ui.Init() if err != nil { log.Fatal(err) } defer ui.Close() if maxGraphs > len(res.TimeSeries) { maxGraphs = len(res.TimeSeries) } var wDivisor, hDivisor int switch maxGraphs { case 1: wDivisor = 1 hDivisor = 1 case 2: wDivisor = 2 hDivisor = 1 case 3, 4: wDivisor = 2 hDivisor = 2 } height := ui.TermHeight() / hDivisor width := ui.TermWidth() / wDivisor xVals, yVals := calculateCoords(maxGraphs, ui.TermWidth()/wDivisor, ui.TermHeight()/hDivisor) graphs := buildGraphs(res, height, width, xVals, yVals) ui.Render(graphs...) ui.Handle("/sys/kbd/q", func(ui.Event) { // press q to quit ui.StopLoop() }) ui.Handle("/sys/kbd/C-c", func(ui.Event) { // handle Ctrl + c combination ui.StopLoop() }) ui.Handle("/timer/1s", func(e ui.Event) { query.SetEndTime(time.Now()) query.SetStartTime(period) res, err := query.Execute() if err != nil { log.Fatal(err) } graphs := buildGraphs(res, height, width, xVals, yVals) ui.Render(graphs...) }) ui.Loop() }
func (s *Stats) Start() { s.cfUI.Say("Starting Stats...") err := termui.Init() if err != nil { s.cfUI.Warn(err.Error()) return } defer termui.Close() go func() { sinkTypeChart := &charts.SinkTypeChart{} sinkTypeChart.Init(s.cfUI) uaaChart := &charts.UAAChart{} uaaChart.Init(s.cfUI) msgLossChart := &charts.MsgLossChart{} msgLossChart.Init(s.cfUI) notesChart := &charts.NotesChart{} notesChart.Init() s.client.Sift( []charts.Chart{ sinkTypeChart, uaaChart, msgLossChart, }, ) termui.Body.AddRows( termui.NewRow( termui.NewCol(6, 0, sinkTypeChart), termui.NewCol(6, 0, uaaChart), ), termui.NewRow( termui.NewCol(6, 0, msgLossChart), termui.NewCol(6, 0, notesChart), ), ) for { termui.Body.Align() termui.Render(termui.Body) time.Sleep(1 * time.Second) } }() termui.Handle("/sys/kbd/q", func(termui.Event) { termui.StopLoop() }) termui.Loop() }
func sparkLinesEventLoop() { ui.Handle("/sys/kbd/q", func(ui.Event) { ui.StopLoop() }) ui.Handle("/sys/wnd/resize", func(e ui.Event) { ui.Body.Width = ui.TermWidth() ui.Body.Align() ui.Render(ui.Body) }) ui.Loop() // blocking call }
// start Starts all the necessary processes/go co-routines for the app to initialize func start(ctx *cli.Context) { log.Info("Starting Lazarus...") cfg := checkAndReadConfig(ctx) ui.EventHandler() render(ctx) go startPlayer(cfg) defer termui.Close() ui.Refresh() termui.Loop() }
func main() { // run as client if len(os.Args) > 1 { fmt.Print(debug.ConnectAndListen()) return } // run as server go func() { panic(debug.ListenAndServe()) }() if err := termui.Init(); err != nil { panic(err) } defer termui.Close() //termui.UseTheme("helloworld") b := termui.NewBlock() b.Width = 20 b.Height = 20 b.Float = termui.AlignCenter b.BorderLabel = "[HELLO](fg-red,bg-white) [WORLD](fg-blue,bg-green)" termui.Render(b) termui.Handle("/sys", func(e termui.Event) { k, ok := e.Data.(termui.EvtKbd) debug.Logf("->%v\n", e) if ok && k.KeyStr == "q" { termui.StopLoop() } }) termui.Handle(("/usr"), func(e termui.Event) { debug.Logf("->%v\n", e) }) termui.Handle("/timer/1s", func(e termui.Event) { t := e.Data.(termui.EvtTimer) termui.SendCustomEvt("/usr/t", t.Count) if t.Count%2 == 0 { b.BorderLabel = "[HELLO](fg-red,bg-green) [WORLD](fg-blue,bg-white)" } else { b.BorderLabel = "[HELLO](fg-blue,bg-white) [WORLD](fg-red,bg-green)" } termui.Render(b) }) termui.Loop() }
func main() { flag.Parse() if err := ui.Init(); err != nil { panic(err) } defer ui.Close() draw() ui.Handle("/sys/kbd", func(e ui.Event) { ev := e.Data.(ui.EvtKbd) switch ev.KeyStr { case ":": promptMsg = ":" case "C-8": if l := len(promptMsg); l != 0 { promptMsg = promptMsg[:l-1] } case "<enter>": handleInput() promptMsg = "" case "<left>": case "<up>": if reportPage > 0 { reportPage-- } case "<right>": case "<down>": reportPage++ case "<escape>": promptMsg = "" default: // TODO: filter irrelevant keys such as up, down, etc. promptMsg += ev.KeyStr } refresh() }) ui.Handle("/sys/kbd/C-c", func(ui.Event) { ui.StopLoop() }) ui.Handle("/timer/1s", func(ui.Event) { loadProfile(false) loadStats() refresh() }) ui.Handle("/sys/wnd/resize", func(e ui.Event) { ui.Body.Width = ui.TermWidth() refresh() }) ui.Body.Align() ui.Render(ui.Body) ui.Loop() }
func main() { if len(os.Args) < 2 { log.Fatal("Usage: ", os.Args[0], " <sparkyfish server hostname/IP>[:port]") } dest := os.Args[1] i := last(dest, ':') if i < 0 { dest = fmt.Sprint(dest, ":7121") } // Initialize our screen err := termui.Init() if err != nil { panic(err) } if termui.TermWidth() < 60 || termui.TermHeight() < 28 { fmt.Println("sparkyfish needs a terminal window at least 60x28 to run.") os.Exit(1) } defer termui.Close() // 'q' quits the program termui.Handle("/sys/kbd/q", func(termui.Event) { termui.StopLoop() }) // 'Q' also works termui.Handle("/sys/kbd/Q", func(termui.Event) { termui.StopLoop() }) sc := newsparkyClient() sc.serverHostname = dest sc.prepareChannels() sc.wr = newwidgetRenderer() // Begin our tests go sc.runTestSequence() termui.Loop() }
func main() { err := termui.Init() if err != nil { panic(err) } defer termui.Close() //termui.UseTheme("helloworld") bc := termui.NewMBarChart() math := []int{90, 85, 90, 80} english := []int{70, 85, 75, 60} science := []int{75, 60, 80, 85} compsci := []int{100, 100, 100, 100} bc.Data[0] = math bc.Data[1] = english bc.Data[2] = science bc.Data[3] = compsci studentsName := []string{"Ken", "Rob", "Dennis", "Linus"} bc.BorderLabel = "Student's Marks X-Axis=Name Y-Axis=Marks[Math,English,Science,ComputerScience] in %" bc.Width = 100 bc.Height = 30 bc.Y = 0 bc.BarWidth = 10 bc.DataLabels = studentsName bc.ShowScale = true //Show y_axis scale value (min and max) bc.SetMax(400) bc.TextColor = termui.ColorGreen //this is color for label (x-axis) bc.BarColor[3] = termui.ColorGreen //BarColor for computerscience bc.BarColor[1] = termui.ColorYellow //Bar Color for english bc.NumColor[3] = termui.ColorRed // Num color for computerscience bc.NumColor[1] = termui.ColorRed // num color for english //Other colors are automatically populated, btw All the students seems do well in computerscience. :p termui.Render(bc) termui.Handle("/sys/kbd/q", func(termui.Event) { termui.StopLoop() }) termui.Loop() }
func main() { err := termui.Init() if err != nil { panic(err) } defer termui.Close() //termui.UseTheme("helloworld") par0 := termui.NewPar("Borderless Text") par0.Height = 1 par0.Width = 20 par0.Y = 1 par0.Border = false par1 := termui.NewPar("你好,世界。") par1.Height = 3 par1.Width = 17 par1.X = 20 par1.BorderLabel = "标签" par2 := termui.NewPar("Simple colored text\nwith label. It [can be](fg-red) multilined with \\n or [break automatically](fg-red,fg-bold)") par2.Height = 5 par2.Width = 37 par2.Y = 4 par2.BorderLabel = "Multiline" par2.BorderFg = termui.ColorYellow par3 := termui.NewPar("Long text with label and it is auto trimmed.") par3.Height = 3 par3.Width = 37 par3.Y = 9 par3.BorderLabel = "Auto Trim" termui.Render(par0, par1, par2, par3) termui.Handle("/sys/kbd/q", func(termui.Event) { termui.StopLoop() }) termui.Loop() }
func UI(refresh uint) { initTranslators() err := termui.Init() if err != nil { panic(err) } defer termui.Close() killChan := make(chan bool) go func() { tickerChan := time.NewTicker(time.Millisecond * time.Duration(refresh)).C for { select { case <-killChan: break case <-tickerChan: if updateBool { render() updateBool = false } } } }() defer func() { killChan <- true }() setupBody() // calculate layout termui.Body.Align() termui.Render(termui.Body) setupHandlers() termui.Loop() }
func main() { if err := ui.Init(); err != nil { panic(err) } defer ui.Close() p := ui.NewPar(":PRESS q TO QUIT DEMO") p.Height = 3 p.Width = 50 p.TextFgColor = ui.ColorWhite p.BorderLabel = "Text Box" p.BorderFg = ui.ColorCyan p.Handle("/timer/1s", func(e ui.Event) { cnt := e.Data.(ui.EvtTimer) if cnt.Count%2 == 0 { p.TextFgColor = ui.ColorRed } else { p.TextFgColor = ui.ColorWhite } }) strs := []string{"[0] gizak/termui", "[1] editbox.go", "[2] iterrupt.go", "[3] keyboard.go", "[4] output.go", "[5] random_out.go", "[6] dashboard.go", "[7] nsf/termbox-go"} list := ui.NewList() list.Items = strs list.ItemFgColor = ui.ColorYellow list.BorderLabel = "List" list.Height = 7 list.Width = 25 list.Y = 4 g := ui.NewGauge() g.Percent = 50 g.Width = 50 g.Height = 3 g.Y = 11 g.BorderLabel = "Gauge" g.BarColor = ui.ColorRed g.BorderFg = ui.ColorWhite g.BorderLabelFg = ui.ColorCyan spark := ui.Sparkline{} spark.Height = 1 spark.Title = "srv 0:" spdata := []int{4, 2, 1, 6, 3, 9, 1, 4, 2, 15, 14, 9, 8, 6, 10, 13, 15, 12, 10, 5, 3, 6, 1, 7, 10, 10, 14, 13, 6, 4, 2, 1, 6, 3, 9, 1, 4, 2, 15, 14, 9, 8, 6, 10, 13, 15, 12, 10, 5, 3, 6, 1, 7, 10, 10, 14, 13, 6, 4, 2, 1, 6, 3, 9, 1, 4, 2, 15, 14, 9, 8, 6, 10, 13, 15, 12, 10, 5, 3, 6, 1, 7, 10, 10, 14, 13, 6, 4, 2, 1, 6, 3, 9, 1, 4, 2, 15, 14, 9, 8, 6, 10, 13, 15, 12, 10, 5, 3, 6, 1, 7, 10, 10, 14, 13, 6} spark.Data = spdata spark.LineColor = ui.ColorCyan spark.TitleColor = ui.ColorWhite spark1 := ui.Sparkline{} spark1.Height = 1 spark1.Title = "srv 1:" spark1.Data = spdata spark1.TitleColor = ui.ColorWhite spark1.LineColor = ui.ColorRed sp := ui.NewSparklines(spark, spark1) sp.Width = 25 sp.Height = 7 sp.BorderLabel = "Sparkline" sp.Y = 4 sp.X = 25 sinps := (func() []float64 { n := 220 ps := make([]float64, n) for i := range ps { ps[i] = 1 + math.Sin(float64(i)/5) } return ps })() lc := ui.NewLineChart() lc.BorderLabel = "dot-mode Line Chart" lc.Data = sinps lc.Width = 50 lc.Height = 11 lc.X = 0 lc.Y = 14 lc.AxesColor = ui.ColorWhite lc.LineColor = ui.ColorRed | ui.AttrBold lc.Mode = "dot" bc := ui.NewBarChart() bcdata := []int{3, 2, 5, 3, 9, 5, 3, 2, 5, 8, 3, 2, 4, 5, 3, 2, 5, 7, 5, 3, 2, 6, 7, 4, 6, 3, 6, 7, 8, 3, 6, 4, 5, 3, 2, 4, 6, 4, 8, 5, 9, 4, 3, 6, 5, 3, 6} bclabels := []string{"S0", "S1", "S2", "S3", "S4", "S5"} bc.BorderLabel = "Bar Chart" bc.Width = 26 bc.Height = 10 bc.X = 51 bc.Y = 0 bc.DataLabels = bclabels bc.BarColor = ui.ColorGreen bc.NumColor = ui.ColorBlack lc1 := ui.NewLineChart() lc1.BorderLabel = "braille-mode Line Chart" lc1.Data = sinps lc1.Width = 26 lc1.Height = 11 lc1.X = 51 lc1.Y = 14 lc1.AxesColor = ui.ColorWhite lc1.LineColor = ui.ColorYellow | ui.AttrBold p1 := ui.NewPar("Hey!\nI am a borderless block!") p1.Border = false p1.Width = 26 p1.Height = 2 p1.TextFgColor = ui.ColorMagenta p1.X = 52 p1.Y = 11 draw := func(t int) { g.Percent = t % 101 list.Items = strs[t%9:] sp.Lines[0].Data = spdata[:30+t%50] sp.Lines[1].Data = spdata[:35+t%50] lc.Data = sinps[t/2%220:] lc1.Data = sinps[2*t%220:] bc.Data = bcdata[t/2%10:] ui.Render(p, list, g, sp, lc, bc, lc1, p1) } ui.Handle("/sys/kbd/q", func(ui.Event) { ui.StopLoop() }) ui.Handle("/timer/1s", func(e ui.Event) { t := e.Data.(ui.EvtTimer) draw(int(t.Count)) }) ui.Loop() }
// func Draw(data reg.New) { func Draw(model reg.New, datasource string) { if datasource == "stdin" { statheader = fmt.Sprintf("Statistics (File: Command line entry)") } else { statheader = fmt.Sprintf("Statistics (File: %s)", datasource) } if err := ui.Init(); err != nil { panic(err) } defer ui.Close() //Main data plot lc := ui.NewLineChart() lc.BorderLabel = "Main plot. Hit 'q' to exit. Drag to resize." lc.Data = []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0.2, 0.1, 0.4, 0.33, 12.23} lc.Mode = "dot" lc.Height = 15 lc.AxesColor = ui.ColorWhite lc.LineColor = ui.ColorRed | ui.AttrBold //Residual plots rp0 := ui.NewLineChart() rp0.BorderLabel = "Residual 1" rp0.Data = []float64{1, 2, 3, 4, 5, 6, 7, 8} rp0.Mode = "dot" rp0.Height = 15 rp0.AxesColor = ui.ColorWhite rp0.LineColor = ui.ColorRed | ui.AttrBold //Display statistics // eq, conf, sd, rgc, intcp // axis lable and axis scale xlab := str("X axis: %s", model.Xlabel) ylab := str("Y axis: %s", model.Ylabel) eqxy := str("Equation(XonY): %s", model.Equation("XonY")) eqyx := str("Equation(YonX): %s", model.Equation("YonX")) conf := str("Confidence: %0.2f %%", model.Conf()) sdx := str("StdDev(X): %0.2f", model.SdX()) sdy := str("StdDev(Y): %0.2f", model.SdY()) bxy := str("RegCof(xy): %0.2f", model.Bxy()) byx := str("RegCof(yx): %0.2f", model.Byx()) cov := str("Covariance: %0.2f", model.Covariance()) ix, iy := model.Intersect() icept := fmt.Sprintf("Intercept: %0.2f, %0.2f", ix, iy) stats := []string{ xlab, ylab, eqxy, eqyx, conf, sdx, sdy, bxy, byx, cov, icept, } lst := ui.NewList() lst.Items = stats // slice lst.Height = 13 lst.Width = 30 lst.Y = 0 lst.BorderLabel = statheader lst.ItemFgColor = ui.ColorWhite ui.Body.AddRows(ui.NewRow(ui.NewCol(8, 0, lc), ui.NewCol(4, 0, rp0)), ui.NewRow(ui.NewCol(12, 0, lst))) // ui.Body.AddRows(ui.NewRow(ui.NewCol(8,0,rp0))) ui.Body.Align() ui.Render(ui.Body) ui.Handle("/sys/kbd/q", func(ui.Event) { ui.StopLoop() }) ui.Handle("sys/wnd/resize", func(e ui.Event) { ui.Body.Width = ui.TermWidth() ui.Body.Align() ui.Render(ui.Body) }) ui.Loop() }
func main() { //set log file logFileName := "btc.log" logFile, logErr := os.OpenFile(logFileName, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666) if logErr != nil { fmt.Println("Fail to find", *logFile, "cServer start Failed") return } log.SetOutput(logFile) log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) log.Printf("cpu num %d", runtime.NumCPU()) runtime.GOMAXPROCS(runtime.NumCPU()) if err := ui.Init(); err != nil { log.Printf("ui init err : %s", err) return } defer ui.Close() par = ui.NewPar("Last Price") par.Height = 3 par.TextFgColor = ui.ColorWhite par.BorderLabel = "Last Price" infoPar = ui.NewPar("Price Info") infoPar.Height = 3 infoPar.TextFgColor = ui.ColorWhite infoPar.BorderLabel = "Price Info" currentTime := time.Now().Format("2006-01-02 15:04:05") timePar := ui.NewPar(currentTime) timePar.Height = 3 timePar.TextFgColor = ui.ColorYellow timePar.BorderLabel = "Current Time" strItems := []string{} delegateList = ui.NewList() delegateList.Items = strItems delegateList.ItemFgColor = ui.ColorYellow delegateList.BorderLabel = "Delegate List" delegateList.Height = 23 dealList = ui.NewList() dealList.Items = strItems dealList.ItemFgColor = ui.ColorYellow dealList.Height = 23 dealList.BorderLabel = "Deal List" ui.Body.AddRows( ui.NewRow( ui.NewCol(6, 0, par), ui.NewCol(6, 0, timePar))) ui.Body.AddRows( ui.NewRow( ui.NewCol(12, 0, infoPar))) ui.Body.AddRows( ui.NewRow( ui.NewCol(6, 0, delegateList), ui.NewCol(6, 0, dealList))) ui.Body.Align() ui.Render(ui.Body) // websocket connect log.Printf("connecting to %s", url) c, _, err := websocket.DefaultDialer.Dial(url, nil) if err != nil { log.Fatal("dial:", err) } defer c.Close() // message done chan done := make(chan struct{}) exit := func() { err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) if err != nil { log.Printf("write close: %s", err) } else { select { case <-done: case <-time.After(time.Second): } c.Close() } ui.StopLoop() } ui.Handle("/sys/kbd/q", func(ui.Event) { exit() }) ui.Handle("/sys/kbd/p", func(ui.Event) { if !uiPaused { uiPaused = true } else { uiPaused = false } }) ui.Handle("/sys/wnd/resize", func(e ui.Event) { ui.Body.Width = ui.TermWidth() ui.Body.Align() ui.Render(ui.Body) }) ui.Handle("/timer/1s", func(e ui.Event) { currentTime := time.Now().Format("2006-01-02 15:04:05") timePar.Text = currentTime }) go func() { for { //or use message if !uiPaused { time.Sleep(time.Millisecond * 50) ui.Render(ui.Body) } else { time.Sleep(time.Millisecond * 200) } } }() //----------------------- stocket message -------------- msgChan := make(chan []byte) //获取消息 go func() { defer c.Close() defer close(done) for { _, message, err := c.ReadMessage() if err != nil { log.Printf("read err: %s", err) return } msgChan <- message } }() //订阅消息 sendSubChannel(c) //heart check via pingChan go func() { defer close(pingChan) for { if c.WriteMessage(websocket.TextMessage, []byte("{\"event\": \"ping\"}")); err != nil { log.Printf("send ping message err: %s", err) break } log.Println("send ping message") select { case <-pingChan: log.Println("server is alive") //收到数据 1s 后继续发送心跳 time.Sleep(time.Second) case <-time.After(time.Second * 1): //超时 重新连接 socket reConnectTimes := 0 for { if reConnectTimes > 5 { log.Fatal("websocket connect failed") break } _c, _, err := websocket.DefaultDialer.Dial(url, nil) if err != nil { log.Println("re-connect websocket faild dial:", err) log.Println("after 3s retry connect websocket") reConnectTimes++ time.Sleep(time.Second * 3) } else { log.Println("re-connect websocket success") c = _c sendSubChannel(c) break } } } } }() //开启10个worker 处理消息 for i := 0; i < 10; i++ { go processMessage(msgChan) } //开始阻塞 循环terminal ui ui.Loop() }
// monitor starts a terminal UI based monitoring tool for the requested metrics. func monitor(ctx *cli.Context) error { var ( client rpc.Client err error ) // Attach to an Expanse node over IPC or RPC endpoint := ctx.String(monitorCommandAttachFlag.Name) if client, err = utils.NewRemoteRPCClientFromString(endpoint); err != nil { utils.Fatalf("Unable to attach to gexp node: %v", err) } defer client.Close() // Retrieve all the available metrics and resolve the user pattens metrics, err := retrieveMetrics(client) if err != nil { utils.Fatalf("Failed to retrieve system metrics: %v", err) } monitored := resolveMetrics(metrics, ctx.Args()) if len(monitored) == 0 { list := expandMetrics(metrics, "") sort.Strings(list) if len(list) > 0 { utils.Fatalf("No metrics specified.\n\nAvailable:\n - %s", strings.Join(list, "\n - ")) } else { utils.Fatalf("No metrics collected by gexp (--%s).\n", utils.MetricsEnabledFlag.Name) } } sort.Strings(monitored) if cols := len(monitored) / ctx.Int(monitorCommandRowsFlag.Name); cols > 6 { utils.Fatalf("Requested metrics (%d) spans more that 6 columns:\n - %s", len(monitored), strings.Join(monitored, "\n - ")) } // Create and configure the chart UI defaults if err := termui.Init(); err != nil { utils.Fatalf("Unable to initialize terminal UI: %v", err) } defer termui.Close() rows := len(monitored) if max := ctx.Int(monitorCommandRowsFlag.Name); rows > max { rows = max } cols := (len(monitored) + rows - 1) / rows for i := 0; i < rows; i++ { termui.Body.AddRows(termui.NewRow()) } // Create each individual data chart footer := termui.NewPar("") footer.Block.Border = true footer.Height = 3 charts := make([]*termui.LineChart, len(monitored)) units := make([]int, len(monitored)) data := make([][]float64, len(monitored)) for i := 0; i < len(monitored); i++ { charts[i] = createChart((termui.TermHeight() - footer.Height) / rows) row := termui.Body.Rows[i%rows] row.Cols = append(row.Cols, termui.NewCol(12/cols, 0, charts[i])) } termui.Body.AddRows(termui.NewRow(termui.NewCol(12, 0, footer))) refreshCharts(client, monitored, data, units, charts, ctx, footer) termui.Body.Align() termui.Render(termui.Body) // Watch for various system events, and periodically refresh the charts termui.Handle("/sys/kbd/C-c", func(termui.Event) { termui.StopLoop() }) termui.Handle("/sys/wnd/resize", func(termui.Event) { termui.Body.Width = termui.TermWidth() for _, chart := range charts { chart.Height = (termui.TermHeight() - footer.Height) / rows } termui.Body.Align() termui.Render(termui.Body) }) go func() { tick := time.NewTicker(time.Duration(ctx.Int(monitorCommandRefreshFlag.Name)) * time.Second) for range tick.C { if refreshCharts(client, monitored, data, units, charts, ctx, footer) { termui.Body.Align() } termui.Render(termui.Body) } }() termui.Loop() return nil }
func main() { configFile := flag.String("config", "config.json", "Configuration file") flag.Parse() monitors := readConfig(*configFile) updates := make(chan monitor.CheckUpdate) logbuf := new(bytes.Buffer) log.SetOutput(logbuf) err := termui.Init() if err != nil { log.Fatalf("Unable to init termui: %v\n", err) } defer termui.Close() list := termui.NewList() var urls []string for _, m := range monitors { e := fmt.Sprintf("[%v] %v", m.index, m.monitor.Source()) urls = append(urls, e) if list.Width < int(float64(len(e))*float64(1.5)) { list.Width = int(float64(len(e)) * float64(1.5)) } } list.Items = urls list.ItemFgColor = termui.ColorYellow list.BorderLabel = "URLs" list.Height = 8 list.Y = 0 list.X = 0 sp := termui.NewSparklines() sp.BorderLabel = "Response times" sp.Y = list.Height sp.X = 0 sp.Height = list.Height for i, _ := range urls { spark := termui.Sparkline{} spark.Height = 1 spark.Title = fmt.Sprintf("URL %v", i) spark.LineColor = termui.ColorCyan spark.TitleColor = termui.ColorYellow sp.Add(spark) } logPar := termui.NewPar(logbuf.String()) logPar.Height = 20 termui.Body.AddRows( termui.NewRow( termui.NewCol(6, 0, list), termui.NewCol(6, 0, sp)), termui.NewRow( termui.NewCol(12, 0, logPar))) termui.Body.Align() for _, m := range monitors { go m.monitor.Check(updates, m.index) } loop: for { select { case u := <-updates: if u.Healthy && u.Err == nil { sp.Lines[u.Id].LineColor = COLOR_OK } else { sp.Lines[u.Id].LineColor = COLOR_KO } case <-time.After(2 * time.Second): break loop } } termui.Render(termui.Body) termui.Handle("/sys/kbd/q", func(termui.Event) { termui.StopLoop() }) termui.Handle("/timer/1s", func(e termui.Event) { t := e.Data.(termui.EvtTimer) if t.Count%5 == 0 { for _, m := range monitors { go m.monitor.Check(updates, m.index) } loop: for { select { case u := <-updates: sp.Lines[u.Id].Data = append(sp.Lines[u.Id].Data, int(u.Duration)) if u.Healthy && u.Err == nil { sp.Lines[u.Id].LineColor = COLOR_OK } else { sp.Lines[u.Id].LineColor = COLOR_KO } case <-time.After(2 * time.Second): break loop } } logPar.Text = logbuf.String() termui.Render(termui.Body) } }) termui.Loop() }
func main() { if err := ui.Init(); err != nil { panic(err) } defer ui.Close() sinps := (func() []float64 { n := 400 ps := make([]float64, n) for i := range ps { ps[i] = 1 + math.Sin(float64(i)/5) } return ps })() sinpsint := (func() []int { ps := make([]int, len(sinps)) for i, v := range sinps { ps[i] = int(100*v + 10) } return ps })() spark := ui.Sparkline{} spark.Height = 8 spdata := sinpsint spark.Data = spdata[:100] spark.LineColor = ui.ColorCyan spark.TitleColor = ui.ColorWhite sp := ui.NewSparklines(spark) sp.Height = 11 sp.BorderLabel = "Sparkline" lc := ui.NewLineChart() lc.BorderLabel = "braille-mode Line Chart" lc.Data = sinps lc.Height = 11 lc.AxesColor = ui.ColorWhite lc.LineColor = ui.ColorYellow | ui.AttrBold gs := make([]*ui.Gauge, 3) for i := range gs { gs[i] = ui.NewGauge() //gs[i].LabelAlign = ui.AlignCenter gs[i].Height = 2 gs[i].Border = false gs[i].Percent = i * 10 gs[i].PaddingBottom = 1 gs[i].BarColor = ui.ColorRed } ls := ui.NewList() ls.Border = false ls.Items = []string{ "[1] Downloading File 1", "", // == \newline "[2] Downloading File 2", "", "[3] Uploading File 3", } ls.Height = 5 par := ui.NewPar("<> This row has 3 columns\n<- Widgets can be stacked up like left side\n<- Stacked widgets are treated as a single widget") par.Height = 5 par.BorderLabel = "Demonstration" // build layout ui.Body.AddRows( ui.NewRow( ui.NewCol(6, 0, sp), ui.NewCol(6, 0, lc)), ui.NewRow( ui.NewCol(3, 0, ls), ui.NewCol(3, 0, gs[0], gs[1], gs[2]), ui.NewCol(6, 0, par))) // calculate layout ui.Body.Align() ui.Render(ui.Body) ui.Handle("/sys/kbd/q", func(ui.Event) { ui.StopLoop() }) ui.Handle("/timer/1s", func(e ui.Event) { t := e.Data.(ui.EvtTimer) i := t.Count if i > 103 { ui.StopLoop() return } for _, g := range gs { g.Percent = (g.Percent + 3) % 100 } sp.Lines[0].Data = spdata[:100+i] lc.Data = sinps[2*i:] ui.Render(ui.Body) }) ui.Handle("/sys/wnd/resize", func(e ui.Event) { ui.Body.Width = ui.TermWidth() ui.Body.Align() ui.Render(ui.Body) }) ui.Loop() }
func (d *Dash) Start() { go d.run() go mock() PL := MAX_WIDTH / d.width err := termui.Init() if err != nil { panic(err) } defer termui.Close() var lists []termui.Bufferer draw := func() { newRow := false row := 0 if d.dashboard { row = 1 // row=0 :view } d.lock.Lock() var hosts []string if len(d.hosts) == 0 { hosts = d.sortHost() } else { hosts = d.hosts } index := 0 for _, h := range hosts { for s := range d.stat[h] { st, ok := d.stat[h][s] if !ok { continue } ls := termui.NewList() ls.Items = st.List() ls.ItemFgColor = termui.ColorYellow ls.BorderLabel = fmt.Sprintf("%s@%s", s, h) ls.Height = d.height ls.Width = d.width ls.X = (index % PL) * d.width if index >= PL && index%PL == 0 { newRow = true } if newRow { row++ } ls.Y = d.height * row newRow = false d.gList = append(d.gList, ls) index++ if index%d.page == 0 && index != 1 { index = 0 row = 0 newRow = false } } } d.lock.Unlock() if len(d.gList) > d.page { lists = d.gList[:d.page] } else { lists = d.gList[:] } } termui.Render(lists...) termui.Handle("/timer/1s", func(e termui.Event) { if len(lists) == 0 { draw() } if d.dashboard { d.drawView() termui.Render(d.view) } else { for index := range lists { ls := lists[index].(*termui.List) dd := strings.Split(ls.BorderLabel, "@") sv, pc := dd[0], dd[1] d.lock.RLock() ls.Items = d.stat[pc][sv].List() d.lock.RUnlock() lists[index] = ls } termui.Render(lists...) } }) termui.Handle("/sys/kbd/q", func(termui.Event) { termui.StopLoop() }) termui.Handle("/sys/kbd/p", func(termui.Event) { termui.Clear() start := (d.curPage - 1) * d.page if start < 0 { start = 0 } else { d.curPage-- } lists = d.gList[start : start+d.page] d.lock.Lock() for index := range lists { ls := lists[index].(*termui.List) dd := strings.Split(ls.BorderLabel, "@") sv, pc := dd[0], dd[1] ls.Items = d.stat[sv][pc].List() lists[index] = ls } d.lock.Unlock() termui.Render(lists...) }) termui.Handle("/sys/kbd/n", func(termui.Event) { termui.Clear() end := (d.curPage + 1) * d.page if end > len(d.gList) { end = len(d.gList) - 1 } else { d.curPage++ } lists = d.gList[end-d.page : end] d.lock.Lock() for index := range lists { ls := lists[index].(*termui.List) dd := strings.Split(ls.BorderLabel, "@") sv, pc := dd[0], dd[1] ls.Items = d.stat[sv][pc].List() lists[index] = ls } d.lock.Unlock() termui.Render(lists...) }) termui.Handle("/sys/kbd/a", func(termui.Event) { termui.Clear() d.dashboard = true }) termui.Handle("/sys/kbd/s", func(termui.Event) { termui.Clear() d.dashboard = false }) termui.Loop() }
func main() { err := termui.Init() if err != nil { panic(err) } defer termui.Close() //termui.UseTheme("helloworld") g0 := termui.NewGauge() g0.Percent = 40 g0.Width = 50 g0.Height = 3 g0.BorderLabel = "Slim Gauge" g0.BarColor = termui.ColorRed g0.BorderFg = termui.ColorWhite g0.BorderLabelFg = termui.ColorCyan gg := termui.NewBlock() gg.Width = 50 gg.Height = 5 gg.Y = 12 gg.BorderLabel = "TEST" gg.Align() g2 := termui.NewGauge() g2.Percent = 60 g2.Width = 50 g2.Height = 3 g2.PercentColor = termui.ColorBlue g2.Y = 3 g2.BorderLabel = "Slim Gauge" g2.BarColor = termui.ColorYellow g2.BorderFg = termui.ColorWhite g1 := termui.NewGauge() g1.Percent = 30 g1.Width = 50 g1.Height = 5 g1.Y = 6 g1.BorderLabel = "Big Gauge" g1.PercentColor = termui.ColorYellow g1.BarColor = termui.ColorGreen g1.BorderFg = termui.ColorWhite g1.BorderLabelFg = termui.ColorMagenta g3 := termui.NewGauge() g3.Percent = 50 g3.Width = 50 g3.Height = 3 g3.Y = 11 g3.BorderLabel = "Gauge with custom label" g3.Label = "{{percent}}% (100MBs free)" g3.LabelAlign = termui.AlignRight g4 := termui.NewGauge() g4.Percent = 50 g4.Width = 50 g4.Height = 3 g4.Y = 14 g4.BorderLabel = "Gauge" g4.Label = "Gauge with custom highlighted label" g4.PercentColor = termui.ColorYellow g4.BarColor = termui.ColorGreen g4.PercentColorHighlighted = termui.ColorBlack termui.Render(g0, g1, g2, g3, g4) termui.Handle("/sys/kbd/q", func(termui.Event) { termui.StopLoop() }) termui.Loop() }
func RenderPipeline(executionId string) { if err := ui.Init(); err != nil { panic(err) } defer ui.Close() ui.Merge("timer", ui.NewTimerCh(time.Second*5)) ui.Body.AddRows( ui.NewRow( ui.NewCol(12, 0, instructions), ), ui.NewRow( ui.NewCol(12, 0, info), ), ui.NewRow( ui.NewCol(5, 0, stages), ui.NewCol(7, 0, exception), ), ) ui.Body.Align() draw := func(exe *Execution) { if exe != nil { drawInstructions() drawInfo(exe) drawStages(exe) ui.Body.Align() } ui.Render(ui.Body) } fetchAndDraw := func() { execution, _ = client.GetExecutionById(executionId) if orcaDetails == nil { debug.Log("fetching orca details\n") searchResults, _ := client.InstanceSearch(execution.ExecutingInstance) if len(searchResults) > 0 && len(searchResults[0].Results) > 0 { result := searchResults[0].Results[0] orcaDetails, _ = client.GetInstanceDetails(result) } } autoscalingUrls := execution.getScalingActivitiesUrls() ch := make(chan []AutoScalingActivity, len(autoscalingUrls)) client.GetAutoScalingActivity(autoscalingUrls, ch) activity := <-ch autoScalingActivities = append(autoScalingActivities, (activity)...) draw(execution) } fetchAndDraw() ui.Handle("/timer/5s", func(e ui.Event) { fetchAndDraw() }) ui.Handle("/sys/wnd/resize", func(e ui.Event) { ui.Body.Width = ui.TermWidth() ui.Body.Align() ui.Render(ui.Body) }) ui.Handle("/sys/kbd/f", func(e ui.Event) { showSucceeded = !showSucceeded fetchAndDraw() }) ui.Handle("/sys/kbd/q", func(e ui.Event) { ui.StopLoop() }) ui.Handle("/sys/kbd/l", func(e ui.Event) { if orcaDetails != nil { tomcatLogUrl := fmt.Sprintf("http://%s:7001/AdminLogs/list?view=tomcat/catalina.out", orcaDetails.PrivateIpAddress) debug.Log(orcaDetails.PrivateIpAddress) cmd := exec.Command("open", tomcatLogUrl) go cmd.Start() } }) ui.Handle("/sys/kbd/s", func(e ui.Event) { sourceUrl := fmt.Sprintf("http://spinnaker-api.prod.netflix.net/pipelines/%s", executionId) cmd := exec.Command("open", sourceUrl) go cmd.Start() }) ui.Handle("/sys/kbd/p", func(e ui.Event) { pipelineUrl := fmt.Sprintf("http://spinnaker.prod.netflix.net/#/applications/%s/executions/%s", execution.Application, execution.Id) cmd := exec.Command("open", pipelineUrl) go cmd.Start() }) ui.Handle("/sys/kbd/c", func(e ui.Event) { pipelineUrl := fmt.Sprintf("http://spinnaker.prod.netflix.net/#/applications/%s/executions/configure/%s", execution.Application, execution.PipelineConfigId) cmd := exec.Command("open", pipelineUrl) go cmd.Start() }) ui.Loop() }
func Run() { var err error logging.SetLevel(logging.NOTICE, "") usage := func(ok bool) { printer := fmt.Printf if !ok { printer = func(format string, args ...interface{}) (int, error) { return fmt.Fprintf(os.Stderr, format, args...) } defer func() { os.Exit(1) }() } else { defer func() { os.Exit(0) }() } output := fmt.Sprintf(` Usage: jira-ui ls <Query Options> jira-ui ISSUE jira-ui General Options: -e --endpoint=URI URI to use for jira -h --help Show this usage -u --user=USER Username to use for authenticaion -v --verbose Increase output logging --skiplogin Skip the login check. You must have a valid session token (eg via 'jira login') --version Print version Ticket View Options: -t --template=FILE Template file to use for viewing tickets -m --max_wrap=VAL Maximum word-wrap width when viewing ticket text (0 disables) Query Options: -q --query=JQL Jira Query Language expression for the search -f --queryfields=FIELDS Fields that are used in "list" view `) printer(output) } jiraCommands := map[string]string{ "list": "list", "ls": "list", "password": "******", "passwd": "password", } cliOpts = make(map[string]interface{}) setopt := func(name string, value interface{}) { cliOpts[name] = value } op := optigo.NewDirectAssignParser(map[string]interface{}{ "h|help": usage, "version": func() { fmt.Println(fmt.Sprintf("version: %s", VERSION)) os.Exit(0) }, "v|verbose+": func() { logging.SetLevel(logging.GetLevel("")+1, "") }, "u|user=s": setopt, "endpoint=s": setopt, "q|query=s": setopt, "f|queryfields=s": setopt, "t|template=s": setopt, "m|max_wrap=i": setopt, "skip_login": setopt, }) if err := op.ProcessAll(os.Args[1:]); err != nil { log.Error("%s", err) usage(false) } args := op.Args var command string if len(args) > 0 { if alias, ok := jiraCommands[args[0]]; ok { command = alias args = args[1:] } else { command = "view" args = args[0:] } } else { command = "toplevel" } requireArgs := func(count int) { if len(args) < count { log.Error("Not enough arguments. %d required, %d provided", count, len(args)) usage(false) } } if val, ok := cliOpts["skip_login"]; !ok || !val.(bool) { err = ensureLoggedIntoJira() if err != nil { log.Error("Login failed. Aborting") os.Exit(2) } } err = ui.Init() if err != nil { panic(err) } defer ui.Close() registerKeyboardHandlers() ticketQueryPage = new(QueryPage) passwordInputBox = new(PasswordInputBox) helpPage = new(HelpPage) commandBar = new(CommandBar) switch command { case "list": ticketListPage = new(TicketListPage) if query := cliOpts["query"]; query == nil { log.Error("Must supply a --query option to %q", command) os.Exit(1) } else { ticketListPage.ActiveQuery.JQL = query.(string) ticketListPage.ActiveQuery.Name = "adhoc" currentPage = ticketListPage } case "view": requireArgs(1) p := new(TicketShowPage) p.TicketId = args[0] currentPage = p case "toplevel": currentPage = ticketQueryPage case "password": currentPage = passwordInputBox default: log.Error("Unknown command %s", command) os.Exit(1) } for exitNow != true { currentPage.Create() ui.Loop() } }