for k, v := range parsed {
BindKey(k, v)
}
+
+ defaultInfos := DefaultInfoBindings()
+ for k, v := range defaultInfos {
+ BindInfoKey(k, v)
+ }
+}
+
+func BindInfoKey(k, v string) {
+ event, err := findEvent(k)
+ if err != nil {
+ screen.TermMessage(err)
+ }
+
+ switch e := event.(type) {
+ case KeyEvent:
+ InfoMapKey(e, v)
+ case KeySequenceEvent:
+ InfoMapKey(e, v)
+ case MouseEvent:
+ InfoMapMouse(e, v)
+ case RawEvent:
+ InfoMapKey(e, v)
+ }
}
func BindKey(k, v string) {
type BufMouseAction func(*BufPane, *tcell.EventMouse) bool
var BufBindings *KeyTree
-var BufKeyBindings map[Event]BufKeyAction
-var BufKeyStrings map[Event]string
-var BufMouseBindings map[MouseEvent]BufMouseAction
func BufKeyActionGeneral(a BufKeyAction) PaneKeyAction {
return func(p Pane) bool {
}
func init() {
- BufKeyBindings = make(map[Event]BufKeyAction)
- BufKeyStrings = make(map[Event]string)
- BufMouseBindings = make(map[MouseEvent]BufMouseAction)
-
BufBindings = NewKeyTree()
}
// BufMapKey maps a key event to an action
func BufMapKey(k Event, action string) {
- // BufKeyStrings[k] = action
var actionfns []func(*BufPane) bool
var names []string
var types []byte
func BufMapMouse(k MouseEvent, action string) {
if f, ok := BufMouseActions[action]; ok {
BufBindings.RegisterMouseBinding(k, BufMouseActionGeneral(f))
- // BufMouseBindings[k] = f
} else {
// TODO
// delete(BufMouseBindings, k)
- // BufMapKey(k, action)
BufMapKey(k, action)
}
}
func BufUnmap(k Event) {
// TODO
// delete(BufKeyBindings, k)
- // delete(BufKeyStrings, k)
//
// switch e := k.(type) {
// case MouseEvent:
// Buf is the buffer this BufPane views
Buf *buffer.Buffer
// Bindings stores the association of key events and actions
- Bindings *KeyTree
+ bindings *KeyTree
// Cursor is the currently active buffer cursor
Cursor *buffer.Cursor
}
}
+func (h *BufPane) Bindings() *KeyTree {
+ if h.bindings != nil {
+ return h.bindings
+ }
+ return BufBindings
+}
+
// DoKeyEvent executes a key event by finding the action it is bound
// to and executing it (possibly multiple times for multiple cursors)
func (h *BufPane) DoKeyEvent(e Event) bool {
- action, more := BufBindings.NextEvent(e, nil)
+ binds := h.Bindings()
+ action, more := binds.NextEvent(e, nil)
log.Println("Next event", e, more)
if action != nil && !more {
action(h)
- BufBindings.ResetEvents()
+ binds.ResetEvents()
} else if action == nil && !more {
- BufBindings.ResetEvents()
+ binds.ResetEvents()
}
- // if action, ok := BufKeyBindings[e]; ok {
- // return action(h)
- // }
return false
}
// DoMouseEvent executes a mouse event by finding the action it is bound
// to and executing it
func (h *BufPane) DoMouseEvent(e MouseEvent, te *tcell.EventMouse) bool {
- log.Println("DOMOUSEEVENT")
- action, _ := BufBindings.NextEvent(e, te)
+ binds := h.Bindings()
+ action, _ := binds.NextEvent(e, te)
if action != nil {
if action(h) {
h.Relocate()
}
- BufBindings.ResetEvents()
+ binds.ResetEvents()
return true
}
// TODO
"Alt-x": "SkipMultiCursor",
}
}
+
+func DefaultInfoBindings() map[string]string {
+ return map[string]string{
+ "Up": "HistoryUp",
+ "Down": "HistoryDown",
+ "Right": "CursorRight",
+ "Left": "CursorLeft",
+ "ShiftUp": "SelectUp",
+ "ShiftDown": "SelectDown",
+ "ShiftLeft": "SelectLeft",
+ "ShiftRight": "SelectRight",
+ "AltLeft": "WordLeft",
+ "AltRight": "WordRight",
+ "AltUp": "CursorStart",
+ "AltDown": "CursorEnd",
+ "AltShiftRight": "SelectWordRight",
+ "AltShiftLeft": "SelectWordLeft",
+ "CtrlLeft": "StartOfTextToggle",
+ "CtrlRight": "EndOfLine",
+ "CtrlShiftLeft": "SelectToStartOfTextToggle",
+ "ShiftHome": "SelectToStartOfTextToggle",
+ "CtrlShiftRight": "SelectToEndOfLine",
+ "ShiftEnd": "SelectToEndOfLine",
+ "CtrlUp": "CursorStart",
+ "CtrlDown": "CursorEnd",
+ "CtrlShiftUp": "SelectToStart",
+ "CtrlShiftDown": "SelectToEnd",
+ "Enter": "ExecuteCommand",
+ "CtrlH": "Backspace",
+ "Backspace": "Backspace",
+ "OldBackspace": "Backspace",
+ "Alt-CtrlH": "DeleteWordLeft",
+ "Alt-Backspace": "DeleteWordLeft",
+ "Tab": "CommandComplete",
+ "Backtab": "CycleAutocompleteBack",
+ "Ctrl-z": "Undo",
+ "Ctrl-y": "Redo",
+ "Ctrl-c": "CopyLine|Copy",
+ "Ctrl-x": "Cut",
+ "Ctrl-k": "CutLine",
+ "Ctrl-v": "Paste",
+ "Home": "StartOfTextToggle",
+ "End": "EndOfLine",
+ "CtrlHome": "CursorStart",
+ "CtrlEnd": "CursorEnd",
+ "Delete": "Delete",
+ "Ctrl-q": "AbortCommand",
+ "Ctrl-e": "EndOfLine",
+ "Ctrl-a": "StartOfLine",
+ "Ctrl-w": "DeleteWordLeft",
+ "Insert": "ToggleOverwriteMode",
+ "Ctrl-b": "WordLeft",
+ "Ctrl-f": "WordRight",
+ "Ctrl-d": "DeleteWordLeft",
+ "Ctrl-m": "ExecuteCommand",
+ "Ctrl-n": "HistoryDown",
+ "Ctrl-p": "HistoryUp",
+ "Ctrl-u": "SelectToStart",
+
+ // Emacs-style keybindings
+ "Alt-f": "WordRight",
+ "Alt-b": "WordLeft",
+ "Alt-a": "StartOfText",
+ "Alt-e": "EndOfLine",
+
+ // Integration with file managers
+ "F10": "AbortCommand",
+ "Esc": "AbortCommand",
+
+ // Mouse bindings
+ "MouseWheelUp": "HistoryUp",
+ "MouseWheelDown": "HistoryDown",
+ "MouseLeft": "MousePress",
+ "MouseMiddle": "PastePrimary",
+ }
+}
"Alt-x": "SkipMultiCursor",
}
}
+
+func DefaultInfoBindings() map[string]string {
+ return map[string]string{
+ "Up": "HistoryUp",
+ "Down": "HistoryDown",
+ "Right": "CursorRight",
+ "Left": "CursorLeft",
+ "ShiftUp": "SelectUp",
+ "ShiftDown": "SelectDown",
+ "ShiftLeft": "SelectLeft",
+ "ShiftRight": "SelectRight",
+ "AltLeft": "StartOfTextToggle",
+ "AltRight": "EndOfLine",
+ "AltUp": "CursorStart",
+ "AltDown": "CursorEnd",
+ "AltShiftRight": "SelectWordRight",
+ "AltShiftLeft": "SelectWordLeft",
+ "CtrlLeft": "WordLeft",
+ "CtrlRight": "WordRight",
+ "CtrlShiftLeft": "SelectToStartOfTextToggle",
+ "ShiftHome": "SelectToStartOfTextToggle",
+ "CtrlShiftRight": "SelectToEndOfLine",
+ "ShiftEnd": "SelectToEndOfLine",
+ "CtrlUp": "CursorStart",
+ "CtrlDown": "CursorEnd",
+ "CtrlShiftUp": "SelectToStart",
+ "CtrlShiftDown": "SelectToEnd",
+ "Enter": "ExecuteCommand",
+ "CtrlH": "Backspace",
+ "Backspace": "Backspace",
+ "OldBackspace": "Backspace",
+ "Alt-CtrlH": "DeleteWordLeft",
+ "Alt-Backspace": "DeleteWordLeft",
+ "Tab": "CommandComplete",
+ "Backtab": "CycleAutocompleteBack",
+ "Ctrl-z": "Undo",
+ "Ctrl-y": "Redo",
+ "Ctrl-c": "CopyLine|Copy",
+ "Ctrl-x": "Cut",
+ "Ctrl-k": "CutLine",
+ "Ctrl-v": "Paste",
+ "Home": "StartOfTextToggle",
+ "End": "EndOfLine",
+ "CtrlHome": "CursorStart",
+ "CtrlEnd": "CursorEnd",
+ "Delete": "Delete",
+ "Ctrl-q": "AbortCommand",
+ "Ctrl-e": "EndOfLine",
+ "Ctrl-a": "StartOfLine",
+ "Ctrl-w": "DeleteWordLeft",
+ "Insert": "ToggleOverwriteMode",
+ "Ctrl-b": "WordLeft",
+ "Ctrl-f": "WordRight",
+ "Ctrl-d": "DeleteWordLeft",
+ "Ctrl-m": "ExecuteCommand",
+ "Ctrl-n": "HistoryDown",
+ "Ctrl-p": "HistoryUp",
+ "Ctrl-u": "SelectToStart",
+
+ // Emacs-style keybindings
+ "Alt-f": "WordRight",
+ "Alt-b": "WordLeft",
+ "Alt-a": "StartOfText",
+ "Alt-e": "EndOfLine",
+
+ // Integration with file managers
+ "F10": "AbortCommand",
+ "Esc": "AbortCommand",
+
+ // Mouse bindings
+ "MouseWheelUp": "HistoryUp",
+ "MouseWheelDown": "HistoryDown",
+ "MouseLeft": "MousePress",
+ "MouseMiddle": "PastePrimary",
+ }
+}
import (
"bytes"
- "strings"
"github.com/zyedidia/micro/v2/internal/buffer"
"github.com/zyedidia/micro/v2/internal/display"
type InfoKeyAction func(*InfoPane)
+var InfoBindings *KeyTree
+var InfoBufBindings *KeyTree
+
+func init() {
+ InfoBindings = NewKeyTree()
+ InfoBufBindings = NewKeyTree()
+}
+
+func InfoMapKey(k Event, action string) {
+ if f, ok := InfoKeyActions[action]; ok {
+ InfoBindings.RegisterKeyBinding(k, InfoKeyActionGeneral(f))
+ } else if f, ok := BufKeyActions[action]; ok {
+ InfoBufBindings.RegisterKeyBinding(k, BufKeyActionGeneral(f))
+ }
+}
+
+func InfoMapMouse(k MouseEvent, action string) {
+ if f, ok := BufMouseActions[action]; ok {
+ InfoBufBindings.RegisterMouseBinding(k, BufMouseActionGeneral(f))
+ } else {
+ InfoMapKey(k, action)
+ }
+}
+
+func InfoKeyActionGeneral(a InfoKeyAction) PaneKeyAction {
+ return func(p Pane) bool {
+ a(p.(*InfoPane))
+ return false
+ }
+}
+
type InfoPane struct {
*BufPane
*info.InfoBuf
ip := new(InfoPane)
ip.InfoBuf = ib
ip.BufPane = NewBufPane(ib.Buffer, w, tab)
+ ip.BufPane.bindings = InfoBufBindings
return ip
}
// DoKeyEvent executes a key event for the command bar, doing any overridden actions
func (h *InfoPane) DoKeyEvent(e KeyEvent) bool {
done := false
- if action, ok := BufKeyBindings[e]; ok {
- estr := BufKeyStrings[e]
- for _, s := range InfoNones {
- if s == estr {
- return false
- }
- }
- for s, a := range InfoOverrides {
- // TODO this is a hack and really we should have support
- // for having binding overrides for different buffers
- if strings.HasPrefix(estr, s) {
- done = true
- a(h)
- break
- }
- }
- if !done {
- done = action(h.BufPane)
- }
+ action, more := InfoBindings.NextEvent(e, nil)
+ if action != nil && !more {
+ action(h)
+ InfoBindings.ResetEvents()
+
+ return true
+ } else if action == nil && !more {
+ InfoBindings.ResetEvents()
+ // return false //TODO:?
+ }
+
+ action, more = InfoBufBindings.NextEvent(e, nil)
+ if action != nil && !more {
+ done = action(h.BufPane)
+ InfoBufBindings.ResetEvents()
+ } else if action == nil && !more {
+ InfoBufBindings.ResetEvents()
}
+
return done
}
-// InfoNones is a list of actions that should have no effect when executed
-// by an infohandler
-var InfoNones = []string{
- "Save",
- "SaveAll",
- "SaveAs",
- "Find",
- "FindNext",
- "FindPrevious",
- "Center",
- "DuplicateLine",
- "MoveLinesUp",
- "MoveLinesDown",
- "OpenFile",
- "Start",
- "End",
- "PageUp",
- "PageDown",
- "SelectPageUp",
- "SelectPageDown",
- "HalfPageUp",
- "HalfPageDown",
- "ToggleHelp",
- "ToggleKeyMenu",
- "ToggleDiffGutter",
- "ToggleRuler",
- "JumpLine",
- "ClearStatus",
- "ShellMode",
- "CommandMode",
- "AddTab",
- "PreviousTab",
- "NextTab",
- "NextSplit",
- "PreviousSplit",
- "Unsplit",
- "VSplit",
- "HSplit",
- "ToggleMacro",
- "PlayMacro",
- "Suspend",
- "ScrollUp",
- "ScrollDown",
- "SpawnMultiCursor",
- "SpawnMultiCursorSelect",
- "RemoveMultiCursor",
- "RemoveAllMultiCursors",
- "SkipMultiCursor",
-}
-
-// InfoOverrides is the list of actions which have been overridden
-// by the infohandler
-var InfoOverrides = map[string]InfoKeyAction{
- "CursorUp": (*InfoPane).CursorUp,
- "CursorDown": (*InfoPane).CursorDown,
- "InsertNewline": (*InfoPane).InsertNewline,
- "Autocomplete": (*InfoPane).Autocomplete,
- "Escape": (*InfoPane).Escape,
- "Quit": (*InfoPane).Quit,
- "QuitAll": (*InfoPane).QuitAll,
-}
-
-// CursorUp cycles history up
-func (h *InfoPane) CursorUp() {
+// HistoryUp cycles history up
+func (h *InfoPane) HistoryUp() {
h.UpHistory(h.History[h.PromptType])
}
-// CursorDown cycles history down
-func (h *InfoPane) CursorDown() {
+// HistoryDown cycles history down
+func (h *InfoPane) HistoryDown() {
h.DownHistory(h.History[h.PromptType])
}
// Autocomplete begins autocompletion
-func (h *InfoPane) Autocomplete() {
+func (h *InfoPane) CommandComplete() {
b := h.Buf
if b.HasSuggestions {
b.CycleAutocomplete(true)
}
}
-// InsertNewline completes the prompt
-func (h *InfoPane) InsertNewline() {
+// ExecuteCommand completes the prompt
+func (h *InfoPane) ExecuteCommand() {
if !h.HasYN {
h.DonePrompt(false)
}
}
-// Quit cancels the prompt
-func (h *InfoPane) Quit() {
- h.DonePrompt(true)
-}
-
-// QuitAll cancels the prompt
-func (h *InfoPane) QuitAll() {
+// AbortCommand cancels the prompt
+func (h *InfoPane) AbortCommand() {
h.DonePrompt(true)
}
-// Escape cancels the prompt
-func (h *InfoPane) Escape() {
- h.DonePrompt(true)
+// BufKeyActions contains the list of all possible key actions the bufhandler could execute
+var InfoKeyActions = map[string]InfoKeyAction{
+ "HistoryUp": (*InfoPane).HistoryUp,
+ "HistoryDown": (*InfoPane).HistoryDown,
+ "CommandComplete": (*InfoPane).CommandComplete,
+ "ExecuteCommand": (*InfoPane).ExecuteCommand,
+ "AbortCommand": (*InfoPane).AbortCommand,
}