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 {
|
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))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user