11package lipgloss
22
33import (
4+ "fmt"
45 "strings"
56
67 "github.com/charmbracelet/x/ansi"
@@ -229,6 +230,7 @@ func HiddenBorder() Border {
229230func (s Style ) applyBorder (str string ) string {
230231 var (
231232 border = s .getBorderStyle ()
233+ title = s .borderTitle
232234 hasTop = s .getAsBool (borderTopKey , false )
233235 hasRight = s .getAsBool (borderRightKey , false )
234236 hasBottom = s .getAsBool (borderBottomKey , false )
@@ -322,7 +324,7 @@ func (s Style) applyBorder(str string) string {
322324
323325 // Render top
324326 if hasTop {
325- top := renderHorizontalEdge (border .TopLeft , border .Top , border .TopRight , width )
327+ top := renderHorizontalEdge (border .TopLeft , border .Top , border .TopRight , title , width )
326328 top = s .styleBorder (top , topFG , topBG )
327329 out .WriteString (top )
328330 out .WriteRune ('\n' )
@@ -360,7 +362,7 @@ func (s Style) applyBorder(str string) string {
360362
361363 // Render bottom
362364 if hasBottom {
363- bottom := renderHorizontalEdge (border .BottomLeft , border .Bottom , border .BottomRight , width )
365+ bottom := renderHorizontalEdge (border .BottomLeft , border .Bottom , border .BottomRight , "" , width )
364366 bottom = s .styleBorder (bottom , bottomFG , bottomBG )
365367 out .WriteRune ('\n' )
366368 out .WriteString (bottom )
@@ -370,27 +372,39 @@ func (s Style) applyBorder(str string) string {
370372}
371373
372374// Render the horizontal (top or bottom) portion of a border.
373- func renderHorizontalEdge (left , middle , right string , width int ) string {
375+ func renderHorizontalEdge (left , middle , right , title string , width int ) string {
374376 if middle == "" {
375377 middle = " "
376378 }
377379
378- leftWidth := ansi .StringWidth (left )
379- rightWidth := ansi .StringWidth (right )
380+ var (
381+ leftWidth = ansi .StringWidth (left )
382+ midWidth = ansi .StringWidth (middle )
383+ runes = []rune (middle )
384+ j = 0
385+ )
380386
381- runes := []rune (middle )
382- j := 0
387+ absWidth := width - leftWidth
383388
384389 out := strings.Builder {}
385390 out .WriteString (left )
386- for i := leftWidth + rightWidth ; i < width + rightWidth ; {
391+
392+ // If there is enough space to print the middle segment a space, the title, a space and middle segment
393+ // Print that and remove it from the absolute length of the border.
394+ if titleLen := ansi .StringWidth (title ) + 2 + 2 * midWidth ; title != "" && titleLen < absWidth {
395+ out .WriteString (fmt .Sprintf ("%s %s %s" , middle , title , middle ))
396+ absWidth -= titleLen
397+ }
398+
399+ for i := 0 ; i < absWidth ; {
387400 out .WriteRune (runes [j ])
388401 j ++
389402 if j >= len (runes ) {
390403 j = 0
391404 }
392405 i += ansi .StringWidth (string (runes [j ]))
393406 }
407+
394408 out .WriteString (right )
395409
396410 return out .String ()
0 commit comments