summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/jesseduffield
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/jesseduffield')
-rw-r--r--vendor/github.com/jesseduffield/gocui/gui.go172
-rw-r--r--vendor/github.com/jesseduffield/gocui/tcell_driver.go17
-rw-r--r--vendor/github.com/jesseduffield/gocui/view.go69
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 {