From: Zachary Yedidia Date: Wed, 1 Jul 2020 21:11:07 +0000 (-0400) Subject: Allow configuration for info/term bindings X-Git-Tag: v2.0.7~15 X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=bbd6f559ab6339095c8b797f7fe17b83a5ac76d6;p=micro.git Allow configuration for info/term bindings This commit exposes the separate infopane bindings to configuration from the user. This also adds support for separate bindings in the terminal emulator view. Default bindings are provided, but can also be rebound in bindings.json. --- diff --git a/internal/action/bindings.go b/internal/action/bindings.go index 17eceb37..59248237 100644 --- a/internal/action/bindings.go +++ b/internal/action/bindings.go @@ -16,6 +16,12 @@ import ( "github.com/zyedidia/tcell" ) +var Binder = map[string]func(e Event, action string){ + "info": InfoMapEvent, + "buffer": BufMapEvent, + "terminal": TermMapEvent, +} + func createBindingsIfNotExist(fname string) { if _, e := os.Stat(fname); os.IsNotExist(e) { ioutil.WriteFile(fname, []byte("{}"), 0644) @@ -24,10 +30,9 @@ func createBindingsIfNotExist(fname string) { // InitBindings intializes the bindings map by reading from bindings.json func InitBindings() { - config.Bindings = DefaultBindings() + config.Bindings = DefaultBindings("buffer") - var parsed map[string]string - defaults := DefaultBindings() + var parsed map[string]interface{} filename := filepath.Join(config.ConfigDir, "bindings.json") createBindingsIfNotExist(filename) @@ -45,55 +50,52 @@ func InitBindings() { } } - for k, v := range defaults { - BindKey(k, v) - } - for k, v := range parsed { - BindKey(k, v) - } - - defaultInfos := DefaultInfoBindings() - for k, v := range defaultInfos { - BindInfoKey(k, v) - } -} + for p, bind := range Binder { + defaults := DefaultBindings(p) -func BindInfoKey(k, v string) { - event, err := findEvent(k) - if err != nil { - screen.TermMessage(err) + for k, v := range defaults { + BindKey(k, v, bind) + } } - switch e := event.(type) { - case KeyEvent: - InfoMapKey(e, v) - case KeySequenceEvent: - InfoMapKey(e, v) - case MouseEvent: - InfoMapMouse(e, v) - case RawEvent: - InfoMapKey(e, v) + for k, v := range parsed { + switch val := v.(type) { + case string: + BindKey(k, val, Binder["buffer"]) + case map[string]interface{}: + bind := Binder[k] + for e, a := range val { + s, ok := a.(string) + if !ok { + screen.TermMessage("Error reading bindings.json: non-string and non-map entry", k) + } else { + BindKey(e, s, bind) + } + } + default: + screen.TermMessage("Error reading bindings.json: non-string and non-map entry", k) + } } } -func BindKey(k, v string) { +func BindKey(k, v string, bind func(e Event, a string)) { event, err := findEvent(k) if err != nil { screen.TermMessage(err) } - switch e := event.(type) { - case KeyEvent: - BufMapKey(e, v) - case KeySequenceEvent: - BufMapKey(e, v) - case MouseEvent: - BufMapMouse(e, v) - case RawEvent: - BufMapKey(e, v) - } - - config.Bindings[k] = v + bind(event, v) + + // switch e := event.(type) { + // case KeyEvent: + // InfoMapKey(e, v) + // case KeySequenceEvent: + // InfoMapKey(e, v) + // case MouseEvent: + // InfoMapMouse(e, v) + // case RawEvent: + // InfoMapKey(e, v) + // } } var r = regexp.MustCompile("<(.+?)>") @@ -276,7 +278,7 @@ func TryBindKey(k, v string, overwrite bool) (bool, error) { parsed[k] = v } - BindKey(k, v) + BindKey(k, v, Binder["buffer"]) txt, _ := json.MarshalIndent(parsed, "", " ") return true, ioutil.WriteFile(filename, append(txt, '\n'), 0644) @@ -316,9 +318,9 @@ func UnbindKey(k string) error { } } - defaults := DefaultBindings() + defaults := DefaultBindings("buffer") if a, ok := defaults[k]; ok { - BindKey(k, a) + BindKey(k, a, Binder["buffer"]) } else if _, ok := config.Bindings[k]; ok { BufUnmap(key) delete(config.Bindings, k) diff --git a/internal/action/bufpane.go b/internal/action/bufpane.go index 3b4ba699..44a07f96 100644 --- a/internal/action/bufpane.go +++ b/internal/action/bufpane.go @@ -1,7 +1,6 @@ package action import ( - "log" "strings" "time" @@ -61,8 +60,17 @@ func LuaAction(fn string) func(*BufPane) bool { } } -// BufMapKey maps a key event to an action -func BufMapKey(k Event, action string) { +// BufMapKey maps an event to an action +func BufMapEvent(k Event, action string) { + 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 @@ -145,13 +153,13 @@ func BufMapKey(k Event, action string) { } // 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 { BufBindings.RegisterMouseBinding(k, BufMouseActionGeneral(f)) } else { // TODO // delete(BufMouseBindings, k) - BufMapKey(k, action) + bufMapKey(k, action) } } @@ -423,14 +431,14 @@ func (h *BufPane) Bindings() *KeyTree { func (h *BufPane) DoKeyEvent(e Event) bool { binds := h.Bindings() action, more := binds.NextEvent(e, nil) - log.Println("Next event", e, more) 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 { diff --git a/internal/action/defaults.go b/internal/action/defaults.go new file mode 100644 index 00000000..c3d15726 --- /dev/null +++ b/internal/action/defaults.go @@ -0,0 +1,21 @@ +package action + +var termdefaults = map[string]string{ + "": "Exit", + "": "CommandMode", + "": "NextSplit", +} + +// DefaultBindings returns a map containing micro's default keybindings +func DefaultBindings(pane string) map[string]string { + switch pane { + case "info": + return infodefaults + case "buffer": + return bufdefaults + case "terminal": + return termdefaults + default: + return map[string]string{} + } +} diff --git a/internal/action/defaults_darwin.go b/internal/action/defaults_darwin.go index 6df65d31..c04d717e 100644 --- a/internal/action/defaults_darwin.go +++ b/internal/action/defaults_darwin.go @@ -1,184 +1,179 @@ package action -// DefaultBindings returns a map containing micro's default keybindings -func DefaultBindings() map[string]string { - return map[string]string{ - "Up": "CursorUp", - "Down": "CursorDown", - "Right": "CursorRight", - "Left": "CursorLeft", - "ShiftUp": "SelectUp", - "ShiftDown": "SelectDown", - "ShiftLeft": "SelectLeft", - "ShiftRight": "SelectRight", - "AltLeft": "WordLeft", - "AltRight": "WordRight", - "AltUp": "MoveLinesUp", - "AltDown": "MoveLinesDown", - "AltShiftRight": "SelectWordRight", - "AltShiftLeft": "SelectWordLeft", - "CtrlLeft": "StartOfTextToggle", - "CtrlRight": "EndOfLine", - "CtrlShiftLeft": "SelectToStartOfTextToggle", - "ShiftHome": "SelectToStartOfTextToggle", - "CtrlShiftRight": "SelectToEndOfLine", - "ShiftEnd": "SelectToEndOfLine", - "CtrlUp": "CursorStart", - "CtrlDown": "CursorEnd", - "CtrlShiftUp": "SelectToStart", - "CtrlShiftDown": "SelectToEnd", - "Alt-{": "ParagraphPrevious", - "Alt-}": "ParagraphNext", - "Enter": "InsertNewline", - "CtrlH": "Backspace", - "Backspace": "Backspace", - "OldBackspace": "Backspace", - "Alt-CtrlH": "DeleteWordLeft", - "Alt-Backspace": "DeleteWordLeft", - "Tab": "Autocomplete|IndentSelection|InsertTab", - "Backtab": "CycleAutocompleteBack|OutdentSelection|OutdentLine", - "Ctrl-o": "OpenFile", - "Ctrl-s": "Save", - "Ctrl-f": "Find", - "Ctrl-n": "FindNext", - "Ctrl-p": "FindPrevious", - "Ctrl-z": "Undo", - "Ctrl-y": "Redo", - "Ctrl-c": "CopyLine|Copy", - "Ctrl-x": "Cut", - "Ctrl-k": "CutLine", - "Ctrl-d": "DuplicateLine", - "Ctrl-v": "Paste", - "Ctrl-a": "SelectAll", - "Ctrl-t": "AddTab", - "Alt-,": "PreviousTab", - "Alt-.": "NextTab", - "Home": "StartOfTextToggle", - "End": "EndOfLine", - "CtrlHome": "CursorStart", - "CtrlEnd": "CursorEnd", - "PageUp": "CursorPageUp", - "PageDown": "CursorPageDown", - "CtrlPageUp": "PreviousTab", - "CtrlPageDown": "NextTab", - "Ctrl-g": "ToggleHelp", - "Alt-g": "ToggleKeyMenu", - "Ctrl-r": "ToggleRuler", - "Ctrl-l": "command-edit:goto ", - "Delete": "Delete", - "Ctrl-b": "ShellMode", - "Ctrl-q": "Quit", - "Ctrl-e": "CommandMode", - "Ctrl-w": "NextSplit", - "Ctrl-u": "ToggleMacro", - "Ctrl-j": "PlayMacro", - "Insert": "ToggleOverwriteMode", +var bufdefaults = map[string]string{ + "Up": "CursorUp", + "Down": "CursorDown", + "Right": "CursorRight", + "Left": "CursorLeft", + "ShiftUp": "SelectUp", + "ShiftDown": "SelectDown", + "ShiftLeft": "SelectLeft", + "ShiftRight": "SelectRight", + "AltLeft": "WordLeft", + "AltRight": "WordRight", + "AltUp": "MoveLinesUp", + "AltDown": "MoveLinesDown", + "AltShiftRight": "SelectWordRight", + "AltShiftLeft": "SelectWordLeft", + "CtrlLeft": "StartOfTextToggle", + "CtrlRight": "EndOfLine", + "CtrlShiftLeft": "SelectToStartOfTextToggle", + "ShiftHome": "SelectToStartOfTextToggle", + "CtrlShiftRight": "SelectToEndOfLine", + "ShiftEnd": "SelectToEndOfLine", + "CtrlUp": "CursorStart", + "CtrlDown": "CursorEnd", + "CtrlShiftUp": "SelectToStart", + "CtrlShiftDown": "SelectToEnd", + "Alt-{": "ParagraphPrevious", + "Alt-}": "ParagraphNext", + "Enter": "InsertNewline", + "CtrlH": "Backspace", + "Backspace": "Backspace", + "OldBackspace": "Backspace", + "Alt-CtrlH": "DeleteWordLeft", + "Alt-Backspace": "DeleteWordLeft", + "Tab": "Autocomplete|IndentSelection|InsertTab", + "Backtab": "CycleAutocompleteBack|OutdentSelection|OutdentLine", + "Ctrl-o": "OpenFile", + "Ctrl-s": "Save", + "Ctrl-f": "Find", + "Ctrl-n": "FindNext", + "Ctrl-p": "FindPrevious", + "Ctrl-z": "Undo", + "Ctrl-y": "Redo", + "Ctrl-c": "CopyLine|Copy", + "Ctrl-x": "Cut", + "Ctrl-k": "CutLine", + "Ctrl-d": "DuplicateLine", + "Ctrl-v": "Paste", + "Ctrl-a": "SelectAll", + "Ctrl-t": "AddTab", + "Alt-,": "PreviousTab", + "Alt-.": "NextTab", + "Home": "StartOfTextToggle", + "End": "EndOfLine", + "CtrlHome": "CursorStart", + "CtrlEnd": "CursorEnd", + "PageUp": "CursorPageUp", + "PageDown": "CursorPageDown", + "CtrlPageUp": "PreviousTab", + "CtrlPageDown": "NextTab", + "Ctrl-g": "ToggleHelp", + "Alt-g": "ToggleKeyMenu", + "Ctrl-r": "ToggleRuler", + "Ctrl-l": "command-edit:goto ", + "Delete": "Delete", + "Ctrl-b": "ShellMode", + "Ctrl-q": "Quit", + "Ctrl-e": "CommandMode", + "Ctrl-w": "NextSplit", + "Ctrl-u": "ToggleMacro", + "Ctrl-j": "PlayMacro", + "Insert": "ToggleOverwriteMode", - // Emacs-style keybindings - "Alt-f": "WordRight", - "Alt-b": "WordLeft", - "Alt-a": "StartOfText", - "Alt-e": "EndOfLine", - // "Alt-p": "CursorUp", - // "Alt-n": "CursorDown", + // Emacs-style keybindings + "Alt-f": "WordRight", + "Alt-b": "WordLeft", + "Alt-a": "StartOfText", + "Alt-e": "EndOfLine", + // "Alt-p": "CursorUp", + // "Alt-n": "CursorDown", - // Integration with file managers - "F2": "Save", - "F3": "Find", - "F4": "Quit", - "F7": "Find", - "F10": "Quit", - "Esc": "Escape,Deselect,ClearInfo,RemoveAllMultiCursors", + // Integration with file managers + "F2": "Save", + "F3": "Find", + "F4": "Quit", + "F7": "Find", + "F10": "Quit", + "Esc": "Escape,Deselect,ClearInfo,RemoveAllMultiCursors", - // Mouse bindings - "MouseWheelUp": "ScrollUp", - "MouseWheelDown": "ScrollDown", - "MouseLeft": "MousePress", - "MouseMiddle": "PastePrimary", - "Ctrl-MouseLeft": "MouseMultiCursor", + // Mouse bindings + "MouseWheelUp": "ScrollUp", + "MouseWheelDown": "ScrollDown", + "MouseLeft": "MousePress", + "MouseMiddle": "PastePrimary", + "Ctrl-MouseLeft": "MouseMultiCursor", - "Alt-n": "SpawnMultiCursor", - "AltShiftUp": "SpawnMultiCursorUp", - "AltShiftDown": "SpawnMultiCursorDown", - "Alt-m": "SpawnMultiCursorSelect", - "Alt-p": "RemoveMultiCursor", - "Alt-c": "RemoveAllMultiCursors", - "Alt-x": "SkipMultiCursor", - } + "Alt-n": "SpawnMultiCursor", + "AltShiftUp": "SpawnMultiCursorUp", + "AltShiftDown": "SpawnMultiCursorDown", + "Alt-m": "SpawnMultiCursorSelect", + "Alt-p": "RemoveMultiCursor", + "Alt-c": "RemoveAllMultiCursors", + "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", +var infodefaults = 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", + // Emacs-style keybindings + "Alt-f": "WordRight", + "Alt-b": "WordLeft", + "Alt-a": "StartOfText", + "Alt-e": "EndOfLine", - // Integration with file managers - "F10": "AbortCommand", - "Esc": "AbortCommand", + // Integration with file managers + "F10": "AbortCommand", + "Esc": "AbortCommand", - // Mouse bindings - "MouseWheelUp": "HistoryUp", - "MouseWheelDown": "HistoryDown", - "MouseLeft": "MousePress", - "MouseMiddle": "PastePrimary", - } + // Mouse bindings + "MouseWheelUp": "HistoryUp", + "MouseWheelDown": "HistoryDown", + "MouseLeft": "MousePress", + "MouseMiddle": "PastePrimary", } diff --git a/internal/action/defaults_other.go b/internal/action/defaults_other.go index ee4e311d..d0290e40 100644 --- a/internal/action/defaults_other.go +++ b/internal/action/defaults_other.go @@ -2,185 +2,180 @@ package action -// DefaultBindings returns a map containing micro's default keybindings -func DefaultBindings() map[string]string { - return map[string]string{ - "Up": "CursorUp", - "Down": "CursorDown", - "Right": "CursorRight", - "Left": "CursorLeft", - "ShiftUp": "SelectUp", - "ShiftDown": "SelectDown", - "ShiftLeft": "SelectLeft", - "ShiftRight": "SelectRight", - "CtrlLeft": "WordLeft", - "CtrlRight": "WordRight", - "AltUp": "MoveLinesUp", - "AltDown": "MoveLinesDown", - "CtrlShiftRight": "SelectWordRight", - "CtrlShiftLeft": "SelectWordLeft", - "AltLeft": "StartOfTextToggle", - "AltRight": "EndOfLine", - "AltShiftLeft": "SelectToStartOfTextToggle", - "ShiftHome": "SelectToStartOfTextToggle", - "AltShiftRight": "SelectToEndOfLine", - "ShiftEnd": "SelectToEndOfLine", - "CtrlUp": "CursorStart", - "CtrlDown": "CursorEnd", - "CtrlShiftUp": "SelectToStart", - "CtrlShiftDown": "SelectToEnd", - "Alt-{": "ParagraphPrevious", - "Alt-}": "ParagraphNext", - "Enter": "InsertNewline", - "CtrlH": "Backspace", - "Backspace": "Backspace", - "OldBackspace": "Backspace", - "Alt-CtrlH": "DeleteWordLeft", - "Alt-Backspace": "DeleteWordLeft", - "Tab": "Autocomplete|IndentSelection|InsertTab", - "Backtab": "CycleAutocompleteBack|OutdentSelection|OutdentLine", - "Ctrl-o": "OpenFile", - "Ctrl-s": "Save", - "Ctrl-f": "Find", - "Ctrl-n": "FindNext", - "Ctrl-p": "FindPrevious", - "Ctrl-z": "Undo", - "Ctrl-y": "Redo", - "Ctrl-c": "CopyLine|Copy", - "Ctrl-x": "Cut", - "Ctrl-k": "CutLine", - "Ctrl-d": "DuplicateLine", - "Ctrl-v": "Paste", - "Ctrl-a": "SelectAll", - "Ctrl-t": "AddTab", - "Alt-,": "PreviousTab", - "Alt-.": "NextTab", - "Home": "StartOfTextToggle", - "End": "EndOfLine", - "CtrlHome": "CursorStart", - "CtrlEnd": "CursorEnd", - "PageUp": "CursorPageUp", - "PageDown": "CursorPageDown", - "CtrlPageUp": "PreviousTab", - "CtrlPageDown": "NextTab", - "Ctrl-g": "ToggleHelp", - "Alt-g": "ToggleKeyMenu", - "Ctrl-r": "ToggleRuler", - "Ctrl-l": "command-edit:goto ", - "Delete": "Delete", - "Ctrl-b": "ShellMode", - "Ctrl-q": "Quit", - "Ctrl-e": "CommandMode", - "Ctrl-w": "NextSplit", - "Ctrl-u": "ToggleMacro", - "Ctrl-j": "PlayMacro", - "Insert": "ToggleOverwriteMode", +var bufdefaults = map[string]string{ + "Up": "CursorUp", + "Down": "CursorDown", + "Right": "CursorRight", + "Left": "CursorLeft", + "ShiftUp": "SelectUp", + "ShiftDown": "SelectDown", + "ShiftLeft": "SelectLeft", + "ShiftRight": "SelectRight", + "CtrlLeft": "WordLeft", + "CtrlRight": "WordRight", + "AltUp": "MoveLinesUp", + "AltDown": "MoveLinesDown", + "CtrlShiftRight": "SelectWordRight", + "CtrlShiftLeft": "SelectWordLeft", + "AltLeft": "StartOfTextToggle", + "AltRight": "EndOfLine", + "AltShiftLeft": "SelectToStartOfTextToggle", + "ShiftHome": "SelectToStartOfTextToggle", + "AltShiftRight": "SelectToEndOfLine", + "ShiftEnd": "SelectToEndOfLine", + "CtrlUp": "CursorStart", + "CtrlDown": "CursorEnd", + "CtrlShiftUp": "SelectToStart", + "CtrlShiftDown": "SelectToEnd", + "Alt-{": "ParagraphPrevious", + "Alt-}": "ParagraphNext", + "Enter": "InsertNewline", + "CtrlH": "Backspace", + "Backspace": "Backspace", + "OldBackspace": "Backspace", + "Alt-CtrlH": "DeleteWordLeft", + "Alt-Backspace": "DeleteWordLeft", + "Tab": "Autocomplete|IndentSelection|InsertTab", + "Backtab": "CycleAutocompleteBack|OutdentSelection|OutdentLine", + "Ctrl-o": "OpenFile", + "Ctrl-s": "Save", + "Ctrl-f": "Find", + "Ctrl-n": "FindNext", + "Ctrl-p": "FindPrevious", + "Ctrl-z": "Undo", + "Ctrl-y": "Redo", + "Ctrl-c": "CopyLine|Copy", + "Ctrl-x": "Cut", + "Ctrl-k": "CutLine", + "Ctrl-d": "DuplicateLine", + "Ctrl-v": "Paste", + "Ctrl-a": "SelectAll", + "Ctrl-t": "AddTab", + "Alt-,": "PreviousTab", + "Alt-.": "NextTab", + "Home": "StartOfTextToggle", + "End": "EndOfLine", + "CtrlHome": "CursorStart", + "CtrlEnd": "CursorEnd", + "PageUp": "CursorPageUp", + "PageDown": "CursorPageDown", + "CtrlPageUp": "PreviousTab", + "CtrlPageDown": "NextTab", + "Ctrl-g": "ToggleHelp", + "Alt-g": "ToggleKeyMenu", + "Ctrl-r": "ToggleRuler", + "Ctrl-l": "command-edit:goto ", + "Delete": "Delete", + "Ctrl-b": "ShellMode", + "Ctrl-q": "Quit", + "Ctrl-e": "CommandMode", + "Ctrl-w": "NextSplit", + "Ctrl-u": "ToggleMacro", + "Ctrl-j": "PlayMacro", + "Insert": "ToggleOverwriteMode", - // Emacs-style keybindings - "Alt-f": "WordRight", - "Alt-b": "WordLeft", - "Alt-a": "StartOfText", - "Alt-e": "EndOfLine", - // "Alt-p": "CursorUp", - // "Alt-n": "CursorDown", + // Emacs-style keybindings + "Alt-f": "WordRight", + "Alt-b": "WordLeft", + "Alt-a": "StartOfText", + "Alt-e": "EndOfLine", + // "Alt-p": "CursorUp", + // "Alt-n": "CursorDown", - // Integration with file managers - "F2": "Save", - "F3": "Find", - "F4": "Quit", - "F7": "Find", - "F10": "Quit", - "Esc": "Escape,Deselect,ClearInfo,RemoveAllMultiCursors", + // Integration with file managers + "F2": "Save", + "F3": "Find", + "F4": "Quit", + "F7": "Find", + "F10": "Quit", + "Esc": "Escape,Deselect,ClearInfo,RemoveAllMultiCursors", - // Mouse bindings - "MouseWheelUp": "ScrollUp", - "MouseWheelDown": "ScrollDown", - "MouseLeft": "MousePress", - "MouseMiddle": "PastePrimary", - "Ctrl-MouseLeft": "MouseMultiCursor", + // Mouse bindings + "MouseWheelUp": "ScrollUp", + "MouseWheelDown": "ScrollDown", + "MouseLeft": "MousePress", + "MouseMiddle": "PastePrimary", + "Ctrl-MouseLeft": "MouseMultiCursor", - "Alt-n": "SpawnMultiCursor", - "Alt-m": "SpawnMultiCursorSelect", - "AltShiftUp": "SpawnMultiCursorUp", - "AltShiftDown": "SpawnMultiCursorDown", - "Alt-p": "RemoveMultiCursor", - "Alt-c": "RemoveAllMultiCursors", - "Alt-x": "SkipMultiCursor", - } + "Alt-n": "SpawnMultiCursor", + "Alt-m": "SpawnMultiCursorSelect", + "AltShiftUp": "SpawnMultiCursorUp", + "AltShiftDown": "SpawnMultiCursorDown", + "Alt-p": "RemoveMultiCursor", + "Alt-c": "RemoveAllMultiCursors", + "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", +var infodefaults = 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", + // Emacs-style keybindings + "Alt-f": "WordRight", + "Alt-b": "WordLeft", + "Alt-a": "StartOfText", + "Alt-e": "EndOfLine", - // Integration with file managers - "F10": "AbortCommand", - "Esc": "AbortCommand", + // Integration with file managers + "F10": "AbortCommand", + "Esc": "AbortCommand", - // Mouse bindings - "MouseWheelUp": "HistoryUp", - "MouseWheelDown": "HistoryDown", - "MouseLeft": "MousePress", - "MouseMiddle": "PastePrimary", - } + // Mouse bindings + "MouseWheelUp": "HistoryUp", + "MouseWheelDown": "HistoryDown", + "MouseLeft": "MousePress", + "MouseMiddle": "PastePrimary", } diff --git a/internal/action/infopane.go b/internal/action/infopane.go index 8c2c6690..ed4aea29 100644 --- a/internal/action/infopane.go +++ b/internal/action/infopane.go @@ -20,7 +20,16 @@ func init() { InfoBufBindings = NewKeyTree() } -func InfoMapKey(k Event, action string) { +func InfoMapEvent(k Event, action string) { + switch e := k.(type) { + case KeyEvent, KeySequenceEvent, RawEvent: + infoMapKey(e, action) + case MouseEvent: + infoMapMouse(e, action) + } +} + +func infoMapKey(k Event, action string) { if f, ok := InfoKeyActions[action]; ok { InfoBindings.RegisterKeyBinding(k, InfoKeyActionGeneral(f)) } else if f, ok := BufKeyActions[action]; ok { @@ -28,18 +37,19 @@ func InfoMapKey(k Event, action string) { } } -func InfoMapMouse(k MouseEvent, action string) { +func infoMapMouse(k MouseEvent, action string) { + // TODO: map mouse if f, ok := BufMouseActions[action]; ok { InfoBufBindings.RegisterMouseBinding(k, BufMouseActionGeneral(f)) } else { - InfoMapKey(k, action) + infoMapKey(k, action) } } func InfoKeyActionGeneral(a InfoKeyAction) PaneKeyAction { return func(p Pane) bool { a(p.(*InfoPane)) - return false + return true } } @@ -107,7 +117,6 @@ 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 action, more := InfoBindings.NextEvent(e, nil) if action != nil && !more { action(h) @@ -119,15 +128,18 @@ func (h *InfoPane) DoKeyEvent(e KeyEvent) bool { // 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() + if !more { + action, more = InfoBufBindings.NextEvent(e, nil) + if action != nil && !more { + done := action(h.BufPane) + InfoBufBindings.ResetEvents() + return done + } else if action == nil && !more { + InfoBufBindings.ResetEvents() + } } - return done + return more } // HistoryUp cycles history up @@ -181,7 +193,7 @@ func (h *InfoPane) AbortCommand() { h.DonePrompt(true) } -// BufKeyActions contains the list of all possible key actions the bufhandler could execute +// InfoKeyActions contains the list of all possible key actions the infopane could execute var InfoKeyActions = map[string]InfoKeyAction{ "HistoryUp": (*InfoPane).HistoryUp, "HistoryDown": (*InfoPane).HistoryDown, diff --git a/internal/action/termpane.go b/internal/action/termpane.go index 860dc192..59ee7e84 100644 --- a/internal/action/termpane.go +++ b/internal/action/termpane.go @@ -12,6 +12,41 @@ import ( "github.com/zyedidia/terminal" ) +type TermKeyAction func(*TermPane) + +var TermBindings *KeyTree + +func init() { + TermBindings = NewKeyTree() +} + +func TermKeyActionGeneral(a TermKeyAction) PaneKeyAction { + return func(p Pane) bool { + a(p.(*TermPane)) + return true + } +} + +func TermMapEvent(k Event, action string) { + switch e := k.(type) { + case KeyEvent, KeySequenceEvent, RawEvent: + termMapKey(e, action) + case MouseEvent: + termMapMouse(e, action) + } +} + +func termMapKey(k Event, action string) { + if f, ok := TermKeyActions[action]; ok { + TermBindings.RegisterKeyBinding(k, TermKeyActionGeneral(f)) + } +} + +func termMapMouse(k MouseEvent, action string) { + // TODO: map mouse + termMapKey(k, action) +} + type TermPane struct { *shell.Terminal display.Window @@ -53,6 +88,7 @@ func (t *TermPane) Tab() *Tab { func (t *TermPane) Close() {} +// Quit closes this termpane func (t *TermPane) Quit() { t.Close() if len(MainTab().Panes) > 1 { @@ -66,6 +102,7 @@ func (t *TermPane) Quit() { } } +// Unsplit removes this split func (t *TermPane) Unsplit() { n := MainTab().GetNode(t.id) n.Unsplit() @@ -81,6 +118,26 @@ func (t *TermPane) Unsplit() { // copy-paste func (t *TermPane) HandleEvent(event tcell.Event) { if e, ok := event.(*tcell.EventKey); ok { + ke := KeyEvent{ + code: e.Key(), + mod: e.Modifiers(), + r: e.Rune(), + } + action, more := TermBindings.NextEvent(ke, nil) + + if !more { + if action != nil { + action(t) + TermBindings.ResetEvents() + return + } + TermBindings.ResetEvents() + } + + if more { + return + } + if t.Status == shell.TTDone { switch e.Key() { case tcell.KeyEscape, tcell.KeyCtrlQ, tcell.KeyEnter: @@ -134,6 +191,41 @@ func (t *TermPane) HandleEvent(event tcell.Event) { } } +// Exit closes the termpane +func (t *TermPane) Exit() { + t.Terminal.Close() + t.Quit() +} + +// CommandMode opens the termpane's command mode +func (t *TermPane) CommandMode() { + InfoBar.Prompt("> ", "", "TerminalCommand", nil, func(resp string, canceled bool) { + if !canceled { + t.HandleCommand(resp) + } + }) +} + +// NextSplit moves to the next split +func (t *TermPane) NextSplit() { + a := t.tab.active + if a < len(t.tab.Panes)-1 { + a++ + } else { + a = 0 + } + + t.tab.SetActive(a) +} + +// HandleCommand handles a command for the term pane func (t *TermPane) HandleCommand(input string) { InfoBar.Error("Commands are unsupported in term for now") } + +// TermKeyActions contains the list of all possible key actions the termpane could execute +var TermKeyActions = map[string]TermKeyAction{ + "Exit": (*TermPane).Exit, + "CommandMode": (*TermPane).CommandMode, + "NextSplit": (*TermPane).NextSplit, +}