prime8dev

prime8dev
git clone https://git.prime8.dev/prime8dev.git
Log | Files | Refs | README | LICENSE

helpers.go (3864B)


      1 package tui
      2 
      3 import (
      4 	"strings"
      5 
      6 	"git.prime8.dev/moncheeta/prime8dev/internal/config"
      7 	"git.prime8.dev/moncheeta/prime8dev/internal/utils"
      8 	"github.com/charmbracelet/lipgloss"
      9 )
     10 
     11 func wrapIndex(v int, size int) int {
     12 	if size == 0 {
     13 		return 0
     14 	}
     15 	for v < 0 {
     16 		v += size
     17 	}
     18 	return v % size
     19 }
     20 
     21 func fitRunes(s string, width int) string {
     22 	if width <= 0 {
     23 		return ""
     24 	}
     25 
     26 	r := []rune(s)
     27 	if len(r) <= width {
     28 		return s
     29 	}
     30 
     31 	if width == 1 {
     32 		return "…"
     33 	}
     34 
     35 	return string(r[:width-1]) + "…"
     36 }
     37 
     38 func fitRunesLeading(s string, width int) string {
     39 	if width <= 0 {
     40 		return ""
     41 	}
     42 
     43 	r := []rune(s)
     44 	if len(r) <= width {
     45 		return s
     46 	}
     47 
     48 	if width <= 3 {
     49 		return strings.Repeat(".", width)
     50 	}
     51 
     52 	return "..." + string(r[len(r)-(width-3):])
     53 }
     54 
     55 func padRunesRight(s string, width int) string {
     56 	r := []rune(s)
     57 	if len(r) >= width {
     58 		return s
     59 	}
     60 	return s + strings.Repeat(" ", width-len(r))
     61 }
     62 
     63 func renderKeyValueFixed(key string, value string, keyWidth int, valueWidth int, keyStyle lipgloss.Style, valueStyle lipgloss.Style) string {
     64 	keyText := padRunesRight(fitRunes(key, keyWidth), keyWidth) + ":"
     65 	valueText := padRunesRight(fitRunesLeading(value, valueWidth), valueWidth)
     66 	return keyStyle.Render(keyText) + " " + valueStyle.Render(valueText)
     67 }
     68 
     69 func renderKeyValueLine(key string, value string, totalWidth int, keyStyle lipgloss.Style, valueStyle lipgloss.Style) string {
     70 	keyLabel := key + ":"
     71 	valueWidth := max(totalWidth-len([]rune(keyLabel))-1, 1)
     72 	return keyStyle.Render(keyLabel) + " " + valueStyle.Render(fitRunesLeading(value, valueWidth))
     73 }
     74 
     75 func clipLines(s string, width int, maxLines int) string {
     76 	if maxLines <= 0 || width <= 0 {
     77 		return ""
     78 	}
     79 	return lipgloss.NewStyle().MaxWidth(width).MaxHeight(maxLines).Render(s)
     80 }
     81 
     82 func renderPanelWithStyle(style lipgloss.Style, width int, totalHeight int, content string) string {
     83 	borderX := style.GetHorizontalBorderSize()
     84 	borderY := style.GetVerticalBorderSize()
     85 	paddingX := style.GetHorizontalPadding()
     86 	paddingY := style.GetVerticalPadding()
     87 
     88 	innerWidth := max(width-borderX-paddingX, 1)
     89 	innerHeight := max(totalHeight-borderY-paddingY, 1)
     90 	clipped := clipLines(content, innerWidth, innerHeight)
     91 	return style.
     92 		Width(max(width-borderX, 1)).
     93 		Height(max(totalHeight-borderY, 1)).
     94 		Render(clipped)
     95 }
     96 
     97 func panelStyleSharedRight(style lipgloss.Style) lipgloss.Style {
     98 	b := lipgloss.NormalBorder()
     99 	b.TopRight = "┬"
    100 	b.BottomRight = "┴"
    101 	return style.BorderStyle(b)
    102 }
    103 
    104 func panelStyleSharedLeft(style lipgloss.Style) lipgloss.Style {
    105 	b := lipgloss.NormalBorder()
    106 	b.TopLeft = "┬"
    107 	b.BottomLeft = "┴"
    108 	return style.BorderStyle(b)
    109 }
    110 
    111 func panelStyleSharedBottom(style lipgloss.Style) lipgloss.Style {
    112 	b := lipgloss.NormalBorder()
    113 	b.BottomLeft = "├"
    114 	b.BottomRight = "┤"
    115 	return style.BorderStyle(b)
    116 }
    117 
    118 func panelStyleSharedTop(style lipgloss.Style) lipgloss.Style {
    119 	b := lipgloss.NormalBorder()
    120 	b.TopLeft = "├"
    121 	b.TopRight = "┤"
    122 	return style.BorderStyle(b)
    123 }
    124 
    125 func panelStyleWithoutRight(style lipgloss.Style) lipgloss.Style {
    126 	return style.Border(lipgloss.NormalBorder(), true, false, true, true)
    127 }
    128 
    129 func panelStyleWithoutLeft(style lipgloss.Style) lipgloss.Style {
    130 	return style.Border(lipgloss.NormalBorder(), true, true, true, false)
    131 }
    132 
    133 func panelStyleWithoutBottom(style lipgloss.Style) lipgloss.Style {
    134 	return style.Border(lipgloss.NormalBorder(), true, true, false, true)
    135 }
    136 
    137 func panelStyleWithoutTop(style lipgloss.Style) lipgloss.Style {
    138 	return style.Border(lipgloss.NormalBorder(), false, true, true, true)
    139 }
    140 
    141 func utilsYearLabel(exp config.Experience) string {
    142 	if exp.Current {
    143 		return "now"
    144 	}
    145 	if exp.EndDate != nil {
    146 		return exp.EndDate.Format("2006")
    147 	}
    148 	return exp.StartDate.Format("2006")
    149 }
    150 
    151 func dateRangeLabel(exp config.Experience) string {
    152 	return utils.FormatMonthYear(exp.StartDate) + " -> " + utils.FormatEndDate(exp.EndDate, exp.Current)
    153 }