244 lines
4.4 KiB
Go
244 lines
4.4 KiB
Go
package view
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"runtime"
|
|
"sort"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/derailed/k9s/internal/model"
|
|
"github.com/derailed/k9s/internal/ui"
|
|
"github.com/derailed/tview"
|
|
"github.com/gdamore/tcell"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
const (
|
|
helpTitle = "Help"
|
|
helpTitleFmt = " [aqua::b]%s "
|
|
)
|
|
|
|
type helpItem struct {
|
|
key, description string
|
|
}
|
|
|
|
// Help presents a help viewer.
|
|
type Help struct {
|
|
*ui.Table
|
|
|
|
app *App
|
|
actions ui.KeyActions
|
|
}
|
|
|
|
// NewHelp returns a new help viewer.
|
|
func NewHelp() *Help {
|
|
return &Help{
|
|
Table: ui.NewTable(helpTitle),
|
|
actions: make(ui.KeyActions),
|
|
}
|
|
}
|
|
|
|
func (v *Help) Init(ctx context.Context) {
|
|
v.app = ctx.Value(ui.KeyApp).(*App)
|
|
|
|
v.resetTitle()
|
|
|
|
v.SetBorder(true)
|
|
v.SetBorderPadding(0, 0, 1, 1)
|
|
v.SetInputCapture(v.keyboard)
|
|
v.bindKeys()
|
|
v.build(v.app.Hint.Peek())
|
|
}
|
|
|
|
func (v *Help) Name() string { return helpTitle }
|
|
func (v *Help) Start() {}
|
|
func (v *Help) Stop() {}
|
|
func (v *Help) Hints() model.MenuHints { return v.actions.Hints() }
|
|
|
|
func (v *Help) bindKeys() {
|
|
v.actions = ui.KeyActions{
|
|
tcell.KeyEsc: ui.NewKeyAction("Back", v.backCmd, true),
|
|
tcell.KeyEnter: ui.NewKeyAction("Back", v.backCmd, false),
|
|
}
|
|
}
|
|
|
|
func (v *Help) keyboard(evt *tcell.EventKey) *tcell.EventKey {
|
|
key := evt.Key()
|
|
if key == tcell.KeyRune {
|
|
key = tcell.Key(evt.Rune())
|
|
}
|
|
|
|
if a, ok := v.actions[key]; ok {
|
|
log.Debug().Msgf(">> TableView handled %s", tcell.KeyNames[key])
|
|
return a.Action(evt)
|
|
}
|
|
|
|
return evt
|
|
}
|
|
|
|
func (v *Help) backCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|
return v.app.PrevCmd(evt)
|
|
}
|
|
|
|
func (v *Help) showHelp() model.MenuHints {
|
|
return model.MenuHints{
|
|
{
|
|
Mnemonic: "?",
|
|
Description: "Help",
|
|
},
|
|
{
|
|
Mnemonic: "Ctrl-a",
|
|
Description: "Aliases",
|
|
},
|
|
}
|
|
}
|
|
|
|
func (v *Help) showNav() model.MenuHints {
|
|
return model.MenuHints{
|
|
{
|
|
Mnemonic: "g",
|
|
Description: "Goto Top",
|
|
},
|
|
{
|
|
Mnemonic: "Shift-g",
|
|
Description: "Goto Bottom",
|
|
},
|
|
{
|
|
Mnemonic: "Ctrl-b",
|
|
Description: "Page Down"},
|
|
{
|
|
Mnemonic: "Ctrl-f",
|
|
Description: "Page Up",
|
|
},
|
|
{
|
|
Mnemonic: "h",
|
|
Description: "Left",
|
|
},
|
|
{
|
|
Mnemonic: "l",
|
|
Description: "Right",
|
|
},
|
|
{
|
|
Mnemonic: "k",
|
|
Description: "Up",
|
|
},
|
|
{
|
|
Mnemonic: "j",
|
|
Description: "Down",
|
|
},
|
|
}
|
|
}
|
|
|
|
func (v *Help) showGeneral() model.MenuHints {
|
|
return model.MenuHints{
|
|
{
|
|
Mnemonic: ":cmd",
|
|
Description: "Command mode",
|
|
},
|
|
{
|
|
Mnemonic: "/term",
|
|
Description: "Filter mode",
|
|
},
|
|
{
|
|
Mnemonic: "esc",
|
|
Description: "Clear filter",
|
|
},
|
|
{
|
|
Mnemonic: "tab",
|
|
Description: "Next Field",
|
|
},
|
|
{
|
|
Mnemonic: "backtab",
|
|
Description: "Previous Field",
|
|
},
|
|
{
|
|
Mnemonic: "Ctrl-r",
|
|
Description: "Refresh",
|
|
},
|
|
{
|
|
Mnemonic: "h",
|
|
Description: "Toggle Header",
|
|
},
|
|
{
|
|
Mnemonic: "Shift-i",
|
|
Description: "Invert Sort",
|
|
},
|
|
{
|
|
Mnemonic: "p",
|
|
Description: "Previous View",
|
|
},
|
|
{
|
|
Mnemonic: ":q",
|
|
Description: "Quit",
|
|
},
|
|
}
|
|
}
|
|
|
|
func (v *Help) getTitle() string {
|
|
return helpTitle
|
|
}
|
|
|
|
func (v *Help) resetTitle() {
|
|
v.SetTitle(fmt.Sprintf(helpTitleFmt, helpTitle))
|
|
}
|
|
|
|
func (v *Help) build(hh model.MenuHints) {
|
|
v.Clear()
|
|
sort.Sort(hh)
|
|
v.addSection(0, 0, "RESOURCE", hh)
|
|
v.addSection(0, 4, "GENERAL", v.showGeneral())
|
|
v.addSection(0, 6, "NAVIGATION", v.showNav())
|
|
v.addSection(0, 8, "HELP", v.showHelp())
|
|
}
|
|
|
|
func (v *Help) addSection(r, c int, title string, hh model.MenuHints) {
|
|
row := r
|
|
cell := tview.NewTableCell(title)
|
|
cell.SetTextColor(tcell.ColorGreen)
|
|
cell.SetAttributes(tcell.AttrBold)
|
|
cell.SetExpansion(2)
|
|
cell.SetAlign(tview.AlignLeft)
|
|
v.SetCell(r, c+1, cell)
|
|
row++
|
|
|
|
for _, h := range hh {
|
|
col := c
|
|
cell := tview.NewTableCell(toMnemonic(h.Mnemonic))
|
|
if _, err := strconv.Atoi(h.Mnemonic); err != nil {
|
|
cell.SetTextColor(tcell.ColorDodgerBlue)
|
|
} else {
|
|
cell.SetTextColor(tcell.ColorFuchsia)
|
|
}
|
|
cell.SetAttributes(tcell.AttrBold)
|
|
cell.SetAlign(tview.AlignRight)
|
|
v.SetCell(row, col, cell)
|
|
col++
|
|
cell = tview.NewTableCell(h.Description)
|
|
cell.SetTextColor(tcell.ColorWhite)
|
|
v.SetCell(row, col, cell)
|
|
row++
|
|
}
|
|
}
|
|
|
|
func toMnemonic(s string) string {
|
|
if len(s) == 0 {
|
|
return s
|
|
}
|
|
|
|
return "<" + keyConv(strings.ToLower(s)) + ">"
|
|
}
|
|
|
|
func keyConv(s string) string {
|
|
if !strings.Contains(s, "alt") {
|
|
return s
|
|
}
|
|
|
|
if runtime.GOOS != "darwin" {
|
|
return s
|
|
}
|
|
|
|
return strings.Replace(s, "alt", "opt", 1)
|
|
}
|