mirror of https://github.com/chzyer/readline.git
Handle keypad mode cursor key escape sequences. (#203)
Normally the terminal uses CSI escape sequences when the UP, DOWN, LEFT, RIGHT and HOME, END keys are pressed. These look like the following ESC [ A etc, where ESC [ is the CSI sequence. xterm and other terminals however can generate an alternative escape sequence called SS3 if in the application keypad mode. This sequence is ESC O A etc. Bash readline understands both modes so nowadays you rarely see OA being printed when you press the up arrow while the terminal is using the keypad mode. readline currently does not understand these sequences. To test this fix, I used an xterm and put it in keypad mode using the command "tput smkx". Then I started the readline-demo and tried using arrow keys. Without this fix, OA is printed when I press up. With this fix, readline fetches the previous command as per regular mode. After testing you can escape back to regular mode using "tput rmkx".
This commit is contained in:
parent
80e2d1961b
commit
8e4bd417b9
16
terminal.go
16
terminal.go
|
@ -125,6 +125,7 @@ func (t *Terminal) ioloop() {
|
||||||
var (
|
var (
|
||||||
isEscape bool
|
isEscape bool
|
||||||
isEscapeEx bool
|
isEscapeEx bool
|
||||||
|
isEscapeSS3 bool
|
||||||
expectNextChar bool
|
expectNextChar bool
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -152,9 +153,15 @@ func (t *Terminal) ioloop() {
|
||||||
if isEscape {
|
if isEscape {
|
||||||
isEscape = false
|
isEscape = false
|
||||||
if r == CharEscapeEx {
|
if r == CharEscapeEx {
|
||||||
|
// ^][
|
||||||
expectNextChar = true
|
expectNextChar = true
|
||||||
isEscapeEx = true
|
isEscapeEx = true
|
||||||
continue
|
continue
|
||||||
|
} else if r == CharO {
|
||||||
|
// ^]O
|
||||||
|
expectNextChar = true
|
||||||
|
isEscapeSS3 = true
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
r = escapeKey(r, buf)
|
r = escapeKey(r, buf)
|
||||||
} else if isEscapeEx {
|
} else if isEscapeEx {
|
||||||
|
@ -177,6 +184,15 @@ func (t *Terminal) ioloop() {
|
||||||
expectNextChar = true
|
expectNextChar = true
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
} else if isEscapeSS3 {
|
||||||
|
isEscapeSS3 = false
|
||||||
|
if key := readEscKey(r, buf); key != nil {
|
||||||
|
r = escapeSS3Key(key)
|
||||||
|
}
|
||||||
|
if r == 0 {
|
||||||
|
expectNextChar = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expectNextChar = true
|
expectNextChar = true
|
||||||
|
|
22
utils.go
22
utils.go
|
@ -43,6 +43,7 @@ const (
|
||||||
CharCtrlY = 25
|
CharCtrlY = 25
|
||||||
CharCtrlZ = 26
|
CharCtrlZ = 26
|
||||||
CharEsc = 27
|
CharEsc = 27
|
||||||
|
CharO = 79
|
||||||
CharEscapeEx = 91
|
CharEscapeEx = 91
|
||||||
CharBackspace = 127
|
CharBackspace = 127
|
||||||
)
|
)
|
||||||
|
@ -123,6 +124,27 @@ func escapeExKey(key *escapeKeyPair) rune {
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// translate EscOX SS3 codes for up/down/etc.
|
||||||
|
func escapeSS3Key(key *escapeKeyPair) rune {
|
||||||
|
var r rune
|
||||||
|
switch key.typ {
|
||||||
|
case 'D':
|
||||||
|
r = CharBackward
|
||||||
|
case 'C':
|
||||||
|
r = CharForward
|
||||||
|
case 'A':
|
||||||
|
r = CharPrev
|
||||||
|
case 'B':
|
||||||
|
r = CharNext
|
||||||
|
case 'H':
|
||||||
|
r = CharLineStart
|
||||||
|
case 'F':
|
||||||
|
r = CharLineEnd
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
type escapeKeyPair struct {
|
type escapeKeyPair struct {
|
||||||
attr string
|
attr string
|
||||||
typ rune
|
typ rune
|
||||||
|
|
Loading…
Reference in New Issue