]> git.lizzy.rs Git - micro.git/blobdiff - internal/action/bufpane.go
More style improvements
[micro.git] / internal / action / bufpane.go
index 7351f1f76fe2b62f1522b74e09d3ba7ad20ca9b6..1183871e1c2930b20e26314b8908f1b3a6b990b0 100644 (file)
@@ -7,27 +7,43 @@ import (
        luar "layeh.com/gopher-luar"
 
        lua "github.com/yuin/gopher-lua"
-       "github.com/zyedidia/micro/internal/buffer"
-       "github.com/zyedidia/micro/internal/config"
-       "github.com/zyedidia/micro/internal/display"
-       ulua "github.com/zyedidia/micro/internal/lua"
-       "github.com/zyedidia/micro/internal/screen"
-       "github.com/zyedidia/tcell"
+       "github.com/zyedidia/micro/v2/internal/buffer"
+       "github.com/zyedidia/micro/v2/internal/clipboard"
+       "github.com/zyedidia/micro/v2/internal/config"
+       "github.com/zyedidia/micro/v2/internal/display"
+       ulua "github.com/zyedidia/micro/v2/internal/lua"
+       "github.com/zyedidia/micro/v2/internal/screen"
+       "github.com/zyedidia/tcell/v2"
 )
 
+// BufKeyAction represents an action bound to a key.
 type BufKeyAction func(*BufPane) bool
+
+// BufMouseAction is an action that must be bound to a mouse event.
 type BufMouseAction func(*BufPane, *tcell.EventMouse) bool
 
-var BufKeyBindings map[Event]BufKeyAction
-var BufKeyStrings map[Event]string
-var BufMouseBindings map[MouseEvent]BufMouseAction
+// BufBindings stores the bindings for the buffer pane type.
+var BufBindings *KeyTree
+
+// BufKeyActionGeneral makes a general pane action from a BufKeyAction.
+func BufKeyActionGeneral(a BufKeyAction) PaneKeyAction {
+       return func(p Pane) bool {
+               return a(p.(*BufPane))
+       }
+}
+
+// BufMouseActionGeneral makes a general pane mouse action from a BufKeyAction.
+func BufMouseActionGeneral(a BufMouseAction) PaneMouseAction {
+       return func(p Pane, me *tcell.EventMouse) bool {
+               return a(p.(*BufPane), me)
+       }
+}
 
 func init() {
-       BufKeyBindings = make(map[Event]BufKeyAction)
-       BufKeyStrings = make(map[Event]string)
-       BufMouseBindings = make(map[MouseEvent]BufMouseAction)
+       BufBindings = NewKeyTree()
 }
 
