forked from Mirrors/bubbletea
Catch the alt key modifier
This commit is contained in:
parent
f88269fb22
commit
eefa9c7aa3
54
key.go
54
key.go
|
@ -11,11 +11,16 @@ import (
|
||||||
type KeyMsg Key
|
type KeyMsg Key
|
||||||
|
|
||||||
// String returns a friendly name for a key
|
// String returns a friendly name for a key
|
||||||
func (k *KeyMsg) String() string {
|
func (k *KeyMsg) String() (str string) {
|
||||||
|
if k.Alt {
|
||||||
|
str += "alt+"
|
||||||
|
}
|
||||||
if k.Type == KeyRune {
|
if k.Type == KeyRune {
|
||||||
return string(k.Rune)
|
str += string(k.Rune)
|
||||||
|
return str
|
||||||
} else if s, ok := keyNames[int(k.Type)]; ok {
|
} else if s, ok := keyNames[int(k.Type)]; ok {
|
||||||
return s
|
str += s
|
||||||
|
return str
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -29,6 +34,7 @@ func (k *KeyMsg) IsRune() bool {
|
||||||
type Key struct {
|
type Key struct {
|
||||||
Type KeyType
|
Type KeyType
|
||||||
Rune rune
|
Rune rune
|
||||||
|
Alt bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// KeyType indicates the key pressed
|
// KeyType indicates the key pressed
|
||||||
|
@ -183,7 +189,6 @@ var sequences = map[string]KeyType{
|
||||||
"\x1b[B": KeyDown,
|
"\x1b[B": KeyDown,
|
||||||
"\x1b[C": KeyRight,
|
"\x1b[C": KeyRight,
|
||||||
"\x1b[D": KeyLeft,
|
"\x1b[D": KeyLeft,
|
||||||
"\x1b5B5A": KeyShiftTab,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadKey reads keypress input from a TTY and returns a string representation
|
// ReadKey reads keypress input from a TTY and returns a string representation
|
||||||
|
@ -192,41 +197,44 @@ func ReadKey(r io.Reader) (Key, error) {
|
||||||
var buf [256]byte
|
var buf [256]byte
|
||||||
|
|
||||||
// Read and block
|
// Read and block
|
||||||
n, err := r.Read(buf[:])
|
numBytes, err := r.Read(buf[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Key{}, err
|
return Key{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hex representation of input sequence
|
// Shift+tab needs some very special handling
|
||||||
hex := fmt.Sprintf("%x", buf[:n])
|
if "1b5b5a" == fmt.Sprintf("%x", buf[:numBytes]) {
|
||||||
|
|
||||||
switch hex {
|
|
||||||
case "1b5b5a":
|
|
||||||
return Key{Type: KeyShiftTab}, nil
|
return Key{Type: KeyShiftTab}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get rune
|
// Get unicode value
|
||||||
c, _ := utf8.DecodeRune(buf[:])
|
char, _ := utf8.DecodeRune(buf[:])
|
||||||
if c == utf8.RuneError {
|
if char == utf8.RuneError {
|
||||||
return Key{}, errors.New("no such rune")
|
return Key{}, errors.New("could not decode rune")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is it a control character?
|
// Is it a control character?
|
||||||
if n == 1 && c <= keyUS || c == keyDEL {
|
if numBytes == 1 && char <= keyUS || char == keyDEL {
|
||||||
return Key{Type: KeyType(c)}, nil
|
return Key{Type: KeyType(char)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is it a special sequence, like an arrow key?
|
// Is it a special sequence, like an arrow key?
|
||||||
if k, ok := sequences[string(buf[:n])]; ok {
|
if k, ok := sequences[string(buf[:numBytes])]; ok {
|
||||||
return Key{Type: k}, nil
|
return Key{Type: k}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the first byte is an escape sequence, and we're still here, just
|
// Is the alt key pressed? The buffer will be prefixed with an escape
|
||||||
// send a null to avoid sending bizarre escape sequences down the line
|
// sequence if so
|
||||||
if n > 0 && buf[0] == 0x1b {
|
if numBytes > 1 && buf[0] == 0x1b {
|
||||||
return Key{Type: KeyNull}, nil
|
// Now remove the initial escape sequence and re-process to get the
|
||||||
|
// character.
|
||||||
|
c, _ := utf8.DecodeRune(buf[1:])
|
||||||
|
if c == utf8.RuneError {
|
||||||
|
return Key{}, errors.New("could not decode rune after removing initial escape")
|
||||||
|
}
|
||||||
|
return Key{Alt: true, Type: KeyRune, Rune: c}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nope, just a regular, ol' rune
|
// Just a regular, ol' rune
|
||||||
return Key{Type: KeyRune, Rune: c}, nil
|
return Key{Type: KeyRune, Rune: char}, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue