Merge pull request #108 from HotelsDotCom/master

line wrapping in log view, closes #106
This commit is contained in:
bradley 2017-12-01 21:47:05 -05:00 committed by GitHub
commit 75f4a91f11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 88 additions and 40 deletions

View File

@ -1,8 +1,6 @@
package widgets package widgets
import ( import (
"fmt"
ui "github.com/gizak/termui" ui "github.com/gizak/termui"
) )
@ -18,7 +16,7 @@ type TextView struct {
} }
func NewTextView(lines <-chan string) *TextView { func NewTextView(lines <-chan string) *TextView {
i := &TextView{ t := &TextView{
Block: *ui.NewBlock(), Block: *ui.NewBlock(),
inputStream: lines, inputStream: lines,
render: make(chan bool), render: make(chan bool),
@ -29,68 +27,83 @@ func NewTextView(lines <-chan string) *TextView {
padding: Padding{4, 2}, padding: Padding{4, 2},
} }
i.BorderFg = ui.ThemeAttr("menu.border.fg") t.BorderFg = ui.ThemeAttr("menu.border.fg")
i.BorderLabelFg = ui.ThemeAttr("menu.label.fg") t.BorderLabelFg = ui.ThemeAttr("menu.label.fg")
t.Height = ui.TermHeight()
t.Width = ui.TermWidth()
i.Resize() t.readInputLoop()
t.renderLoop()
i.readInputLoop() return t
i.renderLoop()
return i
} }
func (i *TextView) Resize() { func (t *TextView) Resize() {
ui.Clear() ui.Clear()
i.Height = ui.TermHeight() t.Height = ui.TermHeight()
i.Width = ui.TermWidth() t.Width = ui.TermWidth()
t.render <- true
} }
func (i *TextView) Buffer() ui.Buffer { func (t *TextView) Buffer() ui.Buffer {
var cell ui.Cell var cell ui.Cell
buf := i.Block.Buffer() buf := t.Block.Buffer()
x := i.Block.X + i.padding[0] x := t.Block.X + t.padding[0]
y := i.Block.Y + i.padding[1] y := t.Block.Y + t.padding[1]
maxWidth := i.Width - (i.padding[0] * 2) for _, line := range t.TextOut {
for _, line := range i.TextOut {
// truncate lines longer than maxWidth
if len(line) > maxWidth {
line = fmt.Sprintf("%s...", line[:maxWidth-3])
}
for _, ch := range line { for _, ch := range line {
cell = ui.Cell{Ch: ch, Fg: i.TextFgColor, Bg: i.TextBgColor} cell = ui.Cell{Ch: ch, Fg: t.TextFgColor, Bg: t.TextBgColor}
buf.Set(x, y, cell) buf.Set(x, y, cell)
x++ x++
} }
x = i.Block.X + i.padding[0] x = t.Block.X + t.padding[0]
y++ y++
} }
return buf return buf
} }
func (i *TextView) renderLoop() { func (t *TextView) renderLoop() {
go func() { go func() {
for range i.render { for range t.render {
size := i.Height - (i.padding[1] * 2) maxWidth := t.Width - (t.padding[0] * 2)
if size > len(i.Text) { height := t.Height - (t.padding[1] * 2)
size = len(i.Text) t.TextOut = []string{}
for i := len(t.Text) - 1; i >= 0; i-- {
lines := splitLine(t.Text[i], maxWidth)
t.TextOut = append(lines, t.TextOut...)
if len(t.TextOut) > height {
t.TextOut = t.TextOut[:height]
break
}
} }
i.TextOut = i.Text[len(i.Text)-size:] ui.Render(t)
ui.Render(i)
} }
}() }()
} }
func (i *TextView) readInputLoop() { func (t *TextView) readInputLoop() {
go func() { go func() {
for line := range i.inputStream { for line := range t.inputStream {
i.Text = append(i.Text, line) t.Text = append(t.Text, line)
i.render <- true t.render <- true
} }
close(i.render) close(t.render)
}() }()
} }
func splitLine(line string, lineSize int) []string {
if line == "" {
return []string{}
}
var lines []string
for {
if len(line) <= lineSize {
lines = append(lines, line)
return lines
}
lines = append(lines, line[:lineSize])
line = line[lineSize:]
}
}

35
widgets/view_test.go Normal file
View File

@ -0,0 +1,35 @@
package widgets
import "testing"
func TestSplitEmptyLine(t *testing.T) {
result := splitLine("", 5)
if len(result) != 0 {
t.Errorf("expected: 0 lines, got: %d", len(result))
}
}
func TestSplitLineShorterThanLimit(t *testing.T) {
result := splitLine("hello", 7)
if len(result) != 1 {
t.Errorf("expected: 0 lines, got: %d", len(result))
}
}
func TestSplitLineLongerThanLimit(t *testing.T) {
result := splitLine("hello", 3)
if len(result) != 2 {
t.Errorf("expected: 0 lines, got: %d", len(result))
}
}
func TestSplitLineSameAsLimit(t *testing.T) {
result := splitLine("hello", 5)
if len(result) != 1 {
t.Errorf("expected: 0 lines, got: %d", len(result))
}
}