Files
zyedidia.micro/cmd/micro/bufactionhandler.go
2019-12-25 17:05:10 -05:00

208 lines
8.5 KiB
Go

package main
import (
"time"
"github.com/zyedidia/micro/cmd/micro/buffer"
"github.com/zyedidia/tcell"
)
type BufKeyAction func(*BufActionHandler) bool
type BufMouseAction func(*BufActionHandler, *tcell.EventMouse) bool
var BufKeyBindings map[KeyEvent]BufKeyAction
var BufMouseBindings map[MouseEvent]BufMouseAction
func init() {
BufKeyBindings = make(map[KeyEvent]BufKeyAction)
BufMouseBindings = make(map[MouseEvent]BufMouseAction)
}
func BufMapKey(k KeyEvent, action string) {
BufKeyBindings[k] = BufKeyActions[action]
}
func BufMapMouse(k MouseEvent, action string) {
BufMouseBindings[k] = BufMouseActions[action]
}
// The BufActionHandler 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
// The ActionHandler can access the window for necessary info about
// visual positions for mouse clicks and scrolling
type BufActionHandler struct {
Buf *buffer.Buffer
Win *Window
cursors []*buffer.Cursor
Cursor *buffer.Cursor // the active cursor
// Since tcell doesn't differentiate between a mouse release event
// and a mouse move event with no keys pressed, we need to keep
// track of whether or not the mouse was pressed (or not released) last event to determine
// mouse release events
mouseReleased bool
// We need to keep track of insert key press toggle
isOverwriteMode bool
// This stores when the last click was
// This is useful for detecting double and triple clicks
lastClickTime time.Time
lastLoc buffer.Loc
// lastCutTime stores when the last ctrl+k was issued.
// It is used for clearing the clipboard to replace it with fresh cut lines.
lastCutTime time.Time
// freshClip returns true if the clipboard has never been pasted.
freshClip bool
// Was the last mouse event actually a double click?
// Useful for detecting triple clicks -- if a double click is detected
// but the last mouse event was actually a double click, it's a triple click
doubleClick bool
// Same here, just to keep track for mouse move events
tripleClick bool
}
func NewBufActionHandler(buf *buffer.Buffer, win *Window) *BufActionHandler {
a := new(BufActionHandler)
a.Buf = buf
a.Win = win
a.cursors = []*buffer.Cursor{&buffer.Cursor{
Buf: buf,
Loc: buf.StartCursor,
}}
buf.SetCursors(a.cursors)
return a
}
// HandleEvent executes the tcell event properly
// TODO: multiple actions bound to one key
func (a *BufActionHandler) HandleEvent(event tcell.Event) {
switch e := event.(type) {
case *tcell.EventKey:
ke := KeyEvent{
code: e.Key(),
mod: e.Modifiers(),
r: e.Rune(),
}
if action, ok := BufKeyBindings[ke]; ok {
action(a)
}
case *tcell.EventMouse:
me := MouseEvent{
btn: e.Buttons(),
mod: e.Modifiers(),
}
if action, ok := BufMouseBindings[me]; ok {
action(a, e)
}
}
}
var BufKeyActions = map[string]BufKeyAction{
"CursorUp": (*BufActionHandler).CursorUp,
"CursorDown": (*BufActionHandler).CursorDown,
"CursorPageUp": (*BufActionHandler).CursorPageUp,
"CursorPageDown": (*BufActionHandler).CursorPageDown,
"CursorLeft": (*BufActionHandler).CursorLeft,
"CursorRight": (*BufActionHandler).CursorRight,
"CursorStart": (*BufActionHandler).CursorStart,
"CursorEnd": (*BufActionHandler).CursorEnd,
"SelectToStart": (*BufActionHandler).SelectToStart,
"SelectToEnd": (*BufActionHandler).SelectToEnd,
"SelectUp": (*BufActionHandler).SelectUp,
"SelectDown": (*BufActionHandler).SelectDown,
"SelectLeft": (*BufActionHandler).SelectLeft,
"SelectRight": (*BufActionHandler).SelectRight,
"WordRight": (*BufActionHandler).WordRight,
"WordLeft": (*BufActionHandler).WordLeft,
"SelectWordRight": (*BufActionHandler).SelectWordRight,
"SelectWordLeft": (*BufActionHandler).SelectWordLeft,
"DeleteWordRight": (*BufActionHandler).DeleteWordRight,
"DeleteWordLeft": (*BufActionHandler).DeleteWordLeft,
"SelectLine": (*BufActionHandler).SelectLine,
"SelectToStartOfLine": (*BufActionHandler).SelectToStartOfLine,
"SelectToEndOfLine": (*BufActionHandler).SelectToEndOfLine,
"ParagraphPrevious": (*BufActionHandler).ParagraphPrevious,
"ParagraphNext": (*BufActionHandler).ParagraphNext,
"InsertNewline": (*BufActionHandler).InsertNewline,
"InsertSpace": (*BufActionHandler).InsertSpace,
"Backspace": (*BufActionHandler).Backspace,
"Delete": (*BufActionHandler).Delete,
"InsertTab": (*BufActionHandler).InsertTab,
"Save": (*BufActionHandler).Save,
"SaveAll": (*BufActionHandler).SaveAll,
"SaveAs": (*BufActionHandler).SaveAs,
"Find": (*BufActionHandler).Find,
"FindNext": (*BufActionHandler).FindNext,
"FindPrevious": (*BufActionHandler).FindPrevious,
"Center": (*BufActionHandler).Center,
"Undo": (*BufActionHandler).Undo,
"Redo": (*BufActionHandler).Redo,
"Copy": (*BufActionHandler).Copy,
"Cut": (*BufActionHandler).Cut,
"CutLine": (*BufActionHandler).CutLine,
"DuplicateLine": (*BufActionHandler).DuplicateLine,
"DeleteLine": (*BufActionHandler).DeleteLine,
"MoveLinesUp": (*BufActionHandler).MoveLinesUp,
"MoveLinesDown": (*BufActionHandler).MoveLinesDown,
"IndentSelection": (*BufActionHandler).IndentSelection,
"OutdentSelection": (*BufActionHandler).OutdentSelection,
"OutdentLine": (*BufActionHandler).OutdentLine,
"Paste": (*BufActionHandler).Paste,
"PastePrimary": (*BufActionHandler).PastePrimary,
"SelectAll": (*BufActionHandler).SelectAll,
"OpenFile": (*BufActionHandler).OpenFile,
"Start": (*BufActionHandler).Start,
"End": (*BufActionHandler).End,
"PageUp": (*BufActionHandler).PageUp,
"PageDown": (*BufActionHandler).PageDown,
"SelectPageUp": (*BufActionHandler).SelectPageUp,
"SelectPageDown": (*BufActionHandler).SelectPageDown,
"HalfPageUp": (*BufActionHandler).HalfPageUp,
"HalfPageDown": (*BufActionHandler).HalfPageDown,
"StartOfLine": (*BufActionHandler).StartOfLine,
"EndOfLine": (*BufActionHandler).EndOfLine,
"ToggleHelp": (*BufActionHandler).ToggleHelp,
"ToggleKeyMenu": (*BufActionHandler).ToggleKeyMenu,
"ToggleRuler": (*BufActionHandler).ToggleRuler,
"JumpLine": (*BufActionHandler).JumpLine,
"ClearStatus": (*BufActionHandler).ClearStatus,
"ShellMode": (*BufActionHandler).ShellMode,
"CommandMode": (*BufActionHandler).CommandMode,
"ToggleOverwriteMode": (*BufActionHandler).ToggleOverwriteMode,
"Escape": (*BufActionHandler).Escape,
"Quit": (*BufActionHandler).Quit,
"QuitAll": (*BufActionHandler).QuitAll,
"AddTab": (*BufActionHandler).AddTab,
"PreviousTab": (*BufActionHandler).PreviousTab,
"NextTab": (*BufActionHandler).NextTab,
"NextSplit": (*BufActionHandler).NextSplit,
"PreviousSplit": (*BufActionHandler).PreviousSplit,
"Unsplit": (*BufActionHandler).Unsplit,
"VSplit": (*BufActionHandler).VSplitBinding,
"HSplit": (*BufActionHandler).HSplitBinding,
"ToggleMacro": (*BufActionHandler).ToggleMacro,
"PlayMacro": (*BufActionHandler).PlayMacro,
"Suspend": (*BufActionHandler).Suspend,
"ScrollUp": (*BufActionHandler).ScrollUpAction,
"ScrollDown": (*BufActionHandler).ScrollDownAction,
"SpawnMultiCursor": (*BufActionHandler).SpawnMultiCursor,
"SpawnMultiCursorSelect": (*BufActionHandler).SpawnMultiCursorSelect,
"RemoveMultiCursor": (*BufActionHandler).RemoveMultiCursor,
"RemoveAllMultiCursors": (*BufActionHandler).RemoveAllMultiCursors,
"SkipMultiCursor": (*BufActionHandler).SkipMultiCursor,
"JumpToMatchingBrace": (*BufActionHandler).JumpToMatchingBrace,
// This was changed to InsertNewline but I don't want to break backwards compatibility
"InsertEnter": (*BufActionHandler).InsertNewline,
}
var BufMouseActions = map[string]BufMouseAction{
"MousePress": (*BufActionHandler).MousePress,
"MouseMultiCursor": (*BufActionHandler).MouseMultiCursor,
}