mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-25 18:07:07 +09:00
Separate bindings for buffers and command bar
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.
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
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:?
|
||||
}
|
||||
}
|
||||
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 {
|
||||
|
||||
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() {
|
||||
// AbortCommand cancels the prompt
|
||||
func (h *InfoPane) AbortCommand() {
|
||||
h.DonePrompt(true)
|
||||
}
|
||||
|
||||
// QuitAll cancels the prompt
|
||||
func (h *InfoPane) QuitAll() {
|
||||
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,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user