Refactor input mapping
All checks were successful
timw4mail/gilo/pipeline/head This commit looks good

This commit is contained in:
Timothy Warren 2021-04-02 11:57:24 -04:00
parent f4a252a294
commit f2e9cd3075

View File

@ -80,6 +80,13 @@ func (e *editor) SetStatusMessage(template string, a ...interface{}) {
func (e *editor) ProcessKeypress() bool { func (e *editor) ProcessKeypress() bool {
ch, _ := terminal.ReadKey() 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 { switch ch {
case key.Ctrl('q'): case key.Ctrl('q'):
if e.document.dirty && e.quitTimes > 0 { if e.document.dirty && e.quitTimes > 0 {
@ -106,34 +113,51 @@ func (e *editor) ProcessKeypress() bool {
// Modifier keys that return ANSI escape sequences // Modifier keys that return ANSI escape sequences
str := parseEscapeSequence() str := parseEscapeSequence()
switch str { // Don't swallow a character after ESC if it doesn't
case keyUp, // start an ANSI escape sequence
keyDown, if len(str) == 1 {
keyLeft, return e.processKeypressChar(rune(str[0]))
keyRight,
keyPageUp,
keyPageDown,
keyHome,
keyEnd:
e.moveCursor(str)
case keyDelete:
e.moveCursor(keyRight)
e.delChar()
} }
e.processKeypressStr(str)
default: default:
e.insertChar(ch) e.insertChar(ch)
} }
// Clear the quit message and restart the
// confirmation count if confirmation is not
// completed
if e.quitTimes != KiloQuitTimes { if e.quitTimes != KiloQuitTimes {
e.quitTimes = KiloQuitTimes e.quitTimes = KiloQuitTimes
e.SetStatusMessage("")
} }
return true 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) { func (e *editor) moveCursor(key string) {
var row *row var row *row
if e.cursor.y >= e.document.rowCount() { 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 // Convert the raw ANSI escape sequences to the type of key input
func parseEscapeSequence() string { 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() ch, size := terminal.ReadKey()
if size == 0 { if size == 0 {
return "\x1b" return string(rune(key.Esc))
} }
runes = append(runes, ch) runes[i] = ch
if i == 1 && runes[1] >= 'A' { if i == 0 && runes[0] >= 'A' && runes[0] <= 'Z' {
// \eOH \eOF return escSeqToKey([]rune{startChar, runes[0]})
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
}
}
} }
// \e[1~ // \e[*~
if i == 2 && runes[0] == '[' && runes[2] == '~' { if i == 1 && startChar == '[' && runes[1] == '~' {
switch runes[1] { return escSeqToKey([]rune{startChar, runes[0], 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
}
} }
} }
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))
} }