+// LuaAction makes a BufKeyAction from a lua function.
 func LuaAction(fn string) func(*BufPane) bool {
        luaFn := strings.Split(fn, ".")
        if len(luaFn) <= 1 {
@@ -51,9 +67,19 @@ func LuaAction(fn string) func(*BufPane) bool {
        }
 }
 
-// BufMapKey maps a key event to an action
-func BufMapKey(k Event, action string) {
-       BufKeyStrings[k] = action
+// BufMapKey maps an event to an action
+func BufMapEvent(k Event, action string) {
+       config.Bindings["buffer"][k.Name()] = action
+
+       switch e := k.(type) {
+       case KeyEvent, KeySequenceEvent, RawEvent:
+               bufMapKey(e, action)
+       case MouseEvent:
+               bufMapMouse(e, action)
+       }
+}
+
+func bufMapKey(k Event, action string) {
        var actionfns []func(*BufPane) bool
        var names []string
        var types []byte
@@ -103,15 +129,16 @@ func BufMapKey(k Event, action string) {
                        afn = f
                        names = append(names, a)
                } else {
-                       screen.TermMessage("Error:", a, "does not exist")
+                       screen.TermMessage("Error in bindings: action", a, "does not exist")
                        continue
                }
                actionfns = append(actionfns, afn)
        }
-       BufKeyBindings[k] = func(h *BufPane) bool {
+       bufAction := func(h *BufPane) bool {
                cursors := h.Buf.GetCursors()
                success := true
                for i, a := range actionfns {
+                       innerSuccess := true
                        for j, c := range cursors {
                                if c == nil {
                                        continue
@@ -119,26 +146,43 @@ func BufMapKey(k Event, action string) {
                                h.Buf.SetCurCursor(c.Num)
                                h.Cursor = c
                                if i == 0 || (success && types[i-1] == '&') || (!success && types[i-1] == '|') || (types[i-1] == ',') {
-                                       success = h.execAction(a, names[i], j)
+                                       innerSuccess = innerSuccess && h.execAction(a, names[i], j)
                                } else {
                                        break
                                }
                        }
+                       // if the action changed the current pane, update the reference
+                       h = MainTab().CurPane()
+                       success = innerSuccess
                }
                return true
        }
+
+       BufBindings.RegisterKeyBinding(k, BufKeyActionGeneral(bufAction))
 }
 
 // BufMapMouse maps a mouse event to an action
-func BufMapMouse(k MouseEvent, action string) {
+func bufMapMouse(k MouseEvent, action string) {
        if f, ok := BufMouseActions[action]; ok {
-               BufMouseBindings[k] = f
+               BufBindings.RegisterMouseBinding(k, BufMouseActionGeneral(f))
        } else {
-               delete(BufMouseBindings, k)
-               BufMapKey(k, action)
+               // TODO
+               // delete(BufMouseBindings, k)
+               bufMapKey(k, action)
        }
 }
 
+// BufUnmap unmaps a key or mouse event from any action
+func BufUnmap(k Event) {
+       // TODO
+       // delete(BufKeyBindings, k)
+       //
+       // switch e := k.(type) {
+       // case MouseEvent:
+       //      delete(BufMouseBindings, e)
+       // }
+}
+
 // The BufPane connects the buffer and the window
 // It provides a cursor (or multiple) and defines a set of actions
 // that can be taken on the buffer
@@ -147,9 +191,13 @@ func BufMapMouse(k MouseEvent, action string) {
 type BufPane struct {
        display.BWindow
 
+       // Buf is the buffer this BufPane views
        Buf *buffer.Buffer
+       // Bindings stores the association of key events and actions
+       bindings *KeyTree
 
-       Cursor *buffer.Cursor // the active cursor
+       // Cursor is the currently active buffer cursor
+       Cursor *buffer.Cursor
 
        // Since tcell doesn't differentiate between a mouse release event
        // and a mouse move event with no keys pressed, we need to keep
@@ -179,7 +227,8 @@ type BufPane struct {
        tripleClick bool
 
        // Last search stores the last successful search for FindNext and FindPrev
-       lastSearch string
+       lastSearch      string
+       lastSearchRegex bool
        // Should the current multiple cursor selection search based on word or
        // based on selection (false for selection, true for word)
        multiWord bool
@@ -191,6 +240,7 @@ type BufPane struct {
        searchOrig buffer.Loc
 }
 
+// NewBufPane creates a new buffer pane with the given window.
 func NewBufPane(buf *buffer.Buffer, win display.BWindow, tab *Tab) *BufPane {
        h := new(BufPane)
        h.Buf = buf
@@ -205,15 +255,19 @@ func NewBufPane(buf *buffer.Buffer, win display.BWindow, tab *Tab) *BufPane {
        return h
 }
 
+// NewBufPaneFromBuf constructs a new pane from the given buffer and automatically
+// creates a buf window.
 func NewBufPaneFromBuf(buf *buffer.Buffer, tab *Tab) *BufPane {
        w := display.NewBufWindow(0, 0, 0, 0, buf)
        return NewBufPane(buf, w, tab)
 }
 
+// SetTab sets this pane's tab.
 func (h *BufPane) SetTab(t *Tab) {
        h.tab = t
 }
 
+// Tab returns this pane's tab.
 func (h *BufPane) Tab() *Tab {
        return h.tab
 }
@@ -224,9 +278,8 @@ func (h *BufPane) ResizePane(size int) {
        h.tab.Resize()
 }
 
-// PluginCB calls all plugin callbacks with a certain name and
-// displays an error if there is one and returns the aggregrate
-// boolean response
+// PluginCB calls all plugin callbacks with a certain name and displays an
+// error if there is one and returns the aggregrate boolean response
 func (h *BufPane) PluginCB(cb string) bool {
        b, err := config.RunPluginFnBool(cb, luar.New(ulua.L, h))
        if err != nil {
@@ -235,8 +288,7 @@ func (h *BufPane) PluginCB(cb string) bool {
        return b
 }
 
-// PluginCBRune is the same as PluginCB but also passes a rune to
-// the plugins
+// PluginCBRune is the same as PluginCB but also passes a rune to the plugins
 func (h *BufPane) PluginCBRune(cb string, r rune) bool {
        b, err := config.RunPluginFnBool(cb, luar.New(ulua.L, h), luar.New(ulua.L, string(r)))
        if err != nil {
@@ -245,6 +297,7 @@ func (h *BufPane) PluginCBRune(cb string, r rune) bool {
        return b
 }
 
+// OpenBuffer opens the given buffer in this pane.
 func (h *BufPane) OpenBuffer(b *buffer.Buffer) {
        h.Buf.Close()
        h.Buf = b
@@ -252,23 +305,26 @@ func (h *BufPane) OpenBuffer(b *buffer.Buffer) {
        h.Cursor = b.GetActiveCursor()
        h.Resize(h.GetView().Width, h.GetView().Height)
        h.Relocate()
-       // Set mouseReleased to true because we assume the mouse is not being pressed when
-       // the editor is opened
+       // Set mouseReleased to true because we assume the mouse is not being
+       // pressed when the editor is opened
        h.mouseReleased = true
-       // Set isOverwriteMode to false, because we assume we are in the default mode when editor
-       // is opened
+       // Set isOverwriteMode to false, because we assume we are in the default
+       // mode when editor is opened
        h.isOverwriteMode = false
        h.lastClickTime = time.Time{}
 }
 
+// ID returns this pane's split id.
 func (h *BufPane) ID() uint64 {
        return h.splitID
 }
 
+// SetID sets the split ID of this pane.
 func (h *BufPane) SetID(i uint64) {
        h.splitID = i
 }
 
+// Name returns the BufPane's name.
 func (h *BufPane) Name() string {
        n := h.Buf.GetName()
        if h.Buf.Modified() {
@@ -305,7 +361,7 @@ func (h *BufPane) HandleEvent(event tcell.Event) {
        case *tcell.EventKey:
                ke := KeyEvent{
                        code: e.Key(),
-                       mod:  e.Modifiers(),
+                       mod:  metaToAlt(e.Modifiers()),
                        r:    e.Rune(),
                }
 
@@ -318,7 +374,7 @@ func (h *BufPane) HandleEvent(event tcell.Event) {
                switch e.Buttons() {
                case tcell.Button1:
                        _, my := e.Position()
-                       if h.Buf.Settings["statusline"].(bool) && my >= h.GetView().Y+h.GetView().Height-1 {
+                       if h.Buf.Type.Kind != buffer.BTInfo.Kind && h.Buf.Settings["statusline"].(bool) && my >= h.GetView().Y+h.GetView().Height-1 {
                                cancel = true
                        }
                case tcell.ButtonNone:
@@ -343,10 +399,11 @@ func (h *BufPane) HandleEvent(event tcell.Event) {
                                // release the mouse
 
                                // if !h.doubleClick && !h.tripleClick {
-                               //      h.Cursor.Loc = mouseLoc
                                //      h.Cursor.SetSelectionEnd(h.Cursor.Loc)
-                               //      h.Cursor.CopySelection("primary")
                                // }
+                               if h.Cursor.HasSelection() {
+                                       h.Cursor.CopySelection(clipboard.PrimaryReg)
+                               }
                                h.mouseReleased = true
                        }
                }
@@ -354,7 +411,7 @@ func (h *BufPane) HandleEvent(event tcell.Event) {
                if !cancel {
                        me := MouseEvent{
                                btn: e.Buttons(),
-                               mod: e.Modifiers(),
+                               mod: metaToAlt(e.Modifiers()),
                        }
                        h.DoMouseEvent(me, e)
                }
@@ -378,13 +435,27 @@ func (h *BufPane) HandleEvent(event tcell.Event) {
        }
 }
 
+// Bindings returns the current bindings tree for this buffer.
+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 {
-       if action, ok := BufKeyBindings[e]; ok {
-               return action(h)
+       binds := h.Bindings()
+       action, more := binds.NextEvent(e, nil)
+       if action != nil && !more {
+               action(h)
+               binds.ResetEvents()
+               return true
+       } else if action == nil && !more {
+               binds.ResetEvents()
        }
-       return false
+       return more
 }
 
 func (h *BufPane) execAction(action func(*BufPane) bool, name string, cursor int) bool {
@@ -399,7 +470,7 @@ func (h *BufPane) execAction(action func(*BufPane) bool, name string, cursor int
                        success = success && h.PluginCB("on"+name)
 
                        if isMulti {
-                               if recording_macro {
+                               if recordingMacro {
                                        if name != "ToggleMacro" && name != "PlayMacro" {
                                                curmacro = append(curmacro, action)
                                        }
@@ -418,22 +489,34 @@ func (h *BufPane) completeAction(action string) {
 }
 
 func (h *BufPane) HasKeyEvent(e Event) bool {
-       _, ok := BufKeyBindings[e]
-       return ok
+       // TODO
+       return true
+       // _, ok := BufKeyBindings[e]
+       // return ok
 }
 
 // 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 {
-       if action, ok := BufMouseBindings[e]; ok {
-               if action(h, te) {
-                       h.Relocate()
-               }
+       binds := h.Bindings()
+       action, _ := binds.NextEvent(e, te)
+       if action != nil {
+               action(h)
+               binds.ResetEvents()
                return true
-       } else if h.HasKeyEvent(e) {
-               return h.DoKeyEvent(e)
        }
+       // TODO
        return false
+
+       // if action, ok := BufMouseBindings[e]; ok {
+       //      if action(h, te) {
+       //              h.Relocate()
+       //      }
+       //      return true
+       // } else if h.HasKeyEvent(e) {
+       //      return h.DoKeyEvent(e)
+       // }
+       // return false
 }
 
 // DoRuneInsert inserts a given rune into the current buffer
@@ -459,7 +542,7 @@ func (h *BufPane) DoRuneInsert(r rune) {
                } else {
                        h.Buf.Insert(c.Loc, string(r))
                }
-               if recording_macro {
+               if recordingMacro {
                        curmacro = append(curmacro, r)
                }
                h.Relocate()
@@ -467,6 +550,7 @@ func (h *BufPane) DoRuneInsert(r rune) {
        }
 }
 
+// VSplitIndex opens the given buffer in a vertical split on the given side.
 func (h *BufPane) VSplitIndex(buf *buffer.Buffer, right bool) *BufPane {
        e := NewBufPaneFromBuf(buf, h.tab)
        e.splitID = MainTab().GetNode(h.splitID).VSplit(right)
@@ -475,6 +559,8 @@ func (h *BufPane) VSplitIndex(buf *buffer.Buffer, right bool) *BufPane {
        MainTab().SetActive(len(MainTab().Panes) - 1)
        return e
 }
+
+// HSplitIndex opens the given buffer in a horizontal split on the given side.
 func (h *BufPane) HSplitIndex(buf *buffer.Buffer, bottom bool) *BufPane {
        e := NewBufPaneFromBuf(buf, h.tab)
        e.splitID = MainTab().GetNode(h.splitID).HSplit(bottom)
@@ -484,16 +570,22 @@ func (h *BufPane) HSplitIndex(buf *buffer.Buffer, bottom bool) *BufPane {
        return e
 }
 
+// VSplitBuf opens the given buffer in a new vertical split.
 func (h *BufPane) VSplitBuf(buf *buffer.Buffer) *BufPane {
        return h.VSplitIndex(buf, h.Buf.Settings["splitright"].(bool))
 }
+
+// HSplitBuf opens the given buffer in a new horizontal split.
 func (h *BufPane) HSplitBuf(buf *buffer.Buffer) *BufPane {
        return h.HSplitIndex(buf, h.Buf.Settings["splitbottom"].(bool))
 }
+
+// Close this pane.
 func (h *BufPane) Close() {
        h.Buf.Close()
 }
 
+// SetActive marks this pane as active.
 func (h *BufPane) SetActive(b bool) {
        h.BWindow.SetActive(b)
        if b {
@@ -516,106 +608,114 @@ func (h *BufPane) SetActive(b bool) {
 
 // BufKeyActions contains the list of all possible key actions the bufhandler could execute
 var BufKeyActions = map[string]BufKeyAction{
-       "CursorUp":               (*BufPane).CursorUp,
-       "CursorDown":             (*BufPane).CursorDown,
-       "CursorPageUp":           (*BufPane).CursorPageUp,
-       "CursorPageDown":         (*BufPane).CursorPageDown,
-       "CursorLeft":             (*BufPane).CursorLeft,
-       "CursorRight":            (*BufPane).CursorRight,
-       "CursorStart":            (*BufPane).CursorStart,
-       "CursorEnd":              (*BufPane).CursorEnd,
-       "SelectToStart":          (*BufPane).SelectToStart,
-       "SelectToEnd":            (*BufPane).SelectToEnd,
-       "SelectUp":               (*BufPane).SelectUp,
-       "SelectDown":             (*BufPane).SelectDown,
-       "SelectLeft":             (*BufPane).SelectLeft,
-       "SelectRight":            (*BufPane).SelectRight,
-       "WordRight":              (*BufPane).WordRight,
-       "WordLeft":               (*BufPane).WordLeft,
-       "SelectWordRight":        (*BufPane).SelectWordRight,
-       "SelectWordLeft":         (*BufPane).SelectWordLeft,
-       "DeleteWordRight":        (*BufPane).DeleteWordRight,
-       "DeleteWordLeft":         (*BufPane).DeleteWordLeft,
-       "SelectLine":             (*BufPane).SelectLine,
-       "SelectToStartOfLine":    (*BufPane).SelectToStartOfLine,
-       "SelectToStartOfText":    (*BufPane).SelectToStartOfText,
-       "SelectToEndOfLine":      (*BufPane).SelectToEndOfLine,
-       "ParagraphPrevious":      (*BufPane).ParagraphPrevious,
-       "ParagraphNext":          (*BufPane).ParagraphNext,
-       "InsertNewline":          (*BufPane).InsertNewline,
-       "Backspace":              (*BufPane).Backspace,
-       "Delete":                 (*BufPane).Delete,
-       "InsertTab":              (*BufPane).InsertTab,
-       "Save":                   (*BufPane).Save,
-       "SaveAll":                (*BufPane).SaveAll,
-       "SaveAs":                 (*BufPane).SaveAs,
-       "Find":                   (*BufPane).Find,
-       "FindNext":               (*BufPane).FindNext,
-       "FindPrevious":           (*BufPane).FindPrevious,
-       "Center":                 (*BufPane).Center,
-       "Undo":                   (*BufPane).Undo,
-       "Redo":                   (*BufPane).Redo,
-       "Copy":                   (*BufPane).Copy,
-       "Cut":                    (*BufPane).Cut,
-       "CutLine":                (*BufPane).CutLine,
-       "DuplicateLine":          (*BufPane).DuplicateLine,
-       "DeleteLine":             (*BufPane).DeleteLine,
-       "MoveLinesUp":            (*BufPane).MoveLinesUp,
-       "MoveLinesDown":          (*BufPane).MoveLinesDown,
-       "IndentSelection":        (*BufPane).IndentSelection,
-       "OutdentSelection":       (*BufPane).OutdentSelection,
-       "Autocomplete":           (*BufPane).Autocomplete,
-       "CycleAutocompleteBack":  (*BufPane).CycleAutocompleteBack,
-       "OutdentLine":            (*BufPane).OutdentLine,
-       "IndentLine":             (*BufPane).IndentLine,
-       "Paste":                  (*BufPane).Paste,
-       "PastePrimary":           (*BufPane).PastePrimary,
-       "SelectAll":              (*BufPane).SelectAll,
-       "OpenFile":               (*BufPane).OpenFile,
-       "Start":                  (*BufPane).Start,
-       "End":                    (*BufPane).End,
-       "PageUp":                 (*BufPane).PageUp,
-       "PageDown":               (*BufPane).PageDown,
-       "SelectPageUp":           (*BufPane).SelectPageUp,
-       "SelectPageDown":         (*BufPane).SelectPageDown,
-       "HalfPageUp":             (*BufPane).HalfPageUp,
-       "HalfPageDown":           (*BufPane).HalfPageDown,
-       "StartOfText":            (*BufPane).StartOfText,
-       "StartOfLine":            (*BufPane).StartOfLine,
-       "EndOfLine":              (*BufPane).EndOfLine,
-       "ToggleHelp":             (*BufPane).ToggleHelp,
-       "ToggleKeyMenu":          (*BufPane).ToggleKeyMenu,
-       "ToggleDiffGutter":       (*BufPane).ToggleDiffGutter,
-       "ToggleRuler":            (*BufPane).ToggleRuler,
-       "ClearStatus":            (*BufPane).ClearStatus,
-       "ShellMode":              (*BufPane).ShellMode,
-       "CommandMode":            (*BufPane).CommandMode,
-       "ToggleOverwriteMode":    (*BufPane).ToggleOverwriteMode,
-       "Escape":                 (*BufPane).Escape,
-       "Quit":                   (*BufPane).Quit,
-       "QuitAll":                (*BufPane).QuitAll,
-       "AddTab":                 (*BufPane).AddTab,
-       "PreviousTab":            (*BufPane).PreviousTab,
-       "NextTab":                (*BufPane).NextTab,
-       "NextSplit":              (*BufPane).NextSplit,
-       "PreviousSplit":          (*BufPane).PreviousSplit,
-       "Unsplit":                (*BufPane).Unsplit,
-       "VSplit":                 (*BufPane).VSplitAction,
-       "HSplit":                 (*BufPane).HSplitAction,
-       "ToggleMacro":            (*BufPane).ToggleMacro,
-       "PlayMacro":              (*BufPane).PlayMacro,
-       "Suspend":                (*BufPane).Suspend,
-       "ScrollUp":               (*BufPane).ScrollUpAction,
-       "ScrollDown":             (*BufPane).ScrollDownAction,
-       "SpawnMultiCursor":       (*BufPane).SpawnMultiCursor,
-       "SpawnMultiCursorUp":     (*BufPane).SpawnMultiCursorUp,
-       "SpawnMultiCursorDown":   (*BufPane).SpawnMultiCursorDown,
-       "SpawnMultiCursorSelect": (*BufPane).SpawnMultiCursorSelect,
-       "RemoveMultiCursor":      (*BufPane).RemoveMultiCursor,
-       "RemoveAllMultiCursors":  (*BufPane).RemoveAllMultiCursors,
-       "SkipMultiCursor":        (*BufPane).SkipMultiCursor,
-       "JumpToMatchingBrace":    (*BufPane).JumpToMatchingBrace,
-       "None":                   (*BufPane).None,
+       "CursorUp":                  (*BufPane).CursorUp,
+       "CursorDown":                (*BufPane).CursorDown,
+       "CursorPageUp":              (*BufPane).CursorPageUp,
+       "CursorPageDown":            (*BufPane).CursorPageDown,
+       "CursorLeft":                (*BufPane).CursorLeft,
+       "CursorRight":               (*BufPane).CursorRight,
+       "CursorStart":               (*BufPane).CursorStart,
+       "CursorEnd":                 (*BufPane).CursorEnd,
+       "SelectToStart":             (*BufPane).SelectToStart,
+       "SelectToEnd":               (*BufPane).SelectToEnd,
+       "SelectUp":                  (*BufPane).SelectUp,
+       "SelectDown":                (*BufPane).SelectDown,
+       "SelectLeft":                (*BufPane).SelectLeft,
+       "SelectRight":               (*BufPane).SelectRight,
+       "WordRight":                 (*BufPane).WordRight,
+       "WordLeft":                  (*BufPane).WordLeft,
+       "SelectWordRight":           (*BufPane).SelectWordRight,
+       "SelectWordLeft":            (*BufPane).SelectWordLeft,
+       "DeleteWordRight":           (*BufPane).DeleteWordRight,
+       "DeleteWordLeft":            (*BufPane).DeleteWordLeft,
+       "SelectLine":                (*BufPane).SelectLine,
+       "SelectToStartOfLine":       (*BufPane).SelectToStartOfLine,
+       "SelectToStartOfText":       (*BufPane).SelectToStartOfText,
+       "SelectToStartOfTextToggle": (*BufPane).SelectToStartOfTextToggle,
+       "SelectToEndOfLine":         (*BufPane).SelectToEndOfLine,
+       "ParagraphPrevious":         (*BufPane).ParagraphPrevious,
+       "ParagraphNext":             (*BufPane).ParagraphNext,
+       "InsertNewline":             (*BufPane).InsertNewline,
+       "Backspace":                 (*BufPane).Backspace,
+       "Delete":                    (*BufPane).Delete,
+       "InsertTab":                 (*BufPane).InsertTab,
+       "Save":                      (*BufPane).Save,
+       "SaveAll":                   (*BufPane).SaveAll,
+       "SaveAs":                    (*BufPane).SaveAs,
+       "Find":                      (*BufPane).Find,
+       "FindLiteral":               (*BufPane).FindLiteral,
+       "FindNext":                  (*BufPane).FindNext,
+       "FindPrevious":              (*BufPane).FindPrevious,
+       "Center":                    (*BufPane).Center,
+       "Undo":                      (*BufPane).Undo,
+       "Redo":                      (*BufPane).Redo,
+       "Copy":                      (*BufPane).Copy,
+       "CopyLine":                  (*BufPane).CopyLine,
+       "Cut":                       (*BufPane).Cut,
+       "CutLine":                   (*BufPane).CutLine,
+       "DuplicateLine":             (*BufPane).DuplicateLine,
+       "DeleteLine":                (*BufPane).DeleteLine,
+       "MoveLinesUp":               (*BufPane).MoveLinesUp,
+       "MoveLinesDown":             (*BufPane).MoveLinesDown,
+       "IndentSelection":           (*BufPane).IndentSelection,
+       "OutdentSelection":          (*BufPane).OutdentSelection,
+       "Autocomplete":              (*BufPane).Autocomplete,
+       "CycleAutocompleteBack":     (*BufPane).CycleAutocompleteBack,
+       "OutdentLine":               (*BufPane).OutdentLine,
+       "IndentLine":                (*BufPane).IndentLine,
+       "Paste":                     (*BufPane).Paste,
+       "PastePrimary":              (*BufPane).PastePrimary,
+       "SelectAll":                 (*BufPane).SelectAll,
+       "OpenFile":                  (*BufPane).OpenFile,
+       "Start":                     (*BufPane).Start,
+       "End":                       (*BufPane).End,
+       "PageUp":                    (*BufPane).PageUp,
+       "PageDown":                  (*BufPane).PageDown,
+       "SelectPageUp":              (*BufPane).SelectPageUp,
+       "SelectPageDown":            (*BufPane).SelectPageDown,
+       "HalfPageUp":                (*BufPane).HalfPageUp,
+       "HalfPageDown":              (*BufPane).HalfPageDown,
+       "StartOfText":               (*BufPane).StartOfText,
+       "StartOfTextToggle":         (*BufPane).StartOfTextToggle,
+       "StartOfLine":               (*BufPane).StartOfLine,
+       "EndOfLine":                 (*BufPane).EndOfLine,
+       "ToggleHelp":                (*BufPane).ToggleHelp,
+       "ToggleKeyMenu":             (*BufPane).ToggleKeyMenu,
+       "ToggleDiffGutter":          (*BufPane).ToggleDiffGutter,
+       "ToggleRuler":               (*BufPane).ToggleRuler,
+       "ClearStatus":               (*BufPane).ClearStatus,
+       "ShellMode":                 (*BufPane).ShellMode,
+       "CommandMode":               (*BufPane).CommandMode,
+       "ToggleOverwriteMode":       (*BufPane).ToggleOverwriteMode,
+       "Escape":                    (*BufPane).Escape,
+       "Quit":                      (*BufPane).Quit,
+       "QuitAll":                   (*BufPane).QuitAll,
+       "ForceQuit":                 (*BufPane).ForceQuit,
+       "AddTab":                    (*BufPane).AddTab,
+       "PreviousTab":               (*BufPane).PreviousTab,
+       "NextTab":                   (*BufPane).NextTab,
+       "NextSplit":                 (*BufPane).NextSplit,
+       "PreviousSplit":             (*BufPane).PreviousSplit,
+       "Unsplit":                   (*BufPane).Unsplit,
+       "VSplit":                    (*BufPane).VSplitAction,
+       "HSplit":                    (*BufPane).HSplitAction,
+       "ToggleMacro":               (*BufPane).ToggleMacro,
+       "PlayMacro":                 (*BufPane).PlayMacro,
+       "Suspend":                   (*BufPane).Suspend,
+       "ScrollUp":                  (*BufPane).ScrollUpAction,
+       "ScrollDown":                (*BufPane).ScrollDownAction,
+       "SpawnMultiCursor":          (*BufPane).SpawnMultiCursor,
+       "SpawnMultiCursorUp":        (*BufPane).SpawnMultiCursorUp,
+       "SpawnMultiCursorDown":      (*BufPane).SpawnMultiCursorDown,
+       "SpawnMultiCursorSelect":    (*BufPane).SpawnMultiCursorSelect,
+       "RemoveMultiCursor":         (*BufPane).RemoveMultiCursor,
+       "RemoveAllMultiCursors":     (*BufPane).RemoveAllMultiCursors,
+       "SkipMultiCursor":           (*BufPane).SkipMultiCursor,
+       "JumpToMatchingBrace":       (*BufPane).JumpToMatchingBrace,
+       "JumpLine":                  (*BufPane).JumpLine,
+       "Deselect":                  (*BufPane).Deselect,
+       "ClearInfo":                 (*BufPane).ClearInfo,
+       "None":                      (*BufPane).None,
 
        // This was changed to InsertNewline but I don't want to break backwards compatibility
        "InsertEnter": (*BufPane).InsertNewline,
@@ -632,54 +732,58 @@ var BufMouseActions = map[string]BufMouseAction{
 // Generally actions that modify global editor state like quitting or
 // saving should not be included in this list
 var MultiActions = map[string]bool{
-       "CursorUp":            true,
-       "CursorDown":          true,
-       "CursorPageUp":        true,
-       "CursorPageDown":      true,
-       "CursorLeft":          true,
-       "CursorRight":         true,
-       "CursorStart":         true,
-       "CursorEnd":           true,
-       "SelectToStart":       true,
-       "SelectToEnd":         true,
-       "SelectUp":            true,
-       "SelectDown":          true,
-       "SelectLeft":          true,
-       "SelectRight":         true,
-       "WordRight":           true,
-       "WordLeft":            true,
-       "SelectWordRight":     true,
-       "SelectWordLeft":      true,
-       "DeleteWordRight":     true,
-       "DeleteWordLeft":      true,
-       "SelectLine":          true,
-       "SelectToStartOfLine": true,
-       "SelectToStartOfText": true,
-       "SelectToEndOfLine":   true,
-       "ParagraphPrevious":   true,
-       "ParagraphNext":       true,
-       "InsertNewline":       true,
-       "Backspace":           true,
-       "Delete":              true,
-       "InsertTab":           true,
-       "FindNext":            true,
-       "FindPrevious":        true,
-       "Cut":                 true,
-       "CutLine":             true,
-       "DuplicateLine":       true,
-       "DeleteLine":          true,
-       "MoveLinesUp":         true,
-       "MoveLinesDown":       true,
-       "IndentSelection":     true,
-       "OutdentSelection":    true,
-       "OutdentLine":         true,
-       "IndentLine":          true,
-       "Paste":               true,
-       "PastePrimary":        true,
-       "SelectPageUp":        true,
-       "SelectPageDown":      true,
-       "StartOfLine":         true,
-       "StartOfText":         true,
-       "EndOfLine":           true,
-       "JumpToMatchingBrace": true,
+       "CursorUp":                  true,
+       "CursorDown":                true,
+       "CursorPageUp":              true,
+       "CursorPageDown":            true,
+       "CursorLeft":                true,
+       "CursorRight":               true,
+       "CursorStart":               true,
+       "CursorEnd":                 true,
+       "SelectToStart":             true,
+       "SelectToEnd":               true,
+       "SelectUp":                  true,
+       "SelectDown":                true,
+       "SelectLeft":                true,
+       "SelectRight":               true,
+       "WordRight":                 true,
+       "WordLeft":                  true,
+       "SelectWordRight":           true,
+       "SelectWordLeft":            true,
+       "DeleteWordRight":           true,
+       "DeleteWordLeft":            true,
+       "SelectLine":                true,
+       "SelectToStartOfLine":       true,
+       "SelectToStartOfText":       true,
+       "SelectToStartOfTextToggle": true,
+       "SelectToEndOfLine":         true,
+       "ParagraphPrevious":         true,
+       "ParagraphNext":             true,
+       "InsertNewline":             true,
+       "Backspace":                 true,
+       "Delete":                    true,
+       "InsertTab":                 true,
+       "FindNext":                  true,
+       "FindPrevious":              true,
+       "CopyLine":                  true,
+       "Copy":                      true,
+       "Cut":                       true,
+       "CutLine":                   true,
+       "DuplicateLine":             true,
+       "DeleteLine":                true,
+       "MoveLinesUp":               true,
+       "MoveLinesDown":             true,
+       "IndentSelection":           true,
+       "OutdentSelection":          true,
+       "OutdentLine":               true,
+       "IndentLine":                true,
+       "Paste":                     true,
+       "PastePrimary":              true,
+       "SelectPageUp":              true,
+       "SelectPageDown":            true,
+       "StartOfLine":               true,
+       "StartOfText":               true,
+       "StartOfTextToggle":         true,
+       "EndOfLine":                 true,
+       "JumpToMatchingBrace":       true,
 }