"github.com/zyedidia/micro/cmd/micro/buffer"
"github.com/zyedidia/micro/cmd/micro/display"
- "github.com/zyedidia/micro/cmd/micro/util"
+ "github.com/zyedidia/micro/cmd/micro/screen"
"github.com/zyedidia/tcell"
)
type BufKeyAction func(*BufHandler) bool
type BufMouseAction func(*BufHandler, *tcell.EventMouse) bool
-var BufKeyBindings map[KeyEvent]BufKeyAction
-var BufKeyStrings map[KeyEvent]string
+var BufKeyBindings map[Event]BufKeyAction
+var BufKeyStrings map[Event]string
var BufMouseBindings map[MouseEvent]BufMouseAction
func init() {
- BufKeyBindings = make(map[KeyEvent]BufKeyAction)
- BufKeyStrings = make(map[KeyEvent]string)
+ BufKeyBindings = make(map[Event]BufKeyAction)
+ BufKeyStrings = make(map[Event]string)
BufMouseBindings = make(map[MouseEvent]BufMouseAction)
}
// BufMapKey maps a key event to an action
-func BufMapKey(k KeyEvent, action string) {
+func BufMapKey(k Event, action string) {
if f, ok := BufKeyActions[action]; ok {
BufKeyStrings[k] = action
BufKeyBindings[k] = f
} else {
- util.TermMessage("Error:", action, "does not exist")
+ screen.TermMessage("Error:", action, "does not exist")
}
}
BufMouseBindings[k] = f
} else if f, ok := BufKeyActions[action]; ok {
// allowed to map mouse buttons to key actions
- BufMouseBindings[k] = func(h *BufHandler, e *tcell.EventMouse) bool {
- return f(h)
- }
+ BufKeyStrings[k] = action
+ BufKeyBindings[k] = f
+ // ensure we don't double bind a key
+ delete(BufMouseBindings, k)
} else {
- util.TermMessage("Error:", action, "does not exist")
+ screen.TermMessage("Error:", action, "does not exist")
}
}
// The ActionHandler can access the window for necessary info about
// visual positions for mouse clicks and scrolling
type BufHandler struct {
+ display.BWindow
+
Buf *buffer.Buffer
- Win display.Window
- cursors []*buffer.Cursor
- Cursor *buffer.Cursor // the active cursor
+ Cursor *buffer.Cursor // the active cursor
StartLine int // Vertical scrolling
StartCol int // Horizontal scrolling
splitID uint64
}
-func NewBufHandler(buf *buffer.Buffer, win display.Window) *BufHandler {
+func NewBufHandler(buf *buffer.Buffer, win display.BWindow) *BufHandler {
h := new(BufHandler)
h.Buf = buf
- h.Win = win
+ h.BWindow = win
- h.cursors = []*buffer.Cursor{buffer.NewCursor(buf, buf.StartCursor)}
- h.Cursor = h.cursors[0]
+ h.Cursor = h.Buf.GetActiveCursor()
h.mouseReleased = true
- buf.SetCursors(h.cursors)
return h
}
+func (h *BufHandler) OpenBuffer(b *buffer.Buffer) {
+ h.Buf.Close()
+ h.Buf = b
+ h.BWindow.SetBuffer(b)
+ h.Cursor = b.GetActiveCursor()
+ v := new(display.View)
+ h.SetView(v)
+ h.Relocate()
+ // 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
+ h.isOverwriteMode = false
+ h.lastClickTime = time.Time{}
+}
+
+func (h *BufHandler) ID() uint64 {
+ return h.splitID
+}
+
+func (h *BufHandler) Name() string {
+ return h.Buf.GetName()
+}
+
// HandleEvent executes the tcell event properly
// TODO: multiple actions bound to one key
func (h *BufHandler) HandleEvent(event tcell.Event) {
switch e := event.(type) {
+ case *tcell.EventRaw:
+ re := RawEvent{
+ esc: e.EscSeq(),
+ }
+ h.DoKeyEvent(re)
case *tcell.EventKey:
ke := KeyEvent{
code: e.Key(),
// Mouse was just released
mx, my := e.Position()
- mouseLoc := h.Win.GetMouseLoc(buffer.Loc{X: mx, Y: my})
+ mouseLoc := h.GetMouseLoc(buffer.Loc{X: mx, Y: my})
// Relocating here isn't really necessary because the cursor will
// be in the right place from the last mouse event
h.DoMouseEvent(me, e)
}
h.Buf.MergeCursors()
+
+ // Display any gutter messages for this line
+ c := h.Buf.GetActiveCursor()
+ none := true
+ for _, m := range h.Buf.Messages {
+ if c.Y == m.Start.Y || c.Y == m.End.Y {
+ InfoBar.GutterMessage(m.Msg)
+ none = false
+ break
+ }
+ }
+ if none && InfoBar.HasGutter {
+ InfoBar.ClearGutter()
+ }
}
// DoKeyEvent executes a key event by finding the action it is bound
// to and executing it (possibly multiple times for multiple cursors)
-func (h *BufHandler) DoKeyEvent(e KeyEvent) bool {
+func (h *BufHandler) DoKeyEvent(e Event) bool {
if action, ok := BufKeyBindings[e]; ok {
estr := BufKeyStrings[e]
for _, s := range MultiActions {
h.Buf.SetCurCursor(c.Num)
h.Cursor = c
if action(h) {
- h.Win.Relocate()
+ h.Relocate()
}
}
return true
}
}
if action(h) {
- h.Win.Relocate()
+ h.Relocate()
}
return true
}
return false
}
+func (h *BufHandler) HasKeyEvent(e Event) bool {
+ _, ok := BufKeyBindings[e]
+ return ok
+}
+
// DoMouseEvent executes a mouse event by finding the action it is bound
// to and executing it
func (h *BufHandler) DoMouseEvent(e MouseEvent, te *tcell.EventMouse) bool {
if action, ok := BufMouseBindings[e]; ok {
if action(h, te) {
- h.Win.Relocate()
+ h.Relocate()
}
return true
+ } else if h.HasKeyEvent(e) {
+ return h.DoKeyEvent(e)
}
return false
}
cursors := h.Buf.GetCursors()
for _, c := range cursors {
// Insert a character
+ h.Buf.SetCurCursor(c.Num)
if c.HasSelection() {
c.DeleteSelection()
c.ResetSelection()
if h.isOverwriteMode {
next := c.Loc
next.X++
- h.Buf.Replace(c.Loc, next, string(r))
+ h.Buf.Replace(c.Loc, next, []byte{byte(r)})
} else {
- h.Buf.Insert(c.Loc, string(r))
+ h.Buf.Insert(c.Loc, []byte{byte(r)})
}
}
}
-func (h *BufHandler) vsplit(buf *buffer.Buffer) {
+func (h *BufHandler) VSplitBuf(buf *buffer.Buffer) {
e := NewBufEditPane(0, 0, 0, 0, buf)
- e.splitID = MainTab.GetNode(h.splitID).VSplit(h.Buf.Settings["splitright"].(bool))
- MainTab.Panes = append(MainTab.Panes, e)
- MainTab.Resize()
- MainTab.SetActive(len(MainTab.Panes) - 1)
+ e.splitID = MainTab().GetNode(h.splitID).VSplit(h.Buf.Settings["splitright"].(bool))
+ MainTab().Panes = append(MainTab().Panes, e)
+ MainTab().Resize()
+ MainTab().SetActive(len(MainTab().Panes) - 1)
}
-func (h *BufHandler) hsplit(buf *buffer.Buffer) {
+func (h *BufHandler) HSplitBuf(buf *buffer.Buffer) {
e := NewBufEditPane(0, 0, 0, 0, buf)
- e.splitID = MainTab.GetNode(h.splitID).HSplit(h.Buf.Settings["splitbottom"].(bool))
- MainTab.Panes = append(MainTab.Panes, e)
- MainTab.Resize()
- MainTab.SetActive(len(MainTab.Panes) - 1)
+ e.splitID = MainTab().GetNode(h.splitID).HSplit(h.Buf.Settings["splitbottom"].(bool))
+ MainTab().Panes = append(MainTab().Panes, e)
+ MainTab().Resize()
+ MainTab().SetActive(len(MainTab().Panes) - 1)
+}
+func (h *BufHandler) Close() {
+ h.Buf.Close()
}
// BufKeyActions contains the list of all possible key actions the bufhandler could execute
"ParagraphPrevious": (*BufHandler).ParagraphPrevious,
"ParagraphNext": (*BufHandler).ParagraphNext,
"InsertNewline": (*BufHandler).InsertNewline,
- "InsertSpace": (*BufHandler).InsertSpace,
"Backspace": (*BufHandler).Backspace,
"Delete": (*BufHandler).Delete,
"InsertTab": (*BufHandler).InsertTab,
"NextSplit": (*BufHandler).NextSplit,
"PreviousSplit": (*BufHandler).PreviousSplit,
"Unsplit": (*BufHandler).Unsplit,
- "VSplit": (*BufHandler).VSplitBinding,
- "HSplit": (*BufHandler).HSplitBinding,
+ "VSplit": (*BufHandler).VSplitAction,
+ "HSplit": (*BufHandler).HSplitAction,
"ToggleMacro": (*BufHandler).ToggleMacro,
"PlayMacro": (*BufHandler).PlayMacro,
"Suspend": (*BufHandler).Suspend,
"ParagraphPrevious",
"ParagraphNext",
"InsertNewline",
- "InsertSpace",
"Backspace",
"Delete",
"InsertTab",