micro/internal/action/infopane.go

204 lines
4.4 KiB
Go
Raw Normal View History

2019-01-03 23:27:43 +03:00
package action
import (
2019-01-21 01:49:20 +03:00
"bytes"
2020-05-04 17:16:15 +03:00
"github.com/zyedidia/micro/v2/internal/buffer"
"github.com/zyedidia/micro/v2/internal/display"
"github.com/zyedidia/micro/v2/internal/info"
"github.com/zyedidia/micro/v2/internal/util"
2020-09-05 21:52:35 +03:00
"github.com/zyedidia/tcell/v2"
2019-01-03 23:27:43 +03:00
)
2019-01-19 23:37:59 +03:00
type InfoKeyAction func(*InfoPane)
2019-01-03 23:27:43 +03:00
var InfoBindings *KeyTree
var InfoBufBindings *KeyTree
func init() {
InfoBindings = NewKeyTree()
InfoBufBindings = NewKeyTree()
}
func InfoMapEvent(k Event, action string) {
switch e := k.(type) {
case KeyEvent, KeySequenceEvent, RawEvent:
infoMapKey(e, action)
case MouseEvent:
infoMapMouse(e, action)
}
}
func infoMapKey(k Event, action string) {
if f, ok := InfoKeyActions[action]; ok {
InfoBindings.RegisterKeyBinding(k, InfoKeyActionGeneral(f))
} else if f, ok := BufKeyActions[action]; ok {
InfoBufBindings.RegisterKeyBinding(k, BufKeyActionGeneral(f))
}
}
func infoMapMouse(k MouseEvent, action string) {
// TODO: map mouse
if f, ok := BufMouseActions[action]; ok {
InfoBufBindings.RegisterMouseBinding(k, BufMouseActionGeneral(f))
} else {
infoMapKey(k, action)
}
}
func InfoKeyActionGeneral(a InfoKeyAction) PaneKeyAction {
return func(p Pane) bool {
a(p.(*InfoPane))
return true
}
}
2019-01-19 23:37:59 +03:00
type InfoPane struct {
*BufPane
2019-01-03 23:27:43 +03:00
*info.InfoBuf
}
2020-02-06 01:16:31 +03:00
func NewInfoPane(ib *info.InfoBuf, w display.BWindow, tab *Tab) *InfoPane {
2019-01-19 23:37:59 +03:00
ip := new(InfoPane)
ip.InfoBuf = ib
2020-02-06 01:16:31 +03:00
ip.BufPane = NewBufPane(ib.Buffer, w, tab)
ip.BufPane.bindings = InfoBufBindings
2019-01-03 23:27:43 +03:00
2019-01-19 23:37:59 +03:00
return ip
2019-01-03 23:27:43 +03:00
}
2019-01-19 23:37:59 +03:00
func NewInfoBar() *InfoPane {
ib := info.NewBuffer()
w := display.NewInfoWindow(ib)
2020-02-06 01:16:31 +03:00
return NewInfoPane(ib, w, nil)
2019-01-19 23:37:59 +03:00
}
func (h *InfoPane) Close() {
h.InfoBuf.Close()
h.BufPane.Close()
}
func (h *InfoPane) HandleEvent(event tcell.Event) {
2019-01-03 23:27:43 +03:00
switch e := event.(type) {
case *tcell.EventKey:
ke := KeyEvent{
code: e.Key(),
mod: e.Modifiers(),
r: e.Rune(),
}
done := h.DoKeyEvent(ke)
2019-01-16 06:45:28 +03:00
hasYN := h.HasYN
if e.Key() == tcell.KeyRune && hasYN {
if e.Rune() == 'y' && hasYN {
2019-01-05 05:48:19 +03:00
h.YNResp = true
h.DonePrompt(false)
2019-01-16 06:45:28 +03:00
} else if e.Rune() == 'n' && hasYN {
2019-01-05 05:48:19 +03:00
h.YNResp = false
h.DonePrompt(false)
}
2019-01-04 01:07:28 +03:00
}
2019-01-16 06:45:28 +03:00
if e.Key() == tcell.KeyRune && !done && !hasYN {
2019-01-15 08:24:53 +03:00
h.DoRuneInsert(e.Rune())
done = true
}
2019-01-16 06:45:28 +03:00
if done && h.HasPrompt && !hasYN {
2019-01-16 07:11:03 +03:00
resp := string(h.LineBytes(0))
2019-01-04 01:07:28 +03:00
hist := h.History[h.PromptType]
hist[h.HistoryNum] = resp
if h.EventCallback != nil {
h.EventCallback(resp)
}
2019-01-03 23:27:43 +03:00
}
default:
2019-01-19 23:37:59 +03:00
h.BufPane.HandleEvent(event)
2019-01-03 23:27:43 +03:00
}
}
2020-02-09 08:40:50 +03:00
// DoKeyEvent executes a key event for the command bar, doing any overridden actions
2019-01-19 23:37:59 +03:00
func (h *InfoPane) DoKeyEvent(e KeyEvent) bool {
action, more := InfoBindings.NextEvent(e, nil)
if action != nil && !more {
action(h)
InfoBindings.ResetEvents()
return true
} else if action == nil && !more {
InfoBindings.ResetEvents()
// return false //TODO:?
}
if !more {
action, more = InfoBufBindings.NextEvent(e, nil)
if action != nil && !more {
done := action(h.BufPane)
InfoBufBindings.ResetEvents()
return done
} else if action == nil && !more {
InfoBufBindings.ResetEvents()
}
2019-01-03 23:27:43 +03:00
}
return more
2019-01-03 23:27:43 +03:00
}
// HistoryUp cycles history up
func (h *InfoPane) HistoryUp() {
2019-01-04 01:07:28 +03:00
h.UpHistory(h.History[h.PromptType])
2019-01-03 23:27:43 +03:00
}
2019-06-16 22:56:39 +03:00
// HistoryDown cycles history down
func (h *InfoPane) HistoryDown() {
2019-01-04 01:07:28 +03:00
h.DownHistory(h.History[h.PromptType])
2019-01-03 23:27:43 +03:00
}
2019-06-16 22:56:39 +03:00
2019-12-25 21:11:38 +03:00
// Autocomplete begins autocompletion
func (h *InfoPane) CommandComplete() {
2019-01-21 01:49:20 +03:00
b := h.Buf
2019-01-25 02:09:57 +03:00
if b.HasSuggestions {
2019-01-25 06:10:57 +03:00
b.CycleAutocomplete(true)
2019-01-25 02:09:57 +03:00
return
}
2019-01-21 01:49:20 +03:00
c := b.GetActiveCursor()
l := b.LineBytes(0)
l = util.SliceStart(l, c.X)
args := bytes.Split(l, []byte{' '})
cmd := string(args[0])
2020-02-18 06:29:33 +03:00
if h.PromptType == "Command" {
if len(args) == 1 {
b.Autocomplete(CommandComplete)
} else if action, ok := commands[cmd]; ok {
2019-01-21 01:49:20 +03:00
if action.completer != nil {
2019-01-25 02:09:57 +03:00
b.Autocomplete(action.completer)
2019-01-21 01:49:20 +03:00
}
}
} else {
// by default use filename autocompletion
2020-02-18 06:29:33 +03:00
b.Autocomplete(buffer.FileComplete)
2019-01-21 01:49:20 +03:00
}
2019-01-03 23:27:43 +03:00
}
2019-06-16 22:56:39 +03:00
// ExecuteCommand completes the prompt
func (h *InfoPane) ExecuteCommand() {
2019-01-05 05:48:19 +03:00
if !h.HasYN {
h.DonePrompt(false)
}
2019-01-03 23:27:43 +03:00
}
2019-06-16 22:56:39 +03:00
// AbortCommand cancels the prompt
func (h *InfoPane) AbortCommand() {
2019-01-03 23:27:43 +03:00
h.DonePrompt(true)
}
2019-06-16 22:56:39 +03:00
// InfoKeyActions contains the list of all possible key actions the infopane could execute
var InfoKeyActions = map[string]InfoKeyAction{
"HistoryUp": (*InfoPane).HistoryUp,
"HistoryDown": (*InfoPane).HistoryDown,
"CommandComplete": (*InfoPane).CommandComplete,
"ExecuteCommand": (*InfoPane).ExecuteCommand,
"AbortCommand": (*InfoPane).AbortCommand,
2019-01-03 23:27:43 +03:00
}