package input import ( "git.gophernest.net/azpect/TextEditor/internal/action" "git.gophernest.net/azpect/TextEditor/internal/motion" ) type Keymap struct { motions map[string]action.Motion operators map[string]action.Operator actions map[string]action.Action // standalone actions: i.e., 'i', 'a' } func NewNormalKeymap() *Keymap { return &Keymap{ motions: map[string]action.Motion{ "j": motion.MoveDown{Count: 1}, "k": motion.MoveUp{Count: 1}, "h": motion.MoveLeft{Count: 1}, "l": motion.MoveRight{Count: 1}, "G": motion.MoveToBottom{}, "gg": motion.MoveToTop{}, "0": motion.MoveToLineStart{}, "$": motion.MoveToLineEnd{}, "w": motion.MoveForwardWord{Count: 1}, "e": motion.MoveForwardWordEnd{Count: 1}, "b": motion.MoveBackwardWord{Count: 1}, }, operators: map[string]action.Operator{ // "d": DeleteOp{}, // "c": ChangeOp{}, // "y": YankOp{}, }, actions: map[string]action.Action{ "i": action.EnterInsert{}, "a": action.EnterInsertAfter{}, "I": action.EnterInsertLineStart{}, "A": action.EnterInsertLineEnd{}, "o": action.OpenLineBelow{}, "O": action.OpenLineAbove{}, "x": action.DeleteChar{Count: 1}, "ctrl+c": action.Quit{}, }, } } // Lookup returns what type of binding a key is func (km *Keymap) Lookup(key string) (kind string, value any) { if m, ok := km.motions[key]; ok { return "motion", m } if o, ok := km.operators[key]; ok { return "operator", o } if a, ok := km.actions[key]; ok { return "action", a } return "", nil } // HasPrefix returns true if any binding starts with this prefix func (km *Keymap) HasPrefix(prefix string) bool { for key := range km.motions { if len(key) > len(prefix) && key[:len(prefix)] == prefix { return true } } for key := range km.operators { if len(key) > len(prefix) && key[:len(prefix)] == prefix { return true } } for key := range km.actions { if len(key) > len(prefix) && key[:len(prefix)] == prefix { return true } } return false }