summaryrefslogtreecommitdiffstats
path: root/pkg/theme/theme.go
blob: d0589754075b0ebb4aee1d9552babf7e854fb9a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package theme

import (
	"github.com/gookit/color"
	"github.com/jesseduffield/gocui"
	"github.com/jesseduffield/lazygit/pkg/config"
	"github.com/jesseduffield/lazygit/pkg/gui/style"
	"github.com/jesseduffield/lazygit/pkg/utils"
)

var (
	// GocuiDefaultTextColor does the same as DefaultTextColor but this one only colors gocui default text colors
	GocuiDefaultTextColor gocui.Attribute

	// ActiveBorderColor is the border color of the active frame
	ActiveBorderColor gocui.Attribute

	// InactiveBorderColor is the border color of the inactive active frames
	InactiveBorderColor gocui.Attribute

	// GocuiSelectedLineBgColor is the background color for the selected line in gocui
	GocuiSelectedLineBgColor gocui.Attribute

	OptionsColor gocui.Attribute

	// DefaultTextColor is the default text color
	DefaultTextColor = style.FgWhite

	// DefaultHiTextColor is the default highlighted text color
	DefaultHiTextColor = style.FgLightWhite

	// SelectedLineBgColor is the background color for the selected line
	SelectedLineBgColor = style.New()

	// SelectedRangeBgColor is the background color of the selected range of lines
	SelectedRangeBgColor = style.New()

	OptionsFgColor = style.New()

	DiffTerminalColor = style.FgMagenta
)

// UpdateTheme updates all theme variables
func UpdateTheme(themeConfig config.ThemeConfig) {
	ActiveBorderColor = GetGocuiStyle(themeConfig.ActiveBorderColor)
	InactiveBorderColor = GetGocuiStyle(themeConfig.InactiveBorderColor)
	SelectedLineBgColor = GetTextStyle(themeConfig.SelectedLineBgColor, true)
	SelectedRangeBgColor = GetTextStyle(themeConfig.SelectedRangeBgColor, true)
	GocuiSelectedLineBgColor = GetGocuiStyle(themeConfig.SelectedLineBgColor)
	OptionsColor = GetGocuiStyle(themeConfig.OptionsTextColor)
	OptionsFgColor = GetTextStyle(themeConfig.OptionsTextColor, false)

	isLightTheme := themeConfig.LightTheme
	if isLightTheme {
		DefaultTextColor = style.FgBlack
		DefaultHiTextColor = style.FgBlackLighter
		GocuiDefaultTextColor = gocui.ColorBlack
	} else {
		DefaultTextColor = style.FgWhite
		DefaultHiTextColor = style.FgLightWhite
		GocuiDefaultTextColor = gocui.ColorWhite
	}
}

// GetAttribute gets the gocui color attribute from the string
func GetGocuiAttribute(key string) gocui.Attribute {
	if utils.IsValidHexValue(key) {
		values := color.HEX(key).Values()
		return gocui.NewRGBColor(int32(values[0]), int32(values[1]), int32(values[2]))
	}

	colorMap := map[string]gocui.Attribute{
		"default":   gocui.ColorDefault,
		"black":     gocui.ColorBlack,
		"red":       gocui.ColorRed,
		"green":     gocui.ColorGreen,
		"yellow":    gocui.ColorYellow,
		"blue":      gocui.ColorBlue,
		"magenta":   gocui.ColorMagenta,
		"cyan":      gocui.ColorCyan,
		"white":     gocui.ColorWhite,
		"bold":      gocui.AttrBold,
		"reverse":   gocui.AttrReverse,
		"underline": gocui.AttrUnderline,
	}
	value, present := colorMap[key]
	if present {
		return value
	}
	return gocui.ColorWhite
}

// GetGocuiStyle bitwise OR's a list of attributes obtained via the given keys
func GetGocuiStyle(keys []string) gocui.Attribute {
	var attribute gocui.Attribute
	for _, key := range keys {
		attribute |= GetGocuiAttribute(key)
	}
	return attribute
}

var colorMap = map[string]struct {
	foreground style.TextStyle
	background style.TextStyle
}{
	"default": {style.FgWhite, style.BgBlack},
	"black":   {style.FgBlack, style.BgBlack},
	"red":     {style.FgRed, style.BgRed},
	"green":   {style.FgGreen, style.BgGreen},
	"yellow":  {style.FgYellow, style.BgYellow},
	"blue":    {style.FgBlue, style.BgBlue},
	"magenta": {style.FgMagenta, style.BgMagenta},
	"cyan":    {style.FgCyan, style.BgCyan},
	"white":   {style.FgWhite, style.BgWhite},
}

func GetTextStyle(keys []string, background bool) style.TextStyle {
	s := style.New()

	for _, key := range keys {
		switch key {
		case "bold":
			s = s.SetBold()
		case "reverse":
			s = s.SetReverse()
		case "underline":
			s = s.SetUnderline()
		default:
			value, present := colorMap[key]
			if present {
				var c style.TextStyle
				if background {
					c = value.background
				} else {
					c = value.foreground
				}
				s = s.MergeStyle(c)
			} else if utils.IsValidHexValue(key) {
				c := style.NewRGBColor(color.HEX(key, background))
				if background {
					s.SetBg(c)
				} else {
					s.SetFg(c)
				}
			}
		}
	}

	return s
}