Line movement and inserting is working
This commit is contained in:
parent
6526578697
commit
a7ff162b69
128
main.go
128
main.go
|
@ -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()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue