mirror of https://github.com/chzyer/readline.git
fix runebuffer refresh
This commit is contained in:
parent
e878807b59
commit
9c65cb7ccf
|
@ -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))
|
||||
}
|
||||
|
|
19
history.go
19
history.go
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
43
runebuf.go
43
runebuf.go
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue