diff options
Diffstat (limited to 'vendor/github.com/jesseduffield')
-rw-r--r-- | vendor/github.com/jesseduffield/gocui/gui.go | 172 | ||||
-rw-r--r-- | vendor/github.com/jesseduffield/gocui/tcell_driver.go | 17 | ||||
-rw-r--r-- | vendor/github.com/jesseduffield/gocui/view.go | 69 |
3 files changed, 158 insertions, 100 deletions
diff --git a/vendor/github.com/jesseduffield/gocui/gui.go b/vendor/github.com/jesseduffield/gocui/gui.go index 3bc701299..c2306c194 100644 --- a/vendor/github.com/jesseduffield/gocui/gui.go +++ b/vendor/github.com/jesseduffield/gocui/gui.go @@ -6,7 +6,6 @@ package gocui import ( standardErrors "errors" - "fmt" "log" "runtime" "strings" @@ -76,6 +75,8 @@ type GuiMutexes struct { tickingMutex sync.Mutex ViewsMutex sync.Mutex + + drawMutex sync.Mutex } type PlayMode int @@ -166,14 +167,14 @@ type Gui struct { } // NewGui returns a new Gui object with a given output mode. -func NewGui(mode OutputMode, supportOverlaps bool, playMode PlayMode, headless bool) (*Gui, error) { +func NewGui(mode OutputMode, supportOverlaps bool, playMode PlayMode, headless bool, runeReplacements map[rune]string) (*Gui, error) { g := &Gui{} var err error if headless { err = g.tcellInitSimulation() } else { - err = g.tcellInit() + err = g.tcellInit(runeReplacements) } if err != nil { return nil, err @@ -664,79 +665,6 @@ func (g *Gui) onResize() { // g.screen.Sync() } -// flush updates the gui, re-drawing frames and buffers. -func (g *Gui) flush() error { - // pretty sure we don't need this, but keeping it here in case we get weird visual artifacts - // g.clear(g.FgColor, g.BgColor) - - maxX, maxY := Screen.Size() - // if GUI's size has changed, we need to redraw all views - if maxX != g.maxX || maxY != g.maxY { - for _, v := range g.views { - v.clearViewLines() - } - } - g.maxX, g.maxY = maxX, maxY - - for _, m := range g.managers { - if err := m.Layout(g); err != nil { - return err - } - } - for _, v := range g.views { - if !v.Visible || v.y1 < v.y0 { - continue - } - if v.Frame { - var fgColor, bgColor, frameColor Attribute - if g.Highlight && v == g.currentView { - fgColor = g.SelFgColor - bgColor = g.SelBgColor - frameColor = g.SelFrameColor - } else { - bgColor = g.BgColor - if v.TitleColor != ColorDefault { - fgColor = v.TitleColor - } else { - fgColor = g.FgColor - } - if v.FrameColor != ColorDefault { - frameColor = v.FrameColor - } else { - frameColor = g.FrameColor - } - } - - if err := g.drawFrameEdges(v, frameColor, bgColor); err != nil { - return err - } - if err := g.drawFrameCorners(v, frameColor, bgColor); err != nil { - return err - } - if v.Title != "" || len(v.Tabs) > 0 { - if err := g.drawTitle(v, fgColor, bgColor); err != nil { - return err - } - } - if v.Subtitle != "" { - if err := g.drawSubtitle(v, fgColor, bgColor); err != nil { - return err - } - } - if v.ContainsList && g.ShowListFooter { - if err := g.drawListFooter(v, fgColor, bgColor); err != nil { - return err - } - } - } - if err := g.draw(v); err != nil { - return err - } - } - Screen.Show() - return nil -} - func (g *Gui) clear(fg, bg Attribute) (int, int) { st := getTcellStyle(oldStyle{fg: fg, bg: bg, outputMode: g.outputMode}) w, h := Screen.Size() @@ -983,7 +911,7 @@ func (g *Gui) drawListFooter(v *View, fgColor, bgColor Attribute) error { return nil } - message := fmt.Sprintf("%d of %d", v.cy+v.oy+1, len(v.lines)) + message := v.Footer if v.y1 < 0 || v.y1 >= g.maxY { return nil @@ -1006,12 +934,102 @@ func (g *Gui) drawListFooter(v *View, fgColor, bgColor Attribute) error { return nil } +// flush updates the gui, re-drawing frames and buffers. +func (g *Gui) flush() error { + g.Mutexes.drawMutex.Lock() + defer g.Mutexes.drawMutex.Unlock() + + // pretty sure we don't need this, but keeping it here in case we get weird visual artifacts + // g.clear(g.FgColor, g.BgColor) + + maxX, maxY := Screen.Size() + // if GUI's size has changed, we need to redraw all views + if maxX != g.maxX || maxY != g.maxY { + for _, v := range g.views { + v.clearViewLines() + } + } + g.maxX, g.maxY = maxX, maxY + + for _, m := range g.managers { + if err := m.Layout(g); err != nil { + return err + } + } + for _, v := range g.views { + if err := g.draw(v); err != nil { + return err + } + } + + Screen.Show() + return nil +} + +func (g *Gui) Draw(v *View) error { + g.Mutexes.drawMutex.Lock() + defer g.Mutexes.drawMutex.Unlock() + + if err := g.draw(v); err != nil { + return err + } + + Screen.Show() + return nil +} + // draw manages the cursor and calls the draw function of a view. func (g *Gui) draw(v *View) error { if g.suspended { return nil } + if !v.Visible || v.y1 < v.y0 { + return nil + } + if v.Frame { + var fgColor, bgColor, frameColor Attribute + if g.Highlight && v == g.currentView { + fgColor = g.SelFgColor + bgColor = g.SelBgColor + frameColor = g.SelFrameColor + } else { + bgColor = g.BgColor + if v.TitleColor != ColorDefault { + fgColor = v.TitleColor + } else { + fgColor = g.FgColor + } + if v.FrameColor != ColorDefault { + frameColor = v.FrameColor + } else { + frameColor = g.FrameColor + } + } + + if err := g.drawFrameEdges(v, frameColor, bgColor); err != nil { + return err + } + if err := g.drawFrameCorners(v, frameColor, bgColor); err != nil { + return err + } + if v.Title != "" || len(v.Tabs) > 0 { + if err := g.drawTitle(v, fgColor, bgColor); err != nil { + return err + } + } + if v.Subtitle != "" { + if err := g.drawSubtitle(v, fgColor, bgColor); err != nil { + return err + } + } + if v.Footer != "" && g.ShowListFooter { + if err := g.drawListFooter(v, fgColor, bgColor); err != nil { + return err + } + } + } + if g.Cursor { if curview := g.currentView; curview != nil { vMaxX, vMaxY := curview.Size() diff --git a/vendor/github.com/jesseduffield/gocui/tcell_driver.go b/vendor/github.com/jesseduffield/gocui/tcell_driver.go index 2783103c3..c5555e30d 100644 --- a/vendor/github.com/jesseduffield/gocui/tcell_driver.go +++ b/vendor/github.com/jesseduffield/gocui/tcell_driver.go @@ -26,6 +26,10 @@ var runeReplacements = map[rune]string{ '┐': "+", '└': "+", '┘': "+", + '╭': "+", + '╮': "+", + '╰': "+", + '╯': "+", '─': "-", // using a hyphen here actually looks weird. @@ -33,6 +37,9 @@ var runeReplacements = map[rune]string{ '╶': " ", '╴': " ", + '┴': "+", + '┬': "+", + '╷': "|", '├': "+", '│': "|", '▼': "v", @@ -42,7 +49,7 @@ var runeReplacements = map[rune]string{ } // tcellInit initializes tcell screen for use. -func (g *Gui) tcellInit() error { +func (g *Gui) tcellInit(runeReplacements map[rune]string) error { runewidth.DefaultCondition.EastAsianWidth = false tcell.SetEncodingFallback(tcell.EncodingFallbackASCII) @@ -51,7 +58,7 @@ func (g *Gui) tcellInit() error { } else if e = s.Init(); e != nil { return e } else { - registerRuneFallbacks(s) + registerRuneFallbacks(s, runeReplacements) g.screen = s Screen = s @@ -59,10 +66,14 @@ func (g *Gui) tcellInit() error { } } -func registerRuneFallbacks(s tcell.Screen) { +func registerRuneFallbacks(s tcell.Screen, additional map[rune]string) { for before, after := range runeReplacements { s.RegisterRuneFallback(before, after) } + + for before, after := range additional { + s.RegisterRuneFallback(before, after) + } } // tcellInitSimulation initializes tcell screen for use. diff --git a/vendor/github.com/jesseduffield/gocui/view.go b/vendor/github.com/jesseduffield/gocui/view.go index 0ebd6e4a2..df9b910f2 100644 --- a/vendor/github.com/jesseduffield/gocui/view.go +++ b/vendor/github.com/jesseduffield/gocui/view.go @@ -153,14 +153,14 @@ type View struct { searcher *searcher - // when ContainsList is true, we show the current index and total count in the view - ContainsList bool - // KeybindOnEdit should be set to true when you want to execute keybindings even when the view is editable // (this is usually not the case) KeybindOnEdit bool TextArea *TextArea + + // something like '1 of 20' for a list view + Footer string } // call this in the event of a view resize, or if you want to render new content @@ -372,11 +372,21 @@ func (v *View) Height() int { // if a view has a frame, that leaves less space for its writeable area func (v *View) InnerWidth() int { - return v.Width() - v.frameOffset() + innerWidth := v.Width() - v.frameOffset() + if innerWidth < 0 { + return 0 + } + + return innerWidth } func (v *View) InnerHeight() int { - return v.Height() - v.frameOffset() + innerHeight := v.Height() - v.frameOffset() + if innerHeight < 0 { + return 0 + } + + return innerHeight } func (v *View) frameOffset() int { @@ -563,8 +573,6 @@ func (v *View) Write(p []byte) (n int, err error) { v.writeMutex.Lock() defer v.writeMutex.Unlock() - v.tainted = true - v.makeWriteable(v.wx, v.wy) v.writeRunes(bytes.Runes(p)) return len(p), nil @@ -574,20 +582,16 @@ func (v *View) WriteRunes(p []rune) { v.writeMutex.Lock() defer v.writeMutex.Unlock() - v.tainted = true - - // Fill with empty cells, if writing outside current view buffer - v.makeWriteable(v.wx, v.wy) v.writeRunes(p) } -func (v *View) WriteString(s string) { - v.WriteRunes([]rune(s)) -} - // writeRunes copies slice of runes into internal lines buffer. -// caller must make sure that writing position is accessable. func (v *View) writeRunes(p []rune) { + v.tainted = true + + // Fill with empty cells, if writing outside current view buffer + v.makeWriteable(v.wx, v.wy) + for _, r := range p { switch r { case '\n': @@ -613,6 +617,16 @@ func (v *View) writeRunes(p []rune) { } } +// exported functions use the mutex. Non-exported functions are for internal use +// and a calling function should use a mutex +func (v *View) WriteString(s string) { + v.WriteRunes([]rune(s)) +} + +func (v *View) writeString(s string) { + v.writeRunes([]rune(s)) +} + // parseInput parses char by char the input written to the View. It returns nil // while processing ESC sequences. Otherwise, it returns a cell slice that // contains the processed data. @@ -696,16 +710,28 @@ func (v *View) Read(p []byte) (n int, err error) { return offset, io.EOF } +// only use this if the calling function has a lock on writeMutex +func (v *View) clear() { + v.rewind() + v.lines = nil + v.clearViewLines() +} + // Clear empties the view's internal buffer. // And resets reading and writing offsets. func (v *View) Clear() { v.writeMutex.Lock() defer v.writeMutex.Unlock() - v.rewind() - v.lines = nil - v.clearViewLines() - v.clearRunes() + v.clear() +} + +func (v *View) SetContent(str string) { + v.writeMutex.Lock() + defer v.writeMutex.Unlock() + + v.clear() + v.writeString(str) } // Rewind sets read and write pos to (0, 0). @@ -802,6 +828,9 @@ func (v *View) IsTainted() bool { // draw re-draws the view's contents. func (v *View) draw() error { + v.writeMutex.Lock() + defer v.writeMutex.Unlock() + v.clearRunes() if !v.Visible { |