You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
605 lines
14 KiB
Go
605 lines
14 KiB
Go
package gui
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/jesseduffield/gocui"
|
|
)
|
|
|
|
// Binding - a keybinding mapping a key and modifier to a handler. The keypress
|
|
// is only handled if the given view has focus, or handled globally if the view
|
|
// is ""
|
|
type Binding struct {
|
|
ViewName string
|
|
Handler func(*gocui.Gui, *gocui.View) error
|
|
Key interface{} // FIXME: find out how to get `gocui.Key | rune`
|
|
Modifier gocui.Modifier
|
|
Description string
|
|
}
|
|
|
|
// GetKey is a function.
|
|
func (b *Binding) GetKey() string {
|
|
key := 0
|
|
|
|
switch b.Key.(type) {
|
|
case rune:
|
|
key = int(b.Key.(rune))
|
|
case gocui.Key:
|
|
key = int(b.Key.(gocui.Key))
|
|
}
|
|
|
|
// special keys
|
|
switch key {
|
|
case 27:
|
|
return "esc"
|
|
case 13:
|
|
return "enter"
|
|
case 32:
|
|
return "space"
|
|
case 65514:
|
|
return "►"
|
|
case 65515:
|
|
return "◄"
|
|
case 65517:
|
|
return "▲"
|
|
case 65516:
|
|
return "▼"
|
|
case 65508:
|
|
return "PgUp"
|
|
case 65507:
|
|
return "PgDn"
|
|
}
|
|
|
|
return fmt.Sprintf("%c", key)
|
|
}
|
|
|
|
// GetInitialKeybindings is a function.
|
|
func (gui *Gui) GetInitialKeybindings() []*Binding {
|
|
bindings := []*Binding{
|
|
{
|
|
ViewName: "",
|
|
Key: gocui.KeyEsc,
|
|
Modifier: gocui.ModNone,
|
|
Handler: wrappedHandler(gui.escape),
|
|
},
|
|
{
|
|
ViewName: "",
|
|
Key: 'q',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.quit,
|
|
},
|
|
{
|
|
ViewName: "",
|
|
Key: gocui.KeyCtrlC,
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.quit,
|
|
},
|
|
{
|
|
ViewName: "",
|
|
Key: gocui.KeyPgup,
|
|
Modifier: gocui.ModNone,
|
|
Handler: wrappedHandler(gui.scrollUpMain),
|
|
},
|
|
{
|
|
ViewName: "",
|
|
Key: gocui.KeyPgdn,
|
|
Modifier: gocui.ModNone,
|
|
Handler: wrappedHandler(gui.scrollDownMain),
|
|
},
|
|
{
|
|
ViewName: "",
|
|
Key: gocui.KeyCtrlU,
|
|
Modifier: gocui.ModNone,
|
|
Handler: wrappedHandler(gui.scrollUpMain),
|
|
},
|
|
{
|
|
ViewName: "",
|
|
Key: gocui.KeyCtrlD,
|
|
Modifier: gocui.ModNone,
|
|
Handler: wrappedHandler(gui.scrollDownMain),
|
|
},
|
|
{
|
|
ViewName: "",
|
|
Key: gocui.KeyEnd,
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.autoScrollMain,
|
|
},
|
|
{
|
|
ViewName: "",
|
|
Key: gocui.KeyHome,
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.jumpToTopMain,
|
|
},
|
|
{
|
|
ViewName: "",
|
|
Key: 'x',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleCreateOptionsMenu,
|
|
},
|
|
{
|
|
ViewName: "",
|
|
Key: '?',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleCreateOptionsMenu,
|
|
},
|
|
{
|
|
ViewName: "",
|
|
Key: 'X',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleCustomCommand,
|
|
},
|
|
{
|
|
ViewName: "project",
|
|
Key: 'e',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleEditConfig,
|
|
Description: gui.Tr.EditConfig,
|
|
},
|
|
{
|
|
ViewName: "project",
|
|
Key: 'o',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleOpenConfig,
|
|
Description: gui.Tr.OpenConfig,
|
|
},
|
|
{
|
|
ViewName: "project",
|
|
Key: 'm',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleViewAllLogs,
|
|
Description: gui.Tr.ViewLogs,
|
|
},
|
|
{
|
|
ViewName: "menu",
|
|
Key: gocui.KeyEsc,
|
|
Modifier: gocui.ModNone,
|
|
Handler: wrappedHandler(gui.handleMenuClose),
|
|
},
|
|
{
|
|
ViewName: "menu",
|
|
Key: 'q',
|
|
Modifier: gocui.ModNone,
|
|
Handler: wrappedHandler(gui.handleMenuClose),
|
|
},
|
|
{
|
|
ViewName: "menu",
|
|
Key: ' ',
|
|
Modifier: gocui.ModNone,
|
|
Handler: wrappedHandler(gui.handleMenuPress),
|
|
},
|
|
{
|
|
ViewName: "menu",
|
|
Key: gocui.KeyEnter,
|
|
Modifier: gocui.ModNone,
|
|
Handler: wrappedHandler(gui.handleMenuPress),
|
|
},
|
|
{
|
|
ViewName: "menu",
|
|
Key: 'y',
|
|
Modifier: gocui.ModNone,
|
|
Handler: wrappedHandler(gui.handleMenuPress),
|
|
},
|
|
{
|
|
ViewName: "information",
|
|
Key: gocui.MouseLeft,
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleDonate,
|
|
},
|
|
{
|
|
ViewName: "containers",
|
|
Key: 'd',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleContainersRemoveMenu,
|
|
Description: gui.Tr.Remove,
|
|
},
|
|
{
|
|
ViewName: "containers",
|
|
Key: 'e',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleHideStoppedContainers,
|
|
Description: gui.Tr.HideStopped,
|
|
},
|
|
{
|
|
ViewName: "containers",
|
|
Key: 'p',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleContainerPause,
|
|
Description: gui.Tr.Pause,
|
|
},
|
|
{
|
|
ViewName: "containers",
|
|
Key: 's',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleContainerStop,
|
|
Description: gui.Tr.Stop,
|
|
},
|
|
{
|
|
ViewName: "containers",
|
|
Key: 'r',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleContainerRestart,
|
|
Description: gui.Tr.Restart,
|
|
},
|
|
{
|
|
ViewName: "containers",
|
|
Key: 'a',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleContainerAttach,
|
|
Description: gui.Tr.Attach,
|
|
},
|
|
{
|
|
ViewName: "containers",
|
|
Key: 'm',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleContainerViewLogs,
|
|
Description: gui.Tr.ViewLogs,
|
|
},
|
|
{
|
|
ViewName: "containers",
|
|
Key: 'E',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleContainersExecShell,
|
|
Description: gui.Tr.ExecShell,
|
|
},
|
|
{
|
|
ViewName: "containers",
|
|
Key: 'c',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleContainersCustomCommand,
|
|
Description: gui.Tr.RunCustomCommand,
|
|
},
|
|
{
|
|
ViewName: "containers",
|
|
Key: 'b',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleContainersBulkCommand,
|
|
Description: gui.Tr.ViewBulkCommands,
|
|
},
|
|
{
|
|
ViewName: "containers",
|
|
Key: 'w',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleContainersOpenInBrowserCommand,
|
|
Description: gui.Tr.OpenInBrowser,
|
|
},
|
|
{
|
|
ViewName: "services",
|
|
Key: 'u',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleServiceUp,
|
|
Description: gui.Tr.UpService,
|
|
},
|
|
{
|
|
ViewName: "services",
|
|
Key: 'd',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleServiceRemoveMenu,
|
|
Description: gui.Tr.RemoveService,
|
|
},
|
|
{
|
|
ViewName: "services",
|
|
Key: 's',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleServiceStop,
|
|
Description: gui.Tr.Stop,
|
|
},
|
|
{
|
|
ViewName: "services",
|
|
Key: 'p',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleServicePause,
|
|
Description: gui.Tr.Pause,
|
|
},
|
|
{
|
|
ViewName: "services",
|
|
Key: 'r',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleServiceRestart,
|
|
Description: gui.Tr.Restart,
|
|
},
|
|
{
|
|
ViewName: "services",
|
|
Key: 'S',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleServiceStart,
|
|
Description: gui.Tr.Start,
|
|
},
|
|
{
|
|
ViewName: "services",
|
|
Key: 'a',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleServiceAttach,
|
|
Description: gui.Tr.Attach,
|
|
},
|
|
{
|
|
ViewName: "services",
|
|
Key: 'm',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleServiceRenderLogsToMain,
|
|
Description: gui.Tr.ViewLogs,
|
|
},
|
|
{
|
|
ViewName: "services",
|
|
Key: 'U',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleProjectUp,
|
|
Description: gui.Tr.UpProject,
|
|
},
|
|
{
|
|
ViewName: "services",
|
|
Key: 'D',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleProjectDown,
|
|
Description: gui.Tr.DownProject,
|
|
},
|
|
{
|
|
ViewName: "services",
|
|
Key: 'R',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleServiceRestartMenu,
|
|
Description: gui.Tr.ViewRestartOptions,
|
|
},
|
|
{
|
|
ViewName: "services",
|
|
Key: 'c',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleServicesCustomCommand,
|
|
Description: gui.Tr.RunCustomCommand,
|
|
},
|
|
{
|
|
ViewName: "services",
|
|
Key: 'b',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleServicesBulkCommand,
|
|
Description: gui.Tr.ViewBulkCommands,
|
|
},
|
|
{
|
|
ViewName: "services",
|
|
Key: 'E',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleServicesExecShell,
|
|
Description: gui.Tr.ExecShell,
|
|
},
|
|
{
|
|
ViewName: "services",
|
|
Key: 'w',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleServicesOpenInBrowserCommand,
|
|
Description: gui.Tr.OpenInBrowser,
|
|
},
|
|
{
|
|
ViewName: "images",
|
|
Key: 'c',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleImagesCustomCommand,
|
|
Description: gui.Tr.RunCustomCommand,
|
|
},
|
|
{
|
|
ViewName: "images",
|
|
Key: 'd',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleImagesRemoveMenu,
|
|
Description: gui.Tr.RemoveImage,
|
|
},
|
|
{
|
|
ViewName: "images",
|
|
Key: 'b',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleImagesBulkCommand,
|
|
Description: gui.Tr.ViewBulkCommands,
|
|
},
|
|
{
|
|
ViewName: "volumes",
|
|
Key: 'c',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleVolumesCustomCommand,
|
|
Description: gui.Tr.RunCustomCommand,
|
|
},
|
|
{
|
|
ViewName: "volumes",
|
|
Key: 'd',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleVolumesRemoveMenu,
|
|
Description: gui.Tr.RemoveVolume,
|
|
},
|
|
{
|
|
ViewName: "volumes",
|
|
Key: 'b',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleVolumesBulkCommand,
|
|
Description: gui.Tr.ViewBulkCommands,
|
|
},
|
|
{
|
|
ViewName: "networks",
|
|
Key: 'c',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleNetworksCustomCommand,
|
|
Description: gui.Tr.RunCustomCommand,
|
|
},
|
|
{
|
|
ViewName: "networks",
|
|
Key: 'd',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleNetworksRemoveMenu,
|
|
Description: gui.Tr.RemoveNetwork,
|
|
},
|
|
{
|
|
ViewName: "networks",
|
|
Key: 'b',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleNetworksBulkCommand,
|
|
Description: gui.Tr.ViewBulkCommands,
|
|
},
|
|
{
|
|
ViewName: "main",
|
|
Key: gocui.KeyEsc,
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleExitMain,
|
|
Description: gui.Tr.Return,
|
|
},
|
|
{
|
|
ViewName: "main",
|
|
Key: gocui.KeyArrowLeft,
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.scrollLeftMain,
|
|
},
|
|
{
|
|
ViewName: "main",
|
|
Key: gocui.KeyArrowRight,
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.scrollRightMain,
|
|
},
|
|
{
|
|
ViewName: "main",
|
|
Key: 'h',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.scrollLeftMain,
|
|
},
|
|
{
|
|
ViewName: "main",
|
|
Key: 'l',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.scrollRightMain,
|
|
},
|
|
{
|
|
ViewName: "filter",
|
|
Key: gocui.KeyEnter,
|
|
Modifier: gocui.ModNone,
|
|
Handler: wrappedHandler(gui.commitFilter),
|
|
},
|
|
{
|
|
ViewName: "filter",
|
|
Key: gocui.KeyEsc,
|
|
Modifier: gocui.ModNone,
|
|
Handler: wrappedHandler(gui.escapeFilterPrompt),
|
|
},
|
|
{
|
|
ViewName: "",
|
|
Key: 'J',
|
|
Modifier: gocui.ModNone,
|
|
Handler: wrappedHandler(gui.scrollDownMain),
|
|
},
|
|
{
|
|
ViewName: "",
|
|
Key: 'K',
|
|
Modifier: gocui.ModNone,
|
|
Handler: wrappedHandler(gui.scrollUpMain),
|
|
},
|
|
{
|
|
ViewName: "",
|
|
Key: 'H',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.scrollLeftMain,
|
|
},
|
|
{
|
|
ViewName: "",
|
|
Key: 'L',
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.scrollRightMain,
|
|
},
|
|
{
|
|
ViewName: "",
|
|
Key: '+',
|
|
Handler: wrappedHandler(gui.nextScreenMode),
|
|
Description: gui.Tr.LcNextScreenMode,
|
|
},
|
|
{
|
|
ViewName: "",
|
|
Key: '_',
|
|
Handler: wrappedHandler(gui.prevScreenMode),
|
|
Description: gui.Tr.LcPrevScreenMode,
|
|
},
|
|
}
|
|
|
|
for _, panel := range gui.allSidePanels() {
|
|
bindings = append(bindings, []*Binding{
|
|
{ViewName: panel.GetView().Name(), Key: gocui.KeyArrowLeft, Modifier: gocui.ModNone, Handler: gui.previousView},
|
|
{ViewName: panel.GetView().Name(), Key: gocui.KeyArrowRight, Modifier: gocui.ModNone, Handler: gui.nextView},
|
|
{ViewName: panel.GetView().Name(), Key: 'h', Modifier: gocui.ModNone, Handler: gui.previousView},
|
|
{ViewName: panel.GetView().Name(), Key: 'l', Modifier: gocui.ModNone, Handler: gui.nextView},
|
|
{ViewName: panel.GetView().Name(), Key: gocui.KeyTab, Modifier: gocui.ModNone, Handler: gui.nextView},
|
|
{ViewName: panel.GetView().Name(), Key: gocui.KeyBacktab, Modifier: gocui.ModNone, Handler: gui.previousView},
|
|
}...)
|
|
}
|
|
|
|
setUpDownClickBindings := func(viewName string, onUp func() error, onDown func() error, onClick func() error) {
|
|
bindings = append(bindings, []*Binding{
|
|
{ViewName: viewName, Key: 'k', Modifier: gocui.ModNone, Handler: wrappedHandler(onUp)},
|
|
{ViewName: viewName, Key: gocui.KeyArrowUp, Modifier: gocui.ModNone, Handler: wrappedHandler(onUp)},
|
|
{ViewName: viewName, Key: gocui.MouseWheelUp, Modifier: gocui.ModNone, Handler: wrappedHandler(onUp)},
|
|
{ViewName: viewName, Key: 'j', Modifier: gocui.ModNone, Handler: wrappedHandler(onDown)},
|
|
{ViewName: viewName, Key: gocui.KeyArrowDown, Modifier: gocui.ModNone, Handler: wrappedHandler(onDown)},
|
|
{ViewName: viewName, Key: gocui.MouseWheelDown, Modifier: gocui.ModNone, Handler: wrappedHandler(onDown)},
|
|
{ViewName: viewName, Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: wrappedHandler(onClick)},
|
|
}...)
|
|
}
|
|
|
|
for _, panel := range gui.allListPanels() {
|
|
setUpDownClickBindings(panel.GetView().Name(), panel.HandlePrevLine, panel.HandleNextLine, panel.HandleClick)
|
|
}
|
|
|
|
setUpDownClickBindings("main", gui.scrollUpMain, gui.scrollDownMain, gui.handleMainClick)
|
|
|
|
for _, panel := range gui.allSidePanels() {
|
|
bindings = append(bindings,
|
|
&Binding{
|
|
ViewName: panel.GetView().Name(),
|
|
Key: gocui.KeyEnter,
|
|
Modifier: gocui.ModNone,
|
|
Handler: gui.handleEnterMain,
|
|
Description: gui.Tr.FocusMain,
|
|
},
|
|
&Binding{
|
|
ViewName: panel.GetView().Name(),
|
|
Key: '[',
|
|
Modifier: gocui.ModNone,
|
|
Handler: wrappedHandler(panel.HandlePrevMainTab),
|
|
Description: gui.Tr.PreviousContext,
|
|
},
|
|
&Binding{
|
|
ViewName: panel.GetView().Name(),
|
|
Key: ']',
|
|
Modifier: gocui.ModNone,
|
|
Handler: wrappedHandler(panel.HandleNextMainTab),
|
|
Description: gui.Tr.NextContext,
|
|
},
|
|
)
|
|
}
|
|
|
|
for _, panel := range gui.allListPanels() {
|
|
if !panel.IsFilterDisabled() {
|
|
bindings = append(bindings, &Binding{
|
|
ViewName: panel.GetView().Name(),
|
|
Key: '/',
|
|
Modifier: gocui.ModNone,
|
|
Handler: wrappedHandler(gui.handleOpenFilter),
|
|
Description: gui.Tr.LcFilter,
|
|
})
|
|
}
|
|
}
|
|
|
|
return bindings
|
|
}
|
|
|
|
func (gui *Gui) keybindings(g *gocui.Gui) error {
|
|
bindings := gui.GetInitialKeybindings()
|
|
|
|
for _, binding := range bindings {
|
|
if err := g.SetKeybinding(binding.ViewName, binding.Key, binding.Modifier, binding.Handler); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if err := g.SetTabClickBinding("main", gui.onMainTabClick); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func wrappedHandler(f func() error) func(*gocui.Gui, *gocui.View) error {
|
|
return func(g *gocui.Gui, v *gocui.View) error {
|
|
return f()
|
|
}
|
|
}
|