mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-15 21:37:09 +09:00
Preliminary support for key sequences
This commit adds support for binding key sequences such as "<Ctrl-x><Ctrl-c>". This commit does not solve the problem of global bindings yet, and therefore the command bar doesn't work properly in this commit.
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
@@ -53,14 +54,16 @@ func InitBindings() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func BindKey(k, v string) {
|
func BindKey(k, v string) {
|
||||||
event, ok := findEvent(k)
|
event, err := findEvent(k)
|
||||||
if !ok {
|
if err != nil {
|
||||||
screen.TermMessage(k, "is not a bindable event")
|
screen.TermMessage(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch e := event.(type) {
|
switch e := event.(type) {
|
||||||
case KeyEvent:
|
case KeyEvent:
|
||||||
BufMapKey(e, v)
|
BufMapKey(e, v)
|
||||||
|
case KeySequenceEvent:
|
||||||
|
BufMapKey(e, v)
|
||||||
case MouseEvent:
|
case MouseEvent:
|
||||||
BufMapMouse(e, v)
|
BufMapMouse(e, v)
|
||||||
case RawEvent:
|
case RawEvent:
|
||||||
@@ -70,8 +73,36 @@ func BindKey(k, v string) {
|
|||||||
config.Bindings[k] = v
|
config.Bindings[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
// findEvent will find binding Key 'b' using string 'k'
|
var r = regexp.MustCompile("<(.+?)>")
|
||||||
func findEvent(k string) (b Event, ok bool) {
|
|
||||||
|
func findEvents(k string) (b KeySequenceEvent, ok bool, err error) {
|
||||||
|
var events []Event = nil
|
||||||
|
for len(k) > 0 {
|
||||||
|
groups := r.FindStringSubmatchIndex(k)
|
||||||
|
|
||||||
|
if len(groups) > 3 {
|
||||||
|
if events == nil {
|
||||||
|
events = make([]Event, 0, 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
e, ok := findSingleEvent(k[groups[2]:groups[3]])
|
||||||
|
if !ok {
|
||||||
|
return KeySequenceEvent{}, false, errors.New("Invalid event " + k[groups[2]:groups[3]])
|
||||||
|
}
|
||||||
|
|
||||||
|
events = append(events, e)
|
||||||
|
|
||||||
|
k = k[groups[3]+1:]
|
||||||
|
} else {
|
||||||
|
return KeySequenceEvent{}, false, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return KeySequenceEvent{events}, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// findSingleEvent will find binding Key 'b' using string 'k'
|
||||||
|
func findSingleEvent(k string) (b Event, ok bool) {
|
||||||
modifiers := tcell.ModNone
|
modifiers := tcell.ModNone
|
||||||
|
|
||||||
// First, we'll strip off all the modifiers in the name and add them to the
|
// First, we'll strip off all the modifiers in the name and add them to the
|
||||||
@@ -162,6 +193,23 @@ modSearch:
|
|||||||
return KeyEvent{}, false
|
return KeyEvent{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func findEvent(k string) (Event, error) {
|
||||||
|
var event Event
|
||||||
|
event, ok, err := findEvents(k)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
event, ok = findSingleEvent(k)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New(k + " is not a bindable event")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return event, nil
|
||||||
|
}
|
||||||
|
|
||||||
// TryBindKey tries to bind a key by writing to config.ConfigDir/bindings.json
|
// TryBindKey tries to bind a key by writing to config.ConfigDir/bindings.json
|
||||||
// Returns true if the keybinding already existed and a possible error
|
// Returns true if the keybinding already existed and a possible error
|
||||||
func TryBindKey(k, v string, overwrite bool) (bool, error) {
|
func TryBindKey(k, v string, overwrite bool) (bool, error) {
|
||||||
@@ -181,14 +229,14 @@ func TryBindKey(k, v string, overwrite bool) (bool, error) {
|
|||||||
return false, errors.New("Error reading bindings.json: " + err.Error())
|
return false, errors.New("Error reading bindings.json: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
key, ok := findEvent(k)
|
key, err := findEvent(k)
|
||||||
if !ok {
|
if err != nil {
|
||||||
return false, errors.New("Invalid event " + k)
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
found := false
|
found := false
|
||||||
for ev := range parsed {
|
for ev := range parsed {
|
||||||
if e, ok := findEvent(ev); ok {
|
if e, err := findEvent(ev); err == nil {
|
||||||
if e == key {
|
if e == key {
|
||||||
if overwrite {
|
if overwrite {
|
||||||
parsed[ev] = v
|
parsed[ev] = v
|
||||||
@@ -231,13 +279,13 @@ func UnbindKey(k string) error {
|
|||||||
return errors.New("Error reading bindings.json: " + err.Error())
|
return errors.New("Error reading bindings.json: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
key, ok := findEvent(k)
|
key, err := findEvent(k)
|
||||||
if !ok {
|
if err != nil {
|
||||||
return errors.New("Invalid event " + k)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for ev := range parsed {
|
for ev := range parsed {
|
||||||
if e, ok := findEvent(ev); ok {
|
if e, err := findEvent(ev); err == nil {
|
||||||
if e == key {
|
if e == key {
|
||||||
delete(parsed, ev)
|
delete(parsed, ev)
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package action
|
package action
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -19,14 +20,29 @@ import (
|
|||||||
type BufKeyAction func(*BufPane) bool
|
type BufKeyAction func(*BufPane) bool
|
||||||
type BufMouseAction func(*BufPane, *tcell.EventMouse) bool
|
type BufMouseAction func(*BufPane, *tcell.EventMouse) bool
|
||||||
|
|
||||||
|
var BufBindings *KeyTree
|
||||||
var BufKeyBindings map[Event]BufKeyAction
|
var BufKeyBindings map[Event]BufKeyAction
|
||||||
var BufKeyStrings map[Event]string
|
var BufKeyStrings map[Event]string
|
||||||
var BufMouseBindings map[MouseEvent]BufMouseAction
|
var BufMouseBindings map[MouseEvent]BufMouseAction
|
||||||
|
|
||||||
|
func BufKeyActionGeneral(a BufKeyAction) PaneKeyAction {
|
||||||
|
return func(p Pane) bool {
|
||||||
|
return a(p.(*BufPane))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BufMouseActionGeneral(a BufMouseAction) PaneMouseAction {
|
||||||
|
return func(p Pane, me *tcell.EventMouse) bool {
|
||||||
|
return a(p.(*BufPane), me)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
BufKeyBindings = make(map[Event]BufKeyAction)
|
BufKeyBindings = make(map[Event]BufKeyAction)
|
||||||
BufKeyStrings = make(map[Event]string)
|
BufKeyStrings = make(map[Event]string)
|
||||||
BufMouseBindings = make(map[MouseEvent]BufMouseAction)
|
BufMouseBindings = make(map[MouseEvent]BufMouseAction)
|
||||||
|
|
||||||
|
BufBindings = NewKeyTree()
|
||||||
}
|
}
|
||||||
|
|
||||||
func LuaAction(fn string) func(*BufPane) bool {
|
func LuaAction(fn string) func(*BufPane) bool {
|
||||||
@@ -54,7 +70,7 @@ func LuaAction(fn string) func(*BufPane) bool {
|
|||||||
|
|
||||||
// BufMapKey maps a key event to an action
|
// BufMapKey maps a key event to an action
|
||||||
func BufMapKey(k Event, action string) {
|
func BufMapKey(k Event, action string) {
|
||||||
BufKeyStrings[k] = action
|
// BufKeyStrings[k] = action
|
||||||
var actionfns []func(*BufPane) bool
|
var actionfns []func(*BufPane) bool
|
||||||
var names []string
|
var names []string
|
||||||
var types []byte
|
var types []byte
|
||||||
@@ -109,7 +125,7 @@ func BufMapKey(k Event, action string) {
|
|||||||
}
|
}
|
||||||
actionfns = append(actionfns, afn)
|
actionfns = append(actionfns, afn)
|
||||||
}
|
}
|
||||||
BufKeyBindings[k] = func(h *BufPane) bool {
|
bufAction := func(h *BufPane) bool {
|
||||||
cursors := h.Buf.GetCursors()
|
cursors := h.Buf.GetCursors()
|
||||||
success := true
|
success := true
|
||||||
for i, a := range actionfns {
|
for i, a := range actionfns {
|
||||||
@@ -132,27 +148,33 @@ func BufMapKey(k Event, action string) {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BufBindings.RegisterKeyBinding(k, BufKeyActionGeneral(bufAction))
|
||||||
}
|
}
|
||||||
|
|
||||||
// BufMapMouse maps a mouse event to an action
|
// BufMapMouse maps a mouse event to an action
|
||||||
func BufMapMouse(k MouseEvent, action string) {
|
func BufMapMouse(k MouseEvent, action string) {
|
||||||
if f, ok := BufMouseActions[action]; ok {
|
if f, ok := BufMouseActions[action]; ok {
|
||||||
BufMouseBindings[k] = f
|
BufBindings.RegisterMouseBinding(k, BufMouseActionGeneral(f))
|
||||||
|
// BufMouseBindings[k] = f
|
||||||
} else {
|
} else {
|
||||||
delete(BufMouseBindings, k)
|
// TODO
|
||||||
|
// delete(BufMouseBindings, k)
|
||||||
|
// BufMapKey(k, action)
|
||||||
BufMapKey(k, action)
|
BufMapKey(k, action)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BufUnmap unmaps a key or mouse event from any action
|
// BufUnmap unmaps a key or mouse event from any action
|
||||||
func BufUnmap(k Event) {
|
func BufUnmap(k Event) {
|
||||||
delete(BufKeyBindings, k)
|
// TODO
|
||||||
delete(BufKeyStrings, k)
|
// delete(BufKeyBindings, k)
|
||||||
|
// delete(BufKeyStrings, k)
|
||||||
switch e := k.(type) {
|
//
|
||||||
case MouseEvent:
|
// switch e := k.(type) {
|
||||||
delete(BufMouseBindings, e)
|
// case MouseEvent:
|
||||||
}
|
// delete(BufMouseBindings, e)
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// The BufPane connects the buffer and the window
|
// The BufPane connects the buffer and the window
|
||||||
@@ -163,9 +185,13 @@ func BufUnmap(k Event) {
|
|||||||
type BufPane struct {
|
type BufPane struct {
|
||||||
display.BWindow
|
display.BWindow
|
||||||
|
|
||||||
|
// Buf is the buffer this BufPane views
|
||||||
Buf *buffer.Buffer
|
Buf *buffer.Buffer
|
||||||
|
// Bindings stores the association of key events and actions
|
||||||
|
Bindings *KeyTree
|
||||||
|
|
||||||
Cursor *buffer.Cursor // the active cursor
|
// Cursor is the currently active buffer cursor
|
||||||
|
Cursor *buffer.Cursor
|
||||||
|
|
||||||
// Since tcell doesn't differentiate between a mouse release event
|
// Since tcell doesn't differentiate between a mouse release event
|
||||||
// and a mouse move event with no keys pressed, we need to keep
|
// and a mouse move event with no keys pressed, we need to keep
|
||||||
@@ -399,9 +425,17 @@ func (h *BufPane) HandleEvent(event tcell.Event) {
|
|||||||
// DoKeyEvent executes a key event by finding the action it is bound
|
// DoKeyEvent executes a key event by finding the action it is bound
|
||||||
// to and executing it (possibly multiple times for multiple cursors)
|
// to and executing it (possibly multiple times for multiple cursors)
|
||||||
func (h *BufPane) DoKeyEvent(e Event) bool {
|
func (h *BufPane) DoKeyEvent(e Event) bool {
|
||||||
if action, ok := BufKeyBindings[e]; ok {
|
action, more := BufBindings.NextEvent(e, nil)
|
||||||
return action(h)
|
log.Println("Next event", e, more)
|
||||||
|
if action != nil && !more {
|
||||||
|
action(h)
|
||||||
|
BufBindings.ResetEvents()
|
||||||
|
} else if action == nil && !more {
|
||||||
|
BufBindings.ResetEvents()
|
||||||
}
|
}
|
||||||
|
// if action, ok := BufKeyBindings[e]; ok {
|
||||||
|
// return action(h)
|
||||||
|
// }
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -436,22 +470,36 @@ func (h *BufPane) completeAction(action string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *BufPane) HasKeyEvent(e Event) bool {
|
func (h *BufPane) HasKeyEvent(e Event) bool {
|
||||||
_, ok := BufKeyBindings[e]
|
// TODO
|
||||||
return ok
|
return true
|
||||||
|
// _, ok := BufKeyBindings[e]
|
||||||
|
// return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// DoMouseEvent executes a mouse event by finding the action it is bound
|
// DoMouseEvent executes a mouse event by finding the action it is bound
|
||||||
// to and executing it
|
// to and executing it
|
||||||
func (h *BufPane) DoMouseEvent(e MouseEvent, te *tcell.EventMouse) bool {
|
func (h *BufPane) DoMouseEvent(e MouseEvent, te *tcell.EventMouse) bool {
|
||||||
if action, ok := BufMouseBindings[e]; ok {
|
log.Println("DOMOUSEEVENT")
|
||||||
if action(h, te) {
|
action, _ := BufBindings.NextEvent(e, te)
|
||||||
|
if action != nil {
|
||||||
|
if action(h) {
|
||||||
h.Relocate()
|
h.Relocate()
|
||||||
}
|
}
|
||||||
|
BufBindings.ResetEvents()
|
||||||
return true
|
return true
|
||||||
} else if h.HasKeyEvent(e) {
|
|
||||||
return h.DoKeyEvent(e)
|
|
||||||
}
|
}
|
||||||
|
// TODO
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
// if action, ok := BufMouseBindings[e]; ok {
|
||||||
|
// if action(h, te) {
|
||||||
|
// h.Relocate()
|
||||||
|
// }
|
||||||
|
// return true
|
||||||
|
// } else if h.HasKeyEvent(e) {
|
||||||
|
// return h.DoKeyEvent(e)
|
||||||
|
// }
|
||||||
|
// return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// DoRuneInsert inserts a given rune into the current buffer
|
// DoRuneInsert inserts a given rune into the current buffer
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Event interface {
|
type Event interface {
|
||||||
String() string
|
Name() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// RawEvent is simply an escape code
|
// RawEvent is simply an escape code
|
||||||
@@ -20,7 +20,7 @@ type RawEvent struct {
|
|||||||
esc string
|
esc string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r RawEvent) String() string {
|
func (r RawEvent) Name() string {
|
||||||
return r.esc
|
return r.esc
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ type KeyEvent struct {
|
|||||||
any bool
|
any bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k KeyEvent) String() string {
|
func (k KeyEvent) Name() string {
|
||||||
if k.any {
|
if k.any {
|
||||||
return "<any>"
|
return "<any>"
|
||||||
}
|
}
|
||||||
@@ -82,10 +82,12 @@ type KeySequenceEvent struct {
|
|||||||
keys []Event
|
keys []Event
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k KeySequenceEvent) String() string {
|
func (k KeySequenceEvent) Name() string {
|
||||||
buf := bytes.Buffer{}
|
buf := bytes.Buffer{}
|
||||||
for _, e := range k.keys {
|
for _, e := range k.keys {
|
||||||
buf.WriteString(e.String())
|
buf.WriteByte('<')
|
||||||
|
buf.WriteString(e.Name())
|
||||||
|
buf.WriteByte('>')
|
||||||
}
|
}
|
||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
@@ -97,7 +99,7 @@ type MouseEvent struct {
|
|||||||
mod tcell.ModMask
|
mod tcell.ModMask
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m MouseEvent) String() string {
|
func (m MouseEvent) Name() string {
|
||||||
mod := ""
|
mod := ""
|
||||||
if m.mod&tcell.ModShift != 0 {
|
if m.mod&tcell.ModShift != 0 {
|
||||||
mod = "Shift-"
|
mod = "Shift-"
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
package action
|
package action
|
||||||
|
|
||||||
type KeyAction func(Pane) bool
|
import (
|
||||||
type MouseAction func(Pane, *MouseEvent) bool
|
"log"
|
||||||
|
|
||||||
type KeyAnyAction func(Pane, []KeyEvent) bool
|
"github.com/zyedidia/tcell"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PaneKeyAction func(Pane) bool
|
||||||
|
type PaneMouseAction func(Pane, *tcell.EventMouse) bool
|
||||||
|
type PaneKeyAnyAction func(Pane, []KeyEvent) bool
|
||||||
|
|
||||||
// A KeyTreeNode stores a single node in the KeyTree (trie). The
|
// A KeyTreeNode stores a single node in the KeyTree (trie). The
|
||||||
// children are stored as a map, and any node may store a list of
|
// children are stored as a map, and any node may store a list of
|
||||||
@@ -30,9 +35,9 @@ func NewKeyTreeNode() *KeyTreeNode {
|
|||||||
// the action to be active.
|
// the action to be active.
|
||||||
type TreeAction struct {
|
type TreeAction struct {
|
||||||
// only one of these can be non-nil
|
// only one of these can be non-nil
|
||||||
action KeyAction
|
action PaneKeyAction
|
||||||
any KeyAnyAction
|
any PaneKeyAnyAction
|
||||||
mouse MouseAction
|
mouse PaneMouseAction
|
||||||
|
|
||||||
modes []ModeConstraint
|
modes []ModeConstraint
|
||||||
}
|
}
|
||||||
@@ -56,13 +61,13 @@ type KeyTreeCursor struct {
|
|||||||
node *KeyTreeNode
|
node *KeyTreeNode
|
||||||
|
|
||||||
wildcards []KeyEvent
|
wildcards []KeyEvent
|
||||||
mouseInfo *MouseEvent
|
mouseInfo *tcell.EventMouse
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeClosure uses the information stored in a key tree cursor to construct
|
// MakeClosure uses the information stored in a key tree cursor to construct
|
||||||
// a KeyAction from a TreeAction (which may have a KeyAction, MouseAction,
|
// a PaneKeyAction from a TreeAction (which may have a PaneKeyAction, PaneMouseAction,
|
||||||
// or AnyAction)
|
// or AnyAction)
|
||||||
func (k *KeyTreeCursor) MakeClosure(a TreeAction) KeyAction {
|
func (k *KeyTreeCursor) MakeClosure(a TreeAction) PaneKeyAction {
|
||||||
if a.action != nil {
|
if a.action != nil {
|
||||||
return a.action
|
return a.action
|
||||||
} else if a.any != nil {
|
} else if a.any != nil {
|
||||||
@@ -80,7 +85,7 @@ func (k *KeyTreeCursor) MakeClosure(a TreeAction) KeyAction {
|
|||||||
|
|
||||||
// NewKeyTree allocates and returns an empty key tree
|
// NewKeyTree allocates and returns an empty key tree
|
||||||
func NewKeyTree() *KeyTree {
|
func NewKeyTree() *KeyTree {
|
||||||
root := new(KeyTreeNode)
|
root := NewKeyTreeNode()
|
||||||
tree := new(KeyTree)
|
tree := new(KeyTree)
|
||||||
|
|
||||||
tree.root = root
|
tree.root = root
|
||||||
@@ -101,8 +106,8 @@ type ModeConstraint struct {
|
|||||||
disabled bool
|
disabled bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterKeyBinding registers a KeyAction with an Event.
|
// RegisterKeyBinding registers a PaneKeyAction with an Event.
|
||||||
func (k *KeyTree) RegisterKeyBinding(e Event, a KeyAction) {
|
func (k *KeyTree) RegisterKeyBinding(e Event, a PaneKeyAction) {
|
||||||
k.registerBinding(e, TreeAction{
|
k.registerBinding(e, TreeAction{
|
||||||
action: a,
|
action: a,
|
||||||
any: nil,
|
any: nil,
|
||||||
@@ -111,9 +116,9 @@ func (k *KeyTree) RegisterKeyBinding(e Event, a KeyAction) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterKeyAnyBinding registers a KeyAnyAction with an Event.
|
// RegisterKeyAnyBinding registers a PaneKeyAnyAction with an Event.
|
||||||
// The event should contain an "any" event.
|
// The event should contain an "any" event.
|
||||||
func (k *KeyTree) RegisterKeyAnyBinding(e Event, a KeyAnyAction) {
|
func (k *KeyTree) RegisterKeyAnyBinding(e Event, a PaneKeyAnyAction) {
|
||||||
k.registerBinding(e, TreeAction{
|
k.registerBinding(e, TreeAction{
|
||||||
action: nil,
|
action: nil,
|
||||||
any: a,
|
any: a,
|
||||||
@@ -122,9 +127,9 @@ func (k *KeyTree) RegisterKeyAnyBinding(e Event, a KeyAnyAction) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterMouseBinding registers a MouseAction with an Event.
|
// RegisterMouseBinding registers a PaneMouseAction with an Event.
|
||||||
// The event should contain a mouse event.
|
// The event should contain a mouse event.
|
||||||
func (k *KeyTree) RegisterMouseBinding(e Event, a MouseAction) {
|
func (k *KeyTree) RegisterMouseBinding(e Event, a PaneMouseAction) {
|
||||||
k.registerBinding(e, TreeAction{
|
k.registerBinding(e, TreeAction{
|
||||||
action: nil,
|
action: nil,
|
||||||
any: nil,
|
any: nil,
|
||||||
@@ -135,19 +140,19 @@ func (k *KeyTree) RegisterMouseBinding(e Event, a MouseAction) {
|
|||||||
|
|
||||||
func (k *KeyTree) registerBinding(e Event, a TreeAction) {
|
func (k *KeyTree) registerBinding(e Event, a TreeAction) {
|
||||||
switch ev := e.(type) {
|
switch ev := e.(type) {
|
||||||
case *KeyEvent, *MouseEvent:
|
case KeyEvent, MouseEvent:
|
||||||
n, ok := k.root.children[e]
|
newNode, ok := k.root.children[e]
|
||||||
if !ok {
|
if !ok {
|
||||||
newNode := NewKeyTreeNode()
|
newNode = NewKeyTreeNode()
|
||||||
k.root.children[e] = newNode
|
k.root.children[e] = newNode
|
||||||
}
|
}
|
||||||
n.actions = append(n.actions, a)
|
newNode.actions = append(newNode.actions, a)
|
||||||
case *KeySequenceEvent:
|
case KeySequenceEvent:
|
||||||
n := k.root
|
n := k.root
|
||||||
for _, key := range ev.keys {
|
for _, key := range ev.keys {
|
||||||
newNode, ok := n.children[key]
|
newNode, ok := n.children[key]
|
||||||
if !ok {
|
if !ok {
|
||||||
newNode := NewKeyTreeNode()
|
newNode = NewKeyTreeNode()
|
||||||
n.children[key] = newNode
|
n.children[key] = newNode
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,8 +163,8 @@ func (k *KeyTree) registerBinding(e Event, a TreeAction) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NextEvent returns the action for the current sequence where e is the next
|
// NextEvent returns the action for the current sequence where e is the next
|
||||||
// event. Even if the action was registered as a KeyAnyAction or MouseAction,
|
// event. Even if the action was registered as a PaneKeyAnyAction or PaneMouseAction,
|
||||||
// it will be returned as a KeyAction closure where the appropriate arguments
|
// it will be returned as a PaneKeyAction closure where the appropriate arguments
|
||||||
// have been provided.
|
// have been provided.
|
||||||
// If no action is associated with the given Event, or mode constraints are not
|
// If no action is associated with the given Event, or mode constraints are not
|
||||||
// met for that action, nil is returned.
|
// met for that action, nil is returned.
|
||||||
@@ -168,15 +173,28 @@ func (k *KeyTree) registerBinding(e Event, a TreeAction) {
|
|||||||
// bindings associated with further sequences starting with this event. The
|
// bindings associated with further sequences starting with this event. The
|
||||||
// calling function can decide what to do about the conflict (e.g. use a
|
// calling function can decide what to do about the conflict (e.g. use a
|
||||||
// timeout).
|
// timeout).
|
||||||
func (k *KeyTree) NextEvent(e Event) (KeyAction, bool) {
|
func (k *KeyTree) NextEvent(e Event, mouse *tcell.EventMouse) (PaneKeyAction, bool) {
|
||||||
n := k.cursor.node
|
n := k.cursor.node
|
||||||
c, ok := n.children[e]
|
c, ok := n.children[e]
|
||||||
|
log.Println("NEXT EVENT", e, len(n.children), ok)
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
more := len(c.children) > 0
|
more := len(c.children) > 0
|
||||||
|
|
||||||
|
k.cursor.node = c
|
||||||
|
|
||||||
|
switch ev := e.(type) {
|
||||||
|
case KeyEvent:
|
||||||
|
if ev.any {
|
||||||
|
k.cursor.wildcards = append(k.cursor.wildcards, ev)
|
||||||
|
}
|
||||||
|
case MouseEvent:
|
||||||
|
k.cursor.mouseInfo = mouse
|
||||||
|
}
|
||||||
|
|
||||||
if len(c.actions) > 0 {
|
if len(c.actions) > 0 {
|
||||||
// check if actions are active
|
// check if actions are active
|
||||||
for _, a := range c.actions {
|
for _, a := range c.actions {
|
||||||
@@ -199,8 +217,8 @@ func (k *KeyTree) NextEvent(e Event) (KeyAction, bool) {
|
|||||||
return nil, more
|
return nil, more
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset sets the current sequence back to the initial value.
|
// ResetEvents sets the current sequence back to the initial value.
|
||||||
func (k *KeyTree) Reset() {
|
func (k *KeyTree) ResetEvents() {
|
||||||
k.cursor.node = k.root
|
k.cursor.node = k.root
|
||||||
k.cursor.wildcards = []KeyEvent{}
|
k.cursor.wildcards = []KeyEvent{}
|
||||||
k.cursor.mouseInfo = nil
|
k.cursor.mouseInfo = nil
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ func (h *RawPane) HandleEvent(event tcell.Event) {
|
|||||||
|
|
||||||
e, err := ConstructEvent(event)
|
e, err := ConstructEvent(event)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
h.Buf.Insert(h.Cursor.Loc, fmt.Sprintf(": %s", e.String()))
|
h.Buf.Insert(h.Cursor.Loc, fmt.Sprintf(": %s", e.Name()))
|
||||||
}
|
}
|
||||||
|
|
||||||
h.Buf.Insert(h.Cursor.Loc, fmt.Sprintf(": %q\n", event.EscSeq()))
|
h.Buf.Insert(h.Cursor.Loc, fmt.Sprintf(": %q\n", event.EscSeq()))
|
||||||
|
|||||||
Reference in New Issue
Block a user