mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-02-13 13:59:06 +02:00
simplify code a bit
This commit is contained in:
parent
79848087bc
commit
117c0bd4f7
@ -98,35 +98,35 @@ func (l *PatchLine) render(selected bool, included bool) string {
|
|||||||
return coloredString(style.FgCyan, match[1], selected, included) + coloredString(theme.DefaultTextColor, match[2], selected, false)
|
return coloredString(style.FgCyan, match[1], selected, included) + coloredString(theme.DefaultTextColor, match[2], selected, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
colorAttr := theme.DefaultTextColor
|
textStyle := theme.DefaultTextColor
|
||||||
switch l.Kind {
|
switch l.Kind {
|
||||||
case PATCH_HEADER:
|
case PATCH_HEADER:
|
||||||
colorAttr = colorAttr.SetBold(true)
|
textStyle = textStyle.SetBold()
|
||||||
case ADDITION:
|
case ADDITION:
|
||||||
colorAttr = colorAttr.SetColor(style.FgGreen)
|
textStyle = style.FgGreen
|
||||||
case DELETION:
|
case DELETION:
|
||||||
colorAttr = colorAttr.SetColor(style.FgRed)
|
textStyle = style.FgRed
|
||||||
case COMMIT_SHA:
|
case COMMIT_SHA:
|
||||||
colorAttr = colorAttr.SetColor(style.FgYellow)
|
textStyle = style.FgYellow
|
||||||
}
|
}
|
||||||
|
|
||||||
return coloredString(colorAttr, content, selected, included)
|
return coloredString(textStyle, content, selected, included)
|
||||||
}
|
}
|
||||||
|
|
||||||
func coloredString(colorAttr style.TextStyle, str string, selected bool, included bool) string {
|
func coloredString(textStyle style.TextStyle, str string, selected bool, included bool) string {
|
||||||
if selected {
|
if selected {
|
||||||
colorAttr = colorAttr.SetColor(theme.SelectedRangeBgColor)
|
textStyle = textStyle.MergeStyle(theme.SelectedRangeBgColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(str) < 2 {
|
if len(str) < 2 {
|
||||||
return colorAttr.Sprint(str)
|
return textStyle.Sprint(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
res := colorAttr.Sprint(str[:1])
|
res := textStyle.Sprint(str[:1])
|
||||||
if included {
|
if included {
|
||||||
return res + colorAttr.SetColor(style.BgGreen).Sprint(str[1:])
|
return res + textStyle.MergeStyle(style.BgGreen).Sprint(str[1:])
|
||||||
}
|
}
|
||||||
return res + colorAttr.Sprint(str[1:])
|
return res + textStyle.Sprint(str[1:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func parsePatch(patch string) ([]int, []int, []*PatchLine) {
|
func parsePatch(patch string) ([]int, []int, []*PatchLine) {
|
||||||
|
@ -28,13 +28,13 @@ func (gui *Gui) GetOnRunCommand() func(entry oscommands.CmdLogEntry) {
|
|||||||
currentSpan = entry.GetSpan()
|
currentSpan = entry.GetSpan()
|
||||||
}
|
}
|
||||||
|
|
||||||
clrAttr := theme.DefaultTextColor
|
textStyle := theme.DefaultTextColor
|
||||||
if !entry.GetCommandLine() {
|
if !entry.GetCommandLine() {
|
||||||
clrAttr = clrAttr.SetColor(style.FgMagenta)
|
textStyle = style.FgMagenta
|
||||||
}
|
}
|
||||||
gui.CmdLog = append(gui.CmdLog, entry.GetCmdStr())
|
gui.CmdLog = append(gui.CmdLog, entry.GetCmdStr())
|
||||||
indentedCmdStr := " " + strings.Replace(entry.GetCmdStr(), "\n", "\n ", -1)
|
indentedCmdStr := " " + strings.Replace(entry.GetCmdStr(), "\n", "\n ", -1)
|
||||||
fmt.Fprint(gui.Views.Extras, "\n"+clrAttr.Sprint(indentedCmdStr))
|
fmt.Fprint(gui.Views.Extras, "\n"+textStyle.Sprint(indentedCmdStr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,8 @@ func (gui *Gui) informationStr() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if gui.g.Mouse {
|
if gui.g.Mouse {
|
||||||
donate := style.FgMagenta.SetUnderline(true).Sprint(gui.Tr.Donate)
|
donate := style.FgMagenta.SetUnderline().Sprint(gui.Tr.Donate)
|
||||||
askQuestion := style.FgYellow.SetUnderline(true).Sprint(gui.Tr.AskQuestion)
|
askQuestion := style.FgYellow.SetUnderline().Sprint(gui.Tr.AskQuestion)
|
||||||
return fmt.Sprintf("%s %s %s", donate, askQuestion, gui.Config.GetVersion())
|
return fmt.Sprintf("%s %s %s", donate, askQuestion, gui.Config.GetVersion())
|
||||||
} else {
|
} else {
|
||||||
return gui.Config.GetVersion()
|
return gui.Config.GetVersion()
|
||||||
|
@ -15,18 +15,18 @@ func ColoredConflictFile(content string, state *State, hasFocus bool) string {
|
|||||||
conflict, remainingConflicts := shiftConflict(state.conflicts)
|
conflict, remainingConflicts := shiftConflict(state.conflicts)
|
||||||
var outputBuffer bytes.Buffer
|
var outputBuffer bytes.Buffer
|
||||||
for i, line := range utils.SplitLines(content) {
|
for i, line := range utils.SplitLines(content) {
|
||||||
colour := theme.DefaultTextColor
|
textStyle := theme.DefaultTextColor
|
||||||
if i == conflict.start || i == conflict.middle || i == conflict.end {
|
if i == conflict.start || i == conflict.middle || i == conflict.end {
|
||||||
colour.SetColor(style.FgRed)
|
textStyle = style.FgRed
|
||||||
}
|
}
|
||||||
|
|
||||||
if hasFocus && state.conflictIndex < len(state.conflicts) && *state.conflicts[state.conflictIndex] == *conflict && shouldHighlightLine(i, conflict, state.conflictTop) {
|
if hasFocus && state.conflictIndex < len(state.conflicts) && *state.conflicts[state.conflictIndex] == *conflict && shouldHighlightLine(i, conflict, state.conflictTop) {
|
||||||
colour = theme.SelectedRangeBgColor.SetBold(true)
|
textStyle = theme.SelectedRangeBgColor.SetBold()
|
||||||
}
|
}
|
||||||
if i == conflict.end && len(remainingConflicts) > 0 {
|
if i == conflict.end && len(remainingConflicts) > 0 {
|
||||||
conflict, remainingConflicts = shiftConflict(remainingConflicts)
|
conflict, remainingConflicts = shiftConflict(remainingConflicts)
|
||||||
}
|
}
|
||||||
outputBuffer.WriteString(colour.Sprint(line) + "\n")
|
outputBuffer.WriteString(textStyle.Sprint(line) + "\n")
|
||||||
}
|
}
|
||||||
return outputBuffer.String()
|
return outputBuffer.String()
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ func (gui *Gui) modeStatuses() []modeStatus {
|
|||||||
{
|
{
|
||||||
isActive: gui.GitCommand.PatchManager.Active,
|
isActive: gui.GitCommand.PatchManager.Active,
|
||||||
description: func() string {
|
description: func() string {
|
||||||
return style.FgYellow.SetBold(true).Sprintf(
|
return style.FgYellow.SetBold().Sprintf(
|
||||||
"%s %s",
|
"%s %s",
|
||||||
gui.Tr.LcBuildingPatch,
|
gui.Tr.LcBuildingPatch,
|
||||||
style.AttrUnderline.Sprint(gui.Tr.ResetInParentheses),
|
style.AttrUnderline.Sprint(gui.Tr.ResetInParentheses),
|
||||||
@ -38,7 +38,7 @@ func (gui *Gui) modeStatuses() []modeStatus {
|
|||||||
{
|
{
|
||||||
isActive: gui.State.Modes.Filtering.Active,
|
isActive: gui.State.Modes.Filtering.Active,
|
||||||
description: func() string {
|
description: func() string {
|
||||||
return style.FgRed.SetBold(true).Sprintf(
|
return style.FgRed.SetBold().Sprintf(
|
||||||
"%s '%s' %s",
|
"%s '%s' %s",
|
||||||
gui.Tr.LcFilteringBy,
|
gui.Tr.LcFilteringBy,
|
||||||
gui.State.Modes.Filtering.GetPath(),
|
gui.State.Modes.Filtering.GetPath(),
|
||||||
|
@ -10,6 +10,8 @@ import (
|
|||||||
"github.com/kyokomi/emoji/v2"
|
"github.com/kyokomi/emoji/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var cherryPickedCommitTextStyle = style.FgCyan.MergeStyle(style.BgBlue)
|
||||||
|
|
||||||
func GetCommitListDisplayStrings(commits []*models.Commit, fullDescription bool, cherryPickedCommitShaMap map[string]bool, diffName string, parseEmoji bool) [][]string {
|
func GetCommitListDisplayStrings(commits []*models.Commit, fullDescription bool, cherryPickedCommitShaMap map[string]bool, diffName string, parseEmoji bool) [][]string {
|
||||||
lines := make([][]string, len(commits))
|
lines := make([][]string, len(commits))
|
||||||
|
|
||||||
@ -49,7 +51,7 @@ func getFullDescriptionDisplayStringsForCommit(c *models.Commit, cherryPickedCom
|
|||||||
// for some reason, setting the background to blue pads out the other commits
|
// for some reason, setting the background to blue pads out the other commits
|
||||||
// horizontally. For the sake of accessibility I'm considering this a feature,
|
// horizontally. For the sake of accessibility I'm considering this a feature,
|
||||||
// not a bug
|
// not a bug
|
||||||
shaColor = style.FgCyan.SetColor(style.BgBlue)
|
shaColor = cherryPickedCommitTextStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
tagString := ""
|
tagString := ""
|
||||||
@ -57,7 +59,7 @@ func getFullDescriptionDisplayStringsForCommit(c *models.Commit, cherryPickedCom
|
|||||||
if c.Action != "" {
|
if c.Action != "" {
|
||||||
secondColumnString = actionColorMap(c.Action).Sprint(c.Action)
|
secondColumnString = actionColorMap(c.Action).Sprint(c.Action)
|
||||||
} else if c.ExtraInfo != "" {
|
} else if c.ExtraInfo != "" {
|
||||||
tagString = theme.DiffTerminalColor.SetBold(true).Sprint(c.ExtraInfo) + " "
|
tagString = theme.DiffTerminalColor.SetBold().Sprint(c.ExtraInfo) + " "
|
||||||
}
|
}
|
||||||
|
|
||||||
truncatedAuthor := utils.TruncateWithEllipsis(c.Author, 17)
|
truncatedAuthor := utils.TruncateWithEllipsis(c.Author, 17)
|
||||||
@ -96,7 +98,7 @@ func getDisplayStringsForCommit(c *models.Commit, cherryPickedCommitShaMap map[s
|
|||||||
// for some reason, setting the background to blue pads out the other commits
|
// for some reason, setting the background to blue pads out the other commits
|
||||||
// horizontally. For the sake of accessibility I'm considering this a feature,
|
// horizontally. For the sake of accessibility I'm considering this a feature,
|
||||||
// not a bug
|
// not a bug
|
||||||
shaColor = style.FgCyan.SetColor(style.BgBlue)
|
shaColor = cherryPickedCommitTextStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
actionString := ""
|
actionString := ""
|
||||||
@ -104,7 +106,7 @@ func getDisplayStringsForCommit(c *models.Commit, cherryPickedCommitShaMap map[s
|
|||||||
if c.Action != "" {
|
if c.Action != "" {
|
||||||
actionString = actionColorMap(c.Action).Sprint(utils.WithPadding(c.Action, 7)) + " "
|
actionString = actionColorMap(c.Action).Sprint(utils.WithPadding(c.Action, 7)) + " "
|
||||||
} else if len(c.Tags) > 0 {
|
} else if len(c.Tags) > 0 {
|
||||||
tagString = theme.DiffTerminalColor.SetBold(true).Sprint(strings.Join(c.Tags, " ")) + " "
|
tagString = theme.DiffTerminalColor.SetBold().Sprint(strings.Join(c.Tags, " ")) + " "
|
||||||
}
|
}
|
||||||
|
|
||||||
name := c.Name
|
name := c.Name
|
||||||
|
@ -29,7 +29,7 @@ func GetReflogCommitListDisplayStrings(commits []*models.Commit, fullDescription
|
|||||||
func coloredReflogSha(c *models.Commit, cherryPickedCommitShaMap map[string]bool) string {
|
func coloredReflogSha(c *models.Commit, cherryPickedCommitShaMap map[string]bool) string {
|
||||||
shaColor := style.FgBlue
|
shaColor := style.FgBlue
|
||||||
if cherryPickedCommitShaMap[c.Sha] {
|
if cherryPickedCommitShaMap[c.Sha] {
|
||||||
shaColor = style.FgCyan.SetColor(style.BgBlue)
|
shaColor = cherryPickedCommitTextStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
return shaColor.Sprint(c.ShortSha())
|
return shaColor.Sprint(c.ShortSha())
|
||||||
|
@ -1,147 +1,98 @@
|
|||||||
package style
|
package style
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/gookit/color"
|
"github.com/gookit/color"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BasicTextStyle struct {
|
type TextStyle struct {
|
||||||
fg color.Color
|
fg *Color
|
||||||
bg color.Color
|
bg *Color
|
||||||
opts []color.Color
|
decoration Decoration
|
||||||
|
|
||||||
style color.Style
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BasicTextStyle) Sprint(a ...interface{}) string {
|
type Sprinter interface {
|
||||||
return b.style.Sprint(a...)
|
Sprint(a ...interface{}) string
|
||||||
|
Sprintf(format string, a ...interface{}) string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BasicTextStyle) Sprintf(format string, a ...interface{}) string {
|
func (b TextStyle) Sprint(a ...interface{}) string {
|
||||||
return b.style.Sprintf(format, a...)
|
return b.deriveStyle().Sprint(a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BasicTextStyle) deriveStyle() BasicTextStyle {
|
func (b TextStyle) Sprintf(format string, a ...interface{}) string {
|
||||||
// b.style[:0] makes sure to use the same slice memory
|
return b.deriveStyle().Sprintf(format, a...)
|
||||||
if b.fg == 0 {
|
}
|
||||||
// Fg is most of the time defined so we reverse the check
|
|
||||||
b.style = b.style[:0]
|
|
||||||
} else {
|
|
||||||
b.style = append(b.style[:0], b.fg)
|
|
||||||
}
|
|
||||||
|
|
||||||
if b.bg != 0 {
|
func (b TextStyle) SetBold() TextStyle {
|
||||||
b.style = append(b.style, b.bg)
|
b.decoration.SetBold()
|
||||||
}
|
|
||||||
|
|
||||||
b.style = append(b.style, b.opts...)
|
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BasicTextStyle) setOpt(opt color.Color, v bool, deriveIfChanged bool) BasicTextStyle {
|
func (b TextStyle) SetUnderline() TextStyle {
|
||||||
if v {
|
b.decoration.SetUnderline()
|
||||||
// Add value
|
|
||||||
for _, listOpt := range b.opts {
|
|
||||||
if listOpt == opt {
|
|
||||||
// Option already added
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
b.opts = append(b.opts, opt)
|
|
||||||
} else {
|
|
||||||
// Remove value
|
|
||||||
for idx, listOpt := range b.opts {
|
|
||||||
if listOpt == opt {
|
|
||||||
b.opts = append(b.opts[:idx], b.opts[idx+1:]...)
|
|
||||||
|
|
||||||
if deriveIfChanged {
|
|
||||||
return b.deriveStyle()
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if deriveIfChanged {
|
|
||||||
return b.deriveStyle()
|
|
||||||
}
|
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BasicTextStyle) SetBold(v bool) TextStyle {
|
func (b TextStyle) SetReverse() TextStyle {
|
||||||
return b.setOpt(color.OpBold, v, true)
|
b.decoration.SetReverse()
|
||||||
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BasicTextStyle) SetReverse(v bool) TextStyle {
|
func (b TextStyle) deriveStyle() Sprinter {
|
||||||
return b.setOpt(color.OpReverse, v, true)
|
// TODO: consider caching
|
||||||
|
return deriveStyle(b.fg, b.bg, b.decoration)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BasicTextStyle) SetUnderline(v bool) TextStyle {
|
func deriveStyle(fg *Color, bg *Color, decoration Decoration) Sprinter {
|
||||||
return b.setOpt(color.OpUnderscore, v, true)
|
if fg == nil && bg == nil {
|
||||||
}
|
return color.Style(decoration.ToOpts())
|
||||||
|
|
||||||
func (b BasicTextStyle) SetRGBColor(red, green, blue uint8, background bool) TextStyle {
|
|
||||||
return b.convertToRGB().SetRGBColor(red, green, blue, background)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b BasicTextStyle) convertToRGB() RGBTextStyle {
|
|
||||||
res := RGBTextStyle{
|
|
||||||
fg: b.fg.RGB(),
|
|
||||||
fgSet: b.fg != 0,
|
|
||||||
opts: b.opts,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.bg != 0 {
|
isRgb := (fg != nil && fg.IsRGB()) || (bg != nil && bg.IsRGB())
|
||||||
// Need to convert bg to fg otherwise .RGB wont work
|
if isRgb {
|
||||||
// for more info see https://github.com/gookit/color/issues/39
|
s := &color.RGBStyle{}
|
||||||
rgbBg := (b.bg - 10).RGB()
|
if fg != nil {
|
||||||
rgbBg[3] = 1
|
s.SetFg(*fg.ToRGB().rgb)
|
||||||
res.bg = &rgbBg
|
}
|
||||||
res.style = *color.NewRGBStyle(res.fg, rgbBg)
|
if bg != nil {
|
||||||
} else {
|
s.SetBg(*bg.ToRGB().rgb)
|
||||||
res.style = *color.NewRGBStyle(res.fg)
|
}
|
||||||
|
s.SetOpts(decoration.ToOpts())
|
||||||
|
return s
|
||||||
}
|
}
|
||||||
res.style.SetOpts(b.opts)
|
|
||||||
|
|
||||||
return res
|
style := make([]color.Color, 0, 5)
|
||||||
|
|
||||||
|
if fg != nil {
|
||||||
|
style = append(style, *fg.basic)
|
||||||
|
}
|
||||||
|
|
||||||
|
if bg != nil {
|
||||||
|
style = append(style, *bg.basic)
|
||||||
|
}
|
||||||
|
|
||||||
|
style = append(style, decoration.ToOpts()...)
|
||||||
|
|
||||||
|
return color.Style(style)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b BasicTextStyle) SetColor(other TextStyle) TextStyle {
|
// // Need to convert bg to fg otherwise .RGB wont work
|
||||||
switch typedOther := other.(type) {
|
// // for more info see https://github.com/gookit/color/issues/39
|
||||||
case BasicTextStyle:
|
// rgbBg := (*b.bg - 10).RGB()
|
||||||
if typedOther.fg != 0 {
|
// rgbBg[3] = 1
|
||||||
b.fg = typedOther.fg
|
// *res.bg = rgbBg
|
||||||
}
|
// res.style = *color.NewRGBStyle(*res.fg, rgbBg)
|
||||||
if typedOther.bg != 0 {
|
|
||||||
b.bg = typedOther.bg
|
|
||||||
}
|
|
||||||
for _, opt := range typedOther.opts {
|
|
||||||
b = b.setOpt(opt, true, false)
|
|
||||||
}
|
|
||||||
return b.deriveStyle()
|
|
||||||
case RGBTextStyle:
|
|
||||||
bAsRGB := b.convertToRGB()
|
|
||||||
|
|
||||||
for _, opt := range typedOther.opts {
|
func (b TextStyle) MergeStyle(other TextStyle) TextStyle {
|
||||||
bAsRGB.setOpt(opt, true)
|
b.decoration = b.decoration.Merge(other.decoration)
|
||||||
}
|
|
||||||
|
|
||||||
if typedOther.fgSet {
|
if other.fg != nil {
|
||||||
bAsRGB.fg = typedOther.fg
|
b.fg = other.fg
|
||||||
bAsRGB.style.SetFg(typedOther.fg)
|
|
||||||
}
|
|
||||||
|
|
||||||
if typedOther.bg != nil {
|
|
||||||
// Making sure to copy the value
|
|
||||||
bAsRGB.bg = &color.RGBColor{}
|
|
||||||
*bAsRGB.bg = *typedOther.bg
|
|
||||||
bAsRGB.style.SetBg(*typedOther.bg)
|
|
||||||
}
|
|
||||||
|
|
||||||
return bAsRGB
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("got %T but expected BasicTextStyle or RGBTextStyle", typedOther))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if other.bg != nil {
|
||||||
|
b.bg = other.bg
|
||||||
|
}
|
||||||
|
|
||||||
|
return b
|
||||||
}
|
}
|
||||||
|
35
pkg/gui/style/color.go
Normal file
35
pkg/gui/style/color.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package style
|
||||||
|
|
||||||
|
import "github.com/gookit/color"
|
||||||
|
|
||||||
|
type Color struct {
|
||||||
|
rgb *color.RGBColor
|
||||||
|
basic *color.Color
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRGBColor(cl color.RGBColor) Color {
|
||||||
|
c := Color{}
|
||||||
|
c.rgb = &cl
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBasicColor(cl color.Color) Color {
|
||||||
|
c := Color{}
|
||||||
|
c.basic = &cl
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Color) IsRGB() bool {
|
||||||
|
return c.rgb != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Color) ToRGB() Color {
|
||||||
|
if c.IsRGB() {
|
||||||
|
return *c
|
||||||
|
}
|
||||||
|
|
||||||
|
rgb := c.basic.RGB()
|
||||||
|
c.rgb = &rgb
|
||||||
|
|
||||||
|
return NewRGBColor(rgb)
|
||||||
|
}
|
53
pkg/gui/style/decoration.go
Normal file
53
pkg/gui/style/decoration.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package style
|
||||||
|
|
||||||
|
import "github.com/gookit/color"
|
||||||
|
|
||||||
|
type Decoration struct {
|
||||||
|
bold bool
|
||||||
|
underline bool
|
||||||
|
reverse bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Decoration) SetBold() {
|
||||||
|
d.bold = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Decoration) SetUnderline() {
|
||||||
|
d.underline = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Decoration) SetReverse() {
|
||||||
|
d.reverse = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Decoration) ToOpts() color.Opts {
|
||||||
|
opts := make([]color.Color, 0, 3)
|
||||||
|
|
||||||
|
if d.bold {
|
||||||
|
opts = append(opts, color.OpBold)
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.underline {
|
||||||
|
opts = append(opts, color.OpUnderscore)
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.reverse {
|
||||||
|
opts = append(opts, color.OpReverse)
|
||||||
|
}
|
||||||
|
|
||||||
|
return opts
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Decoration) Merge(other Decoration) Decoration {
|
||||||
|
if other.bold {
|
||||||
|
d.bold = true
|
||||||
|
}
|
||||||
|
if other.underline {
|
||||||
|
d.underline = true
|
||||||
|
}
|
||||||
|
if other.reverse {
|
||||||
|
d.reverse = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return d
|
||||||
|
}
|
@ -1,111 +0,0 @@
|
|||||||
package style
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/gookit/color"
|
|
||||||
)
|
|
||||||
|
|
||||||
type RGBTextStyle struct {
|
|
||||||
opts color.Opts
|
|
||||||
fgSet bool
|
|
||||||
fg color.RGBColor
|
|
||||||
bg *color.RGBColor
|
|
||||||
style color.RGBStyle
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b RGBTextStyle) Sprint(a ...interface{}) string {
|
|
||||||
return b.style.Sprint(a...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b RGBTextStyle) Sprintf(format string, a ...interface{}) string {
|
|
||||||
return b.style.Sprintf(format, a...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b RGBTextStyle) setOpt(opt color.Color, v bool) RGBTextStyle {
|
|
||||||
if v {
|
|
||||||
// Add value
|
|
||||||
for _, listOpt := range b.opts {
|
|
||||||
if listOpt == opt {
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
}
|
|
||||||
b.opts = append(b.opts, opt)
|
|
||||||
} else {
|
|
||||||
// Remove value
|
|
||||||
for idx, listOpt := range b.opts {
|
|
||||||
if listOpt == opt {
|
|
||||||
b.opts = append(b.opts[:idx], b.opts[idx+1:]...)
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b RGBTextStyle) SetBold(v bool) TextStyle {
|
|
||||||
b = b.setOpt(color.OpBold, v)
|
|
||||||
b.style.SetOpts(b.opts)
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b RGBTextStyle) SetReverse(v bool) TextStyle {
|
|
||||||
b = b.setOpt(color.OpReverse, v)
|
|
||||||
b.style.SetOpts(b.opts)
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b RGBTextStyle) SetUnderline(v bool) TextStyle {
|
|
||||||
b = b.setOpt(color.OpUnderscore, v)
|
|
||||||
b.style.SetOpts(b.opts)
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b RGBTextStyle) SetColor(style TextStyle) TextStyle {
|
|
||||||
var rgbStyle RGBTextStyle
|
|
||||||
|
|
||||||
switch typedStyle := style.(type) {
|
|
||||||
case BasicTextStyle:
|
|
||||||
rgbStyle = typedStyle.convertToRGB()
|
|
||||||
case RGBTextStyle:
|
|
||||||
rgbStyle = typedStyle
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("got %T but expected BasicTextStyle or RGBTextStyle", typedStyle))
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, opt := range rgbStyle.GetOpts() {
|
|
||||||
b = b.setOpt(opt, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
if rgbStyle.fgSet {
|
|
||||||
b.fg = rgbStyle.fg
|
|
||||||
b.style.SetFg(rgbStyle.fg)
|
|
||||||
b.fgSet = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if rgbStyle.bg != nil {
|
|
||||||
// Making sure to copy value
|
|
||||||
b.bg = &color.RGBColor{}
|
|
||||||
*b.bg = *rgbStyle.bg
|
|
||||||
b.style.SetBg(*rgbStyle.bg)
|
|
||||||
}
|
|
||||||
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b RGBTextStyle) SetRGBColor(red, green, blue uint8, background bool) TextStyle {
|
|
||||||
parsedColor := color.Rgb(red, green, blue, background)
|
|
||||||
if background {
|
|
||||||
b.bg = &parsedColor
|
|
||||||
b.style.SetBg(parsedColor)
|
|
||||||
} else {
|
|
||||||
b.fg = parsedColor
|
|
||||||
b.style.SetFg(parsedColor)
|
|
||||||
b.fgSet = true
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b RGBTextStyle) GetOpts() color.Opts {
|
|
||||||
return b.opts
|
|
||||||
}
|
|
@ -5,91 +5,90 @@ import (
|
|||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TextStyle interface {
|
|
||||||
Sprint(a ...interface{}) string
|
|
||||||
Sprintf(format string, a ...interface{}) string
|
|
||||||
SetBold(v bool) TextStyle
|
|
||||||
SetReverse(v bool) TextStyle
|
|
||||||
SetUnderline(v bool) TextStyle
|
|
||||||
SetColor(style TextStyle) TextStyle
|
|
||||||
SetRGBColor(r, g, b uint8, background bool) TextStyle
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
FgWhite = New(color.FgWhite, 0)
|
// FgWhite = New(pointerTo(color.FgWhite), nil)
|
||||||
FgLightWhite = New(color.FgLightWhite, 0)
|
FgWhite = FromBasicFg(color.FgWhite)
|
||||||
FgBlack = New(color.FgBlack, 0)
|
FgLightWhite = FromBasicFg(color.FgLightWhite)
|
||||||
FgBlackLighter = New(color.FgBlack.Light(), 0)
|
FgBlack = FromBasicFg(color.FgBlack)
|
||||||
FgCyan = New(color.FgCyan, 0)
|
FgBlackLighter = FromBasicFg(color.FgBlack.Light())
|
||||||
FgRed = New(color.FgRed, 0)
|
FgCyan = FromBasicFg(color.FgCyan)
|
||||||
FgGreen = New(color.FgGreen, 0)
|
FgRed = FromBasicFg(color.FgRed)
|
||||||
FgBlue = New(color.FgBlue, 0)
|
FgGreen = FromBasicFg(color.FgGreen)
|
||||||
FgYellow = New(color.FgYellow, 0)
|
FgBlue = FromBasicFg(color.FgBlue)
|
||||||
FgMagenta = New(color.FgMagenta, 0)
|
FgYellow = FromBasicFg(color.FgYellow)
|
||||||
|
FgMagenta = FromBasicFg(color.FgMagenta)
|
||||||
|
|
||||||
BgWhite = New(0, color.BgWhite)
|
BgWhite = FromBasicBg(color.BgWhite)
|
||||||
BgBlack = New(0, color.BgBlack)
|
BgBlack = FromBasicBg(color.BgBlack)
|
||||||
BgRed = New(0, color.BgRed)
|
BgRed = FromBasicBg(color.BgRed)
|
||||||
BgGreen = New(0, color.BgGreen)
|
BgGreen = FromBasicBg(color.BgGreen)
|
||||||
BgYellow = New(0, color.BgYellow)
|
BgYellow = FromBasicBg(color.BgYellow)
|
||||||
BgBlue = New(0, color.BgBlue)
|
BgBlue = FromBasicBg(color.BgBlue)
|
||||||
BgMagenta = New(0, color.BgMagenta)
|
BgMagenta = FromBasicBg(color.BgMagenta)
|
||||||
BgCyan = New(0, color.BgCyan)
|
BgCyan = FromBasicBg(color.BgCyan)
|
||||||
|
|
||||||
AttrUnderline = New(0, 0).SetUnderline(true)
|
AttrUnderline = New().SetUnderline()
|
||||||
AttrBold = New(0, 0).SetUnderline(true)
|
AttrBold = New().SetBold()
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(fg color.Color, bg color.Color, opts ...color.Color) TextStyle {
|
func New() TextStyle {
|
||||||
return BasicTextStyle{
|
return TextStyle{}
|
||||||
fg: fg,
|
|
||||||
bg: bg,
|
|
||||||
opts: opts,
|
|
||||||
style: color.Style{},
|
|
||||||
}.deriveStyle()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetConfigStyles(s TextStyle, keys []string, background bool) TextStyle {
|
func FromBasicFg(fg color.Color) TextStyle {
|
||||||
|
s := New()
|
||||||
|
c := NewBasicColor(fg)
|
||||||
|
s.fg = &c
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func FromBasicBg(bg color.Color) TextStyle {
|
||||||
|
s := New()
|
||||||
|
c := NewBasicColor(bg)
|
||||||
|
s.bg = &c
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
var colorMap = map[string]struct {
|
||||||
|
forground TextStyle
|
||||||
|
background TextStyle
|
||||||
|
}{
|
||||||
|
"default": {FgWhite, BgBlack},
|
||||||
|
"black": {FgBlack, BgBlack},
|
||||||
|
"red": {FgRed, BgRed},
|
||||||
|
"green": {FgGreen, BgGreen},
|
||||||
|
"yellow": {FgYellow, BgYellow},
|
||||||
|
"blue": {FgBlue, BgBlue},
|
||||||
|
"magenta": {FgMagenta, BgMagenta},
|
||||||
|
"cyan": {FgCyan, BgCyan},
|
||||||
|
"white": {FgWhite, BgWhite},
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetConfigStyles(keys []string, background bool) TextStyle {
|
||||||
|
s := New()
|
||||||
|
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
colorMap := map[string]struct {
|
switch key {
|
||||||
forground TextStyle
|
case "bold":
|
||||||
background TextStyle
|
s = s.SetBold()
|
||||||
}{
|
case "reverse":
|
||||||
"default": {FgWhite, BgBlack},
|
s = s.SetReverse()
|
||||||
"black": {FgBlack, BgBlack},
|
case "underline":
|
||||||
"red": {FgRed, BgRed},
|
s = s.SetUnderline()
|
||||||
"green": {FgGreen, BgGreen},
|
default:
|
||||||
"yellow": {FgYellow, BgYellow},
|
value, present := colorMap[key]
|
||||||
"blue": {FgBlue, BgBlue},
|
if present {
|
||||||
"magenta": {FgMagenta, BgMagenta},
|
var c TextStyle
|
||||||
"cyan": {FgCyan, BgCyan},
|
if background {
|
||||||
"white": {FgWhite, BgWhite},
|
c = value.background
|
||||||
}
|
} else {
|
||||||
value, present := colorMap[key]
|
c = value.forground
|
||||||
if present {
|
}
|
||||||
if background {
|
s = s.MergeStyle(c)
|
||||||
s = s.SetColor(value.background)
|
} else if utils.IsValidHexValue(key) {
|
||||||
} else {
|
c := NewRGBColor(color.HEX(key, background))
|
||||||
s = s.SetColor(value.forground)
|
s.bg = &c
|
||||||
}
|
}
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if key == "bold" {
|
|
||||||
s = s.SetBold(true)
|
|
||||||
continue
|
|
||||||
} else if key == "reverse" {
|
|
||||||
s = s.SetReverse(true)
|
|
||||||
continue
|
|
||||||
} else if key == "underline" {
|
|
||||||
s = s.SetUnderline(true)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
r, g, b, validHexColor := utils.GetHexColorValues(key)
|
|
||||||
if validHexColor {
|
|
||||||
s = s.SetRGBColor(r, g, b, background)
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,39 +53,39 @@ func TestNewStyle(t *testing.T) {
|
|||||||
func TestBasicSetColor(t *testing.T) {
|
func TestBasicSetColor(t *testing.T) {
|
||||||
type scenario struct {
|
type scenario struct {
|
||||||
name string
|
name string
|
||||||
colorToSet BasicTextStyle
|
colorToSet TextStyle
|
||||||
expect BasicTextStyle
|
expect TextStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
scenarios := []scenario{
|
scenarios := []scenario{
|
||||||
{
|
{
|
||||||
"empty color",
|
"empty color",
|
||||||
BasicTextStyle{},
|
TextStyle{},
|
||||||
BasicTextStyle{fg: color.FgRed, bg: color.BgBlue, opts: []color.Color{color.OpBold}}},
|
TextStyle{fg: color.FgRed, bg: color.BgBlue, opts: []color.Color{color.OpBold}}},
|
||||||
{
|
{
|
||||||
"set new fg color",
|
"set new fg color",
|
||||||
BasicTextStyle{fg: color.FgCyan},
|
TextStyle{fg: color.FgCyan},
|
||||||
BasicTextStyle{fg: color.FgCyan, bg: color.BgBlue, opts: []color.Color{color.OpBold}},
|
TextStyle{fg: color.FgCyan, bg: color.BgBlue, opts: []color.Color{color.OpBold}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"set new bg color",
|
"set new bg color",
|
||||||
BasicTextStyle{bg: color.BgGray},
|
TextStyle{bg: color.BgGray},
|
||||||
BasicTextStyle{fg: color.FgRed, bg: color.BgGray, opts: []color.Color{color.OpBold}},
|
TextStyle{fg: color.FgRed, bg: color.BgGray, opts: []color.Color{color.OpBold}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"set new fg and bg color",
|
"set new fg and bg color",
|
||||||
BasicTextStyle{fg: color.FgCyan, bg: color.BgGray},
|
TextStyle{fg: color.FgCyan, bg: color.BgGray},
|
||||||
BasicTextStyle{fg: color.FgCyan, bg: color.BgGray, opts: []color.Color{color.OpBold}},
|
TextStyle{fg: color.FgCyan, bg: color.BgGray, opts: []color.Color{color.OpBold}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"add options",
|
"add options",
|
||||||
BasicTextStyle{opts: []color.Color{color.OpUnderscore}},
|
TextStyle{opts: []color.Color{color.OpUnderscore}},
|
||||||
BasicTextStyle{fg: color.FgRed, bg: color.BgBlue, opts: []color.Color{color.OpBold, color.OpUnderscore}},
|
TextStyle{fg: color.FgRed, bg: color.BgBlue, opts: []color.Color{color.OpBold, color.OpUnderscore}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"add options that already exists",
|
"add options that already exists",
|
||||||
BasicTextStyle{opts: []color.Color{color.OpBold}},
|
TextStyle{opts: []color.Color{color.OpBold}},
|
||||||
BasicTextStyle{fg: color.FgRed, bg: color.BgBlue, opts: []color.Color{color.OpBold}},
|
TextStyle{fg: color.FgRed, bg: color.BgBlue, opts: []color.Color{color.OpBold}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,12 +127,12 @@ func TestRGBSetColor(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"empty BasicTextStyle input",
|
"empty BasicTextStyle input",
|
||||||
BasicTextStyle{},
|
TextStyle{},
|
||||||
RGBTextStyle{fgSet: true, fg: red, bg: toBg(blue), opts: []color.Color{color.OpBold}},
|
RGBTextStyle{fgSet: true, fg: red, bg: toBg(blue), opts: []color.Color{color.OpBold}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"set fg and bg color using BasicTextStyle",
|
"set fg and bg color using BasicTextStyle",
|
||||||
BasicTextStyle{fg: color.FgCyan, bg: color.BgGray},
|
TextStyle{fg: color.FgCyan, bg: color.BgGray},
|
||||||
RGBTextStyle{fgSet: true, fg: cyan, bg: toBg(gray), opts: []color.Color{color.OpBold}},
|
RGBTextStyle{fgSet: true, fg: cyan, bg: toBg(gray), opts: []color.Color{color.OpBold}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -147,7 +147,7 @@ func TestRGBSetColor(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"add options using BasicTextStyle",
|
"add options using BasicTextStyle",
|
||||||
BasicTextStyle{opts: []color.Color{color.OpUnderscore}},
|
TextStyle{opts: []color.Color{color.OpUnderscore}},
|
||||||
RGBTextStyle{fgSet: true, fg: red, bg: toBg(blue), opts: []color.Color{color.OpBold, color.OpUnderscore}},
|
RGBTextStyle{fgSet: true, fg: red, bg: toBg(blue), opts: []color.Color{color.OpBold, color.OpUnderscore}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -159,10 +159,10 @@ func TestRGBSetColor(t *testing.T) {
|
|||||||
|
|
||||||
for _, s := range scenarios {
|
for _, s := range scenarios {
|
||||||
t.Run(s.name, func(t *testing.T) {
|
t.Run(s.name, func(t *testing.T) {
|
||||||
style, ok := New(color.FgRed, color.BgBlue).SetBold(true).(BasicTextStyle)
|
style, ok := New(color.FgRed, color.BgBlue).SetBold().(BasicTextStyle)
|
||||||
assert.True(t, ok, "SetBold should return a interface of type BasicTextStyle")
|
assert.True(t, ok, "SetBold should return a interface of type BasicTextStyle")
|
||||||
|
|
||||||
rgbStyle, ok := style.convertToRGB().SetColor(s.colorToSet).(RGBTextStyle)
|
rgbStyle, ok := style.convertToRGB().MergeStyle(s.colorToSet).(RGBTextStyle)
|
||||||
assert.True(t, ok, "SetColor should return a interface of type RGBTextColor")
|
assert.True(t, ok, "SetColor should return a interface of type RGBTextColor")
|
||||||
|
|
||||||
rgbStyle.style = color.RGBStyle{}
|
rgbStyle.style = color.RGBStyle{}
|
||||||
|
@ -24,31 +24,31 @@ var (
|
|||||||
OptionsColor gocui.Attribute
|
OptionsColor gocui.Attribute
|
||||||
|
|
||||||
// DefaultTextColor is the default text color
|
// DefaultTextColor is the default text color
|
||||||
DefaultTextColor = style.New(color.FgWhite, 0)
|
DefaultTextColor = style.FgWhite
|
||||||
|
|
||||||
// DefaultHiTextColor is the default highlighted text color
|
// DefaultHiTextColor is the default highlighted text color
|
||||||
DefaultHiTextColor = style.New(color.FgLightWhite, 0)
|
DefaultHiTextColor = style.FgLightWhite
|
||||||
|
|
||||||
// SelectedLineBgColor is the background color for the selected line
|
// SelectedLineBgColor is the background color for the selected line
|
||||||
SelectedLineBgColor = style.New(0, 0)
|
SelectedLineBgColor = style.New()
|
||||||
|
|
||||||
// SelectedRangeBgColor is the background color of the selected range of lines
|
// SelectedRangeBgColor is the background color of the selected range of lines
|
||||||
SelectedRangeBgColor = style.New(0, 0)
|
SelectedRangeBgColor = style.New()
|
||||||
|
|
||||||
OptionsFgColor = style.New(0, 0)
|
OptionsFgColor = style.New()
|
||||||
|
|
||||||
DiffTerminalColor = style.New(color.FgMagenta, 0)
|
DiffTerminalColor = style.FgMagenta
|
||||||
)
|
)
|
||||||
|
|
||||||
// UpdateTheme updates all theme variables
|
// UpdateTheme updates all theme variables
|
||||||
func UpdateTheme(themeConfig config.ThemeConfig) {
|
func UpdateTheme(themeConfig config.ThemeConfig) {
|
||||||
ActiveBorderColor = GetGocuiColor(themeConfig.ActiveBorderColor)
|
ActiveBorderColor = GetGocuiColor(themeConfig.ActiveBorderColor)
|
||||||
InactiveBorderColor = GetGocuiColor(themeConfig.InactiveBorderColor)
|
InactiveBorderColor = GetGocuiColor(themeConfig.InactiveBorderColor)
|
||||||
SelectedLineBgColor = style.SetConfigStyles(SelectedLineBgColor, themeConfig.SelectedLineBgColor, true)
|
SelectedLineBgColor = style.SetConfigStyles(themeConfig.SelectedLineBgColor, true)
|
||||||
SelectedRangeBgColor = style.SetConfigStyles(SelectedRangeBgColor, themeConfig.SelectedRangeBgColor, true)
|
SelectedRangeBgColor = style.SetConfigStyles(themeConfig.SelectedRangeBgColor, true)
|
||||||
GocuiSelectedLineBgColor = GetGocuiColor(themeConfig.SelectedLineBgColor)
|
GocuiSelectedLineBgColor = GetGocuiColor(themeConfig.SelectedLineBgColor)
|
||||||
OptionsColor = GetGocuiColor(themeConfig.OptionsTextColor)
|
OptionsColor = GetGocuiColor(themeConfig.OptionsTextColor)
|
||||||
OptionsFgColor = style.SetConfigStyles(OptionsFgColor, themeConfig.OptionsTextColor, false)
|
OptionsFgColor = style.SetConfigStyles(themeConfig.OptionsTextColor, false)
|
||||||
|
|
||||||
isLightTheme := themeConfig.LightTheme
|
isLightTheme := themeConfig.LightTheme
|
||||||
if isLightTheme {
|
if isLightTheme {
|
||||||
@ -64,9 +64,9 @@ func UpdateTheme(themeConfig config.ThemeConfig) {
|
|||||||
|
|
||||||
// GetAttribute gets the gocui color attribute from the string
|
// GetAttribute gets the gocui color attribute from the string
|
||||||
func GetGocuiAttribute(key string) gocui.Attribute {
|
func GetGocuiAttribute(key string) gocui.Attribute {
|
||||||
r, g, b, validHexColor := utils.GetHexColorValues(key)
|
if utils.IsValidHexValue(key) {
|
||||||
if validHexColor {
|
values := color.HEX(key).Values()
|
||||||
return gocui.NewRGBColor(int32(r), int32(g), int32(b))
|
return gocui.NewRGBColor(int32(values[0]), int32(values[1]), int32(values[2]))
|
||||||
}
|
}
|
||||||
|
|
||||||
colorMap := map[string]gocui.Attribute{
|
colorMap := map[string]gocui.Attribute{
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -33,22 +32,23 @@ func getPadWidths(stringArrays [][]string) []int {
|
|||||||
return padWidths
|
return padWidths
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHexColorValues returns the rgb values of a hex color
|
func IsValidHexValue(v string) bool {
|
||||||
func GetHexColorValues(v string) (r uint8, g uint8, b uint8, valid bool) {
|
if len(v) != 4 && len(v) != 7 {
|
||||||
if len(v) == 4 {
|
return false
|
||||||
v = string([]byte{v[0], v[1], v[1], v[2], v[2], v[3], v[3]})
|
|
||||||
} else if len(v) != 7 {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if v[0] != '#' {
|
if v[0] != '#' {
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
rgb, err := hex.DecodeString(v[1:])
|
for _, char := range v[1:] {
|
||||||
if err != nil {
|
switch char {
|
||||||
return
|
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F':
|
||||||
|
continue
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rgb[0], rgb[1], rgb[2], true
|
return true
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user