diff options
Diffstat (limited to 'vendor/github.com/jesseduffield/gocui/view.go')
-rw-r--r-- | vendor/github.com/jesseduffield/gocui/view.go | 88 |
1 files changed, 61 insertions, 27 deletions
diff --git a/vendor/github.com/jesseduffield/gocui/view.go b/vendor/github.com/jesseduffield/gocui/view.go index 462cb474e..0dd897aa4 100644 --- a/vendor/github.com/jesseduffield/gocui/view.go +++ b/vendor/github.com/jesseduffield/gocui/view.go @@ -10,6 +10,7 @@ import ( "io" "strings" + "github.com/mattn/go-runewidth" "github.com/nsf/termbox-go" ) @@ -312,24 +313,14 @@ func (v *View) draw() error { if v.tainted { v.viewLines = nil for i, line := range v.lines { + wrap := 0 if v.Wrap { - if len(line) < maxX { - vline := viewLine{linesX: 0, linesY: i, line: line} - v.viewLines = append(v.viewLines, vline) - continue - } else { - for n := 0; n <= len(line); n += maxX { - if len(line[n:]) <= maxX { - vline := viewLine{linesX: n, linesY: i, line: line[n:]} - v.viewLines = append(v.viewLines, vline) - } else { - vline := viewLine{linesX: n, linesY: i, line: line[n : n+maxX]} - v.viewLines = append(v.viewLines, vline) - } - } - } - } else { - vline := viewLine{linesX: 0, linesY: i, line: line} + wrap = maxX + } + + ls := lineWrap(line, wrap) + for j := range ls { + vline := viewLine{linesX: j, linesY: i, line: ls[j]} v.viewLines = append(v.viewLines, vline) } } @@ -368,7 +359,7 @@ func (v *View) draw() error { if err := v.setRune(x, y, c.chr, fgColor, bgColor); err != nil { return err } - x++ + x += runewidth.RuneWidth(c.chr) } y++ } @@ -438,11 +429,7 @@ func (v *View) BufferLines() []string { // Buffer returns a string with the contents of the view's internal // buffer. func (v *View) Buffer() string { - str := "" - for _, l := range v.lines { - str += lineType(l).String() + "\n" - } - return strings.Replace(str, "\x00", " ", -1) + return linesToString(v.lines) } // ViewBufferLines returns the lines in the view's internal @@ -460,11 +447,12 @@ func (v *View) ViewBufferLines() []string { // ViewBuffer returns a string with the contents of the view's buffer that is // shown to the user. func (v *View) ViewBuffer() string { - str := "" - for _, l := range v.viewLines { - str += lineType(l.line).String() + "\n" + lines := make([][]cell, len(v.viewLines)) + for i := range v.viewLines { + lines[i] = v.viewLines[i].line } - return strings.Replace(str, "\x00", " ", -1) + + return linesToString(lines) } // Line returns a string with the line of the view's internal buffer @@ -516,3 +504,49 @@ func (v *View) Word(x, y int) (string, error) { func indexFunc(r rune) bool { return r == ' ' || r == 0 } + +func lineWidth(line []cell) (n int) { + for i := range line { + n += runewidth.RuneWidth(line[i].chr) + } + + return +} + +func lineWrap(line []cell, columns int) [][]cell { + if columns == 0 { + return [][]cell{line} + } + + var n int + var offset int + lines := make([][]cell, 0, 1) + for i := range line { + rw := runewidth.RuneWidth(line[i].chr) + n += rw + if n > columns { + n = rw + lines = append(lines, line[offset:i-1]) + offset = i + } + } + + lines = append(lines, line[offset:]) + return lines +} + +func linesToString(lines [][]cell) string { + str := make([]string, len(lines)) + for i := range lines { + rns := make([]rune, 0, len(lines[i])) + line := lineType(lines[i]).String() + for _, c := range line { + if c != '\x00' { + rns = append(rns, c) + } + } + str[i] = string(rns) + } + + return strings.Join(str, "\n") +} |