From aee0fa669ff97af4d5ed3c67a7f95935f82a74b5 Mon Sep 17 00:00:00 2001 From: mrsinham Date: Mon, 2 Oct 2017 14:39:53 +0200 Subject: [PATCH] fix: on linux multine move was not working (#103) on linux, if you want to change line, \b are not enough. You need to change line and move to the right. --- runebuf.go | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/runebuf.go b/runebuf.go index 27b0f7a..81d2da5 100644 --- a/runebuf.go +++ b/runebuf.go @@ -4,6 +4,7 @@ import ( "bufio" "bytes" "io" + "strconv" "strings" "sync" ) @@ -486,7 +487,7 @@ func (r *RuneBuffer) output() []byte { buf.Write([]byte(string(r.cfg.MaskRune))) } if len(r.buf) > r.idx { - buf.Write(runes.Backspace(r.buf[r.idx:])) + buf.Write(r.getBackspaceSequence()) } } else { @@ -501,13 +502,43 @@ func (r *RuneBuffer) output() []byte { buf.Write([]byte(" \b")) } } - + // cursor position if len(r.buf) > r.idx { - buf.Write(runes.Backspace(r.buf[r.idx:])) + buf.Write(r.getBackspaceSequence()) } return buf.Bytes() } +func (r *RuneBuffer) getBackspaceSequence() []byte { + var sep = map[int]bool{} + + var i int + for { + if i >= runes.WidthAll(r.buf) { + break + } + + if i == 0 { + i -= r.promptLen() + } + i += r.width + + sep[i] = true + } + var buf []byte + for i := len(r.buf); i > r.idx; i-- { + // move input to the left of one + buf = append(buf, '\b') + if sep[i] { + // up one line, go to the start of the line and move cursor right to the end (r.width) + buf = append(buf, "\033[A\r"+"\033["+strconv.Itoa(r.width)+"C"...) + } + } + + return buf + +} + func (r *RuneBuffer) Reset() []rune { ret := runes.Copy(r.buf) r.buf = r.buf[:0]