1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-02-09 13:47:11 +02:00
2021-04-06 19:34:32 +10:00

166 lines
5.2 KiB
Go

// Copyright 2020 The gocui Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gocui
import "github.com/gdamore/tcell/v2"
// Attribute affects the presentation of characters, such as color, boldness, etc.
type Attribute uint64
const (
// ColorDefault is used to leave the Color unchanged from whatever system or teminal default may exist.
ColorDefault = Attribute(tcell.ColorDefault)
// AttrIsValidColor is used to indicate the color value is actually
// valid (initialized). This is useful to permit the zero value
// to be treated as the default.
AttrIsValidColor = Attribute(tcell.ColorValid)
// AttrIsRGBColor is used to indicate that the Attribute value is RGB value of color.
// The lower order 3 bytes are RGB.
// (It's not a color in basic ANSI range 256).
AttrIsRGBColor = Attribute(tcell.ColorIsRGB)
// AttrColorBits is a mask where color is located in Attribute
AttrColorBits = 0xffffffffff // roughly 5 bytes, tcell uses 4 bytes and half-byte as a special flags for color (rest is reserved for future)
// AttrStyleBits is a mask where character attributes (e.g.: bold, italic, underline) are located in Attribute
AttrStyleBits = 0xffffff0000000000 // remaining 3 bytes in the 8 bytes Attribute (tcell is not using it, so we should be fine)
)
// Color attributes. These colors are compatible with tcell.Color type and can be expanded like:
// g.FgColor := gocui.Attribute(tcell.ColorLime)
const (
ColorBlack Attribute = AttrIsValidColor + iota
ColorRed
ColorGreen
ColorYellow
ColorBlue
ColorMagenta
ColorCyan
ColorWhite
)
// grayscale indexes (for backward compatibility with termbox-go original grayscale)
var grayscale = []tcell.Color{
16, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,
245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 231,
}
// Attributes are not colors, but effects (e.g.: bold, dim) which affect the display of text.
// They can be combined.
const (
AttrBold Attribute = 1 << (40 + iota)
AttrBlink
AttrReverse
AttrUnderline
AttrDim
AttrItalic
AttrStrikeThrough
AttrNone Attribute = 0 // Just normal text.
)
// AttrAll represents all the text effect attributes turned on
const AttrAll = AttrBold | AttrBlink | AttrReverse | AttrUnderline | AttrDim | AttrItalic
// IsValidColor indicates if the Attribute is a valid color value (has been set).
func (a Attribute) IsValidColor() bool {
return a&AttrIsValidColor != 0
}
// Hex returns the color's hexadecimal RGB 24-bit value with each component
// consisting of a single byte, ala R << 16 | G << 8 | B. If the color
// is unknown or unset, -1 is returned.
//
// This function produce the same output as `tcell.Hex()` with additional
// support for `termbox-go` colors (to 256).
func (a Attribute) Hex() int32 {
if !a.IsValidColor() {
return -1
}
tc := getTcellColor(a, OutputTrue)
return tc.Hex()
}
// RGB returns the red, green, and blue components of the color, with
// each component represented as a value 0-255. If the color
// is unknown or unset, -1 is returned for each component.
//
// This function produce the same output as `tcell.RGB()` with additional
// support for `termbox-go` colors (to 256).
func (a Attribute) RGB() (int32, int32, int32) {
v := a.Hex()
if v < 0 {
return -1, -1, -1
}
return (v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff
}
// GetColor creates a Color from a color name (W3C name). A hex value may
// be supplied as a string in the format "#ffffff".
func GetColor(color string) Attribute {
return Attribute(tcell.GetColor(color))
}
// Get256Color creates Attribute which stores ANSI color (0-255)
func Get256Color(color int32) Attribute {
return Attribute(color) | AttrIsValidColor
}
// GetRGBColor creates Attribute which stores RGB color.
// Color is passed as 24bit RGB value, where R << 16 | G << 8 | B
func GetRGBColor(color int32) Attribute {
return Attribute(color) | AttrIsValidColor | AttrIsRGBColor
}
// NewRGBColor creates Attribute which stores RGB color.
func NewRGBColor(r, g, b int32) Attribute {
return Attribute(tcell.NewRGBColor(r, g, b))
}
// getTcellColor transform Attribute into tcell.Color
func getTcellColor(c Attribute, omode OutputMode) tcell.Color {
c = c & AttrColorBits
// Default color is 0 in tcell/v2 and was 0 in termbox-go, so we are good here
if c == ColorDefault {
return tcell.ColorDefault
}
tc := tcell.ColorDefault
// Check if we have valid color
if c.IsValidColor() {
tc = tcell.Color(c)
} else if c > 0 && c <= 256 {
// It's not valid color, but it has value in range 1-256
// This is old Attribute style of color from termbox-go (black=1, etc.)
// convert to tcell color (black=0|ColorValid)
tc = tcell.Color(c-1) | tcell.ColorValid
}
switch omode {
case OutputTrue:
return tc
case OutputNormal:
tc &= tcell.Color(0xf) | tcell.ColorValid
case Output256:
tc &= tcell.Color(0xff) | tcell.ColorValid
case Output216:
tc &= tcell.Color(0xff)
if tc > 215 {
return tcell.ColorDefault
}
tc += tcell.Color(16) | tcell.ColorValid
case OutputGrayscale:
tc &= tcell.Color(0x1f)
if tc > 26 {
return tcell.ColorDefault
}
tc = grayscale[tc] | tcell.ColorValid
default:
return tcell.ColorDefault
}
return tc
}