Decompose tcell ReadChar key translation (refactor step 7)
ReadChar's key switch moves into translateKey with namedKey split into motionKey/editingKey halves. term is complexity-clean. Behavior unchanged.
This commit is contained in:
114
term/tcell.go
114
term/tcell.go
@@ -89,48 +89,88 @@ func (t *Tcell) ReadChar() byte {
|
|||||||
t.Render(t.last)
|
t.Render(t.last)
|
||||||
}
|
}
|
||||||
case *tcell.EventKey:
|
case *tcell.EventKey:
|
||||||
switch ev.Key() {
|
if b, ok := translateKey(ev); ok {
|
||||||
case tcell.KeyUp:
|
return b
|
||||||
return 'k'
|
|
||||||
case tcell.KeyDown:
|
|
||||||
return 'j'
|
|
||||||
case tcell.KeyLeft:
|
|
||||||
return 'h'
|
|
||||||
case tcell.KeyRight:
|
|
||||||
return 'l'
|
|
||||||
case tcell.KeyHome:
|
|
||||||
return 'y'
|
|
||||||
case tcell.KeyPgUp:
|
|
||||||
return 'u'
|
|
||||||
case tcell.KeyEnd:
|
|
||||||
return 'b'
|
|
||||||
case tcell.KeyPgDn:
|
|
||||||
return 'n'
|
|
||||||
case tcell.KeyEnter:
|
|
||||||
return '\n'
|
|
||||||
case tcell.KeyEscape:
|
|
||||||
return game.Escape
|
|
||||||
case tcell.KeyBackspace, tcell.KeyBackspace2:
|
|
||||||
return 8
|
|
||||||
case tcell.KeyDelete:
|
|
||||||
return 0x7f
|
|
||||||
case tcell.KeyTab:
|
|
||||||
return '\t'
|
|
||||||
case tcell.KeyCtrlC:
|
|
||||||
return 3
|
|
||||||
default:
|
|
||||||
if ev.Key() >= tcell.KeyCtrlA && ev.Key() <= tcell.KeyCtrlZ {
|
|
||||||
return byte(ev.Key()) //nolint:gosec // G115: 1..26 fits
|
|
||||||
}
|
|
||||||
|
|
||||||
if r := ev.Rune(); r > 0 && r < 0x80 {
|
|
||||||
return byte(r)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// translateKey converts a key event to a game input byte; ok is false
|
||||||
|
// for keys the C game does not understand.
|
||||||
|
func translateKey(ev *tcell.EventKey) (byte, bool) {
|
||||||
|
if b, ok := namedKey(ev.Key()); ok {
|
||||||
|
return b, true
|
||||||
|
}
|
||||||
|
|
||||||
|
if ev.Key() >= tcell.KeyCtrlA && ev.Key() <= tcell.KeyCtrlZ {
|
||||||
|
return byte(ev.Key()), true //nolint:gosec // G115: 1..26 fits
|
||||||
|
}
|
||||||
|
|
||||||
|
if r := ev.Rune(); r > 0 && r < 0x80 {
|
||||||
|
return byte(r), true
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// namedKey translates tcell's navigation and editing keys to the single
|
||||||
|
// bytes the C game reads (arrows become hjkl, etc.); ok is false for
|
||||||
|
// keys handled elsewhere.
|
||||||
|
func namedKey(k tcell.Key) (byte, bool) {
|
||||||
|
if b, ok := motionKey(k); ok {
|
||||||
|
return b, true
|
||||||
|
}
|
||||||
|
|
||||||
|
return editingKey(k)
|
||||||
|
}
|
||||||
|
|
||||||
|
// motionKey translates the arrow and paging keys to Rogue's movement
|
||||||
|
// letters (tcell.go ReadChar).
|
||||||
|
func motionKey(k tcell.Key) (byte, bool) {
|
||||||
|
switch k {
|
||||||
|
case tcell.KeyUp:
|
||||||
|
return 'k', true
|
||||||
|
case tcell.KeyDown:
|
||||||
|
return 'j', true
|
||||||
|
case tcell.KeyLeft:
|
||||||
|
return 'h', true
|
||||||
|
case tcell.KeyRight:
|
||||||
|
return 'l', true
|
||||||
|
case tcell.KeyHome:
|
||||||
|
return 'y', true
|
||||||
|
case tcell.KeyPgUp:
|
||||||
|
return 'u', true
|
||||||
|
case tcell.KeyEnd:
|
||||||
|
return 'b', true
|
||||||
|
case tcell.KeyPgDn:
|
||||||
|
return 'n', true
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// editingKey translates the editing and control keys to their C0 codes
|
||||||
|
// (tcell.go ReadChar).
|
||||||
|
func editingKey(k tcell.Key) (byte, bool) {
|
||||||
|
switch k {
|
||||||
|
case tcell.KeyEnter:
|
||||||
|
return '\n', true
|
||||||
|
case tcell.KeyEscape:
|
||||||
|
return game.Escape, true
|
||||||
|
case tcell.KeyBackspace, tcell.KeyBackspace2:
|
||||||
|
return 8, true
|
||||||
|
case tcell.KeyDelete:
|
||||||
|
return 0x7f, true
|
||||||
|
case tcell.KeyTab:
|
||||||
|
return '\t', true
|
||||||
|
case tcell.KeyCtrlC:
|
||||||
|
return 3, true
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
// ShellEscape suspends the screen and runs the user's shell (main.c
|
// ShellEscape suspends the screen and runs the user's shell (main.c
|
||||||
// shell + md_shellescape).
|
// shell + md_shellescape).
|
||||||
func (t *Tcell) ShellEscape() {
|
func (t *Tcell) ShellEscape() {
|
||||||
|
|||||||
Reference in New Issue
Block a user