package theme import ( "sort" "strings" "github.com/gdamore/tcell/v2" ) // Theme maps style keys to the styles the editor draws with. // // Use Style to read a key: it falls back along the dots, so asking for // "syntax.keyword" in a theme that only defines "syntax" gets the latter, and // a theme that defines neither gets KeyDefault. type Theme struct { name string description string styles map[string]tcell.Style } // Name returns the theme's display name, which is what the Options menu lists. func (t *Theme) Name() string { return t.name } // Description returns the one-line description from the theme file, or the // empty string when it has none. func (t *Theme) Description() string { return t.description } // Style returns the style for a key, falling back along the dots and finally // onto KeyDefault. // // s := th.Style(theme.KeySyntaxKeyword) // // a theme defining only "syntax" answers that; one defining neither // // answers "default". func (t *Theme) Style(key string) tcell.Style { for { if style, ok := t.styles[key]; ok { return style } dot := strings.LastIndexByte(key, '.') if dot < 0 { break } key = key[:dot] } return t.styles[KeyDefault] } // Keys returns every key the theme defines, sorted. It exists for tooling and // for tests that check a theme file is complete. func (t *Theme) Keys() []string { keys := make([]string, 0, len(t.styles)) for key := range t.styles { keys = append(keys, key) } sort.Strings(keys) return keys } // Defines reports whether the theme sets this exact key, without any fallback. func (t *Theme) Defines(key string) bool { _, ok := t.styles[key] return ok } // fallbackStyle is what a theme resolves to before any file is read: white on // black, which stays legible on every terminal. func fallbackStyle() tcell.Style { return tcell.StyleDefault. Foreground(tcell.ColorWhite). Background(tcell.ColorBlack) }