]> git.lizzy.rs Git - micro.git/blobdiff - internal/action/termpane.go
Fix internal string binding representation
[micro.git] / internal / action / termpane.go
index b5a2da527f22ca4c3671312ef337688f10e1043f..bbb1e17b7cd10fc3dfc7453349a0102c7a8b5fab 100644 (file)
@@ -1,31 +1,76 @@
 package action
 
 import (
+       "errors"
        "runtime"
 
-       "github.com/zyedidia/clipboard"
-       "github.com/zyedidia/micro/internal/display"
-       "github.com/zyedidia/micro/internal/screen"
-       "github.com/zyedidia/micro/internal/shell"
-       "github.com/zyedidia/tcell"
+       "github.com/zyedidia/micro/v2/internal/clipboard"
+       "github.com/zyedidia/micro/v2/internal/config"
+       "github.com/zyedidia/micro/v2/internal/display"
+       "github.com/zyedidia/micro/v2/internal/screen"
+       "github.com/zyedidia/micro/v2/internal/shell"
+       "github.com/zyedidia/tcell/v2"
        "github.com/zyedidia/terminal"
 )
 
+type TermKeyAction func(*TermPane)
+
+var TermBindings *KeyTree
+
+func init() {
+       TermBindings = NewKeyTree()
+}
+
+func TermKeyActionGeneral(a TermKeyAction) PaneKeyAction {
+       return func(p Pane) bool {
+               a(p.(*TermPane))
+               return true
+       }
+}
+
+func TermMapEvent(k Event, action string) {
+       config.Bindings["terminal"][k.Name()] = action
+
+       switch e := k.(type) {
+       case KeyEvent, KeySequenceEvent, RawEvent:
+               termMapKey(e, action)
+       case MouseEvent:
+               termMapMouse(e, action)
+       }
+}
+
+func termMapKey(k Event, action string) {
+       if f, ok := TermKeyActions[action]; ok {
+               TermBindings.RegisterKeyBinding(k, TermKeyActionGeneral(f))
+       }
+}
+
+func termMapMouse(k MouseEvent, action string) {
+       // TODO: map mouse
+       termMapKey(k, action)
+}
+
 type TermPane struct {
        *shell.Terminal
        display.Window
 
        mouseReleased bool
        id            uint64
+       tab           *Tab
 }
 
-func NewTermPane(x, y, w, h int, t *shell.Terminal, id uint64) *TermPane {
+func NewTermPane(x, y, w, h int, t *shell.Terminal, id uint64, tab *Tab) (*TermPane, error) {
+       if !TermEmuSupported {
+               return nil, errors.New("Terminal emulator is not supported on this system")
+       }
+
        th := new(TermPane)
        th.Terminal = t
        th.id = id
        th.mouseReleased = true
        th.Window = display.NewTermWindow(x, y, w, h, t)
-       return th
+       th.tab = tab
+       return th, nil
 }
 
 func (t *TermPane) ID() uint64 {
@@ -36,8 +81,17 @@ func (t *TermPane) SetID(i uint64) {
        t.id = i
 }
 
+func (t *TermPane) SetTab(tab *Tab) {
+       t.tab = tab
+}
+
+func (t *TermPane) Tab() *Tab {
+       return t.tab
+}
+
 func (t *TermPane) Close() {}
 
+// Quit closes this termpane
 func (t *TermPane) Quit() {
        t.Close()
        if len(MainTab().Panes) > 1 {
@@ -51,6 +105,7 @@ func (t *TermPane) Quit() {
        }
 }
 
+// Unsplit removes this split
 func (t *TermPane) Unsplit() {
        n := MainTab().GetNode(t.id)
        n.Unsplit()
@@ -66,6 +121,26 @@ func (t *TermPane) Unsplit() {
 // copy-paste
 func (t *TermPane) HandleEvent(event tcell.Event) {
        if e, ok := event.(*tcell.EventKey); ok {
+               ke := KeyEvent{
+                       code: e.Key(),
+                       mod:  metaToAlt(e.Modifiers()),
+                       r:    e.Rune(),
+               }
+               action, more := TermBindings.NextEvent(ke, nil)
+
+               if !more {
+                       if action != nil {
+                               action(t)
+                               TermBindings.ResetEvents()
+                               return
+                       }
+                       TermBindings.ResetEvents()
+               }
+
+               if more {
+                       return
+               }
+
                if t.Status == shell.TTDone {
                        switch e.Key() {
                        case tcell.KeyEscape, tcell.KeyCtrlQ, tcell.KeyEnter:
@@ -75,13 +150,17 @@ func (t *TermPane) HandleEvent(event tcell.Event) {
                        }
                }
                if e.Key() == tcell.KeyCtrlC && t.HasSelection() {
-                       clipboard.WriteAll(t.GetSelection(t.GetView().Width), "clipboard")
+                       clipboard.Write(t.GetSelection(t.GetView().Width), clipboard.ClipboardReg)
                        InfoBar.Message("Copied selection to clipboard")
                } else if t.Status != shell.TTDone {
                        t.WriteString(event.EscSeq())
                }
+       } else if _, ok := event.(*tcell.EventPaste); ok {
+               if t.Status != shell.TTDone {
+                       t.WriteString(event.EscSeq())
+               }
        } else if e, ok := event.(*tcell.EventMouse); e != nil && (!ok || t.State.Mode(terminal.ModeMouseMask)) {
-               t.WriteString(event.EscSeq())
+               // t.WriteString(event.EscSeq())
        } else if e != nil {
                x, y := e.Position()
                v := t.GetView()
@@ -115,6 +194,41 @@ func (t *TermPane) HandleEvent(event tcell.Event) {
        }
 }
 
+// Exit closes the termpane
+func (t *TermPane) Exit() {
+       t.Terminal.Close()
+       t.Quit()
+}
+
+// CommandMode opens the termpane's command mode
+func (t *TermPane) CommandMode() {
+       InfoBar.Prompt("> ", "", "TerminalCommand", nil, func(resp string, canceled bool) {
+               if !canceled {
+                       t.HandleCommand(resp)
+               }
+       })
+}
+
+// NextSplit moves to the next split
+func (t *TermPane) NextSplit() {
+       a := t.tab.active
+       if a < len(t.tab.Panes)-1 {
+               a++
+       } else {
+               a = 0
+       }
+
+       t.tab.SetActive(a)
+}
+
+// HandleCommand handles a command for the term pane
 func (t *TermPane) HandleCommand(input string) {
        InfoBar.Error("Commands are unsupported in term for now")
 }
+
+// TermKeyActions contains the list of all possible key actions the termpane could execute
+var TermKeyActions = map[string]TermKeyAction{
+       "Exit":        (*TermPane).Exit,
+       "CommandMode": (*TermPane).CommandMode,
+       "NextSplit":   (*TermPane).NextSplit,
+}