okami.mom/albedo

git clone https://git.nkp.pet/okami.mom/albedo

nekomimi.pettui: pointer app model, shared styles, reused glamour renderers, own transcript pane, reuse rows across older pages, gogc 500b9f48f

main
2.1 KiB88 linesraw
1package tui
2
3import (
4	"slices"
5	"strings"
6
7	"charm.land/lipgloss/v2"
8	"github.com/charmbracelet/x/ansi"
9)
10
11// Effort choices come from the active model, not the command catalog's examples.
12func (m *ChatModel) openEffortSelector(levels []string) {
13	m.effortOptions = slices.Clone(levels)
14	m.effortSelected = max(0, slices.Index(levels, m.Effort))
15	m.TextArea.Reset()
16	m.syncLayout()
17}
18
19func (m ChatModel) effortSelectorView() string {
20	if len(m.effortOptions) == 0 {
21		return ""
22	}
23	width := m.chatWidth()
24	selected := m.effortSelected
25	// Keep the selected tier visible when the terminal cannot fit every tier.
26	left, right := 0, len(m.effortOptions)
27	label := func(i int) string {
28		if i == selected {
29			return " [" + m.effortOptions[i] + "] "
30		}
31		return m.effortOptions[i]
32	}
33	plain := func() string {
34		parts := make([]string, 0, right-left)
35		for i := left; i < right; i++ {
36			parts = append(parts, label(i))
37		}
38		line := strings.Join(parts, " ─ ")
39		if left > 0 {
40			line = "‹ " + line
41		}
42		if right < len(m.effortOptions) {
43			line += " ›"
44		}
45		return line
46	}
47	for ansi.StringWidth(plain()) > width && right-left > 1 {
48		if selected-left > right-1-selected {
49			left++
50		} else {
51			right--
52		}
53	}
54	parts := make([]string, 0, right-left)
55	for i := left; i < right; i++ {
56		style := m.effortTierStyle(m.effortOptions[i])
57		if i == selected {
58			style = style.Inherit(DefaultStyles.Selected).Bold(true)
59		}
60		parts = append(parts, style.Render(label(i)))
61	}
62	decor := DefaultStyles.Decor.Render
63	prefix, suffix := "", ""
64	if left > 0 {
65		prefix = decor("‹ ")
66	}
67	if right < len(m.effortOptions) {
68		suffix = decor(" ›")
69	}
70	return ansi.Truncate(prefix+strings.Join(parts, decor(" ─ "))+suffix, width, "")
71}
72
73func (m ChatModel) effortTierStyle(level string) lipgloss.Style {
74	switch level {
75	case "low":
76		return DefaultStyles.EffortLow
77	case "medium":
78		return DefaultStyles.EffortMedium
79	case "high":
80		return DefaultStyles.EffortHigh
81	case "xhigh":
82		return DefaultStyles.EffortXHigh
83	case "max":
84		return DefaultStyles.EffortMax
85	default:
86		return DefaultStyles.Muted
87	}
88}