468 lines
9.8 KiB
Go
468 lines
9.8 KiB
Go
package config
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"path/filepath"
|
|
|
|
"github.com/derailed/tview"
|
|
"github.com/gdamore/tcell"
|
|
"gopkg.in/yaml.v2"
|
|
)
|
|
|
|
// K9sStylesFile represents K9s skins file location.
|
|
var K9sStylesFile = filepath.Join(K9sHome, "skin.yml")
|
|
|
|
// StyleListener represents a skin's listener.
|
|
type StyleListener interface {
|
|
// StylesChanged notifies listener the skin changed.
|
|
StylesChanged(*Styles)
|
|
}
|
|
|
|
type (
|
|
// Color represents a color.
|
|
Color string
|
|
|
|
// Colors tracks multiple colors.
|
|
Colors []Color
|
|
|
|
// Styles tracks K9s styling options.
|
|
Styles struct {
|
|
K9s Style `yaml:"k9s"`
|
|
listeners []StyleListener
|
|
}
|
|
|
|
// Style tracks K9s styles.
|
|
Style struct {
|
|
Body Body `yaml:"body"`
|
|
Frame Frame `yaml:"frame"`
|
|
Info Info `yaml:"info"`
|
|
Views Views `yaml:"views"`
|
|
}
|
|
|
|
// Body tracks body styles.
|
|
Body struct {
|
|
FgColor Color `yaml:"fgColor"`
|
|
BgColor Color `yaml:"bgColor"`
|
|
LogoColor Color `yaml:"logoColor"`
|
|
}
|
|
|
|
// Frame tracks frame styles.
|
|
Frame struct {
|
|
Title Title `yaml:"title"`
|
|
Border Border `yaml:"border"`
|
|
Menu Menu `yaml:"menu"`
|
|
Crumb Crumb `yaml:"crumbs"`
|
|
Status Status `yaml:"status"`
|
|
}
|
|
|
|
// Views tracks individual view styles.
|
|
Views struct {
|
|
Table Table `yaml:"table"`
|
|
Xray Xray `yaml:"xray"`
|
|
Charts Charts `yaml:"charts"`
|
|
Yaml Yaml `yaml:"yaml"`
|
|
Log Log `yaml:"logs"`
|
|
}
|
|
|
|
// Status tracks resource status styles.
|
|
Status struct {
|
|
NewColor Color `yaml:"newColor"`
|
|
ModifyColor Color `yaml:"modifyColor"`
|
|
AddColor Color `yaml:"addColor"`
|
|
ErrorColor Color `yaml:"errorColor"`
|
|
HighlightColor Color `yaml:"highlightColor"`
|
|
KillColor Color `yaml:"killColor"`
|
|
CompletedColor Color `yaml:"completedColor"`
|
|
}
|
|
|
|
// Log tracks Log styles.
|
|
Log struct {
|
|
FgColor Color `yaml:"fgColor"`
|
|
BgColor Color `yaml:"bgColor"`
|
|
}
|
|
|
|
// Yaml tracks yaml styles.
|
|
Yaml struct {
|
|
KeyColor Color `yaml:"keyColor"`
|
|
ValueColor Color `yaml:"valueColor"`
|
|
ColonColor Color `yaml:"colonColor"`
|
|
}
|
|
|
|
// Title tracks title styles.
|
|
Title struct {
|
|
FgColor Color `yaml:"fgColor"`
|
|
BgColor Color `yaml:"bgColor"`
|
|
HighlightColor Color `yaml:"highlightColor"`
|
|
CounterColor Color `yaml:"counterColor"`
|
|
FilterColor Color `yaml:"filterColor"`
|
|
}
|
|
|
|
// Info tracks info styles.
|
|
Info struct {
|
|
SectionColor Color `yaml:"sectionColor"`
|
|
FgColor Color `yaml:"fgColor"`
|
|
}
|
|
|
|
// Border tracks border styles.
|
|
Border struct {
|
|
FgColor Color `yaml:"fgColor"`
|
|
FocusColor Color `yaml:"focusColor"`
|
|
}
|
|
|
|
// Crumb tracks crumbs styles.
|
|
Crumb struct {
|
|
FgColor Color `yaml:"fgColor"`
|
|
BgColor Color `yaml:"bgColor"`
|
|
ActiveColor Color `yaml:"activeColor"`
|
|
}
|
|
|
|
// Table tracks table styles.
|
|
Table struct {
|
|
FgColor Color `yaml:"fgColor"`
|
|
BgColor Color `yaml:"bgColor"`
|
|
CursorColor Color `yaml:"cursorColor"`
|
|
MarkColor Color `yaml:"markColor"`
|
|
Header TableHeader `yaml:"header"`
|
|
}
|
|
|
|
// TableHeader tracks table header styles.
|
|
TableHeader struct {
|
|
FgColor Color `yaml:"fgColor"`
|
|
BgColor Color `yaml:"bgColor"`
|
|
SorterColor Color `yaml:"sorterColor"`
|
|
}
|
|
|
|
// Xray tracks xray styles.
|
|
Xray struct {
|
|
FgColor Color `yaml:"fgColor"`
|
|
BgColor Color `yaml:"bgColor"`
|
|
CursorColor Color `yaml:"cursorColor"`
|
|
GraphicColor Color `yaml:"graphicColor"`
|
|
ShowIcons bool `yaml:"showIcons"`
|
|
}
|
|
|
|
// Menu tracks menu styles.
|
|
Menu struct {
|
|
FgColor Color `yaml:"fgColor"`
|
|
KeyColor Color `yaml:"keyColor"`
|
|
NumKeyColor Color `yaml:"numKeyColor"`
|
|
}
|
|
|
|
// Charts tracks charts styles.
|
|
Charts struct {
|
|
BgColor Color `yaml:"bgColor"`
|
|
DialBgColor Color `yaml:"dialBgColor"`
|
|
ChartBgColor Color `yaml:"chartBgColor"`
|
|
DefaultDialColors Colors `yaml:"defaultDialColors"`
|
|
DefaultChartColors Colors `yaml:"defaultChartColors"`
|
|
ResourceColors map[string]Colors `yaml:"resourceColors"`
|
|
}
|
|
)
|
|
|
|
const (
|
|
// DefaultColor represents a default color.
|
|
DefaultColor Color = "default"
|
|
|
|
// TransparentColor represents the terminal bg color.
|
|
TransparentColor Color = "-"
|
|
)
|
|
|
|
// NewColor returns a new color.
|
|
func NewColor(c string) Color {
|
|
return Color(c)
|
|
}
|
|
|
|
// String returns color as string.
|
|
func (c Color) String() string {
|
|
return string(c)
|
|
}
|
|
|
|
// Color returns a view color.
|
|
func (c Color) Color() tcell.Color {
|
|
if c == DefaultColor {
|
|
return tcell.ColorDefault
|
|
}
|
|
if color, ok := tcell.ColorNames[c.String()]; ok {
|
|
return color
|
|
}
|
|
return tcell.GetColor(c.String())
|
|
}
|
|
|
|
// Colors converts series string colors to colors.
|
|
func (c Colors) Colors() []tcell.Color {
|
|
cc := make([]tcell.Color, 0, len(c))
|
|
for _, color := range c {
|
|
cc = append(cc, color.Color())
|
|
}
|
|
return cc
|
|
}
|
|
|
|
func newStyle() Style {
|
|
return Style{
|
|
Body: newBody(),
|
|
Frame: newFrame(),
|
|
Info: newInfo(),
|
|
Views: newViews(),
|
|
}
|
|
}
|
|
|
|
func newCharts() Charts {
|
|
return Charts{
|
|
BgColor: "default",
|
|
DialBgColor: "default",
|
|
ChartBgColor: "default",
|
|
DefaultDialColors: Colors{Color("palegreen"), Color("orangered")},
|
|
DefaultChartColors: Colors{Color("palegreen"), Color("orangered")},
|
|
}
|
|
}
|
|
func newViews() Views {
|
|
return Views{
|
|
Table: newTable(),
|
|
Xray: newXray(),
|
|
Charts: newCharts(),
|
|
Yaml: newYaml(),
|
|
Log: newLog(),
|
|
}
|
|
}
|
|
|
|
func newFrame() Frame {
|
|
return Frame{
|
|
Title: newTitle(),
|
|
Border: newBorder(),
|
|
Menu: newMenu(),
|
|
Crumb: newCrumb(),
|
|
Status: newStatus(),
|
|
}
|
|
}
|
|
|
|
func newBody() Body {
|
|
return Body{
|
|
FgColor: "cadetblue",
|
|
BgColor: "black",
|
|
LogoColor: "orange",
|
|
}
|
|
}
|
|
|
|
func newStatus() Status {
|
|
return Status{
|
|
NewColor: "lightskyblue",
|
|
ModifyColor: "greenyellow",
|
|
AddColor: "dodgerblue",
|
|
ErrorColor: "orangered",
|
|
HighlightColor: "aqua",
|
|
KillColor: "mediumpurple",
|
|
CompletedColor: "lightslategray",
|
|
}
|
|
}
|
|
|
|
// NewLog returns a new log style.
|
|
func newLog() Log {
|
|
return Log{
|
|
FgColor: "lightskyblue",
|
|
BgColor: "black",
|
|
}
|
|
}
|
|
|
|
// NewYaml returns a new yaml style.
|
|
func newYaml() Yaml {
|
|
return Yaml{
|
|
KeyColor: "steelblue",
|
|
ColonColor: "white",
|
|
ValueColor: "papayawhip",
|
|
}
|
|
}
|
|
|
|
// NewTitle returns a new title style.
|
|
func newTitle() Title {
|
|
return Title{
|
|
FgColor: "aqua",
|
|
BgColor: "black",
|
|
HighlightColor: "fuchsia",
|
|
CounterColor: "papayawhip",
|
|
FilterColor: "seagreen",
|
|
}
|
|
}
|
|
|
|
// NewInfo returns a new info style.
|
|
func newInfo() Info {
|
|
return Info{
|
|
SectionColor: "white",
|
|
FgColor: "orange",
|
|
}
|
|
}
|
|
|
|
// NewXray returns a new xray style.
|
|
func newXray() Xray {
|
|
return Xray{
|
|
FgColor: "aqua",
|
|
BgColor: "black",
|
|
CursorColor: "whitesmoke",
|
|
GraphicColor: "floralwhite",
|
|
ShowIcons: true,
|
|
}
|
|
}
|
|
|
|
// NewTable returns a new table style.
|
|
func newTable() Table {
|
|
return Table{
|
|
FgColor: "aqua",
|
|
BgColor: "black",
|
|
CursorColor: "aqua",
|
|
MarkColor: "palegreen",
|
|
Header: newTableHeader(),
|
|
}
|
|
}
|
|
|
|
// NewTableHeader returns a new table header style.
|
|
func newTableHeader() TableHeader {
|
|
return TableHeader{
|
|
FgColor: "white",
|
|
BgColor: "black",
|
|
SorterColor: "aqua",
|
|
}
|
|
}
|
|
|
|
// NewCrumb returns a new crumbs style.
|
|
func newCrumb() Crumb {
|
|
return Crumb{
|
|
FgColor: "black",
|
|
BgColor: "aqua",
|
|
ActiveColor: "orange",
|
|
}
|
|
}
|
|
|
|
// NewBorder returns a new border style.
|
|
func newBorder() Border {
|
|
return Border{
|
|
FgColor: "dodgerblue",
|
|
FocusColor: "lightskyblue",
|
|
}
|
|
}
|
|
|
|
// NewMenu returns a new menu style.
|
|
func newMenu() Menu {
|
|
return Menu{
|
|
FgColor: "white",
|
|
KeyColor: "dodgerblue",
|
|
NumKeyColor: "fuchsia",
|
|
}
|
|
}
|
|
|
|
// NewStyles creates a new default config.
|
|
func NewStyles() *Styles {
|
|
return &Styles{
|
|
K9s: newStyle(),
|
|
}
|
|
}
|
|
|
|
// Reset resets styles.
|
|
func (s *Styles) Reset() {
|
|
s.K9s = newStyle()
|
|
}
|
|
|
|
// DefaultSkin loads the default skin
|
|
func (s *Styles) DefaultSkin() {
|
|
s.K9s = newStyle()
|
|
}
|
|
|
|
// FgColor returns the foreground color.
|
|
func (s *Styles) FgColor() tcell.Color {
|
|
return s.Body().FgColor.Color()
|
|
}
|
|
|
|
// BgColor returns the background color.
|
|
func (s *Styles) BgColor() tcell.Color {
|
|
return s.Body().BgColor.Color()
|
|
}
|
|
|
|
// AddListener registers a new listener.
|
|
func (s *Styles) AddListener(l StyleListener) {
|
|
s.listeners = append(s.listeners, l)
|
|
}
|
|
|
|
// RemoveListener unregister a listener.
|
|
func (s *Styles) RemoveListener(l StyleListener) {
|
|
victim := -1
|
|
for i, lis := range s.listeners {
|
|
if lis == l {
|
|
victim = i
|
|
break
|
|
}
|
|
}
|
|
if victim == -1 {
|
|
return
|
|
}
|
|
s.listeners = append(s.listeners[:victim], s.listeners[victim+1:]...)
|
|
}
|
|
|
|
func (s *Styles) fireStylesChanged() {
|
|
for _, list := range s.listeners {
|
|
list.StylesChanged(s)
|
|
}
|
|
}
|
|
|
|
// Body returns body styles.
|
|
func (s *Styles) Body() Body {
|
|
return s.K9s.Body
|
|
}
|
|
|
|
// Frame returns frame styles.
|
|
func (s *Styles) Frame() Frame {
|
|
return s.K9s.Frame
|
|
}
|
|
|
|
// Crumb returns crumb styles.
|
|
func (s *Styles) Crumb() Crumb {
|
|
return s.Frame().Crumb
|
|
}
|
|
|
|
// Title returns title styles.
|
|
func (s *Styles) Title() Title {
|
|
return s.Frame().Title
|
|
}
|
|
|
|
// Charts returns charts styles.
|
|
func (s *Styles) Charts() Charts {
|
|
return s.K9s.Views.Charts
|
|
}
|
|
|
|
// Table returns table styles.
|
|
func (s *Styles) Table() Table {
|
|
return s.K9s.Views.Table
|
|
}
|
|
|
|
// Xray returns xray styles.
|
|
func (s *Styles) Xray() Xray {
|
|
return s.K9s.Views.Xray
|
|
}
|
|
|
|
// Views returns views styles.
|
|
func (s *Styles) Views() Views {
|
|
return s.K9s.Views
|
|
}
|
|
|
|
// Load K9s configuration from file
|
|
func (s *Styles) Load(path string) error {
|
|
f, err := ioutil.ReadFile(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := yaml.Unmarshal(f, s); err != nil {
|
|
return err
|
|
}
|
|
s.fireStylesChanged()
|
|
|
|
return nil
|
|
}
|
|
|
|
// Update apply terminal colors based on styles.
|
|
func (s *Styles) Update() {
|
|
tview.Styles.PrimitiveBackgroundColor = s.BgColor()
|
|
tview.Styles.ContrastBackgroundColor = s.BgColor()
|
|
tview.Styles.PrimaryTextColor = s.FgColor()
|
|
tview.Styles.BorderColor = s.K9s.Frame.Border.FgColor.Color()
|
|
tview.Styles.FocusColor = s.K9s.Frame.Border.FocusColor.Color()
|
|
s.fireStylesChanged()
|
|
}
|