mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-25 18:07:07 +09:00
Allow configuration for info/term bindings
This commit exposes the separate infopane bindings to configuration from the user. This also adds support for separate bindings in the terminal emulator view. Default bindings are provided, but can also be rebound in bindings.json.
This commit is contained in:
@@ -12,6 +12,41 @@ import (
|
||||
"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) {
|
||||
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
|
||||
@@ -53,6 +88,7 @@ func (t *TermPane) Tab() *Tab {
|
||||
|
||||
func (t *TermPane) Close() {}
|
||||
|
||||
// Quit closes this termpane
|
||||
func (t *TermPane) Quit() {
|
||||
t.Close()
|
||||
if len(MainTab().Panes) > 1 {
|
||||
@@ -66,6 +102,7 @@ func (t *TermPane) Quit() {
|
||||
}
|
||||
}
|
||||
|
||||
// Unsplit removes this split
|
||||
func (t *TermPane) Unsplit() {
|
||||
n := MainTab().GetNode(t.id)
|
||||
n.Unsplit()
|
||||
@@ -81,6 +118,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: 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:
|
||||
@@ -134,6 +191,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,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user