diff --git a/style/border.go b/style/border.go index ca87b4f..6cc803a 100644 --- a/style/border.go +++ b/style/border.go @@ -23,6 +23,25 @@ func resolveBorderType(name string) lipgloss.Border { return lipgloss.RoundedBorder() } +type LayoutBorderMode string + +const ( + LayoutBorderFull LayoutBorderMode = "full" + LayoutBorderSidebar LayoutBorderMode = "sidebar" + LayoutBorderSeparator LayoutBorderMode = "separator" +) + +func resolveLayoutBorder(name string) LayoutBorderMode { + switch strings.ToLower(strings.TrimSpace(name)) { + case string(LayoutBorderSidebar): + return LayoutBorderSidebar + case string(LayoutBorderSeparator): + return LayoutBorderSeparator + default: + return LayoutBorderFull + } +} + func ContentHeight(totalH int) int { h := totalH - 2 if h < 0 { @@ -62,3 +81,37 @@ func RenderWithTitle(border lipgloss.Style, title, content string, width, height return lipgloss.JoinVertical(lipgloss.Left, topLine, box) } + +func RenderPlain(border lipgloss.Style, title, content string, width, height int) string { + if titleW := lipgloss.Width(title); titleW > width { + title = ansi.Truncate(title, width, "") + } + titleLine := lipgloss.NewStyle(). + Bold(true). + Foreground(border.GetBorderTopForeground()). + Width(width). + Render(title) + + contentH := max(height-1, 0) + lines := strings.Split(content, "\n") + if len(lines) > contentH { + content = strings.Join(lines[:contentH], "\n") + } + box := lipgloss.NewStyle().Width(width).Height(contentH).Render(content) + + return lipgloss.JoinVertical(lipgloss.Left, titleLine, box) +} + +func VerticalDivider(border lipgloss.Style, height int) string { + b, _, _, _, _ := border.GetBorder() + ch := b.Left + if ch == "" { + ch = "│" + } + line := lipgloss.NewStyle().Foreground(border.GetBorderLeftForeground()).Render(ch) + rows := make([]string, max(height, 0)) + for i := range rows { + rows[i] = line + } + return strings.Join(rows, "\n") +} diff --git a/style/config.go b/style/config.go index 0f8cd20..23a5313 100644 --- a/style/config.go +++ b/style/config.go @@ -20,9 +20,10 @@ type colorsYAML struct { } type configYAML struct { - Colors colorsYAML `yaml:"colors"` - NerdFonts bool `yaml:"nerd_fonts"` - Border string `yaml:"border"` + Colors colorsYAML `yaml:"colors"` + NerdFonts bool `yaml:"nerd_fonts"` + Border string `yaml:"border"` + LayoutBorder string `yaml:"layout_border"` } func pickString(base, user string) string { @@ -36,8 +37,9 @@ func mergeConfig(base, user configYAML) configYAML { return configYAML{ Colors: mergeColors(base.Colors, user.Colors), - NerdFonts: base.NerdFonts || user.NerdFonts, - Border: pickString(base.Border, user.Border), + NerdFonts: base.NerdFonts || user.NerdFonts, + Border: pickString(base.Border, user.Border), + LayoutBorder: pickString(base.LayoutBorder, user.LayoutBorder), } } diff --git a/style/default.yaml b/style/default.yaml index cbfa8ea..55a98f9 100644 --- a/style/default.yaml +++ b/style/default.yaml @@ -9,6 +9,12 @@ nerd_fonts: false # One of: rounded, normal, thick, double, hidden, ascii. border: rounded +# How sidebar+content layouts draw their borders. One of: +# full: both the sidebar and content panes get a full titled border. +# sidebar: only the sidebar gets a full border +# separator: neither pane is bordered; a single vertical line divides them. +layout_border: full + colors: base00: "#110F12" # Background base01: "#1C1920" # Lighter Background / Status Bars diff --git a/style/style.go b/style/style.go index 59644fa..a937218 100644 --- a/style/style.go +++ b/style/style.go @@ -39,8 +39,9 @@ type Styles struct { Bold lipgloss.Style Faint lipgloss.Style - NerdFonts bool - BorderType lipgloss.Border + NerdFonts bool + BorderType lipgloss.Border + LayoutBorder LayoutBorderMode Panel lipgloss.Style PanelFocused lipgloss.Style @@ -49,7 +50,7 @@ type Styles struct { PagerDotInactive string } -func newStyles(c colorsYAML, nerdFonts bool, borderName string) Styles { +func newStyles(c colorsYAML, nerdFonts bool, borderName, layoutBorderName string) Styles { lc := func(s string) color.Color { s = strings.TrimSpace(s) if s != "" && s[0] != '#' { @@ -76,6 +77,7 @@ func newStyles(c colorsYAML, nerdFonts bool, borderName string) Styles { b0F := lc(c.Base0F) borderType := resolveBorderType(borderName) + layoutBorder := resolveLayoutBorder(layoutBorderName) return Styles{ Base00: b00, Base01: b01, Base02: b02, Base03: b03, @@ -97,8 +99,9 @@ func newStyles(c colorsYAML, nerdFonts bool, borderName string) Styles { Bold: lipgloss.NewStyle().Bold(true), Faint: lipgloss.NewStyle().Foreground(b03).Faint(true), - NerdFonts: nerdFonts, - BorderType: borderType, + NerdFonts: nerdFonts, + BorderType: borderType, + LayoutBorder: layoutBorder, Panel: lipgloss.NewStyle(). Border(borderType). diff --git a/style/theme.go b/style/theme.go index 61851a5..8bfd41f 100644 --- a/style/theme.go +++ b/style/theme.go @@ -72,7 +72,7 @@ func stylesFromBytes(data []byte) (Styles, error) { return Styles{}, fmt.Errorf("style: parse config: %w", err) } merged := mergeConfig(base, user) - return newStyles(merged.Colors, merged.NerdFonts, merged.Border), nil + return newStyles(merged.Colors, merged.NerdFonts, merged.Border, merged.LayoutBorder), nil } func configDir() string {