main
6d86999 ยท 6 months ago 26 commits
 1package app
 2
 3import (
 4	"strings"
 5
 6	"github.com/charmbracelet/lipgloss"
 7	"github.com/muesli/reflow/truncate"
 8)
 9
10func PlaceOverlay(x, y int, fg, bg string) string {
11	fgLines := strings.Split(fg, "\n")
12	bgLines := strings.Split(bg, "\n")
13	result := make([]string, len(bgLines))
14	copy(result, bgLines)
15
16	for i, fgLine := range fgLines {
17		bgY := y + i
18		if bgY < 0 || bgY >= len(bgLines) {
19			continue
20		}
21
22		fgW := uint(lipgloss.Width(fgLine))
23		bgLine := bgLines[bgY]
24		bgW := uint(lipgloss.Width(bgLine))
25
26		if uint(x) >= bgW {
27			continue
28		}
29
30		left := truncate.String(bgLine, uint(x))
31		right := ""
32		if end := uint(x) + fgW; end < bgW {
33			right = rightSlice(bgLine, int(end))
34		}
35
36		result[bgY] = left + fgLine + right
37	}
38
39	return strings.Join(result, "\n")
40}
41
42func rightSlice(s string, fromVisible int) string {
43	visible := 0
44	inEsc := false
45	runes := []rune(s)
46	for i, r := range runes {
47		if r == '\x1b' {
48			inEsc = true
49		}
50		if inEsc {
51			if r == 'm' {
52				inEsc = false
53			}
54			continue
55		}
56		if visible == fromVisible {
57			return string(runes[i:])
58		}
59		visible++
60	}
61	return ""
62}
63