mirror of
https://github.com/peco/peco.git
synced 2026-09-10 07:16:29 -04:00
Remove global Keyseq, embed in Keymap
This commit is contained in:
parent
8d84660f67
commit
9264c9fa7e
41
action.go
41
action.go
|
|
@ -1,6 +1,7 @@
|
|||
package peco
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"unicode"
|
||||
|
||||
"github.com/nsf/termbox-go"
|
||||
|
|
@ -24,7 +25,7 @@ type ActionFunc func(*Input, termbox.Event)
|
|||
var nameToActions map[string]Action
|
||||
|
||||
// This is the default keybinding used by NewKeymap()
|
||||
var defaultKeyBinding map[termbox.Key]Action
|
||||
var defaultKeyBinding map[string]Action
|
||||
|
||||
// Execute fulfills the Action interface for AfterFunc
|
||||
func (a ActionFunc) Execute(i *Input, e termbox.Event) {
|
||||
|
|
@ -37,18 +38,22 @@ func (a ActionFunc) Execute(i *Input, e termbox.Event) {
|
|||
func (a ActionFunc) Register(name string, defaultKeys ...termbox.Key) {
|
||||
nameToActions["peco."+name] = a
|
||||
for _, k := range defaultKeys {
|
||||
Keyseq.Add(keyseq.KeyList{keyseq.NewKeyFromKey(k)}, a)
|
||||
a.RegisterKeySequence(keyseq.KeyList{keyseq.NewKeyFromKey(k)})
|
||||
}
|
||||
}
|
||||
|
||||
func (a ActionFunc) RegisterKeySequence(k keyseq.KeyList) {
|
||||
Keyseq.Add(k, a)
|
||||
b, err := json.Marshal(k)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defaultKeyBinding[string(b)] = a
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Build the global maps
|
||||
nameToActions = map[string]Action{}
|
||||
defaultKeyBinding = map[termbox.Key]Action{}
|
||||
defaultKeyBinding = map[string]Action{}
|
||||
|
||||
ActionFunc(doBeginningOfLine).Register("BeginningOfLine", termbox.KeyCtrlA)
|
||||
ActionFunc(doBackwardChar).Register("BackwardChar", termbox.KeyCtrlB)
|
||||
|
|
@ -109,21 +114,19 @@ func init() {
|
|||
|
||||
ActionFunc(doKonamiCommand).RegisterKeySequence(
|
||||
keyseq.KeyList{
|
||||
keyseq.Key{0,termbox.KeyCtrlX,0},
|
||||
keyseq.Key{0,termbox.KeyArrowUp,0},
|
||||
keyseq.Key{0,termbox.KeyArrowUp,0},
|
||||
keyseq.Key{0,termbox.KeyArrowDown,0},
|
||||
keyseq.Key{0,termbox.KeyArrowDown,0},
|
||||
keyseq.Key{0,termbox.KeyArrowLeft,0},
|
||||
keyseq.Key{0,termbox.KeyArrowRight,0},
|
||||
keyseq.Key{0,termbox.KeyArrowLeft,0},
|
||||
keyseq.Key{0,termbox.KeyArrowRight,0},
|
||||
keyseq.Key{0,0,'b'},
|
||||
keyseq.Key{0,0,'a'},
|
||||
keyseq.Key{0, termbox.KeyCtrlX, 0},
|
||||
keyseq.Key{0, termbox.KeyArrowUp, 0},
|
||||
keyseq.Key{0, termbox.KeyArrowUp, 0},
|
||||
keyseq.Key{0, termbox.KeyArrowDown, 0},
|
||||
keyseq.Key{0, termbox.KeyArrowDown, 0},
|
||||
keyseq.Key{0, termbox.KeyArrowLeft, 0},
|
||||
keyseq.Key{0, termbox.KeyArrowRight, 0},
|
||||
keyseq.Key{0, termbox.KeyArrowLeft, 0},
|
||||
keyseq.Key{0, termbox.KeyArrowRight, 0},
|
||||
keyseq.Key{0, 0, 'b'},
|
||||
keyseq.Key{0, 0, 'a'},
|
||||
},
|
||||
)
|
||||
|
||||
Keyseq.Compile()
|
||||
}
|
||||
|
||||
// This is a noop action
|
||||
|
|
@ -224,8 +227,8 @@ func doFinish(i *Input, _ termbox.Event) {
|
|||
}
|
||||
|
||||
func doCancel(i *Input, ev termbox.Event) {
|
||||
if Keyseq.InMiddleOfChain() {
|
||||
Keyseq.CancelChain()
|
||||
if i.currentKeymap.Keyseq.InMiddleOfChain() {
|
||||
i.currentKeymap.Keyseq.CancelChain()
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
2
ctx.go
2
ctx.go
|
|
@ -245,7 +245,7 @@ func (c *Ctx) NewInput() *Input {
|
|||
// Create a new keymap object
|
||||
k := NewKeymap()
|
||||
k.ApplyConfig(c.config.Keymap)
|
||||
return &Input{c, &sync.Mutex{}, nil, k, false}
|
||||
return &Input{c, &sync.Mutex{}, nil, k}
|
||||
}
|
||||
|
||||
func (c *Ctx) Stop() {
|
||||
|
|
|
|||
3
input.go
3
input.go
|
|
@ -12,7 +12,6 @@ type Input struct {
|
|||
mutex *sync.Mutex // Currently only used for protecting Alt/Esc workaround
|
||||
mod *time.Timer
|
||||
currentKeymap Keymap
|
||||
chained bool
|
||||
}
|
||||
|
||||
func (i *Input) Loop() {
|
||||
|
|
@ -84,7 +83,7 @@ func (i *Input) handleInputEvent(ev termbox.Event) {
|
|||
}
|
||||
|
||||
func (i *Input) handleKeyEvent(ev termbox.Event) {
|
||||
if h := i.currentKeymap.Handler(ev, i.chained); h != nil {
|
||||
if h := i.currentKeymap.Handler(ev); h != nil {
|
||||
h.Execute(i, ev)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
35
keymap.go
35
keymap.go
|
|
@ -1,6 +1,7 @@
|
|||
package peco
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
|
@ -16,13 +17,9 @@ const (
|
|||
ModMax
|
||||
)
|
||||
|
||||
// Keyseq does successive matches against key events.
|
||||
var Keyseq = keyseq.New()
|
||||
|
||||
type Keymap [ModMax]RawKeymap
|
||||
|
||||
// RawKeymap contains the actual mapping from termbox.Key to Action
|
||||
type RawKeymap map[termbox.Key]Action
|
||||
type Keymap struct {
|
||||
Keyseq *keyseq.Keyseq
|
||||
}
|
||||
|
||||
type KeymapStringKey string
|
||||
|
||||
|
|
@ -153,24 +150,26 @@ func (ksk KeymapStringKey) ToKey() (k termbox.Key, modifier int, ch rune, err er
|
|||
}
|
||||
|
||||
func NewKeymap() Keymap {
|
||||
def := RawKeymap{}
|
||||
for k, v := range defaultKeyBinding {
|
||||
def[k] = v
|
||||
}
|
||||
return Keymap{
|
||||
def,
|
||||
{},
|
||||
k := keyseq.New()
|
||||
for s, a := range defaultKeyBinding {
|
||||
kl := keyseq.KeyList{}
|
||||
if err := json.Unmarshal([]byte(s), &kl); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
k.Add(kl, a)
|
||||
}
|
||||
k.Compile()
|
||||
return Keymap{k}
|
||||
}
|
||||
|
||||
func (km Keymap) Handler(ev termbox.Event, chained bool) Action {
|
||||
func (km Keymap) Handler(ev termbox.Event) Action {
|
||||
modifier := ModNone
|
||||
if (ev.Mod & termbox.ModAlt) != 0 {
|
||||
modifier = ModAlt
|
||||
}
|
||||
|
||||
key := keyseq.Key{modifier, ev.Key, ev.Ch}
|
||||
action, err := Keyseq.AcceptKey(key)
|
||||
action, err := km.Keyseq.AcceptKey(key)
|
||||
|
||||
switch err {
|
||||
case nil:
|
||||
|
|
@ -204,11 +203,11 @@ func (km Keymap) ApplyConfig(c map[string]string) {
|
|||
continue
|
||||
}
|
||||
|
||||
Keyseq.Add(list, v)
|
||||
km.Keyseq.Add(list, v)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: this needs to be fixed.
|
||||
func (km Keymap) hasModifierMaps() bool {
|
||||
return len(km[ModAlt]) > 0
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,26 +39,31 @@ func TestKeymapStrToKeyValue(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestKeymapStrToKeyValueWithAlt(t *testing.T) {
|
||||
expected := map[string]termbox.Key{
|
||||
"M-v": termbox.Key('v'),
|
||||
"M-C-v": termbox.KeyCtrlV,
|
||||
"M-Space": termbox.KeySpace,
|
||||
"M-MouseLeft": termbox.MouseLeft,
|
||||
expected := map[string]struct{
|
||||
key termbox.Key
|
||||
ch rune
|
||||
} {
|
||||
"M-v": {0, 'v'},
|
||||
"M-C-v": {termbox.KeyCtrlV,rune(0)},
|
||||
"M-Space": {termbox.KeySpace, rune(0)},
|
||||
"M-MouseLeft": {termbox.MouseLeft, rune(0)},
|
||||
}
|
||||
|
||||
t.Logf("Checking Alt prefixed key name mapping...")
|
||||
for n, v := range expected {
|
||||
t.Logf(" checking %s...", n)
|
||||
// TODO ch isn't being checked
|
||||
k, modifier, _, err := KeymapStringKey(n).ToKey()
|
||||
k, modifier, ch, err := KeymapStringKey(n).ToKey()
|
||||
if err != nil {
|
||||
t.Errorf("Failed ToKey: Key name %s", n)
|
||||
}
|
||||
if modifier != 1 {
|
||||
t.Errorf("Key name %s has Alt prefix", n)
|
||||
}
|
||||
if k != v {
|
||||
t.Errorf("Expected '%s' to be '%d', but got '%d'", n, v, stringToKey[n])
|
||||
if k != v.key {
|
||||
t.Errorf("Expected '%s' to be '%d', but got '%d'", n, v.key, k)
|
||||
}
|
||||
if ch != v.ch {
|
||||
t.Errorf("Expected '%s' to be '%c', but got '%c'", n, v.ch, ch)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue