1// Copyright 2014 The gocui Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package main 6 7import ( 8 "fmt" 9 "io" 10 "io/ioutil" 11 "log" 12 "strings" 13 14 "github.com/jroimartin/gocui" 15) 16 17func nextView(g *gocui.Gui, v *gocui.View) error { 18 if v == nil || v.Name() == "side" { 19 return g.SetCurrentView("main") 20 } 21 return g.SetCurrentView("side") 22} 23 24func cursorDown(g *gocui.Gui, v *gocui.View) error { 25 if v != nil { 26 cx, cy := v.Cursor() 27 if err := v.SetCursor(cx, cy+1); err != nil { 28 ox, oy := v.Origin() 29 if err := v.SetOrigin(ox, oy+1); err != nil { 30 return err 31 } 32 } 33 } 34 return nil 35} 36 37func cursorUp(g *gocui.Gui, v *gocui.View) error { 38 if v != nil { 39 ox, oy := v.Origin() 40 cx, cy := v.Cursor() 41 if err := v.SetCursor(cx, cy-1); err != nil && oy > 0 { 42 if err := v.SetOrigin(ox, oy-1); err != nil { 43 return err 44 } 45 } 46 } 47 return nil 48} 49 50func getLine(g *gocui.Gui, v *gocui.View) error { 51 var l string 52 var err error 53 54 _, cy := v.Cursor() 55 if l, err = v.Line(cy); err != nil { 56 l = "" 57 } 58 59 maxX, maxY := g.Size() 60 if v, err := g.SetView("msg", maxX/2-30, maxY/2, maxX/2+30, maxY/2+2); err != nil { 61 if err != gocui.ErrUnknownView { 62 return err 63 } 64 fmt.Fprintln(v, l) 65 if err := g.SetCurrentView("msg"); err != nil { 66 return err 67 } 68 } 69 return nil 70} 71 72func delMsg(g *gocui.Gui, v *gocui.View) error { 73 if err := g.DeleteView("msg"); err != nil { 74 return err 75 } 76 if err := g.SetCurrentView("side"); err != nil { 77 return err 78 } 79 return nil 80} 81 82func quit(g *gocui.Gui, v *gocui.View) error { 83 return gocui.ErrQuit 84} 85 86func keybindings(g *gocui.Gui) error { 87 if err := g.SetKeybinding("side", gocui.KeyCtrlSpace, gocui.ModNone, nextView); err != nil { 88 return err 89 } 90 if err := g.SetKeybinding("main", gocui.KeyCtrlSpace, gocui.ModNone, nextView); err != nil { 91 return err 92 } 93 if err := g.SetKeybinding("side", gocui.KeyArrowDown, gocui.ModNone, cursorDown); err != nil { 94 return err 95 } 96 if err := g.SetKeybinding("side", gocui.KeyArrowUp, gocui.ModNone, cursorUp); err != nil { 97 return err 98 } 99 if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { 100 return err 101 } 102 if err := g.SetKeybinding("side", gocui.KeyEnter, gocui.ModNone, getLine); err != nil { 103 return err 104 } 105 if err := g.SetKeybinding("msg", gocui.KeyEnter, gocui.ModNone, delMsg); err != nil { 106 return err 107 } 108 109 if err := g.SetKeybinding("main", gocui.KeyCtrlS, gocui.ModNone, saveMain); err != nil { 110 return err 111 } 112 if err := g.SetKeybinding("main", gocui.KeyCtrlW, gocui.ModNone, saveVisualMain); err != nil { 113 return err 114 } 115 return nil 116} 117 118func saveMain(g *gocui.Gui, v *gocui.View) error { 119 f, err := ioutil.TempFile("", "gocui_demo_") 120 if err != nil { 121 return err 122 } 123 defer f.Close() 124 125 p := make([]byte, 5) 126 v.Rewind() 127 for { 128 n, err := v.Read(p) 129 if n > 0 { 130 if _, err := f.Write(p[:n]); err != nil { 131 return err 132 } 133 } 134 if err == io.EOF { 135 break 136 } 137 if err != nil { 138 return err 139 } 140 } 141 return nil 142} 143 144func saveVisualMain(g *gocui.Gui, v *gocui.View) error { 145 f, err := ioutil.TempFile("", "gocui_demo_") 146 if err != nil { 147 return err 148 } 149 defer f.Close() 150 151 vb := v.ViewBuffer() 152 if _, err := io.Copy(f, strings.NewReader(vb)); err != nil { 153 return err 154 } 155 return nil 156} 157 158func layout(g *gocui.Gui) error { 159 maxX, maxY := g.Size() 160 if v, err := g.SetView("side", -1, -1, 30, maxY); err != nil { 161 if err != gocui.ErrUnknownView { 162 return err 163 } 164 v.Highlight = true 165 fmt.Fprintln(v, "Item 1") 166 fmt.Fprintln(v, "Item 2") 167 fmt.Fprintln(v, "Item 3") 168 fmt.Fprint(v, "\rWill be") 169 fmt.Fprint(v, "deleted\rItem 4\nItem 5") 170 } 171 if v, err := g.SetView("main", 30, -1, maxX, maxY); err != nil { 172 if err != gocui.ErrUnknownView { 173 return err 174 } 175 b, err := ioutil.ReadFile("Mark.Twain-Tom.Sawyer.txt") 176 if err != nil { 177 panic(err) 178 } 179 fmt.Fprintf(v, "%s", b) 180 v.Editable = true 181 v.Wrap = true 182 if err := g.SetCurrentView("main"); err != nil { 183 return err 184 } 185 } 186 return nil 187} 188 189func main() { 190 g := gocui.NewGui() 191 if err := g.Init(); err != nil { 192 log.Panicln(err) 193 } 194 defer g.Close() 195 196 g.SetLayout(layout) 197 if err := keybindings(g); err != nil { 198 log.Panicln(err) 199 } 200 g.SelBgColor = gocui.ColorGreen 201 g.SelFgColor = gocui.ColorBlack 202 g.Cursor = true 203 204 if err := g.MainLoop(); err != nil && err != gocui.ErrQuit { 205 log.Panicln(err) 206 } 207} 208