2013-09-21 00:27:12 +08:00
|
|
|
package edit
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"bufio"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Key struct {
|
|
|
|
rune
|
|
|
|
Ctrl bool
|
|
|
|
Alt bool
|
|
|
|
}
|
|
|
|
|
|
|
|
func PlainKey(r rune) Key {
|
|
|
|
return Key{rune: r}
|
|
|
|
}
|
|
|
|
|
|
|
|
func CtrlKey(r rune) Key {
|
|
|
|
return Key{rune: r, Ctrl: true}
|
|
|
|
}
|
|
|
|
|
2013-09-21 00:31:20 +08:00
|
|
|
func (k Key) String() (s string) {
|
|
|
|
if k.Ctrl {
|
|
|
|
s += "Ctrl-"
|
|
|
|
}
|
|
|
|
if k.Alt {
|
|
|
|
s += "Alt-"
|
|
|
|
}
|
|
|
|
s += string(k.rune)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2013-09-21 00:27:12 +08:00
|
|
|
const (
|
|
|
|
F1 rune = -1-iota
|
|
|
|
F2
|
|
|
|
F3
|
|
|
|
F4
|
|
|
|
F5
|
|
|
|
F6
|
|
|
|
F7
|
|
|
|
F8
|
|
|
|
F9
|
|
|
|
F10
|
|
|
|
F11
|
|
|
|
F12
|
|
|
|
|
|
|
|
Escape // ^[
|
|
|
|
Backspace // ^?
|
|
|
|
|
|
|
|
Up // ^[OA
|
|
|
|
Down // ^[OB
|
|
|
|
Right // ^[OC
|
|
|
|
Left // ^[OD
|
|
|
|
|
|
|
|
Home // ^[[1~
|
|
|
|
Insert // ^[[2~
|
|
|
|
Delete // ^[[3~
|
|
|
|
End // ^[[4~
|
|
|
|
PageUp // ^[[5~
|
|
|
|
PageDown // ^[[6~
|
|
|
|
)
|
|
|
|
|
|
|
|
// reader is the part of an Editor responsible for reading and decoding
|
|
|
|
// terminal key sequences.
|
|
|
|
type reader struct {
|
|
|
|
bufReader *bufio.Reader
|
2013-09-21 10:28:59 +08:00
|
|
|
readAhead []Key
|
2013-09-21 00:27:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func newReader(f *os.File) *reader {
|
2013-09-21 10:28:59 +08:00
|
|
|
return &reader{bufio.NewReaderSize(f, 0), make([]Key, 0)}
|
2013-09-21 00:27:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// type readerState func(rune) (bool, readerState)
|
|
|
|
|
|
|
|
func (rd *reader) readKey() (k Key, err error) {
|
2013-09-21 10:28:59 +08:00
|
|
|
if n := len(rd.readAhead); n > 0 {
|
|
|
|
k = rd.readAhead[0]
|
|
|
|
rd.readAhead = rd.readAhead[1:]
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2013-09-21 00:27:12 +08:00
|
|
|
r, _, err := rd.bufReader.ReadRune()
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
2013-09-21 00:32:55 +08:00
|
|
|
switch r {
|
|
|
|
case 0x0:
|
2013-09-21 00:27:12 +08:00
|
|
|
k = CtrlKey('`')
|
2013-09-21 00:32:55 +08:00
|
|
|
case 0x1d:
|
2013-09-21 00:27:12 +08:00
|
|
|
k = CtrlKey('6')
|
2013-09-21 00:32:55 +08:00
|
|
|
case 0x1f:
|
2013-09-21 00:27:12 +08:00
|
|
|
k = CtrlKey('/')
|
2013-09-21 00:32:55 +08:00
|
|
|
case 0x7f:
|
2013-09-21 00:27:12 +08:00
|
|
|
k = PlainKey(Backspace)
|
|
|
|
/*
|
2013-09-21 00:32:55 +08:00
|
|
|
case 0x1b:
|
2013-09-21 00:27:12 +08:00
|
|
|
// ^[, or Escape
|
|
|
|
k = CtrlKey('[')
|
|
|
|
*/
|
|
|
|
default:
|
2013-09-21 00:32:55 +08:00
|
|
|
if 0x1 <= r && r <= 0x1d {
|
|
|
|
k = CtrlKey(r+0x40)
|
|
|
|
} else {
|
|
|
|
k = PlainKey(r)
|
|
|
|
}
|
2013-09-21 00:27:12 +08:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|