]> git.lizzy.rs Git - micro.git/blobdiff - cmd/micro/action/bufhandler.go
Add keymenu
[micro.git] / cmd / micro / action / bufhandler.go
index 4af5be9948d5508505718c81d80239abcb79f144..ede74b5fd619bc6236b98e57e60f716898c1262e 100644 (file)
@@ -5,30 +5,30 @@ import (
 
        "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")
        }
 }
 
@@ -38,11 +38,12 @@ func BufMapMouse(k MouseEvent, action string) {
                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")
        }
 }
 
@@ -52,11 +53,11 @@ func BufMapMouse(k MouseEvent, action string) {
 // 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
@@ -97,23 +98,51 @@ type BufHandler struct {
        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(),
@@ -133,7 +162,7 @@ func (h *BufHandler) HandleEvent(event tcell.Event) {
                                // 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
@@ -157,11 +186,25 @@ func (h *BufHandler) HandleEvent(event tcell.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 {
@@ -171,28 +214,35 @@ func (h *BufHandler) DoKeyEvent(e KeyEvent) bool {
                                        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
 }
@@ -203,6 +253,7 @@ func (h *BufHandler) DoRuneInsert(r rune) {
        cursors := h.Buf.GetCursors()
        for _, c := range cursors {
                // Insert a character
+               h.Buf.SetCurCursor(c.Num)
                if c.HasSelection() {
                        c.DeleteSelection()
                        c.ResetSelection()
@@ -211,27 +262,30 @@ func (h *BufHandler) DoRuneInsert(r rune) {
                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)
 }
-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)
 }
+func (h *BufHandler) Close() {
+       h.Buf.Close()
+}
 
 // BufKeyActions contains the list of all possible key actions the bufhandler could execute
 var BufKeyActions = map[string]BufKeyAction{
@@ -314,8 +368,8 @@ var BufKeyActions = map[string]BufKeyAction{
        "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,