Improve internal keyevent names

This commit is contained in:
Zachary Yedidia 2020-06-29 00:50:19 -04:00
parent 626b08e991
commit 6c53407e6d
3 changed files with 129 additions and 6 deletions

View file

@ -1,10 +1,17 @@
package action
import (
"bytes"
"errors"
"fmt"
"strings"
"github.com/zyedidia/tcell"
)
type Event interface{}
type Event interface {
String() string
}
// RawEvent is simply an escape code
// We allow users to directly bind escape codes
@ -13,6 +20,10 @@ type RawEvent struct {
esc string
}
func (r RawEvent) String() string {
return r.esc
}
// KeyEvent is a key event containing a key code,
// some possible modifiers (alt, ctrl, etc...) and
// a rune if it was simply a character press
@ -22,6 +33,60 @@ type KeyEvent struct {
code tcell.Key
mod tcell.ModMask
r rune
any bool
}
func (k KeyEvent) String() string {
if k.any {
return "<any>"
}
s := ""
m := []string{}
if k.mod&tcell.ModShift != 0 {
m = append(m, "Shift")
}
if k.mod&tcell.ModAlt != 0 {
m = append(m, "Alt")
}
if k.mod&tcell.ModMeta != 0 {
m = append(m, "Meta")
}
if k.mod&tcell.ModCtrl != 0 {
m = append(m, "Ctrl")
}
ok := false
if s, ok = tcell.KeyNames[k.code]; !ok {
if k.code == tcell.KeyRune {
s = string(k.r)
} else {
s = fmt.Sprintf("Key[%d,%d]", k.code, int(k.r))
}
}
if len(m) != 0 {
if k.mod&tcell.ModCtrl != 0 && strings.HasPrefix(s, "Ctrl-") {
s = s[5:]
if len(s) == 1 {
s = strings.ToLower(s)
}
}
return fmt.Sprintf("%s-%s", strings.Join(m, "-"), s)
}
return s
}
// A KeySequence defines a list of consecutive
// key events
type KeySequenceEvent struct {
keys []KeyEvent
}
func (k KeySequenceEvent) String() string {
buf := bytes.Buffer{}
for _, e := range k.keys {
buf.WriteString(e.String())
}
return buf.String()
}
// MouseEvent is a mouse event with a mouse button and
@ -31,8 +96,54 @@ type MouseEvent struct {
mod tcell.ModMask
}
type KeyAction func(Handler) bool
type MouseAction func(Handler, tcell.EventMouse) bool
func (m MouseEvent) String() string {
mod := ""
if m.mod&tcell.ModShift != 0 {
mod = "Shift-"
}
if m.mod&tcell.ModAlt != 0 {
mod = "Alt-"
}
if m.mod&tcell.ModMeta != 0 {
mod = "Meta-"
}
if m.mod&tcell.ModCtrl != 0 {
mod = "Ctrl-"
}
for k, v := range mouseEvents {
if v == m.btn {
return fmt.Sprintf("%s%s", mod, k)
}
}
return ""
}
// ConstructEvent takes a tcell event and returns a micro
// event. Note that tcell events can't express certain
// micro events such as key sequences. This function is
// mostly used for debugging/raw panes or constructing
// intermediate micro events while parsing a sequence.
func ConstructEvent(event tcell.Event) (Event, error) {
switch e := event.(type) {
case *tcell.EventKey:
return KeyEvent{
code: e.Key(),
mod: e.Modifiers(),
r: e.Rune(),
}, nil
case *tcell.EventRaw:
return RawEvent{
esc: e.EscSeq(),
}, nil
case *tcell.EventMouse:
return MouseEvent{
btn: e.Buttons(),
mod: e.Modifiers(),
}, nil
}
return nil, errors.New("No micro event equivalent")
}
// A Handler will take a tcell event and execute it
// appropriately

View file

@ -0,0 +1,12 @@
package action
type KeyAction func(Pane) bool
type MouseAction func(Pane, *MouseEvent) bool
type KeyAnyAction func(Pane, keys []KeyEvent)
type KeyTreeNode struct {
children map[Event]KeyTreeNode
// action KeyAction
// any KeyAnyAction
}

View file

@ -36,9 +36,9 @@ func (h *RawPane) HandleEvent(event tcell.Event) {
h.Buf.Insert(h.Cursor.Loc, reflect.TypeOf(event).String()[7:])
switch e := event.(type) {
case *tcell.EventKey:
h.Buf.Insert(h.Cursor.Loc, fmt.Sprintf(": %s", e.Name()))
e, err := ConstructEvent(event)
if err == nil {
h.Buf.Insert(h.Cursor.Loc, fmt.Sprintf(": %s", e.String()))
}
h.Buf.Insert(h.Cursor.Loc, fmt.Sprintf(": %q\n", event.EscSeq()))