mirror of
https://github.com/charmbracelet/lipgloss.git
synced 2024-08-18 02:10:23 +03:00
refactor: replace props map with struct fields
Use an int to store property existence and style struct fields to store the actual values for each non-bool property. Fixes: https://github.com/charmbracelet/lipgloss/pull/139 Fixes: https://github.com/charmbracelet/lipgloss/pull/141
This commit is contained in:
parent
f16ea2bdcb
commit
387f2d73e8
104
get.go
104
get.go
@ -416,74 +416,114 @@ func (s Style) GetTransform() func(string) string {
|
||||
|
||||
// Returns whether or not the given property is set.
|
||||
func (s Style) isSet(k propKey) bool {
|
||||
_, exists := s.rules[k]
|
||||
return exists
|
||||
return s.props.has(k)
|
||||
}
|
||||
|
||||
func (s Style) getAsBool(k propKey, defaultVal bool) bool {
|
||||
v, ok := s.rules[k]
|
||||
if !ok {
|
||||
if !s.isSet(k) {
|
||||
return defaultVal
|
||||
}
|
||||
if b, ok := v.(bool); ok {
|
||||
return b
|
||||
}
|
||||
return defaultVal
|
||||
return s.attrs&int(k) != 0
|
||||
}
|
||||
|
||||
func (s Style) getAsColor(k propKey) TerminalColor {
|
||||
v, ok := s.rules[k]
|
||||
if !ok {
|
||||
if !s.isSet(k) {
|
||||
return noColor
|
||||
}
|
||||
if c, ok := v.(TerminalColor); ok {
|
||||
|
||||
var c TerminalColor
|
||||
switch k {
|
||||
case foregroundKey:
|
||||
c = s.fgColor
|
||||
case backgroundKey:
|
||||
c = s.bgColor
|
||||
case marginBackgroundKey:
|
||||
c = s.marginBgColor
|
||||
case borderTopForegroundKey:
|
||||
c = s.borderTopFgColor
|
||||
case borderRightForegroundKey:
|
||||
c = s.borderRightFgColor
|
||||
case borderBottomForegroundKey:
|
||||
c = s.borderBottomFgColor
|
||||
case borderLeftForegroundKey:
|
||||
c = s.borderLeftFgColor
|
||||
case borderTopBackgroundKey:
|
||||
c = s.borderTopBgColor
|
||||
case borderRightBackgroundKey:
|
||||
c = s.borderRightBgColor
|
||||
case borderBottomBackgroundKey:
|
||||
c = s.borderBottomBgColor
|
||||
case borderLeftBackgroundKey:
|
||||
c = s.borderLeftBgColor
|
||||
}
|
||||
|
||||
if c != nil {
|
||||
return c
|
||||
}
|
||||
|
||||
return noColor
|
||||
}
|
||||
|
||||
func (s Style) getAsInt(k propKey) int {
|
||||
v, ok := s.rules[k]
|
||||
if !ok {
|
||||
if !s.isSet(k) {
|
||||
return 0
|
||||
}
|
||||
if i, ok := v.(int); ok {
|
||||
return i
|
||||
switch k {
|
||||
case widthKey:
|
||||
return s.width
|
||||
case heightKey:
|
||||
return s.height
|
||||
case paddingTopKey:
|
||||
return s.paddingTop
|
||||
case paddingRightKey:
|
||||
return s.paddingRight
|
||||
case paddingBottomKey:
|
||||
return s.paddingBottom
|
||||
case paddingLeftKey:
|
||||
return s.paddingLeft
|
||||
case marginTopKey:
|
||||
return s.marginTop
|
||||
case marginRightKey:
|
||||
return s.marginRight
|
||||
case marginBottomKey:
|
||||
return s.marginBottom
|
||||
case marginLeftKey:
|
||||
return s.marginLeft
|
||||
case maxWidthKey:
|
||||
return s.maxWidth
|
||||
case maxHeightKey:
|
||||
return s.maxHeight
|
||||
case tabWidthKey:
|
||||
return s.tabWidth
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (s Style) getAsPosition(k propKey) Position {
|
||||
v, ok := s.rules[k]
|
||||
if !ok {
|
||||
if !s.isSet(k) {
|
||||
return Position(0)
|
||||
}
|
||||
if p, ok := v.(Position); ok {
|
||||
return p
|
||||
switch k {
|
||||
case alignHorizontalKey:
|
||||
return s.alignHorizontal
|
||||
case alignVerticalKey:
|
||||
return s.alignVertical
|
||||
}
|
||||
return Position(0)
|
||||
}
|
||||
|
||||
func (s Style) getBorderStyle() Border {
|
||||
v, ok := s.rules[borderStyleKey]
|
||||
if !ok {
|
||||
if !s.isSet(borderStyleKey) {
|
||||
return noBorder
|
||||
}
|
||||
if b, ok := v.(Border); ok {
|
||||
return b
|
||||
}
|
||||
return noBorder
|
||||
return s.borderStyle
|
||||
}
|
||||
|
||||
func (s Style) getAsTransform(k propKey) func(string) string {
|
||||
v, ok := s.rules[k]
|
||||
if !ok {
|
||||
func (s Style) getAsTransform(propKey) func(string) string {
|
||||
if !s.isSet(transformKey) {
|
||||
return nil
|
||||
}
|
||||
if fn, ok := v.(func(string) string); ok {
|
||||
return fn
|
||||
}
|
||||
return nil
|
||||
return s.transform
|
||||
}
|
||||
|
||||
// Split a string into lines, additionally returning the size of the widest
|
||||
|
173
set.go
173
set.go
@ -1,34 +1,161 @@
|
||||
package lipgloss
|
||||
|
||||
// This could (should) probably just be moved into NewStyle(). We've broken it
|
||||
// out, so we can call it in a lazy way.
|
||||
func (s *Style) init() {
|
||||
if s.rules == nil {
|
||||
s.rules = make(rules)
|
||||
}
|
||||
}
|
||||
|
||||
// Set a value on the underlying rules map.
|
||||
func (s *Style) set(key propKey, value interface{}) {
|
||||
s.init()
|
||||
|
||||
switch v := value.(type) {
|
||||
case int:
|
||||
// We don't allow negative integers on any of our other values, so just keep
|
||||
// them at zero or above. We could use uints instead, but the
|
||||
// conversions are a little tedious, so we're sticking with ints for
|
||||
// sake of usability.
|
||||
switch key {
|
||||
case foregroundKey:
|
||||
s.fgColor = colorOrNil(value)
|
||||
case backgroundKey:
|
||||
s.bgColor = colorOrNil(value)
|
||||
case widthKey:
|
||||
s.width = max(0, value.(int))
|
||||
case heightKey:
|
||||
s.height = max(0, value.(int))
|
||||
case alignHorizontalKey:
|
||||
s.alignHorizontal = value.(Position)
|
||||
case alignVerticalKey:
|
||||
s.alignVertical = value.(Position)
|
||||
case paddingTopKey:
|
||||
s.paddingTop = max(0, value.(int))
|
||||
case paddingRightKey:
|
||||
s.paddingRight = max(0, value.(int))
|
||||
case paddingBottomKey:
|
||||
s.paddingBottom = max(0, value.(int))
|
||||
case paddingLeftKey:
|
||||
s.paddingLeft = max(0, value.(int))
|
||||
case marginTopKey:
|
||||
s.marginTop = max(0, value.(int))
|
||||
case marginRightKey:
|
||||
s.marginRight = max(0, value.(int))
|
||||
case marginBottomKey:
|
||||
s.marginBottom = max(0, value.(int))
|
||||
case marginLeftKey:
|
||||
s.marginLeft = max(0, value.(int))
|
||||
case marginBackgroundKey:
|
||||
s.marginBgColor = colorOrNil(value)
|
||||
case borderStyleKey:
|
||||
s.borderStyle = value.(Border)
|
||||
case borderTopForegroundKey:
|
||||
s.borderTopFgColor = colorOrNil(value)
|
||||
case borderRightForegroundKey:
|
||||
s.borderRightFgColor = colorOrNil(value)
|
||||
case borderBottomForegroundKey:
|
||||
s.borderBottomFgColor = colorOrNil(value)
|
||||
case borderLeftForegroundKey:
|
||||
s.borderLeftFgColor = colorOrNil(value)
|
||||
case borderTopBackgroundKey:
|
||||
s.borderTopBgColor = colorOrNil(value)
|
||||
case borderRightBackgroundKey:
|
||||
s.borderRightBgColor = colorOrNil(value)
|
||||
case borderBottomBackgroundKey:
|
||||
s.borderBottomBgColor = colorOrNil(value)
|
||||
case borderLeftBackgroundKey:
|
||||
s.borderLeftBgColor = colorOrNil(value)
|
||||
case maxWidthKey:
|
||||
s.maxWidth = max(0, value.(int))
|
||||
case maxHeightKey:
|
||||
s.maxHeight = max(0, value.(int))
|
||||
case tabWidthKey:
|
||||
// TabWidth is the only property that may have a negative value (and
|
||||
// that negative value can be no less than -1).
|
||||
if key == tabWidthKey {
|
||||
s.rules[key] = v
|
||||
break
|
||||
}
|
||||
|
||||
// We don't allow negative integers on any of our other values, so just keep
|
||||
// them at zero or above. We could use uints instead, but the
|
||||
// conversions are a little tedious, so we're sticking with ints for
|
||||
// sake of usability.
|
||||
s.rules[key] = max(0, v)
|
||||
s.tabWidth = value.(int)
|
||||
case transformKey:
|
||||
s.transform = value.(func(string) string)
|
||||
default:
|
||||
s.rules[key] = v
|
||||
if v, ok := value.(bool); ok {
|
||||
if v {
|
||||
s.attrs |= int(key)
|
||||
} else {
|
||||
s.attrs &^= int(key)
|
||||
}
|
||||
} else if attrs, ok := value.(int); ok {
|
||||
// bool attrs
|
||||
if attrs&int(key) != 0 {
|
||||
s.attrs |= int(key)
|
||||
} else {
|
||||
s.attrs &^= int(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the prop on
|
||||
s.props = s.props.set(key)
|
||||
}
|
||||
|
||||
// setFrom sets the property from another style.
|
||||
func (s *Style) setFrom(key propKey, i Style) {
|
||||
switch key {
|
||||
case foregroundKey:
|
||||
s.set(foregroundKey, i.fgColor)
|
||||
case backgroundKey:
|
||||
s.set(backgroundKey, i.bgColor)
|
||||
case widthKey:
|
||||
s.set(widthKey, i.width)
|
||||
case heightKey:
|
||||
s.set(heightKey, i.height)
|
||||
case alignHorizontalKey:
|
||||
s.set(alignHorizontalKey, i.alignHorizontal)
|
||||
case alignVerticalKey:
|
||||
s.set(alignVerticalKey, i.alignVertical)
|
||||
case paddingTopKey:
|
||||
s.set(paddingTopKey, i.paddingTop)
|
||||
case paddingRightKey:
|
||||
s.set(paddingRightKey, i.paddingRight)
|
||||
case paddingBottomKey:
|
||||
s.set(paddingBottomKey, i.paddingBottom)
|
||||
case paddingLeftKey:
|
||||
s.set(paddingLeftKey, i.paddingLeft)
|
||||
case marginTopKey:
|
||||
s.set(marginTopKey, i.marginTop)
|
||||
case marginRightKey:
|
||||
s.set(marginRightKey, i.marginRight)
|
||||
case marginBottomKey:
|
||||
s.set(marginBottomKey, i.marginBottom)
|
||||
case marginLeftKey:
|
||||
s.set(marginLeftKey, i.marginLeft)
|
||||
case marginBackgroundKey:
|
||||
s.set(marginBackgroundKey, i.marginBgColor)
|
||||
case borderStyleKey:
|
||||
s.set(borderStyleKey, i.borderStyle)
|
||||
case borderTopForegroundKey:
|
||||
s.set(borderTopForegroundKey, i.borderTopFgColor)
|
||||
case borderRightForegroundKey:
|
||||
s.set(borderRightForegroundKey, i.borderRightFgColor)
|
||||
case borderBottomForegroundKey:
|
||||
s.set(borderBottomForegroundKey, i.borderBottomFgColor)
|
||||
case borderLeftForegroundKey:
|
||||
s.set(borderLeftForegroundKey, i.borderLeftFgColor)
|
||||
case borderTopBackgroundKey:
|
||||
s.set(borderTopBackgroundKey, i.borderTopBgColor)
|
||||
case borderRightBackgroundKey:
|
||||
s.set(borderRightBackgroundKey, i.borderRightBgColor)
|
||||
case borderBottomBackgroundKey:
|
||||
s.set(borderBottomBackgroundKey, i.borderBottomBgColor)
|
||||
case borderLeftBackgroundKey:
|
||||
s.set(borderLeftBackgroundKey, i.borderLeftBgColor)
|
||||
case maxWidthKey:
|
||||
s.set(maxWidthKey, i.maxWidth)
|
||||
case maxHeightKey:
|
||||
s.set(maxHeightKey, i.maxHeight)
|
||||
case tabWidthKey:
|
||||
s.set(tabWidthKey, i.tabWidth)
|
||||
case transformKey:
|
||||
s.set(transformKey, i.transform)
|
||||
default:
|
||||
// Set attributes for set bool properties
|
||||
s.set(key, i.attrs)
|
||||
}
|
||||
}
|
||||
|
||||
func colorOrNil(c interface{}) TerminalColor {
|
||||
if c, ok := c.(TerminalColor); ok {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Bold sets a bold formatting rule.
|
||||
|
102
style.go
102
style.go
@ -17,13 +17,20 @@ type propKey int
|
||||
|
||||
// Available properties.
|
||||
const (
|
||||
boldKey propKey = iota
|
||||
// bool props come first
|
||||
boldKey propKey = 1 << iota
|
||||
italicKey
|
||||
underlineKey
|
||||
strikethroughKey
|
||||
reverseKey
|
||||
blinkKey
|
||||
faintKey
|
||||
underlineSpacesKey
|
||||
strikethroughSpacesKey
|
||||
colorWhitespaceKey
|
||||
|
||||
// non-bool props
|
||||
|
||||
foregroundKey
|
||||
backgroundKey
|
||||
widthKey
|
||||
@ -37,8 +44,6 @@ const (
|
||||
paddingBottomKey
|
||||
paddingLeftKey
|
||||
|
||||
colorWhitespaceKey
|
||||
|
||||
// Margins.
|
||||
marginTopKey
|
||||
marginRightKey
|
||||
@ -71,14 +76,27 @@ const (
|
||||
maxWidthKey
|
||||
maxHeightKey
|
||||
tabWidthKey
|
||||
underlineSpacesKey
|
||||
strikethroughSpacesKey
|
||||
|
||||
transformKey
|
||||
)
|
||||
|
||||
// A set of properties.
|
||||
type rules map[propKey]interface{}
|
||||
// props is a set of properties.
|
||||
type props int
|
||||
|
||||
// set sets a property.
|
||||
func (p props) set(k propKey) props {
|
||||
return p | props(k)
|
||||
}
|
||||
|
||||
// unset unsets a property.
|
||||
func (p props) unset(k propKey) props {
|
||||
return p &^ props(k)
|
||||
}
|
||||
|
||||
// has checks if a property is set.
|
||||
func (p props) has(k propKey) bool {
|
||||
return p&props(k) != 0
|
||||
}
|
||||
|
||||
// NewStyle returns a new, empty Style. While it's syntactic sugar for the
|
||||
// Style{} primitive, it's recommended to use this function for creating styles
|
||||
@ -100,8 +118,48 @@ func (r *Renderer) NewStyle() Style {
|
||||
// Style contains a set of rules that comprise a style as a whole.
|
||||
type Style struct {
|
||||
r *Renderer
|
||||
rules map[propKey]interface{}
|
||||
props props
|
||||
value string
|
||||
|
||||
// we store bool props values here
|
||||
attrs int
|
||||
|
||||
// props that have values
|
||||
fgColor TerminalColor
|
||||
bgColor TerminalColor
|
||||
|
||||
width int
|
||||
height int
|
||||
|
||||
alignHorizontal Position
|
||||
alignVertical Position
|
||||
|
||||
paddingTop int
|
||||
paddingRight int
|
||||
paddingBottom int
|
||||
paddingLeft int
|
||||
|
||||
marginTop int
|
||||
marginRight int
|
||||
marginBottom int
|
||||
marginLeft int
|
||||
marginBgColor TerminalColor
|
||||
|
||||
borderStyle Border
|
||||
borderTopFgColor TerminalColor
|
||||
borderRightFgColor TerminalColor
|
||||
borderBottomFgColor TerminalColor
|
||||
borderLeftFgColor TerminalColor
|
||||
borderTopBgColor TerminalColor
|
||||
borderRightBgColor TerminalColor
|
||||
borderBottomBgColor TerminalColor
|
||||
borderLeftBgColor TerminalColor
|
||||
|
||||
maxWidth int
|
||||
maxHeight int
|
||||
tabWidth int
|
||||
|
||||
transform func(string) string
|
||||
}
|
||||
|
||||
// joinString joins a list of strings into a single string separated with a
|
||||
@ -133,15 +191,10 @@ func (s Style) String() string {
|
||||
}
|
||||
|
||||
// Copy returns a copy of this style, including any underlying string values.
|
||||
//
|
||||
// Deprecated: Copy is deprecated and will be removed in a future release.
|
||||
func (s Style) Copy() Style {
|
||||
o := NewStyle()
|
||||
o.init()
|
||||
for k, v := range s.rules {
|
||||
o.rules[k] = v
|
||||
}
|
||||
o.r = s.r
|
||||
o.value = s.value
|
||||
return o
|
||||
return s
|
||||
}
|
||||
|
||||
// Inherit overlays the style in the argument onto this style by copying each explicitly
|
||||
@ -150,9 +203,11 @@ func (s Style) Copy() Style {
|
||||
//
|
||||
// Margins, padding, and underlying string values are not inherited.
|
||||
func (s Style) Inherit(i Style) Style {
|
||||
s.init()
|
||||
for k := boldKey; k <= transformKey; k <<= 1 {
|
||||
if !i.isSet(k) {
|
||||
continue
|
||||
}
|
||||
|
||||
for k, v := range i.rules {
|
||||
switch k { //nolint:exhaustive
|
||||
case marginTopKey, marginRightKey, marginBottomKey, marginLeftKey:
|
||||
// Margins are not inherited
|
||||
@ -163,14 +218,15 @@ func (s Style) Inherit(i Style) Style {
|
||||
case backgroundKey:
|
||||
// The margins also inherit the background color
|
||||
if !s.isSet(marginBackgroundKey) && !i.isSet(marginBackgroundKey) {
|
||||
s.rules[marginBackgroundKey] = v
|
||||
s.set(marginBackgroundKey, i.bgColor)
|
||||
}
|
||||
}
|
||||
|
||||
if _, exists := s.rules[k]; exists {
|
||||
if s.isSet(k) {
|
||||
continue
|
||||
}
|
||||
s.rules[k] = v
|
||||
|
||||
s.setFrom(k, i)
|
||||
}
|
||||
return s
|
||||
}
|
||||
@ -235,7 +291,7 @@ func (s Style) Render(strs ...string) string {
|
||||
str = transform(str)
|
||||
}
|
||||
|
||||
if len(s.rules) == 0 {
|
||||
if s.props == 0 {
|
||||
return s.maybeConvertTabs(str)
|
||||
}
|
||||
|
||||
@ -511,7 +567,7 @@ func pad(str string, n int, style *termenv.Style) string {
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
func max(a, b int) int { // nolint:unparam
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
|
@ -213,114 +213,114 @@ func TestStyleUnset(t *testing.T) {
|
||||
|
||||
s := NewStyle().Bold(true)
|
||||
requireTrue(t, s.GetBold())
|
||||
s.UnsetBold()
|
||||
s = s.UnsetBold()
|
||||
requireFalse(t, s.GetBold())
|
||||
|
||||
s = NewStyle().Italic(true)
|
||||
requireTrue(t, s.GetItalic())
|
||||
s.UnsetItalic()
|
||||
s = s.UnsetItalic()
|
||||
requireFalse(t, s.GetItalic())
|
||||
|
||||
s = NewStyle().Underline(true)
|
||||
requireTrue(t, s.GetUnderline())
|
||||
s.UnsetUnderline()
|
||||
s = s.UnsetUnderline()
|
||||
requireFalse(t, s.GetUnderline())
|
||||
|
||||
s = NewStyle().Strikethrough(true)
|
||||
requireTrue(t, s.GetStrikethrough())
|
||||
s.UnsetStrikethrough()
|
||||
s = s.UnsetStrikethrough()
|
||||
requireFalse(t, s.GetStrikethrough())
|
||||
|
||||
s = NewStyle().Reverse(true)
|
||||
requireTrue(t, s.GetReverse())
|
||||
s.UnsetReverse()
|
||||
s = s.UnsetReverse()
|
||||
requireFalse(t, s.GetReverse())
|
||||
|
||||
s = NewStyle().Blink(true)
|
||||
requireTrue(t, s.GetBlink())
|
||||
s.UnsetBlink()
|
||||
s = s.UnsetBlink()
|
||||
requireFalse(t, s.GetBlink())
|
||||
|
||||
s = NewStyle().Faint(true)
|
||||
requireTrue(t, s.GetFaint())
|
||||
s.UnsetFaint()
|
||||
s = s.UnsetFaint()
|
||||
requireFalse(t, s.GetFaint())
|
||||
|
||||
s = NewStyle().Inline(true)
|
||||
requireTrue(t, s.GetInline())
|
||||
s.UnsetInline()
|
||||
s = s.UnsetInline()
|
||||
requireFalse(t, s.GetInline())
|
||||
|
||||
// colors
|
||||
col := Color("#ffffff")
|
||||
s = NewStyle().Foreground(col)
|
||||
requireEqual(t, col, s.GetForeground())
|
||||
s.UnsetForeground()
|
||||
s = s.UnsetForeground()
|
||||
requireNotEqual(t, col, s.GetForeground())
|
||||
|
||||
s = NewStyle().Background(col)
|
||||
requireEqual(t, col, s.GetBackground())
|
||||
s.UnsetBackground()
|
||||
s = s.UnsetBackground()
|
||||
requireNotEqual(t, col, s.GetBackground())
|
||||
|
||||
// margins
|
||||
s = NewStyle().Margin(1, 2, 3, 4)
|
||||
requireEqual(t, 1, s.GetMarginTop())
|
||||
s.UnsetMarginTop()
|
||||
s = s.UnsetMarginTop()
|
||||
requireEqual(t, 0, s.GetMarginTop())
|
||||
|
||||
requireEqual(t, 2, s.GetMarginRight())
|
||||
s.UnsetMarginRight()
|
||||
s = s.UnsetMarginRight()
|
||||
requireEqual(t, 0, s.GetMarginRight())
|
||||
|
||||
requireEqual(t, 3, s.GetMarginBottom())
|
||||
s.UnsetMarginBottom()
|
||||
s = s.UnsetMarginBottom()
|
||||
requireEqual(t, 0, s.GetMarginBottom())
|
||||
|
||||
requireEqual(t, 4, s.GetMarginLeft())
|
||||
s.UnsetMarginLeft()
|
||||
s = s.UnsetMarginLeft()
|
||||
requireEqual(t, 0, s.GetMarginLeft())
|
||||
|
||||
// padding
|
||||
s = NewStyle().Padding(1, 2, 3, 4)
|
||||
requireEqual(t, 1, s.GetPaddingTop())
|
||||
s.UnsetPaddingTop()
|
||||
s = s.UnsetPaddingTop()
|
||||
requireEqual(t, 0, s.GetPaddingTop())
|
||||
|
||||
requireEqual(t, 2, s.GetPaddingRight())
|
||||
s.UnsetPaddingRight()
|
||||
s = s.UnsetPaddingRight()
|
||||
requireEqual(t, 0, s.GetPaddingRight())
|
||||
|
||||
requireEqual(t, 3, s.GetPaddingBottom())
|
||||
s.UnsetPaddingBottom()
|
||||
s = s.UnsetPaddingBottom()
|
||||
requireEqual(t, 0, s.GetPaddingBottom())
|
||||
|
||||
requireEqual(t, 4, s.GetPaddingLeft())
|
||||
s.UnsetPaddingLeft()
|
||||
s = s.UnsetPaddingLeft()
|
||||
requireEqual(t, 0, s.GetPaddingLeft())
|
||||
|
||||
// border
|
||||
s = NewStyle().Border(normalBorder, true, true, true, true)
|
||||
requireTrue(t, s.GetBorderTop())
|
||||
s.UnsetBorderTop()
|
||||
s = s.UnsetBorderTop()
|
||||
requireFalse(t, s.GetBorderTop())
|
||||
|
||||
requireTrue(t, s.GetBorderRight())
|
||||
s.UnsetBorderRight()
|
||||
s = s.UnsetBorderRight()
|
||||
requireFalse(t, s.GetBorderRight())
|
||||
|
||||
requireTrue(t, s.GetBorderBottom())
|
||||
s.UnsetBorderBottom()
|
||||
s = s.UnsetBorderBottom()
|
||||
requireFalse(t, s.GetBorderBottom())
|
||||
|
||||
requireTrue(t, s.GetBorderLeft())
|
||||
s.UnsetBorderLeft()
|
||||
s = s.UnsetBorderLeft()
|
||||
requireFalse(t, s.GetBorderLeft())
|
||||
|
||||
// tab width
|
||||
s = NewStyle().TabWidth(2)
|
||||
requireEqual(t, s.GetTabWidth(), 2)
|
||||
s.UnsetTabWidth()
|
||||
s = s.UnsetTabWidth()
|
||||
requireNotEqual(t, s.GetTabWidth(), 4)
|
||||
}
|
||||
|
||||
@ -460,10 +460,12 @@ func BenchmarkStyleRender(b *testing.B) {
|
||||
}
|
||||
|
||||
func requireTrue(tb testing.TB, b bool) {
|
||||
tb.Helper()
|
||||
requireEqual(tb, true, b)
|
||||
}
|
||||
|
||||
func requireFalse(tb testing.TB, b bool) {
|
||||
tb.Helper()
|
||||
requireEqual(tb, false, b)
|
||||
}
|
||||
|
||||
|
127
unset.go
127
unset.go
@ -1,159 +1,164 @@
|
||||
package lipgloss
|
||||
|
||||
// unset unsets a property from a style.
|
||||
func (s *Style) unset(key propKey) {
|
||||
s.props = s.props.unset(key)
|
||||
}
|
||||
|
||||
// UnsetBold removes the bold style rule, if set.
|
||||
func (s Style) UnsetBold() Style {
|
||||
delete(s.rules, boldKey)
|
||||
s.unset(boldKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetItalic removes the italic style rule, if set.
|
||||
func (s Style) UnsetItalic() Style {
|
||||
delete(s.rules, italicKey)
|
||||
s.unset(italicKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetUnderline removes the underline style rule, if set.
|
||||
func (s Style) UnsetUnderline() Style {
|
||||
delete(s.rules, underlineKey)
|
||||
s.unset(underlineKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetStrikethrough removes the strikethrough style rule, if set.
|
||||
func (s Style) UnsetStrikethrough() Style {
|
||||
delete(s.rules, strikethroughKey)
|
||||
s.unset(strikethroughKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetReverse removes the reverse style rule, if set.
|
||||
func (s Style) UnsetReverse() Style {
|
||||
delete(s.rules, reverseKey)
|
||||
s.unset(reverseKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetBlink removes the blink style rule, if set.
|
||||
func (s Style) UnsetBlink() Style {
|
||||
delete(s.rules, blinkKey)
|
||||
s.unset(blinkKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetFaint removes the faint style rule, if set.
|
||||
func (s Style) UnsetFaint() Style {
|
||||
delete(s.rules, faintKey)
|
||||
s.unset(faintKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetForeground removes the foreground style rule, if set.
|
||||
func (s Style) UnsetForeground() Style {
|
||||
delete(s.rules, foregroundKey)
|
||||
s.unset(foregroundKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetBackground removes the background style rule, if set.
|
||||
func (s Style) UnsetBackground() Style {
|
||||
delete(s.rules, backgroundKey)
|
||||
s.unset(backgroundKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetWidth removes the width style rule, if set.
|
||||
func (s Style) UnsetWidth() Style {
|
||||
delete(s.rules, widthKey)
|
||||
s.unset(widthKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetHeight removes the height style rule, if set.
|
||||
func (s Style) UnsetHeight() Style {
|
||||
delete(s.rules, heightKey)
|
||||
s.unset(heightKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetAlign removes the horizontal and vertical text alignment style rule, if set.
|
||||
func (s Style) UnsetAlign() Style {
|
||||
delete(s.rules, alignHorizontalKey)
|
||||
delete(s.rules, alignVerticalKey)
|
||||
s.unset(alignHorizontalKey)
|
||||
s.unset(alignVerticalKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetAlignHorizontal removes the horizontal text alignment style rule, if set.
|
||||
func (s Style) UnsetAlignHorizontal() Style {
|
||||
delete(s.rules, alignHorizontalKey)
|
||||
s.unset(alignHorizontalKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetAlignVertical removes the vertical text alignment style rule, if set.
|
||||
func (s Style) UnsetAlignVertical() Style {
|
||||
delete(s.rules, alignVerticalKey)
|
||||
s.unset(alignVerticalKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetPadding removes all padding style rules.
|
||||
func (s Style) UnsetPadding() Style {
|
||||
delete(s.rules, paddingLeftKey)
|
||||
delete(s.rules, paddingRightKey)
|
||||
delete(s.rules, paddingTopKey)
|
||||
delete(s.rules, paddingBottomKey)
|
||||
s.unset(paddingLeftKey)
|
||||
s.unset(paddingRightKey)
|
||||
s.unset(paddingTopKey)
|
||||
s.unset(paddingBottomKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetPaddingLeft removes the left padding style rule, if set.
|
||||
func (s Style) UnsetPaddingLeft() Style {
|
||||
delete(s.rules, paddingLeftKey)
|
||||
s.unset(paddingLeftKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetPaddingRight removes the right padding style rule, if set.
|
||||
func (s Style) UnsetPaddingRight() Style {
|
||||
delete(s.rules, paddingRightKey)
|
||||
s.unset(paddingRightKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetPaddingTop removes the top padding style rule, if set.
|
||||
func (s Style) UnsetPaddingTop() Style {
|
||||
delete(s.rules, paddingTopKey)
|
||||
s.unset(paddingTopKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetPaddingBottom removes the bottom padding style rule, if set.
|
||||
func (s Style) UnsetPaddingBottom() Style {
|
||||
delete(s.rules, paddingBottomKey)
|
||||
s.unset(paddingBottomKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetColorWhitespace removes the rule for coloring padding, if set.
|
||||
func (s Style) UnsetColorWhitespace() Style {
|
||||
delete(s.rules, colorWhitespaceKey)
|
||||
s.unset(colorWhitespaceKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetMargins removes all margin style rules.
|
||||
func (s Style) UnsetMargins() Style {
|
||||
delete(s.rules, marginLeftKey)
|
||||
delete(s.rules, marginRightKey)
|
||||
delete(s.rules, marginTopKey)
|
||||
delete(s.rules, marginBottomKey)
|
||||
s.unset(marginLeftKey)
|
||||
s.unset(marginRightKey)
|
||||
s.unset(marginTopKey)
|
||||
s.unset(marginBottomKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetMarginLeft removes the left margin style rule, if set.
|
||||
func (s Style) UnsetMarginLeft() Style {
|
||||
delete(s.rules, marginLeftKey)
|
||||
s.unset(marginLeftKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetMarginRight removes the right margin style rule, if set.
|
||||
func (s Style) UnsetMarginRight() Style {
|
||||
delete(s.rules, marginRightKey)
|
||||
s.unset(marginRightKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetMarginTop removes the top margin style rule, if set.
|
||||
func (s Style) UnsetMarginTop() Style {
|
||||
delete(s.rules, marginTopKey)
|
||||
s.unset(marginTopKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetMarginBottom removes the bottom margin style rule, if set.
|
||||
func (s Style) UnsetMarginBottom() Style {
|
||||
delete(s.rules, marginBottomKey)
|
||||
s.unset(marginBottomKey)
|
||||
return s
|
||||
}
|
||||
|
||||
@ -161,153 +166,153 @@ func (s Style) UnsetMarginBottom() Style {
|
||||
// margin's background color can be set from the background color of another
|
||||
// style during inheritance.
|
||||
func (s Style) UnsetMarginBackground() Style {
|
||||
delete(s.rules, marginBackgroundKey)
|
||||
s.unset(marginBackgroundKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetBorderStyle removes the border style rule, if set.
|
||||
func (s Style) UnsetBorderStyle() Style {
|
||||
delete(s.rules, borderStyleKey)
|
||||
s.unset(borderStyleKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetBorderTop removes the border top style rule, if set.
|
||||
func (s Style) UnsetBorderTop() Style {
|
||||
delete(s.rules, borderTopKey)
|
||||
s.unset(borderTopKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetBorderRight removes the border right style rule, if set.
|
||||
func (s Style) UnsetBorderRight() Style {
|
||||
delete(s.rules, borderRightKey)
|
||||
s.unset(borderRightKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetBorderBottom removes the border bottom style rule, if set.
|
||||
func (s Style) UnsetBorderBottom() Style {
|
||||
delete(s.rules, borderBottomKey)
|
||||
s.unset(borderBottomKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetBorderLeft removes the border left style rule, if set.
|
||||
func (s Style) UnsetBorderLeft() Style {
|
||||
delete(s.rules, borderLeftKey)
|
||||
s.unset(borderLeftKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetBorderForeground removes all border foreground color styles, if set.
|
||||
func (s Style) UnsetBorderForeground() Style {
|
||||
delete(s.rules, borderTopForegroundKey)
|
||||
delete(s.rules, borderRightForegroundKey)
|
||||
delete(s.rules, borderBottomForegroundKey)
|
||||
delete(s.rules, borderLeftForegroundKey)
|
||||
s.unset(borderTopForegroundKey)
|
||||
s.unset(borderRightForegroundKey)
|
||||
s.unset(borderBottomForegroundKey)
|
||||
s.unset(borderLeftForegroundKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetBorderTopForeground removes the top border foreground color rule,
|
||||
// if set.
|
||||
func (s Style) UnsetBorderTopForeground() Style {
|
||||
delete(s.rules, borderTopForegroundKey)
|
||||
s.unset(borderTopForegroundKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetBorderRightForeground removes the right border foreground color rule,
|
||||
// if set.
|
||||
func (s Style) UnsetBorderRightForeground() Style {
|
||||
delete(s.rules, borderRightForegroundKey)
|
||||
s.unset(borderRightForegroundKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetBorderBottomForeground removes the bottom border foreground color
|
||||
// rule, if set.
|
||||
func (s Style) UnsetBorderBottomForeground() Style {
|
||||
delete(s.rules, borderBottomForegroundKey)
|
||||
s.unset(borderBottomForegroundKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetBorderLeftForeground removes the left border foreground color rule,
|
||||
// if set.
|
||||
func (s Style) UnsetBorderLeftForeground() Style {
|
||||
delete(s.rules, borderLeftForegroundKey)
|
||||
s.unset(borderLeftForegroundKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetBorderBackground removes all border background color styles, if
|
||||
// set.
|
||||
func (s Style) UnsetBorderBackground() Style {
|
||||
delete(s.rules, borderTopBackgroundKey)
|
||||
delete(s.rules, borderRightBackgroundKey)
|
||||
delete(s.rules, borderBottomBackgroundKey)
|
||||
delete(s.rules, borderLeftBackgroundKey)
|
||||
s.unset(borderTopBackgroundKey)
|
||||
s.unset(borderRightBackgroundKey)
|
||||
s.unset(borderBottomBackgroundKey)
|
||||
s.unset(borderLeftBackgroundKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetBorderTopBackgroundColor removes the top border background color rule,
|
||||
// if set.
|
||||
func (s Style) UnsetBorderTopBackgroundColor() Style {
|
||||
delete(s.rules, borderTopBackgroundKey)
|
||||
s.unset(borderTopBackgroundKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetBorderRightBackground removes the right border background color
|
||||
// rule, if set.
|
||||
func (s Style) UnsetBorderRightBackground() Style {
|
||||
delete(s.rules, borderRightBackgroundKey)
|
||||
s.unset(borderRightBackgroundKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetBorderBottomBackground removes the bottom border background color
|
||||
// rule, if set.
|
||||
func (s Style) UnsetBorderBottomBackground() Style {
|
||||
delete(s.rules, borderBottomBackgroundKey)
|
||||
s.unset(borderBottomBackgroundKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetBorderLeftBackground removes the left border color rule, if set.
|
||||
func (s Style) UnsetBorderLeftBackground() Style {
|
||||
delete(s.rules, borderLeftBackgroundKey)
|
||||
s.unset(borderLeftBackgroundKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetInline removes the inline style rule, if set.
|
||||
func (s Style) UnsetInline() Style {
|
||||
delete(s.rules, inlineKey)
|
||||
s.unset(inlineKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetMaxWidth removes the max width style rule, if set.
|
||||
func (s Style) UnsetMaxWidth() Style {
|
||||
delete(s.rules, maxWidthKey)
|
||||
s.unset(maxWidthKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetMaxHeight removes the max height style rule, if set.
|
||||
func (s Style) UnsetMaxHeight() Style {
|
||||
delete(s.rules, maxHeightKey)
|
||||
s.unset(maxHeightKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetTabWidth removes the tab width style rule, if set.
|
||||
func (s Style) UnsetTabWidth() Style {
|
||||
delete(s.rules, tabWidthKey)
|
||||
s.unset(tabWidthKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetUnderlineSpaces removes the value set by UnderlineSpaces.
|
||||
func (s Style) UnsetUnderlineSpaces() Style {
|
||||
delete(s.rules, underlineSpacesKey)
|
||||
s.unset(underlineSpacesKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetStrikethroughSpaces removes the value set by StrikethroughSpaces.
|
||||
func (s Style) UnsetStrikethroughSpaces() Style {
|
||||
delete(s.rules, strikethroughSpacesKey)
|
||||
s.unset(strikethroughSpacesKey)
|
||||
return s
|
||||
}
|
||||
|
||||
// UnsetTransform removes the value set by Transform.
|
||||
func (s Style) UnsetTransform() Style {
|
||||
delete(s.rules, transformKey)
|
||||
s.unset(transformKey)
|
||||
return s
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user