Skip to content

Commit

Permalink
Merge pull request #42 from chzyer/bugfix/use_single_again
Browse files Browse the repository at this point in the history
Fix breaking scroll buffer
  • Loading branch information
chzyer committed Mar 31, 2016
2 parents 30b462e + 1965712 commit 91ba4d4
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 81 deletions.
64 changes: 20 additions & 44 deletions runebuf.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package readline
import (
"bufio"
"bytes"
"fmt"
"io"
"strings"

Expand Down Expand Up @@ -31,17 +30,7 @@ type RuneBuffer struct {
}

func (r *RuneBuffer) OnWidthChange(newWidth int) {
oldWidth := r.width
if newWidth < oldWidth {
sp := SplitByMultiLine(
r.PromptLen(), oldWidth, newWidth, r.buf[:r.idx])
idxLine := len(sp) - 1
r.clean(idxLine)
} else {
r.Clean()
}
r.width = newWidth
r.print()
}

func (r *RuneBuffer) Backup() {
Expand Down Expand Up @@ -348,8 +337,20 @@ func (r *RuneBuffer) MoveTo(ch rune, prevChar, reverse bool) (success bool) {
return
}

func (r *RuneBuffer) isInLineEdge() bool {
if isWindows {
return false
}
sp := r.getSplitByLine(r.buf)
return len(sp[len(sp)-1]) == 0
}

func (r *RuneBuffer) getSplitByLine(rs []rune) []string {
return SplitByLine(r.PromptLen(), r.width, rs)
}

func (r *RuneBuffer) IdxLine(width int) int {
sp := SplitByLine(r.PromptLen(), width, r.buf[:r.idx])
sp := r.getSplitByLine(r.buf[:r.idx])
return len(sp) - 1
}

Expand Down Expand Up @@ -391,40 +392,15 @@ func (r *RuneBuffer) output() []byte {
}

} else {
sp := SplitByLine(r.PromptLen(), r.width, r.buf)
written := 0
idxInLine := 0
for idx, s := range sp {
buf.Write([]byte(s))
if r.idx > written && r.idx < written+len(s) {
idxInLine = r.idx - written
}
written += len(s)

if idx < len(sp)-1 && !isWindows {
buf.Write([]byte{'\n'})
}
}
if len(r.buf) > r.idx {
targetLine := r.IdxLine(r.width)
currentLine := len(sp) - 1
// assert currentLine >= targetLine
if targetLine == 0 {
idxInLine += r.PromptLen()
}
buf.WriteString("\r")
if currentLine > targetLine {
buf.WriteString(fmt.Sprintf(
"\033[%vA", currentLine-targetLine,
))
}
if idxInLine > 0 {
buf.WriteString(fmt.Sprintf(
"\033[%vC", idxInLine,
))
}
buf.Write([]byte(string(r.buf)))
if r.isInLineEdge() {
buf.Write([]byte(" \b"))
}
}

if len(r.buf) > r.idx {
buf.Write(runes.Backspace(r.buf[r.idx:]))
}
return buf.Bytes()
}

Expand Down
23 changes: 0 additions & 23 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,29 +86,6 @@ func escapeKey(r rune) rune {
return r
}

func SplitByMultiLine(start, oldWidth, newWidth int, rs []rune) []string {
var ret []string
buf := bytes.NewBuffer(nil)
currentWidth := start
for _, r := range rs {
w := runes.Width(r)
currentWidth += w
buf.WriteRune(r)
if currentWidth == newWidth {
ret = append(ret, buf.String())
buf.Reset()
continue
}
if currentWidth >= oldWidth {
ret = append(ret, buf.String())
buf.Reset()
currentWidth = 0
}
}
ret = append(ret, buf.String())
return ret
}

func SplitByLine(start, screenWidth int, rs []rune) []string {
var ret []string
buf := bytes.NewBuffer(nil)
Expand Down
14 changes: 0 additions & 14 deletions utils_test.go
Original file line number Diff line number Diff line change
@@ -1,15 +1 @@
package readline

import (
"reflect"
"testing"
)

func TestSplitByMultiLine(t *testing.T) {
rs := []rune("hello!bye!!!!")
expected := []string{"hell", "o!", "bye!", "!!", "!"}
ret := SplitByMultiLine(0, 6, 4, rs)
if !reflect.DeepEqual(ret, expected) {
t.Fatal(ret, expected)
}
}

0 comments on commit 91ba4d4

Please sign in to comment.