1
1
Fork 0

Line movement and inserting is working

This commit is contained in:
sloum 2021-04-01 14:40:15 -07:00
parent 6526578697
commit a7ff162b69
1 changed files with 112 additions and 16 deletions

128
main.go
View File

@ -26,8 +26,92 @@ const (
BackSpace rune = 127
)
func readKey() (rune, error) {
type Buffer struct {
buf []rune
cursor int
}
func (lb Buffer) String() string {
return string(lb.buf)
}
func (lb *Buffer) AddChar(c rune, echo bool) {
if lb.cursor == len(lb.buf) {
lb.buf = append(lb.buf, c)
lb.cursor++
if echo {
fmt.Printf("%c", c)
}
} else {
lb.buf = append(lb.buf[:lb.cursor+1], lb.buf[lb.cursor:]...)
lb.buf[lb.cursor] = c
lb.cursor++
if echo {
s := string(lb.buf[lb.cursor-1:])
fmt.Printf("%s\033[%dD", s, len(s)-1)
}
}
}
func (lb *Buffer) controlInput(c rune) {
switch c {
case BackSpace:
lb.cursor--
fmt.Printf("%c", BackSpace)
case LeftArrow:
if lb.cursor > 0 {
lb.cursor--
fmt.Print("\033[1D")
}
case RightArrow:
if lb.cursor < len(lb.buf) {
lb.cursor++
fmt.Print("\033[1C")
}
}
}
func (lb *Buffer) seedContent(s string) {
for _, r := range s {
lb.AddChar(r, false)
}
}
func GetText(prompt string, content string, endChar rune, includeEndChar bool) string {
b := Buffer{make([]rune, 0, (len(content)+1)*2), 0}
b.seedContent(content)
fmt.Print(prompt)
fmt.Print(b.String())
var ch rune
var err error
reader := bufio.NewReader(os.Stdin)
for {
ch, err = readKey(reader)
if err != nil {
continue
}
if ch == endChar {
if includeEndChar {
b.AddChar(ch, true)
}
break
}
if isControl(ch) {
b.controlInput(ch)
} else {
b.AddChar(ch, true)
}
}
return b.String()
}
func readKey(reader *bufio.Reader) (rune, error) {
char, _, err := reader.ReadRune()
if err != nil {
return 0, err
@ -57,11 +141,11 @@ func readKey() (rune, error) {
char = PageUp
case escSeq == "\033[6~":
char = PageDown
case IsHomeKey(escSeq):
case isHomeKey(escSeq):
char = Home
case IsEndKey(escSeq):
case isEndKey(escSeq):
char = End
case escSeq == "\033[3~" || escSeq == "\033[P":
case isDeleteKey(escSeq):
char = Delete
default:
fmt.Printf("Odd sequence: %s\n", escSeq[1:])
@ -70,7 +154,25 @@ func readKey() (rune, error) {
return char, nil
}
func IsHomeKey(seq string) bool {
func isControl(c rune) bool {
switch c {
case UpArrow, DownArrow, RightArrow, LeftArrow, PageUp, PageDown, Home, End, Delete, BackSpace, CarriageReturn, NewLine, Escape:
return true
default:
return false
}
}
func isDeleteKey(seq string) bool {
switch seq {
case "\033[3~", "\033[P":
return true
default:
return false
}
}
func isHomeKey(seq string) bool {
switch seq {
case "\033[1~", "\033[7~", "\033[H", "\033OH":
return true
@ -79,7 +181,7 @@ func IsHomeKey(seq string) bool {
}
}
func IsEndKey(seq string) bool {
func isEndKey(seq string) bool {
switch seq {
case "\033[4~", "\033[8~", "\033[F", "\033OF":
return true
@ -120,17 +222,11 @@ func PrintKey(k rune) {
func main() {
termios.SetCharMode()
defer termios.Restore()
str := "Hi"
for {
k, e := readKey()
if e != nil {
fmt.Println(e.Error())
continue
}
PrintKey(k)
if k == NewLine || k == CarriageReturn {
break
}
fmt.Print("\n")
str = GetText("> ", str, '\n', false)
}
termios.Restore()
}