mirror of
https://github.com/charmbracelet/lipgloss.git
synced 2024-08-17 09:50:31 +03:00
Option to set whitespace color in place functions + whitespace renderer
This commit is contained in:
parent
25d9c64aa9
commit
73f6cab6ac
13
color.go
13
color.go
@ -13,6 +13,7 @@ var (
|
||||
// ColorType is an interface used in color specifications.
|
||||
type ColorType interface {
|
||||
value() string
|
||||
color() termenv.Color
|
||||
}
|
||||
|
||||
// NoColor is used to specify the absence of color styling. When this is active
|
||||
@ -29,6 +30,10 @@ func (n NoColor) value() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (n NoColor) color() termenv.Color {
|
||||
return color("")
|
||||
}
|
||||
|
||||
var noColor = NoColor{}
|
||||
|
||||
// Color specifies a color by hex or ANSI value. For example:
|
||||
@ -42,6 +47,10 @@ func (c Color) value() string {
|
||||
return string(c)
|
||||
}
|
||||
|
||||
func (c Color) color() termenv.Color {
|
||||
return color(string(c))
|
||||
}
|
||||
|
||||
// AdaptiveColor provides color options for light and dark backgrounds. The
|
||||
// appropriate color with be returned based on the darkness of the terminal
|
||||
// background color determined at runtime.
|
||||
@ -61,3 +70,7 @@ func (a AdaptiveColor) value() string {
|
||||
}
|
||||
return a.Light
|
||||
}
|
||||
|
||||
func (a AdaptiveColor) color() termenv.Color {
|
||||
return color(a.value())
|
||||
}
|
||||
|
33
position.go
33
position.go
@ -31,14 +31,14 @@ const (
|
||||
|
||||
// Place places a string or text block vertically in an unstyled box of a given
|
||||
// width or height.
|
||||
func Place(width, height int, hPos, vPos Position, str string) string {
|
||||
return PlaceVertical(height, vPos, PlaceHorizontal(width, hPos, str))
|
||||
func Place(width, height int, hPos, vPos Position, str string, opts ...WhitespaceOption) string {
|
||||
return PlaceVertical(height, vPos, PlaceHorizontal(width, hPos, str, opts...), opts...)
|
||||
}
|
||||
|
||||
// PlaceHorizontal places a string or text block horizontally in an unstyled
|
||||
// block of a given width. If the given width is shorter than the max width of
|
||||
// the string (measured by it's longest line) this will be a noöp.
|
||||
func PlaceHorizontal(width int, pos Position, str string) string {
|
||||
func PlaceHorizontal(width int, pos Position, str string, opts ...WhitespaceOption) string {
|
||||
lines, contentWidth := getLines(str)
|
||||
gap := width - contentWidth
|
||||
|
||||
@ -46,16 +46,21 @@ func PlaceHorizontal(width int, pos Position, str string) string {
|
||||
return str
|
||||
}
|
||||
|
||||
ws := &whitespace{}
|
||||
for _, opt := range opts {
|
||||
opt(ws)
|
||||
}
|
||||
|
||||
var b strings.Builder
|
||||
for i, l := range lines {
|
||||
switch pos {
|
||||
|
||||
case Left:
|
||||
b.WriteString(l)
|
||||
b.WriteString(strings.Repeat(" ", gap))
|
||||
b.WriteString(ws.render(gap))
|
||||
|
||||
case Right:
|
||||
b.WriteString(strings.Repeat(" ", gap))
|
||||
b.WriteString(ws.render(gap))
|
||||
b.WriteString(l)
|
||||
|
||||
default: // somewhere in the middle
|
||||
@ -63,9 +68,9 @@ func PlaceHorizontal(width int, pos Position, str string) string {
|
||||
left := gap - split
|
||||
right := gap - left
|
||||
|
||||
b.WriteString(strings.Repeat(" ", left))
|
||||
b.WriteString(ws.render(left))
|
||||
b.WriteString(l)
|
||||
b.WriteString(strings.Repeat(" ", right))
|
||||
b.WriteString(ws.render(right))
|
||||
}
|
||||
|
||||
if i < len(lines)-1 {
|
||||
@ -79,7 +84,7 @@ func PlaceHorizontal(width int, pos Position, str string) string {
|
||||
// PlaceVertical places a string or text block vertically in an unstyled block
|
||||
// of a given height. If the given height is shorter than the height of the
|
||||
// string (measured by it's newlines) then this will be a noöp.
|
||||
func PlaceVertical(height int, pos Position, str string) string {
|
||||
func PlaceVertical(height int, pos Position, str string, opts ...WhitespaceOption) string {
|
||||
contentHeight := strings.Count(str, "\n") + 1
|
||||
gap := height - contentHeight
|
||||
|
||||
@ -87,14 +92,20 @@ func PlaceVertical(height int, pos Position, str string) string {
|
||||
return str
|
||||
}
|
||||
|
||||
ws := &whitespace{}
|
||||
for _, opt := range opts {
|
||||
opt(ws)
|
||||
}
|
||||
|
||||
_, width := getLines(str)
|
||||
emptyLine := strings.Repeat(" ", width)
|
||||
emptyLine := ws.render(width)
|
||||
b := strings.Builder{}
|
||||
|
||||
switch pos {
|
||||
|
||||
case Top:
|
||||
b.WriteString(str)
|
||||
b.WriteRune('\n')
|
||||
for i := 0; i < gap; i++ {
|
||||
b.WriteString(emptyLine)
|
||||
if i < gap-1 {
|
||||
@ -115,10 +126,8 @@ func PlaceVertical(height int, pos Position, str string) string {
|
||||
b.WriteString(str)
|
||||
|
||||
for i := 0; i < bottom; i++ {
|
||||
b.WriteRune('\n')
|
||||
b.WriteString(emptyLine)
|
||||
if i < bottom-1 {
|
||||
b.WriteRune('\n')
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
4
style.go
4
style.go
@ -207,7 +207,7 @@ func (s Style) Render(str string) string {
|
||||
}
|
||||
|
||||
if fg != noColor {
|
||||
fgc := color(fg.value())
|
||||
fgc := fg.color()
|
||||
te = te.Foreground(fgc)
|
||||
te.Foreground(fgc)
|
||||
if styleWhitespace {
|
||||
@ -219,7 +219,7 @@ func (s Style) Render(str string) string {
|
||||
}
|
||||
|
||||
if bg != noColor {
|
||||
bgc := color(bg.value())
|
||||
bgc := bg.color()
|
||||
te = te.Background(bgc)
|
||||
if colorWhitespace {
|
||||
teWhitespace = teWhitespace.Background(bgc)
|
||||
|
42
whitespace.go
Normal file
42
whitespace.go
Normal file
@ -0,0 +1,42 @@
|
||||
package lipgloss
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/muesli/reflow/ansi"
|
||||
"github.com/muesli/termenv"
|
||||
)
|
||||
|
||||
// whitespace is a whitespace renderer.
|
||||
type whitespace struct {
|
||||
style termenv.Style
|
||||
chars string
|
||||
}
|
||||
|
||||
// Render spacespace.
|
||||
func (w whitespace) render(width int) string {
|
||||
if w.chars == "" {
|
||||
w.chars = " "
|
||||
}
|
||||
|
||||
charWidth := ansi.PrintableRuneWidth(w.chars)
|
||||
line := strings.Repeat(w.chars, width/charWidth)
|
||||
|
||||
// Fill in gaps with spaces
|
||||
short := width - ansi.PrintableRuneWidth(line)
|
||||
if short > 0 {
|
||||
line += strings.Repeat(" ", short)
|
||||
}
|
||||
|
||||
return w.style.Styled(line)
|
||||
}
|
||||
|
||||
// WhiteSpaceOption sets a styling rule for rendering whitespace.
|
||||
type WhitespaceOption func(*whitespace)
|
||||
|
||||
// WithWhiteSpaceBackground sets the background color of the whitespace.
|
||||
func WithWhitespaceBackground(c Color) WhitespaceOption {
|
||||
return func(w *whitespace) {
|
||||
w.style = w.style.Background(c.color())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user