micro/internal/action/infopane.go

225 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"
2019-12-25 21:11:38 +03:00
"strings"
2019-01-21 01:49:20 +03:00
2020-02-18 06:29:33 +03:00
"github.com/zyedidia/micro/internal/buffer"
2019-02-04 07:17:24 +03:00
"github.com/zyedidia/micro/internal/display"
"github.com/zyedidia/micro/internal/info"
"github.com/zyedidia/micro/internal/util"
2020-01-01 04:15:45 +03:00
"github.com/zyedidia/tcell"
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
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)
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 {
2019-01-03 23:27:43 +03:00
done := false
if action, ok := BufKeyBindings[e]; ok {
estr := BufKeyStrings[e]
for _, s := range InfoNones {
if s == estr {
return false
}
}
for s, a := range InfoOverrides {
2019-12-25 21:11:38 +03:00
// TODO this is a hack and really we should have support
// for having binding overrides for different buffers
2020-02-03 00:16:53 +03:00
if strings.HasPrefix(estr, s) {
2019-01-03 23:27:43 +03:00
done = true
a(h)
break
}
}
if !done {
2019-01-19 23:37:59 +03:00
done = action(h.BufPane)
2019-01-03 23:27:43 +03:00
}
}
return done
}
// InfoNones is a list of actions that should have no effect when executed
// by an infohandler
var InfoNones = []string{
"Save",
"SaveAll",
"SaveAs",
"Find",
"FindNext",
"FindPrevious",
"Center",
"DuplicateLine",
"MoveLinesUp",
"MoveLinesDown",
"OpenFile",
"Start",
"End",
"PageUp",
"PageDown",
"SelectPageUp",
"SelectPageDown",
"HalfPageUp",
"HalfPageDown",
"ToggleHelp",
"ToggleKeyMenu",
2020-02-08 10:56:24 +03:00
"ToggleDiffGutter",
2019-01-03 23:27:43 +03:00
"ToggleRuler",
"JumpLine",
"ClearStatus",
"ShellMode",
"CommandMode",
"AddTab",
"PreviousTab",
"NextTab",
"NextSplit",
"PreviousSplit",
"Unsplit",
"VSplit",
"HSplit",
"ToggleMacro",
"PlayMacro",
"Suspend",
"ScrollUp",
"ScrollDown",
"SpawnMultiCursor",
"SpawnMultiCursorSelect",
"RemoveMultiCursor",
"RemoveAllMultiCursors",
"SkipMultiCursor",
}
2019-12-30 06:02:14 +03:00
// InfoOverrides is the list of actions which have been overridden
2019-01-03 23:27:43 +03:00
// by the infohandler
var InfoOverrides = map[string]InfoKeyAction{
2019-01-19 23:37:59 +03:00
"CursorUp": (*InfoPane).CursorUp,
"CursorDown": (*InfoPane).CursorDown,
"InsertNewline": (*InfoPane).InsertNewline,
2019-12-25 21:11:38 +03:00
"Autocomplete": (*InfoPane).Autocomplete,
2019-01-19 23:37:59 +03:00
"Escape": (*InfoPane).Escape,
"Quit": (*InfoPane).Quit,
"QuitAll": (*InfoPane).QuitAll,
2019-01-03 23:27:43 +03:00
}
2019-06-16 22:56:39 +03:00
// CursorUp cycles history up
2019-01-19 23:37:59 +03:00
func (h *InfoPane) CursorUp() {
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
// CursorDown cycles history down
2019-01-19 23:37:59 +03:00
func (h *InfoPane) CursorDown() {
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) Autocomplete() {
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
// InsertNewline completes the prompt
2019-01-19 23:37:59 +03:00
func (h *InfoPane) InsertNewline() {
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
// Quit cancels the prompt
2019-01-19 23:37:59 +03:00
func (h *InfoPane) Quit() {
2019-01-03 23:27:43 +03:00
h.DonePrompt(true)
}
2019-06-16 22:56:39 +03:00
// QuitAll cancels the prompt
2019-01-19 23:37:59 +03:00
func (h *InfoPane) QuitAll() {
2019-01-03 23:27:43 +03:00
h.DonePrompt(true)
}
2019-06-16 22:56:39 +03:00
// Escape cancels the prompt
2019-01-19 23:37:59 +03:00
func (h *InfoPane) Escape() {
2019-01-03 23:27:43 +03:00
h.DonePrompt(true)
}