1
1
Fork 0
qline/main.go

137 lines
2.3 KiB
Go

package main
import (
"bufio"
"fmt"
"os"
"strings"
"tildegit.org/sloum/lines/termios"
)
const (
UpArrow rune = iota - 20
DownArrow
LeftArrow
RightArrow
Delete
Home
End
PrintScreen
PageUp
PageDown
Escape rune = 27
NewLine rune = 10
CarriageReturn rune = 13
BackSpace rune = 127
)
func readKey() (rune, error) {
reader := bufio.NewReader(os.Stdin)
char, _, err := reader.ReadRune()
if err != nil {
return 0, err
}
avail := reader.Buffered()
if char == Escape && avail > 0 {
var b strings.Builder
b.WriteRune(27)
for ; avail > 0; avail-- {
c, _, e := reader.ReadRune()
if e != nil {
break
}
b.WriteRune(c)
}
escSeq := b.String()
switch true {
case escSeq == "\033[A":
char = UpArrow
case escSeq == "\033[B":
char = DownArrow
case escSeq == "\033[C":
char = RightArrow
case escSeq == "\033[D":
char = LeftArrow
case escSeq == "\033[5~":
char = PageUp
case escSeq == "\033[6~":
char = PageDown
case IsHomeKey(escSeq):
char = Home
case IsEndKey(escSeq):
char = End
case escSeq == "\033[3~" || escSeq == "\033[P":
char = Delete
default:
fmt.Printf("Odd sequence: %s\n", escSeq[1:])
}
}
return char, nil
}
func IsHomeKey(seq string) bool {
switch seq {
case "\033[1~", "\033[7~", "\033[H", "\033OH":
return true
default:
return false
}
}
func IsEndKey(seq string) bool {
switch seq {
case "\033[4~", "\033[8~", "\033[F", "\033OF":
return true
default:
return false
}
}
func PrintKey(k rune) {
switch true {
case k == UpArrow:
fmt.Println("UpArrow")
case k == DownArrow:
fmt.Println("DownArrow")
case k == LeftArrow:
fmt.Println("LeftArrow")
case k == RightArrow:
fmt.Println("RightArrow")
case k == Escape:
fmt.Println("Escape")
case k == NewLine:
fmt.Println("NewLine")
case k == CarriageReturn:
fmt.Println("CarriageReturn")
case k == Delete:
fmt.Println("Delete")
case k == Home:
fmt.Println("Home")
case k == End:
fmt.Println("End")
case k == BackSpace:
fmt.Println("BackSpace")
default:
fmt.Printf("%c (%d)\n", k, k)
}
}
func main() {
termios.SetCharMode()
for {
k, e := readKey()
if e != nil {
fmt.Println(e.Error())
continue
}
PrintKey(k)
if k == NewLine || k == CarriageReturn {
break
}
}
termios.Restore()
}