in vim-engine/src/main/kotlin/com/maddyhome/idea/vim/common/DigraphSequence.kt [51:199]
fun processKey(key: KeyStroke, editor: VimEditor): DigraphResult {
return when (digraphState) {
DigraphState.DIG_STATE_PENDING -> {
logger.debug("DIG_STATE_PENDING")
if (key.keyCode == KeyEvent.VK_BACK_SPACE && injector.options(editor).digraph) {
digraphState = DigraphState.DIG_STATE_BACK_SPACE
} else if (key.keyChar != KeyEvent.CHAR_UNDEFINED) {
digraphChar = key.keyChar
}
DigraphResult.Unhandled
}
DigraphState.DIG_STATE_BACK_SPACE -> {
logger.debug("DIG_STATE_BACK_SPACE")
digraphState = DigraphState.DIG_STATE_PENDING
if (key.keyChar != KeyEvent.CHAR_UNDEFINED) {
val codepoint = injector.digraphGroup.getCharacterForDigraph(digraphChar, key.keyChar)
digraphChar = 0.toChar()
return done(codepoint)
}
DigraphResult.Unhandled
}
DigraphState.DIG_STATE_DIG_ONE -> {
logger.debug("DIG_STATE_DIG_ONE")
if (key.keyChar != KeyEvent.CHAR_UNDEFINED) {
digraphChar = key.keyChar
digraphState = DigraphState.DIG_STATE_DIG_TWO
return handled(digraphChar)
}
digraphState = DigraphState.DIG_STATE_PENDING
DigraphResult.Bad
}
DigraphState.DIG_STATE_DIG_TWO -> {
logger.debug("DIG_STATE_DIG_TWO")
digraphState = DigraphState.DIG_STATE_PENDING
if (key.keyChar != KeyEvent.CHAR_UNDEFINED) {
val codepoint = injector.digraphGroup.getCharacterForDigraph(digraphChar, key.keyChar)
return done(codepoint)
}
DigraphResult.Bad
}
DigraphState.DIG_STATE_CODE_START -> {
logger.debug("DIG_STATE_CODE_START")
when (key.keyChar) {
'o', 'O' -> {
codeMax = 3
digraphState = DigraphState.DIG_STATE_CODE_CHAR
codeType = 8
logger.debug("Octal")
DigraphResult.HandledLiteral
}
'x', 'X' -> {
codeMax = 2
digraphState = DigraphState.DIG_STATE_CODE_CHAR
codeType = 16
logger.debug("hex2")
DigraphResult.HandledLiteral
}
'u' -> {
codeMax = 4
digraphState = DigraphState.DIG_STATE_CODE_CHAR
codeType = 16
logger.debug("hex4")
DigraphResult.HandledLiteral
}
'U' -> {
codeMax = 8
digraphState = DigraphState.DIG_STATE_CODE_CHAR
codeType = 16
logger.debug("hex8")
DigraphResult.HandledLiteral
}
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9' -> {
codeMax = 3
digraphState = DigraphState.DIG_STATE_CODE_CHAR
codeType = 10
codeChars[codeCnt++] = key.keyChar
logger.debug("decimal")
DigraphResult.HandledLiteral
}
else -> {
digraphState = DigraphState.DIG_STATE_PENDING
if (key.keyCode == KeyEvent.VK_TAB) {
return done('\t'.code)
}
val codepoint = specialKeyToCodepoint(key)
if (codepoint != null) {
return done(codepoint)
}
logger.debug("unknown")
done(key.keyChar.code)
}
}
}
DigraphState.DIG_STATE_CODE_CHAR -> {
logger.debug("DIG_STATE_CODE_CHAR")
var valid = false
when (codeType) {
10 -> if (key.keyChar in '0'..'9') {
valid = true
}
8 -> if (key.keyChar in '0'..'7') {
valid = true
}
16 -> if (key.keyChar in '0'..'9' || key.keyChar in 'a'..'f' || key.keyChar in 'A'..'F') {
valid = true
}
}
if (valid) {
logger.debug("valid")
codeChars[codeCnt++] = key.keyChar
return if (codeCnt == codeMax) {
digraphState = DigraphState.DIG_STATE_PENDING
val digits = String(codeChars, 0, codeCnt)
val codepoint = digits.toInt(codeType)
done(codepoint)
} else {
DigraphResult.HandledLiteral
}
} else if (codeCnt > 0) {
logger.debug("invalid")
digraphState = DigraphState.DIG_STATE_PENDING
val digits = String(codeChars, 0, codeCnt)
val codepoint = digits.toInt(codeType)
if (!injector.application.isUnitTest()) {
// The key we received isn't part of the literal, so post it to be handled after we've handled the literal.
// This requires swing, so we can't run it in tests.
injector.application.postKey(key, editor)
}
return done(codepoint)
} else if (codeCnt == 0) {
digraphState = DigraphState.DIG_STATE_PENDING
return specialKeyToCodepoint(key)?.let { done(it) } ?: done(key.keyChar.code)
}
DigraphResult.Bad
}
}
}