162 lines
4.5 KiB
Go
162 lines
4.5 KiB
Go
package input
|
|
|
|
import (
|
|
"git.gophernest.net/azpect/TextEditor/internal/action"
|
|
"git.gophernest.net/azpect/TextEditor/internal/command"
|
|
"git.gophernest.net/azpect/TextEditor/internal/motion"
|
|
"git.gophernest.net/azpect/TextEditor/internal/operator"
|
|
)
|
|
|
|
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{},
|
|
"_": motion.MoveToLineContentStart{},
|
|
"w": motion.MoveForwardWord{Count: 1},
|
|
"e": motion.MoveForwardWordEnd{Count: 1},
|
|
"b": motion.MoveBackwardWord{Count: 1},
|
|
},
|
|
operators: map[string]action.Operator{
|
|
"d": operator.DeleteOperator{},
|
|
// "c": ChangeOp{},
|
|
// "y": YankOp{},
|
|
// "p": PasteOp{},
|
|
// "s": SubstitueOp{},
|
|
// "~": SwapCaseOp{},
|
|
},
|
|
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{},
|
|
":": action.EnterComandMode{},
|
|
"v": action.EnterVisualMode{},
|
|
"V": action.EnterVisualLineMode{},
|
|
"ctrl+v": action.EnterVisualBlockMode{},
|
|
"D": action.DeleteToEndOfLine{Count: 1},
|
|
},
|
|
}
|
|
}
|
|
|
|
func NewVisualKeymap() *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{},
|
|
"_": motion.MoveToLineContentStart{},
|
|
"w": motion.MoveForwardWord{Count: 1},
|
|
"e": motion.MoveForwardWordEnd{Count: 1},
|
|
"b": motion.MoveBackwardWord{Count: 1},
|
|
},
|
|
operators: map[string]action.Operator{
|
|
"d": operator.DeleteOperator{},
|
|
"x": operator.DeleteOperator{},
|
|
// "c": ChangeOp{},
|
|
// "y": YankOp{},
|
|
// "p": PasteOp{},
|
|
// "s": SubstitueOp{},
|
|
// "~": SwapCaseOp{},
|
|
},
|
|
actions: map[string]action.Action{
|
|
"ctrl+c": action.Quit{},
|
|
// ":": action.EnterComandMode{}, // Different OP
|
|
},
|
|
}
|
|
}
|
|
|
|
func NewInsertKeymap() *Keymap {
|
|
return &Keymap{
|
|
motions: map[string]action.Motion{
|
|
"down": motion.MoveDown{Count: 1},
|
|
"up": motion.MoveUp{Count: 1},
|
|
"left": motion.MoveLeft{Count: 1},
|
|
"right": motion.MoveRight{Count: 1},
|
|
},
|
|
operators: map[string]action.Operator{}, // this will likely be empty
|
|
actions: map[string]action.Action{
|
|
"enter": action.InsertNewline{},
|
|
"backspace": action.InsertBackspace{},
|
|
"delete": action.InsertDelete{},
|
|
"tab": action.InsertTab{},
|
|
"ctrl+w": action.InsertDeletePreviousWord{},
|
|
"ctrl+c": action.Quit{},
|
|
},
|
|
}
|
|
|
|
}
|
|
|
|
func NewCommandKeymap() *Keymap {
|
|
return &Keymap{
|
|
motions: map[string]action.Motion{
|
|
"left": motion.MoveCommandLeft{},
|
|
"right": motion.MoveCommandRight{},
|
|
},
|
|
operators: map[string]action.Operator{}, // this will likely be empty
|
|
actions: map[string]action.Action{
|
|
"esc": action.ExitCommandMode{},
|
|
"enter": action.CommandExecute{Registry: command.DefaultRegistry},
|
|
"backspace": action.CommandBackspace{},
|
|
"delete": action.CommandDelete{},
|
|
"ctrl+w": action.CommandDeletePreviousWord{},
|
|
},
|
|
}
|
|
|
|
}
|
|
|
|
// 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
|
|
}
|