]> git.lizzy.rs Git - micro.git/commitdiff
Separate bindings for buffers and command bar
authorZachary Yedidia <zyedidia@gmail.com>
Wed, 1 Jul 2020 02:51:13 +0000 (22:51 -0400)
committerZachary Yedidia <zyedidia@gmail.com>
Sun, 9 Aug 2020 20:42:03 +0000 (16:42 -0400)
This commit separates actions in the command bar from actions in
a normal buffer, and implements what is needed to allow rebinding,
although an interface for command bar keybindings is not yet exposed
to the user.

internal/action/bindings.go
internal/action/bufpane.go
internal/action/defaults_darwin.go
internal/action/defaults_other.go
internal/action/infopane.go

index 92715f8b11492ea203caeca486c4d1c7f77c7c4e..17eceb375653850ed705df46db76de6094ac3d7d 100644 (file)
@@ -51,6 +51,29 @@ func InitBindings() {
        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) {
index 1e18da0f7856e057ebe637cfcb266c835f2f04f7..3b4ba699fc695faba891a69427efb98b1b2fd355 100644 (file)
@@ -21,9 +21,6 @@ type BufKeyAction func(*BufPane) bool
 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 {
@@ -38,10 +35,6 @@ func BufMouseActionGeneral(a BufMouseAction) PaneMouseAction {
 }
 
 func init() {
-       BufKeyBindings = make(map[Event]BufKeyAction)
-       BufKeyStrings = make(map[Event]string)
-       BufMouseBindings = make(map[MouseEvent]BufMouseAction)
-
        BufBindings = NewKeyTree()
 }
 
@@ -70,7 +63,6 @@ func LuaAction(fn string) func(*BufPane) bool {
 
 // 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
@@ -156,11 +148,9 @@ func BufMapKey(k Event, action string) {
 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)
        }
 }
@@ -169,7 +159,6 @@ func BufMapMouse(k MouseEvent, action string) {
 func BufUnmap(k Event) {
        // TODO
        // delete(BufKeyBindings, k)
-       // delete(BufKeyStrings, k)
        //
        // switch e := k.(type) {
        // case MouseEvent:
@@ -188,7 +177,7 @@ type BufPane struct {
        // 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
@@ -422,20 +411,25 @@ func (h *BufPane) HandleEvent(event tcell.Event) {
        }
 }
 
+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
 }
 
@@ -479,13 +473,13 @@ func (h *BufPane) HasKeyEvent(e Event) bool {
 // 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
index aac1ebec5227eabeadc96fe376fc223b8d7b8dbd..6df65d31b37b46df07b97b814b12e0c156a64b90 100644 (file)
@@ -106,3 +106,79 @@ func DefaultBindings() map[string]string {
                "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",
+       }
+}
index e518e781125bf823e9981de3c2ca94fbac5414d5..ee4e311dae5b4d32f5d7c451d0a3e07ecd126c7b 100644 (file)
@@ -108,3 +108,79 @@ func DefaultBindings() map[string]string {
                "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",
+       }
+}
index c72c9ebd9ba15e193afa45cd2383d744d3369a77..8c2c66903d85dfc677388676287acb5e971b1664 100644 (file)
@@ -2,7 +2,6 @@ package action
 
 import (
        "bytes"
-       "strings"
 
        "github.com/zyedidia/micro/v2/internal/buffer"
        "github.com/zyedidia/micro/v2/internal/display"
@@ -13,6 +12,37 @@ import (
 
 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
@@ -22,6 +52,7 @@ func NewInfoPane(ib *info.InfoBuf, w display.BWindow, tab *Tab) *InfoPane {
        ip := new(InfoPane)
        ip.InfoBuf = ib
        ip.BufPane = NewBufPane(ib.Buffer, w, tab)
+       ip.BufPane.bindings = InfoBufBindings
 
        return ip
 }
@@ -77,103 +108,40 @@ func (h *InfoPane) HandleEvent(event tcell.Event) {
 // 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)
@@ -201,24 +169,23 @@ func (h *InfoPane) Autocomplete() {
        }
 }
 
-// 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,
 }