mirror of
https://github.com/zyedidia/micro.git
synced 2026-02-05 14:40:20 +09:00
208 lines
8.5 KiB
Go
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,
|
|
}
|