Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: lipgloss renderer #140

Merged
merged 16 commits into from Feb 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
ssh_example_ed25519*
70 changes: 58 additions & 12 deletions README.md
Expand Up @@ -20,17 +20,17 @@ Users familiar with CSS will feel at home with Lip Gloss.
import "github.com/charmbracelet/lipgloss"

var style = lipgloss.NewStyle().
SetString("Hello, kitty.").
Bold(true).
Foreground(lipgloss.Color("#FAFAFA")).
Background(lipgloss.Color("#7D56F4")).
PaddingTop(2).
PaddingLeft(4).
Width(22)

fmt.Println(style.Render("Hello, kitty."))
fmt.Println(style)
```


## Colors

Lip Gloss supports the following color profiles:
Expand Down Expand Up @@ -77,6 +77,29 @@ lipgloss.AdaptiveColor{Light: "236", Dark: "248"}
The terminal's background color will automatically be detected and the
appropriate color will be chosen at runtime.

### Complete Colors

CompleteColor specifies exact values for truecolor, ANSI256, and ANSI color
profiles.

```go
lipgloss.CompleteColor{True: "#0000FF", ANSI256: "86", ANSI: "5"}
```

Automatic color degradation will not be performed in this case and it will be
based on the color specified.

### Complete Adaptive Colors

You can use CompleteColor with AdaptiveColor to specify the exact values for
light and dark backgrounds without automatic color degradation.

```go
lipgloss.CompleteAdaptiveColor{
Light: CompleteColor{TrueColor: "#d7ffae", ANSI256: "193", ANSI: "11"},
Dark: CompleteColor{TrueColor: "#d75fee", ANSI256: "163", ANSI: "5"},
}
```

## Inline Formatting

Expand Down Expand Up @@ -151,11 +174,11 @@ var style = lipgloss.NewStyle().
Setting a minimum width and height is simple and straightforward.

```go
var str = lipgloss.NewStyle().
var style = lipgloss.NewStyle().
SetString("What’s for lunch?").
Width(24).
Height(32).
Foreground(lipgloss.Color("63")).
Render("What’s for lunch?")
Foreground(lipgloss.Color("63"))
```


Expand Down Expand Up @@ -274,20 +297,40 @@ someStyle.MaxWidth(5).MaxHeight(5).Render("yadda yadda")

## Rendering

Generally, you just call the `Render(string)` method on a `lipgloss.Style`:
Generally, you just call the `Render(string...)` method on a `lipgloss.Style`:

```go
fmt.Println(lipgloss.NewStyle().Bold(true).Render("Hello, kitty."))
style := lipgloss.NewStyle(lipgloss.WithString("Hello,")).Bold(true)
fmt.Println(style.Render("kitty.")) // Hello, kitty.
fmt.Println(style.Render("puppy.")) // Hello, puppy.
```

But you could also use the Stringer interface:

```go
var style = lipgloss.NewStyle().SetString("你好,猫咪。").Bold(true)
var style = lipgloss.NewStyle(lipgloss.WithString("你好,猫咪。")).Bold(true)

fmt.Println(style)
```

### Custom Renderers

Use custom renderers to enforce rendering your styles in a specific way. You can
specify the color profile to use, True Color, ANSI 256, 8-bit ANSI, or good ol'
ASCII. You can also specify whether or not to assume dark background colors.

```go
renderer := lipgloss.NewRenderer(
lipgloss.WithColorProfile(termenv.ANSI256),
lipgloss.WithDarkBackground(true),
)

fmt.Printf("%s\n", style)
var style = renderer.NewStyle().Background(lipgloss.AdaptiveColor{Light: "63", Dark: "228"})
fmt.Println(style.Render("Lip Gloss")) // This will always use the dark background color
```

This is also useful when using lipgloss with an SSH server like [Wish][wish].
See the [ssh example][ssh-example] for more details.

## Utilities

Expand Down Expand Up @@ -318,10 +361,11 @@ Sometimes you’ll want to know the width and height of text blocks when buildin
your layouts.

```go
var block string = lipgloss.NewStyle().
// Render a block of text.
var style = lipgloss.NewStyle().
Width(40).
Padding(2).
Render(someLongString)
Padding(2)
var block string = style.Render(someLongString)

// Get the actual, physical dimensions of the text block.
width := lipgloss.Width(block)
Expand Down Expand Up @@ -408,3 +452,5 @@ Charm热爱开源 • Charm loves open source


[docs]: https://pkg.go.dev/github.com/charmbracelet/lipgloss?tab=doc
[wish]: https://github.com/charmbracelet/wish
[ssh-example]: examples/ssh
14 changes: 7 additions & 7 deletions borders.go
Expand Up @@ -298,7 +298,7 @@ func (s Style) applyBorder(str string) string {
// Render top
if hasTop {
top := renderHorizontalEdge(border.TopLeft, border.Top, border.TopRight, width)
top = styleBorder(top, topFG, topBG)
top = s.styleBorder(top, topFG, topBG)
out.WriteString(top)
out.WriteRune('\n')
}
Expand All @@ -317,7 +317,7 @@ func (s Style) applyBorder(str string) string {
if leftIndex >= len(leftRunes) {
leftIndex = 0
}
out.WriteString(styleBorder(r, leftFG, leftBG))
out.WriteString(s.styleBorder(r, leftFG, leftBG))
}
out.WriteString(l)
if hasRight {
Expand All @@ -326,7 +326,7 @@ func (s Style) applyBorder(str string) string {
if rightIndex >= len(rightRunes) {
rightIndex = 0
}
out.WriteString(styleBorder(r, rightFG, rightBG))
out.WriteString(s.styleBorder(r, rightFG, rightBG))
}
if i < len(lines)-1 {
out.WriteRune('\n')
Expand All @@ -336,7 +336,7 @@ func (s Style) applyBorder(str string) string {
// Render bottom
if hasBottom {
bottom := renderHorizontalEdge(border.BottomLeft, border.Bottom, border.BottomRight, width)
bottom = styleBorder(bottom, bottomFG, bottomBG)
bottom = s.styleBorder(bottom, bottomFG, bottomBG)
out.WriteRune('\n')
out.WriteString(bottom)
}
Expand Down Expand Up @@ -376,18 +376,18 @@ func renderHorizontalEdge(left, middle, right string, width int) string {
}

// Apply foreground and background styling to a border.
func styleBorder(border string, fg, bg TerminalColor) string {
func (s Style) styleBorder(border string, fg, bg TerminalColor) string {
if fg == noColor && bg == noColor {
return border
}

var style = termenv.Style{}

if fg != noColor {
style = style.Foreground(ColorProfile().Color(fg.value()))
style = style.Foreground(fg.color(s.r))
}
if bg != noColor {
style = style.Background(ColorProfile().Color(bg.value()))
style = style.Background(bg.color(s.r))
}

return style.Styled(border)
Expand Down