fix runebuffer refresh

This commit is contained in:
Cheney 2015-09-21 22:27:40 +08:00
parent e878807b59
commit 9c65cb7ccf
6 changed files with 59 additions and 24 deletions

View File

@ -9,8 +9,15 @@ import (
"github.com/chzyer/readline"
)
func usage(w io.Writer) {
io.WriteString(w, `
sayhello: start to display oneline log per second
bye: quit
`[1:])
}
func main() {
l, err := readline.New("> ")
l, err := readline.New("home -> ")
if err != nil {
panic(err)
}
@ -24,7 +31,7 @@ func main() {
}
switch line {
case "help":
io.WriteString(l.Stderr(), "sayhello: start to display oneline log per second\nbye: quit\n")
usage(l.Stderr())
case "sayhello":
go func() {
for _ = range time.Tick(time.Second) {
@ -33,6 +40,7 @@ func main() {
}()
case "bye":
goto exit
case "":
default:
log.Println("you said:", strconv.Quote(line))
}

View File

@ -47,10 +47,21 @@ func (o *Operation) NextHistory() ([]rune, bool) {
func (o *Operation) NewHistory(current []rune) {
// if just use last command without modify
// just clean lastest history
if o.current == o.history.Back().Prev() {
use := o.current.Value.(*HisItem)
if equalRunes(use.Tmp, use.Source) {
o.current = o.history.Back()
if back := o.history.Back(); back != nil {
prev := back.Prev()
if prev != nil {
use := o.current.Value.(*HisItem)
if equalRunes(use.Tmp, prev.Value.(*HisItem).Source) {
o.current = o.history.Back()
o.current.Value.(*HisItem).Clean()
o.historyVer++
return
}
}
}
if len(current) == 0 {
o.current = o.history.Back()
if o.current != nil {
o.current.Value.(*HisItem).Clean()
o.historyVer++
return

View File

@ -81,7 +81,6 @@ func (l *Operation) ioloop() {
data = data[:len(data)-1] // trim \n
l.outchan <- data
l.NewHistory(data)
debugList(l.history)
case CharBackward:
l.buf.MoveBackward()
case CharForward:

View File

@ -10,15 +10,14 @@ type RuneBuffer struct {
idx int
prompt []byte
w io.Writer
hasPrompt bool
lastWritten int
printPrompt bool
}
func NewRuneBuffer(w io.Writer, prompt string) *RuneBuffer {
rb := &RuneBuffer{
prompt: []byte(prompt),
w: w,
printPrompt: true,
prompt: []byte(prompt),
w: w,
}
return rb
}
@ -161,18 +160,24 @@ func (r *RuneBuffer) MoveToLineEnd() {
}
func (r *RuneBuffer) Refresh(chlen, chidx int) {
s := r.Output(len(r.buf)-chlen, r.idx-chidx)
s := r.Output(len(r.buf)-chlen, r.idx-chidx, true)
r.w.Write(s)
}
func (r *RuneBuffer) RefreshSet(originLength, originIdx int) {
r.w.Write(r.Output(originLength, originIdx))
r.w.Write(r.Output(originLength, originIdx, true))
}
func (r *RuneBuffer) Output(originLength, originIdx int) []byte {
func (r *RuneBuffer) Output(originLength, originIdx int, prompt bool) []byte {
buf := bytes.NewBuffer(nil)
buf.Write(bytes.Repeat([]byte{'\b'}, originIdx+len(r.prompt)))
buf.Write(r.prompt)
buf.Write(bytes.Repeat([]byte{'\b'}, originIdx))
if prompt {
if r.hasPrompt {
buf.Write(bytes.Repeat([]byte{'\b'}, len(r.prompt)))
}
buf.Write(r.prompt)
}
r.hasPrompt = prompt
buf.Write([]byte(string(r.buf)))
if originLength > len(r.buf) {
buf.Write(bytes.Repeat([]byte{' '}, originLength-len(r.buf)))
@ -184,21 +189,29 @@ func (r *RuneBuffer) Output(originLength, originIdx int) []byte {
func (r *RuneBuffer) Clean() {
moveToFirst := r.idx
moveToFirst += len(r.prompt)
if r.hasPrompt {
moveToFirst += len(r.prompt)
}
r.w.Write(bytes.Repeat([]byte{'\b'}, moveToFirst))
length := len(r.buf) + len(r.prompt)
length := len(r.buf)
if r.hasPrompt {
length += len(r.prompt)
}
r.w.Write(bytes.Repeat([]byte{' '}, length))
r.w.Write(bytes.Repeat([]byte{'\b'}, length))
r.printPrompt = true
r.hasPrompt = false
}
func (r *RuneBuffer) ResetScreen() {
r.w.Write(r.Output(0, 0, false))
}
func (r *RuneBuffer) Reset() []rune {
ret := r.buf
r.buf = r.buf[:0]
r.idx = 0
r.printPrompt = true
r.Refresh(-len(ret), r.SetIdx(0))
r.hasPrompt = false
return ret
}

View File

@ -72,7 +72,6 @@ func (t *Terminal) ioloop() {
isEscapeEx := false
for {
r, _, err := buf.ReadRune()
Debug(r, isEscape, isEscapeEx)
if err != nil {
break
}
@ -87,7 +86,6 @@ func (t *Terminal) ioloop() {
} else if isEscapeEx {
isEscapeEx = false
r = escapeExKey(r)
Debug("r:", r)
}
if IsPrintable(r) || r < 0 {

View File

@ -5,6 +5,7 @@ import (
"fmt"
"os"
"syscall"
"time"
"unsafe"
"golang.org/x/crypto/ssh/terminal"
@ -103,3 +104,8 @@ func equalRunes(a, b []rune) bool {
}
return true
}
func sleep(n int) {
Debug(n)
time.Sleep(2000 * time.Millisecond)
}