This commit is contained in:
Cheney 2015-09-27 10:50:14 +08:00
parent 092d0fe477
commit 593678baa5
5 changed files with 47 additions and 45 deletions

View File

@ -65,7 +65,7 @@ func (o *opCompleter) OnComplete() {
buf := o.op.buf buf := o.op.buf
rs := buf.Runes() rs := buf.Runes()
if o.IsInCompleteMode() && EqualRunes(rs, o.candidateSource) { if o.IsInCompleteMode() && RunesEqual(rs, o.candidateSource) {
o.EnterCompleteSelectMode() o.EnterCompleteSelectMode()
o.doSelect() o.doSelect()
return return
@ -87,7 +87,7 @@ func (o *opCompleter) OnComplete() {
return return
} }
same, size := AggRunes(newLines) same, size := RunesAggregate(newLines)
if size > 0 { if size > 0 {
buf.WriteRunes(same) buf.WriteRunes(same)
o.ExitCompleteMode(false) o.ExitCompleteMode(false)

29
debug.go Normal file
View File

@ -0,0 +1,29 @@
package readline
import (
"container/list"
"fmt"
"os"
"time"
)
func sleep(n int) {
Debug(n)
time.Sleep(2000 * time.Millisecond)
}
// print a linked list to Debug()
func debugList(l *list.List) {
idx := 0
for e := l.Front(); e != nil; e = e.Next() {
Debug(idx, fmt.Sprintf("%+v", e.Value))
idx++
}
}
// append log info to another file
func Debug(o ...interface{}) {
f, _ := os.OpenFile("debug.tmp", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
fmt.Fprintln(f, o...)
f.Close()
}

View File

@ -146,7 +146,7 @@ func (o *opHistory) NewHistory(current []rune) {
prev := back.Prev() prev := back.Prev()
if prev != nil { if prev != nil {
use := o.showItem(o.current.Value.(*hisItem)) use := o.showItem(o.current.Value.(*hisItem))
if equalRunes(use, prev.Value.(*hisItem).Source) { if RunesEqual(use, prev.Value.(*hisItem).Source) {
o.current = o.history.Back() o.current = o.history.Back()
o.current.Value.(*hisItem).Clean() o.current.Value.(*hisItem).Clean()
o.historyVer++ o.historyVer++

View File

@ -1,11 +1,7 @@
package readline package readline
import ( import (
"container/list"
"fmt"
"os"
"syscall" "syscall"
"time"
"unicode" "unicode"
"unsafe" "unsafe"
@ -24,6 +20,7 @@ func MakeRaw(fd int) (*terminal.State, error) {
func Restore(fd int, state *terminal.State) error { func Restore(fd int, state *terminal.State) error {
err := terminal.Restore(fd, state) err := terminal.Restore(fd, state)
if err != nil { if err != nil {
// errno 0 means everything is ok :)
if err.Error() == "errno 0" { if err.Error() == "errno 0" {
err = nil err = nil
} }
@ -36,6 +33,7 @@ func IsPrintable(key rune) bool {
return key >= 32 && !isInSurrogateArea return key >= 32 && !isInSurrogateArea
} }
// translate Esc[X
func escapeExKey(r rune) rune { func escapeExKey(r rune) rune {
switch r { switch r {
case 'D': case 'D':
@ -50,6 +48,7 @@ func escapeExKey(r rune) rune {
return r return r
} }
// translate EscX to Meta+X
func escapeKey(r rune) rune { func escapeKey(r rune) rune {
switch r { switch r {
case 'b': case 'b':
@ -68,12 +67,6 @@ func escapeKey(r rune) rune {
return r return r
} }
func Debug(o ...interface{}) {
f, _ := os.OpenFile("debug.tmp", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
fmt.Fprintln(f, o...)
f.Close()
}
type winsize struct { type winsize struct {
Row uint16 Row uint16
Col uint16 Col uint16
@ -81,6 +74,8 @@ type winsize struct {
Ypixel uint16 Ypixel uint16
} }
// get width of the terminal
// we can cache it here and refresh after received signal
func getWidth() int { func getWidth() int {
ws := &winsize{} ws := &winsize{}
retCode, _, errno := syscall.Syscall(syscall.SYS_IOCTL, retCode, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
@ -94,15 +89,7 @@ func getWidth() int {
return int(ws.Col) return int(ws.Col)
} }
func debugList(l *list.List) { func RunesEqual(a, b []rune) bool {
idx := 0
for e := l.Front(); e != nil; e = e.Next() {
Debug(idx, fmt.Sprintf("%+v", e.Value))
idx++
}
}
func equalRunes(a, b []rune) bool {
if len(a) != len(b) { if len(a) != len(b) {
return false return false
} }
@ -114,11 +101,7 @@ func equalRunes(a, b []rune) bool {
return true return true
} }
func sleep(n int) { // calculate how many lines for N character
Debug(n)
time.Sleep(2000 * time.Millisecond)
}
func LineCount(w int) int { func LineCount(w int) int {
screenWidth := getWidth() screenWidth := getWidth()
r := w / screenWidth r := w / screenWidth
@ -128,6 +111,7 @@ func LineCount(w int) int {
return r return r
} }
// Search in runes from end to front
func RunesIndexBck(r, sub []rune) int { func RunesIndexBck(r, sub []rune) int {
for i := len(r) - len(sub); i >= 0; i-- { for i := len(r) - len(sub); i >= 0; i-- {
found := true found := true
@ -144,6 +128,7 @@ func RunesIndexBck(r, sub []rune) int {
return -1 return -1
} }
// Search in runes from front to end
func RunesIndex(r, sub []rune) int { func RunesIndex(r, sub []rune) int {
for i := 0; i < len(r); i++ { for i := 0; i < len(r); i++ {
found := true found := true
@ -229,7 +214,7 @@ func RunesWidth(r []rune) (length int) {
return return
} }
func AggRunes(candicate [][]rune) (same []rune, size int) { func RunesAggregate(candicate [][]rune) (same []rune, size int) {
for i := 0; i < len(candicate[0]); i++ { for i := 0; i < len(candicate[0]); i++ {
for j := 0; j < len(candicate)-1; j++ { for j := 0; j < len(candicate)-1; j++ {
if i >= len(candicate[j]) || i >= len(candicate[j+1]) { if i >= len(candicate[j]) || i >= len(candicate[j+1]) {
@ -243,9 +228,9 @@ func AggRunes(candicate [][]rune) (same []rune, size int) {
} }
aggregate: aggregate:
if size > 0 { if size > 0 {
same = CopyRunes(candicate[0][:size]) same = RunesCopy(candicate[0][:size])
for i := 0; i < len(candicate); i++ { for i := 0; i < len(candicate); i++ {
n := CopyRunes(candicate[i]) n := RunesCopy(candicate[i])
copy(n, n[size:]) copy(n, n[size:])
candicate[i] = n[:len(n)-size] candicate[i] = n[:len(n)-size]
} }
@ -253,27 +238,15 @@ aggregate:
return return
} }
func CopyRunes(r []rune) []rune { func RunesCopy(r []rune) []rune {
n := make([]rune, len(r)) n := make([]rune, len(r))
copy(n, r) copy(n, r)
return n return n
} }
func EqualRunes(r, r2 []rune) bool {
if len(r) != len(r2) {
return false
}
for idx := range r {
if r[idx] != r2[idx] {
return false
}
}
return true
}
func RunesHasPrefix(r, prefix []rune) bool { func RunesHasPrefix(r, prefix []rune) bool {
if len(r) < len(prefix) { if len(r) < len(prefix) {
return false return false
} }
return EqualRunes(r[:len(prefix)], prefix) return RunesEqual(r[:len(prefix)], prefix)
} }

View File

@ -54,7 +54,7 @@ func TestAggRunes(t *testing.T) {
}, },
} }
for _, r := range runes { for _, r := range runes {
same, off := AggRunes(r.r) same, off := RunesAggregate(r.r)
if off != r.length { if off != r.length {
t.Fatal("result not expect", off) t.Fatal("result not expect", off)
} }