on main help sign in
chore: go mod vendor
commitc510f030bc35fef3052d19cb89c5c1695cee3886 authorAyman Bagabas <ayman.bagabas@gmail.com> dateThu 10 Jul 2025, 14:53 (1 year ago) parent27c27b9
7 files changed+105−127
vendor/github.com/charmbracelet/bubbletea/v2/tea.go+15−4 vendor/github.com/charmbracelet/lipgloss/v2/get.go+33 vendor/github.com/charmbracelet/lipgloss/v2/set.go+27 vendor/github.com/charmbracelet/lipgloss/v2/style.go+18−8 vendor/github.com/charmbracelet/lipgloss/v2/unset.go+7 vendor/github.com/charmbracelet/ultraviolet/screen/screen.go−109 vendor/modules.txt+5−6
vendor/github.com/charmbracelet/bubbletea/v2/tea.go+15−4
@@ -624,6 +624,10 @@ func (p *Program) eventLoop(model Model, cmds chan Cmd) (Model, error) {
624624 switch msg.Mode {
625625 case ansi.AltScreenSaveCursorMode:
626626 p.renderer.enterAltScreen()
627+ // Main and alternate screen have their own Kitty keyboard
628+ // stack. We need to request keyboard enhancements again
629+ // when entering/exiting the alternate screen.
630+ p.requestKeyboardEnhancements()
627631 case ansi.TextCursorEnableMode:
628632 p.renderer.showCursor()
629633 case ansi.GraphemeClusteringMode:
@@ -645,6 +649,10 @@ func (p *Program) eventLoop(model Model, cmds chan Cmd) (Model, error) {
645649 switch msg.Mode {
646650 case ansi.AltScreenSaveCursorMode:
647651 p.renderer.exitAltScreen()
652+ // Main and alternate screen have their own Kitty keyboard
653+ // stack. We need to request keyboard enhancements again
654+ // when entering/exiting the alternate screen.
655+ p.requestKeyboardEnhancements()
648656 case ansi.TextCursorEnableMode:
649657 p.renderer.hideCursor()
650658 default:
@@ -1410,13 +1418,16 @@ func (p *Program) stopRenderer(kill bool) {
14101418// requestKeyboardEnhancements tries to enable keyboard enhancements and read
14111419// the active keyboard enhancements from the terminal.
14121420func (p *Program) requestKeyboardEnhancements() {
1421+ // XXX: We write to the renderer directly so that we synchronize with the
1422+ // alt-screen state of the renderer. This is because the main screen and
1423+ // alternate screen have their own Kitty keyboard state stack.
14131424 if p.requestedEnhancements.modifyOtherKeys > 0 {
1414− p.execute(ansi.KeyModifierOptions(4, p.requestedEnhancements.modifyOtherKeys)) //nolint:mnd
1415− p.execute(ansi.QueryModifyOtherKeys)
1425+ _, _ = p.renderer.writeString(ansi.KeyModifierOptions(4, p.requestedEnhancements.modifyOtherKeys)) //nolint:mnd
1426+ _, _ = p.renderer.writeString(ansi.QueryModifyOtherKeys)
14161427 }
14171428 if p.requestedEnhancements.kittyFlags > 0 {
1418− p.execute(ansi.PushKittyKeyboard(p.requestedEnhancements.kittyFlags))
1419− p.execute(ansi.RequestKittyKeyboard)
1429+ _, _ = p.renderer.writeString(ansi.PushKittyKeyboard(p.requestedEnhancements.kittyFlags))
1430+ _, _ = p.renderer.writeString(ansi.RequestKittyKeyboard)
14201431 }
14211432}
14221433
vendor/github.com/charmbracelet/lipgloss/v2/get.go+33
@@ -135,6 +135,16 @@ func (s Style) GetPaddingLeft() int {
135135 return s.getAsInt(paddingLeftKey)
136136}
137137
138+// GetPaddingChar returns the style's padding character. If no value is set a
139+// space (`\u0020`) is returned.
140+func (s Style) GetPaddingChar() rune {
141+ char := s.getAsRune(paddingCharKey)
142+ if char == 0 {
143+ return ' '
144+ }
145+ return char
146+}
147+
138148// GetHorizontalPadding returns the style's left and right padding. Unset
139149// values are measured as 0.
140150func (s Style) GetHorizontalPadding() int {
@@ -186,6 +196,16 @@ func (s Style) GetMarginLeft() int {
186196 return s.getAsInt(marginLeftKey)
187197}
188198
199+// GetMarginChar returns the style's padding character. If no value is set a
200+// space (`\u0020`) is returned.
201+func (s Style) GetMarginChar() rune {
202+ char := s.getAsRune(marginCharKey)
203+ if char == 0 {
204+ return ' '
205+ }
206+ return char
207+}
208+
189209// GetHorizontalMargins returns the style's left and right margins. Unset
190210// values are measured as 0.
191211func (s Style) GetHorizontalMargins() int {
@@ -432,6 +452,19 @@ func (s Style) isSet(k propKey) bool {
432452 return s.props.has(k)
433453}
434454
455+func (s Style) getAsRune(k propKey) rune {
456+ if !s.isSet(k) {
457+ return 0
458+ }
459+ switch k { //nolint:exhaustive
460+ case paddingCharKey:
461+ return s.paddingChar
462+ case marginCharKey:
463+ return s.marginChar
464+ }
465+ return 0
466+}
467+
435468func (s Style) getAsBool(k propKey, defaultVal bool) bool {
436469 if !s.isSet(k) {
437470 return defaultVal
vendor/github.com/charmbracelet/lipgloss/v2/set.go+27
@@ -29,6 +29,8 @@ func (s *Style) set(key propKey, value any) {
2929 s.paddingBottom = max(0, value.(int))
3030 case paddingLeftKey:
3131 s.paddingLeft = max(0, value.(int))
32+ case paddingCharKey:
33+ s.paddingChar = value.(rune)
3234 case marginTopKey:
3335 s.marginTop = max(0, value.(int))
3436 case marginRightKey:
@@ -39,6 +41,8 @@ func (s *Style) set(key propKey, value any) {
3941 s.marginLeft = max(0, value.(int))
4042 case marginBackgroundKey:
4143 s.marginBgColor = colorOrNil(value)
44+ case marginCharKey:
45+ s.marginChar = value.(rune)
4246 case borderStyleKey:
4347 s.borderStyle = value.(Border)
4448 case borderTopForegroundKey:
@@ -111,6 +115,8 @@ func (s *Style) setFrom(key propKey, i Style) {
111115 s.set(paddingBottomKey, i.paddingBottom)
112116 case paddingLeftKey:
113117 s.set(paddingLeftKey, i.paddingLeft)
118+ case paddingCharKey:
119+ s.set(paddingCharKey, i.paddingChar)
114120 case marginTopKey:
115121 s.set(marginTopKey, i.marginTop)
116122 case marginRightKey:
@@ -121,6 +127,8 @@ func (s *Style) setFrom(key propKey, i Style) {
121127 s.set(marginLeftKey, i.marginLeft)
122128 case marginBackgroundKey:
123129 s.set(marginBackgroundKey, i.marginBgColor)
130+ case marginCharKey:
131+ s.set(marginCharKey, i.marginChar)
124132 case borderStyleKey:
125133 s.set(borderStyleKey, i.borderStyle)
126134 case borderTopForegroundKey:
@@ -320,6 +328,18 @@ func (s Style) PaddingBottom(i int) Style {
320328 return s
321329}
322330
331+// PaddingChar sets the character used for padding. This is useful for
332+// rendering blocks with a specific character, such as a space or a dot.
333+// Example of using [NBSP] as padding to prevent line breaks:
334+//
335+// ```go
336+// s := lipgloss.NewStyle().PaddingChar(lipgloss.NBSP)
337+// ```
338+func (s Style) PaddingChar(r rune) Style {
339+ s.set(paddingCharKey, r)
340+ return s
341+}
342+
323343// ColorWhitespace determines whether or not the background color should be
324344// applied to the padding. This is true by default as it's more than likely the
325345// desired and expected behavior, but it can be disabled for certain graphic
@@ -390,6 +410,13 @@ func (s Style) MarginBackground(c color.Color) Style {
390410 return s
391411}
392412
413+// MarginChar sets the character used for the margin. This is useful for
414+// rendering blocks with a specific character, such as a space or a dot.
415+func (s Style) MarginChar(r rune) Style {
416+ s.set(marginCharKey, r)
417+ return s
418+}
419+
393420// Border is shorthand for setting the border style and which sides should
394421// have a border at once. The variadic argument sides works as follows:
395422//
vendor/github.com/charmbracelet/lipgloss/v2/style.go+18−8
@@ -10,7 +10,8 @@ import (
1010)
1111
1212const (
13− nbsp = '\u00A0'
13+ // NBSP is the non-breaking space rune.
14+ NBSP = '\u00A0'
1415 tabWidthDefault = 4
1516)
1617
@@ -44,6 +45,7 @@ const (
4445 paddingRightKey
4546 paddingBottomKey
4647 paddingLeftKey
48+ paddingCharKey
4749
4850 // Margins.
4951 marginTopKey
@@ -51,6 +53,7 @@ const (
5153 marginBottomKey
5254 marginLeftKey
5355 marginBackgroundKey
56+ marginCharKey
5457
5558 // Border runes.
5659 borderStyleKey
@@ -128,12 +131,14 @@ type Style struct {
128131 paddingRight int
129132 paddingBottom int
130133 paddingLeft int
134+ paddingChar rune
131135
132136 marginTop int
133137 marginRight int
134138 marginBottom int
135139 marginLeft int
136140 marginBgColor color.Color
141+ marginChar rune
137142
138143 borderStyle Border
139144 borderTopFgColor color.Color
@@ -387,23 +392,24 @@ func (s Style) Render(strs ...string) string {
387392
388393 // Padding
389394 if !inline { //nolint:nestif
395+ padChar := s.paddingChar
396+ if padChar == 0 {
397+ padChar = ' '
398+ }
390399 if leftPadding > 0 {
391400 var st *ansi.Style
392401 if colorWhitespace || styleWhitespace {
393402 st = &teWhitespace
394403 }
395− str = padLeft(str, leftPadding, st, nbsp)
404+ str = padLeft(str, leftPadding, st, padChar)
396405 }
397406
398− // XXX: We use a non-breaking space to pad so that the padding is
399− // preserved when the string is copied and pasted.
400−
401407 if rightPadding > 0 {
402408 var st *ansi.Style
403409 if colorWhitespace || styleWhitespace {
404410 st = &teWhitespace
405411 }
406− str = padRight(str, rightPadding, st, nbsp)
412+ str = padRight(str, rightPadding, st, padChar)
407413 }
408414
409415 if topPadding > 0 {
@@ -494,8 +500,12 @@ func (s Style) applyMargins(str string, inline bool) string {
494500 }
495501
496502 // Add left and right margin
497− str = padLeft(str, leftMargin, &style, ' ')
498− str = padRight(str, rightMargin, &style, ' ')
503+ marginChar := s.marginChar
504+ if marginChar == 0 {
505+ marginChar = ' '
506+ }
507+ str = padLeft(str, leftMargin, &style, marginChar)
508+ str = padRight(str, rightMargin, &style, marginChar)
499509
500510 // Top/bottom margin
501511 if !inline {
vendor/github.com/charmbracelet/lipgloss/v2/unset.go+7
@@ -96,6 +96,13 @@ func (s Style) UnsetPadding() Style {
9696 s.unset(paddingRightKey)
9797 s.unset(paddingTopKey)
9898 s.unset(paddingBottomKey)
99+ s.unset(paddingCharKey)
100+ return s
101+}
102+
103+// UnsetPaddingChar removes the padding character style rule, if set.
104+func (s Style) UnsetPaddingChar() Style {
105+ s.unset(paddingCharKey)
99106 return s
100107}
101108
vendor/github.com/charmbracelet/ultraviolet/screen/screen.godeleted−109
@@ -1,109 +0,0 @@
1−// Package screen provides functions and helpers to manipulate a [uv.Screen].
2−package screen
3−
4−import uv "github.com/charmbracelet/ultraviolet"
5−
6−// Clear clears the screen with empty cells. This is equivalent to filling the
7−// screen with empty cells.
8−//
9−// If the screen implements a [Clear] method, it will be called instead of
10−// filling the screen with empty cells.
11−func Clear(scr uv.Screen) {
12− if c, ok := scr.(interface {
13− Clear()
14− }); ok {
15− c.Clear()
16− return
17− }
18− Fill(scr, nil)
19−}
20−
21−// ClearArea clears the given area of the screen with empty cells. This is
22−// equivalent to filling the area with empty cells.
23−//
24−// If the screen implements a [ClearArea] method, it will be called instead of
25−// filling the area with empty cells.
26−func ClearArea(scr uv.Screen, area uv.Rectangle) {
27− if c, ok := scr.(interface {
28− ClearArea(area uv.Rectangle)
29− }); ok {
30− c.ClearArea(area)
31− return
32− }
33− FillArea(scr, nil, area)
34−}
35−
36−// Fill fills the screen with the given cell. If the cell is nil, it fills the
37−// screen with empty cells.
38−//
39−// If the screen implements a [Fill] method, it will be called instead of
40−// filling the screen with empty cells.
41−func Fill(scr uv.Screen, cell *uv.Cell) {
42− if f, ok := scr.(interface {
43− Fill(cell *uv.Cell)
44− }); ok {
45− f.Fill(cell)
46− return
47− }
48− FillArea(scr, cell, scr.Bounds())
49−}
50−
51−// FillArea fills the given area of the screen with the given cell. If the cell
52−// is nil, it fills the area with empty cells.
53−//
54−// If the screen implements a [FillArea] method, it will be called instead of
55−// filling the area with empty cells.
56−func FillArea(scr uv.Screen, cell *uv.Cell, area uv.Rectangle) {
57− if f, ok := scr.(interface {
58− FillArea(cell *uv.Cell, area uv.Rectangle)
59− }); ok {
60− f.FillArea(cell, area)
61− return
62− }
63− for y := area.Min.Y; y < area.Max.Y; y++ {
64− for x := area.Min.X; x < area.Max.X; x++ {
65− scr.SetCell(x, y, cell)
66− }
67− }
68−}
69−
70−// CloneArea clones the given area of the screen and returns a new buffer
71−// with the same size as the area. The new buffer will contain the same cells
72−// as the area in the screen.
73−// Use [uv.Buffer.Draw] to draw the cloned buffer to a screen again.
74−//
75−// If the screen implements a [CloneArea] method, it will be called instead of
76−// cloning the area manually.
77−func CloneArea(scr uv.Screen, area uv.Rectangle) *uv.Buffer {
78− if c, ok := scr.(interface {
79− CloneArea(area uv.Rectangle) *uv.Buffer
80− }); ok {
81− return c.CloneArea(area)
82− }
83− buf := uv.NewBuffer(area.Dx(), area.Dy())
84− for y := area.Min.Y; y < area.Max.Y; y++ {
85− for x := area.Min.X; x < area.Max.X; x++ {
86− cell := scr.CellAt(x, y)
87− if cell == nil || cell.IsZero() {
88− continue
89− }
90− buf.SetCell(x-area.Min.X, y-area.Min.Y, cell.Clone())
91− }
92− }
93− return buf
94−}
95−
96−// Clone creates a new [uv.Buffer] clone of the given screen. The new buffer will
97−// have the same size as the screen and will contain the same cells.
98−// Use [uv.Buffer.Draw] to draw the cloned buffer to a screen again.
99−//
100−// If the screen implements a [Clone] method, it will be called instead of
101−// cloning the entire screen manually.
102−func Clone(scr uv.Screen) *uv.Buffer {
103− if c, ok := scr.(interface {
104− Clone() *uv.Buffer
105− }); ok {
106− return c.Clone()
107− }
108− return CloneArea(scr, scr.Bounds())
109−}
vendor/modules.txt+5−6
@@ -254,8 +254,8 @@ github.com/charmbracelet/bubbles/v2/spinner
254254github.com/charmbracelet/bubbles/v2/textarea
255255github.com/charmbracelet/bubbles/v2/textinput
256256github.com/charmbracelet/bubbles/v2/viewport
257−# github.com/charmbracelet/bubbletea/v2 v2.0.0-beta.1 => github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250708152737-144080f3d891
258−## explicit; go 1.24.3
257+# github.com/charmbracelet/bubbletea/v2 v2.0.0-beta.1 => github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250710185017-3c0ffd25e595
258+## explicit; go 1.24.0
259259github.com/charmbracelet/bubbletea/v2
260260# github.com/charmbracelet/colorprofile v0.3.1
261261## explicit; go 1.23.0
@@ -269,7 +269,7 @@ github.com/charmbracelet/glamour/v2
269269github.com/charmbracelet/glamour/v2/ansi
270270github.com/charmbracelet/glamour/v2/internal/autolink
271271github.com/charmbracelet/glamour/v2/styles
272−# github.com/charmbracelet/lipgloss/v2 v2.0.0-beta.2.0.20250703152125-8e1c474f8a71 => github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250708152830-0fa4ef151093
272+# github.com/charmbracelet/lipgloss/v2 v2.0.0-beta.2.0.20250703152125-8e1c474f8a71 => github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250710185058-03664cb9cecb
273273## explicit; go 1.24.2
274274github.com/charmbracelet/lipgloss/v2
275275github.com/charmbracelet/lipgloss/v2/table
@@ -280,7 +280,6 @@ github.com/charmbracelet/log/v2
280280# github.com/charmbracelet/ultraviolet v0.0.0-20250708152637-0fe0235c8db9
281281## explicit; go 1.24.0
282282github.com/charmbracelet/ultraviolet
283−github.com/charmbracelet/ultraviolet/screen
284283# github.com/charmbracelet/x/ansi v0.9.3
285284## explicit; go 1.23.0
286285github.com/charmbracelet/x/ansi
@@ -839,5 +838,5 @@ mvdan.cc/sh/v3/fileutil
839838mvdan.cc/sh/v3/interp
840839mvdan.cc/sh/v3/pattern
841840mvdan.cc/sh/v3/syntax
842−# github.com/charmbracelet/bubbletea/v2 => github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250708152737-144080f3d891
843−# github.com/charmbracelet/lipgloss/v2 => github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250708152830-0fa4ef151093
841+# github.com/charmbracelet/bubbletea/v2 => github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250710185017-3c0ffd25e595
842+# github.com/charmbracelet/lipgloss/v2 => github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250710185058-03664cb9cecb