Refactor input mapping
All checks were successful
timw4mail/gilo/pipeline/head This commit looks good
All checks were successful
timw4mail/gilo/pipeline/head This commit looks good
This commit is contained in:
parent
f4a252a294
commit
f2e9cd3075
174
editor/editor.go
174
editor/editor.go
@ -80,6 +80,13 @@ func (e *editor) SetStatusMessage(template string, a ...interface{}) {
|
||||
func (e *editor) ProcessKeypress() bool {
|
||||
ch, _ := terminal.ReadKey()
|
||||
|
||||
return e.processKeypressChar(ch)
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine what to do with an individual character of input
|
||||
*/
|
||||
func (e *editor) processKeypressChar(ch rune) bool {
|
||||
switch ch {
|
||||
case key.Ctrl('q'):
|
||||
if e.document.dirty && e.quitTimes > 0 {
|
||||
@ -106,34 +113,51 @@ func (e *editor) ProcessKeypress() bool {
|
||||
// Modifier keys that return ANSI escape sequences
|
||||
str := parseEscapeSequence()
|
||||
|
||||
switch str {
|
||||
case keyUp,
|
||||
keyDown,
|
||||
keyLeft,
|
||||
keyRight,
|
||||
keyPageUp,
|
||||
keyPageDown,
|
||||
keyHome,
|
||||
keyEnd:
|
||||
|
||||
e.moveCursor(str)
|
||||
|
||||
case keyDelete:
|
||||
e.moveCursor(keyRight)
|
||||
e.delChar()
|
||||
// Don't swallow a character after ESC if it doesn't
|
||||
// start an ANSI escape sequence
|
||||
if len(str) == 1 {
|
||||
return e.processKeypressChar(rune(str[0]))
|
||||
}
|
||||
|
||||
e.processKeypressStr(str)
|
||||
|
||||
default:
|
||||
e.insertChar(ch)
|
||||
}
|
||||
|
||||
// Clear the quit message and restart the
|
||||
// confirmation count if confirmation is not
|
||||
// completed
|
||||
if e.quitTimes != KiloQuitTimes {
|
||||
e.quitTimes = KiloQuitTimes
|
||||
e.SetStatusMessage("")
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine what do do with a parsed ANSI escape sequence
|
||||
*/
|
||||
func (e *editor) processKeypressStr(key string) {
|
||||
switch key {
|
||||
case keyUp,
|
||||
keyDown,
|
||||
keyLeft,
|
||||
keyRight,
|
||||
keyPageUp,
|
||||
keyPageDown,
|
||||
keyHome,
|
||||
keyEnd:
|
||||
|
||||
e.moveCursor(key)
|
||||
|
||||
case keyDelete:
|
||||
e.moveCursor(keyRight)
|
||||
e.delChar()
|
||||
}
|
||||
}
|
||||
|
||||
func (e *editor) moveCursor(key string) {
|
||||
var row *row
|
||||
if e.cursor.y >= e.document.rowCount() {
|
||||
@ -229,64 +253,84 @@ func (e *editor) delChar() {
|
||||
|
||||
// Convert the raw ANSI escape sequences to the type of key input
|
||||
func parseEscapeSequence() string {
|
||||
var runes []rune
|
||||
// If we aren't starting an escape sequence,
|
||||
// return the character
|
||||
startChar, _ := terminal.ReadKey()
|
||||
if startChar != '[' && startChar != 'O' {
|
||||
return string(startChar)
|
||||
}
|
||||
|
||||
for i := 0; i < 3; i++ {
|
||||
// Read one or two characters after
|
||||
// \e[ or \eO, which is the end of the
|
||||
// handled escape sequences
|
||||
runes := [2]rune{'\000', '\000'}
|
||||
for i := 0; i < 2; i++ {
|
||||
ch, size := terminal.ReadKey()
|
||||
if size == 0 {
|
||||
return "\x1b"
|
||||
return string(rune(key.Esc))
|
||||
}
|
||||
runes = append(runes, ch)
|
||||
runes[i] = ch
|
||||
|
||||
if i == 1 && runes[1] >= 'A' {
|
||||
// \eOH \eOF
|
||||
if runes[0] == 'O' {
|
||||
switch runes[1] {
|
||||
case 'H':
|
||||
return keyHome
|
||||
case 'F':
|
||||
return keyEnd
|
||||
}
|
||||
}
|
||||
// \e[A
|
||||
if runes[0] == '[' {
|
||||
switch runes[1] {
|
||||
case 'A':
|
||||
return keyUp
|
||||
case 'B':
|
||||
return keyDown
|
||||
case 'C':
|
||||
return keyRight
|
||||
case 'D':
|
||||
return keyLeft
|
||||
case 'H':
|
||||
return keyHome
|
||||
case 'F':
|
||||
return keyEnd
|
||||
}
|
||||
}
|
||||
if i == 0 && runes[0] >= 'A' && runes[0] <= 'Z' {
|
||||
return escSeqToKey([]rune{startChar, runes[0]})
|
||||
}
|
||||
|
||||
// \e[1~
|
||||
if i == 2 && runes[0] == '[' && runes[2] == '~' {
|
||||
switch runes[1] {
|
||||
case '1':
|
||||
return keyHome
|
||||
case '3':
|
||||
return keyDelete
|
||||
case '4':
|
||||
return keyEnd
|
||||
case '5':
|
||||
return keyPageUp
|
||||
case '6':
|
||||
return keyPageDown
|
||||
case '7':
|
||||
return keyHome
|
||||
case '8':
|
||||
return keyEnd
|
||||
}
|
||||
// \e[*~
|
||||
if i == 1 && startChar == '[' && runes[1] == '~' {
|
||||
return escSeqToKey([]rune{startChar, runes[0], runes[1]})
|
||||
}
|
||||
}
|
||||
|
||||
return string('\x1b')
|
||||
return string(rune(key.Esc))
|
||||
}
|
||||
|
||||
func escSeqToKey (seq []rune) string {
|
||||
// \eO*
|
||||
// \e[*
|
||||
if len(seq) == 2 {
|
||||
startChar, cmd := seq[0], seq[1]
|
||||
if startChar == 'O' {
|
||||
switch cmd {
|
||||
case 'H':
|
||||
return keyHome
|
||||
case 'F':
|
||||
return keyEnd
|
||||
}
|
||||
} else if startChar == '[' {
|
||||
switch cmd {
|
||||
case 'A':
|
||||
return keyUp
|
||||
case 'B':
|
||||
return keyDown
|
||||
case 'C':
|
||||
return keyRight
|
||||
case 'D':
|
||||
return keyLeft
|
||||
case 'H':
|
||||
return keyHome
|
||||
case 'F':
|
||||
return keyEnd
|
||||
}
|
||||
}
|
||||
} else if len(seq) == 3 { // \e[*~
|
||||
cmd := seq[1]
|
||||
switch cmd {
|
||||
case '1':
|
||||
return keyHome
|
||||
case '3':
|
||||
return keyDelete
|
||||
case '4':
|
||||
return keyEnd
|
||||
case '5':
|
||||
return keyPageUp
|
||||
case '6':
|
||||
return keyPageDown
|
||||
case '7':
|
||||
return keyHome
|
||||
case '8':
|
||||
return keyEnd
|
||||
}
|
||||
}
|
||||
|
||||
return string(rune(key.Esc))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user