From bf0f9285a86ce6754e370267eb917876a9af5919 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 12:32:59 +0000 Subject: [PATCH] Bump github.com/charmbracelet/bubbletea from 1.1.2 to 1.2.1 Bumps [github.com/charmbracelet/bubbletea](https://github.com/charmbracelet/bubbletea) from 1.1.2 to 1.2.1. - [Release notes](https://github.com/charmbracelet/bubbletea/releases) - [Changelog](https://github.com/charmbracelet/bubbletea/blob/main/.goreleaser.yml) - [Commits](https://github.com/charmbracelet/bubbletea/compare/v1.1.2...v1.2.1) --- updated-dependencies: - dependency-name: github.com/charmbracelet/bubbletea dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 6 +- go.sum | 12 +- .../bubbletea/.golangci-soft.yml | 40 +++++ .../bubbletea/standard_renderer.go | 139 +++++++++--------- .../charmbracelet/lipgloss/.golangci-soft.yml | 8 +- .../charmbracelet/lipgloss/.golangci.yml | 2 - .../charmbracelet/lipgloss/README.md | 114 +++++++------- .../charmbracelet/lipgloss/style.go | 6 +- .../github.com/charmbracelet/x/ansi/cursor.go | 24 +++ .../charmbracelet/x/ansi/notification.go | 13 ++ .../charmbracelet/x/ansi/parser_decode.go | 53 +++++-- .../github.com/charmbracelet/x/ansi/wrap.go | 4 +- vendor/modules.txt | 6 +- 13 files changed, 267 insertions(+), 160 deletions(-) create mode 100644 vendor/github.com/charmbracelet/bubbletea/.golangci-soft.yml create mode 100644 vendor/github.com/charmbracelet/x/ansi/notification.go diff --git a/go.mod b/go.mod index 5824a33..9907a34 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.22.0 require ( github.com/atotto/clipboard v0.1.4 - github.com/charmbracelet/bubbletea v1.1.2 + github.com/charmbracelet/bubbletea v1.2.1 github.com/spf13/cobra v1.8.1 github.com/tobischo/gokeepasslib/v3 v3.6.0 golang.org/x/term v0.25.0 @@ -12,8 +12,8 @@ require ( require ( github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect - github.com/charmbracelet/lipgloss v0.13.0 // indirect - github.com/charmbracelet/x/ansi v0.4.0 // indirect + github.com/charmbracelet/lipgloss v1.0.0 // indirect + github.com/charmbracelet/x/ansi v0.4.5 // indirect github.com/charmbracelet/x/term v0.2.0 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect diff --git a/go.sum b/go.sum index 60b17d4..8d37b2f 100644 --- a/go.sum +++ b/go.sum @@ -2,12 +2,12 @@ github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= -github.com/charmbracelet/bubbletea v1.1.2 h1:naQXF2laRxyLyil/i7fxdpiz1/k06IKquhm4vBfHsIc= -github.com/charmbracelet/bubbletea v1.1.2/go.mod h1:9HIU/hBV24qKjlehyj8z1r/tR9TYTQEag+cWZnuXo8E= -github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw= -github.com/charmbracelet/lipgloss v0.13.0/go.mod h1:nw4zy0SBX/F/eAO1cWdcvy6qnkDUxr8Lw7dvFrAIbbY= -github.com/charmbracelet/x/ansi v0.4.0 h1:NqwHA4B23VwsDn4H3VcNX1W1tOmgnvY1NDx5tOXdnOU= -github.com/charmbracelet/x/ansi v0.4.0/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= +github.com/charmbracelet/bubbletea v1.2.1 h1:J041h57zculJKEKf/O2pS4edXGIz+V0YvojvfGXePIk= +github.com/charmbracelet/bubbletea v1.2.1/go.mod h1:viLoDL7hG4njLJSKU2gw7kB3LSEmWsrM80rO1dBJWBI= +github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg= +github.com/charmbracelet/lipgloss v1.0.0/go.mod h1:U5fy9Z+C38obMs+T+tJqst9VGzlOYGj4ri9reL3qUlo= +github.com/charmbracelet/x/ansi v0.4.5 h1:LqK4vwBNaXw2AyGIICa5/29Sbdq58GbGdFngSexTdRM= +github.com/charmbracelet/x/ansi v0.4.5/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0= github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= diff --git a/vendor/github.com/charmbracelet/bubbletea/.golangci-soft.yml b/vendor/github.com/charmbracelet/bubbletea/.golangci-soft.yml new file mode 100644 index 0000000..d325d4f --- /dev/null +++ b/vendor/github.com/charmbracelet/bubbletea/.golangci-soft.yml @@ -0,0 +1,40 @@ +run: + tests: false + issues-exit-code: 0 + +issues: + include: + - EXC0001 + - EXC0005 + - EXC0011 + - EXC0012 + - EXC0013 + + max-issues-per-linter: 0 + max-same-issues: 0 + +linters: + enable: + - exhaustive + - goconst + - godot + - godox + - mnd + - gomoddirectives + - goprintffuncname + - misspell + - nakedret + - nestif + - noctx + - nolintlint + - prealloc + - wrapcheck + + # disable default linters, they are already enabled in .golangci.yml + disable: + - errcheck + - gosimple + - govet + - ineffassign + - staticcheck + - unused diff --git a/vendor/github.com/charmbracelet/bubbletea/standard_renderer.go b/vendor/github.com/charmbracelet/bubbletea/standard_renderer.go index 0cb0ef3..2585bcc 100644 --- a/vendor/github.com/charmbracelet/bubbletea/standard_renderer.go +++ b/vendor/github.com/charmbracelet/bubbletea/standard_renderer.go @@ -161,14 +161,20 @@ func (r *standardRenderer) flush() { defer r.mtx.Unlock() if r.buf.Len() == 0 || r.buf.String() == r.lastRender { - // Nothing to do + // Nothing to do. return } - // Output buffer + // Output buffer. buf := &bytes.Buffer{} + // Moving to the beginning of the section, that we rendered. + if r.linesRendered > 1 { + buf.WriteString(ansi.CursorUp(r.linesRendered - 1)) + } + newLines := strings.Split(r.buf.String(), "\n") + oldLines := strings.Split(r.lastRender, "\n") // If we know the output's height, we can use it to determine how many // lines we can render. We drop lines from the top of the render buffer if @@ -179,95 +185,82 @@ func (r *standardRenderer) flush() { } numLinesThisFlush := len(newLines) - oldLines := strings.Split(r.lastRender, "\n") - skipLines := make(map[int]struct{}) flushQueuedMessages := len(r.queuedMessageLines) > 0 && !r.altScreenActive - // Clear any lines we painted in the last render. - if r.linesRendered > 0 { - for i := r.linesRendered - 1; i > 0; i-- { - // if we are clearing queued messages, we want to clear all lines, since - // printing messages allows for native terminal word-wrap, we - // don't have control over the queued lines - if flushQueuedMessages { - buf.WriteString(ansi.EraseEntireLine) - } else if (len(newLines) <= len(oldLines)) && (len(newLines) > i && len(oldLines) > i) && (newLines[i] == oldLines[i]) { - // If the number of lines we want to render hasn't increased and - // new line is the same as the old line we can skip rendering for - // this line as a performance optimization. - skipLines[i] = struct{}{} - } else if _, exists := r.ignoreLines[i]; !exists { - buf.WriteString(ansi.EraseEntireLine) - } - - buf.WriteString(ansi.CursorUp1) - } - - if _, exists := r.ignoreLines[0]; !exists { - // We need to return to the start of the line here to properly - // erase it. Going back the entire width of the terminal will - // usually be farther than we need to go, but terminal emulators - // will stop the cursor at the start of the line as a rule. - // - // We use this sequence in particular because it's part of the ANSI - // standard (whereas others are proprietary to, say, VT100/VT52). - // If cursor previous line (ESC[ + + F) were better supported - // we could use that above to eliminate this step. - buf.WriteString(ansi.CursorLeft(r.width)) - buf.WriteString(ansi.EraseEntireLine) - } - } - - // Merge the set of lines we're skipping as a rendering optimization with - // the set of lines we've explicitly asked the renderer to ignore. - for k, v := range r.ignoreLines { - skipLines[k] = v - } - if flushQueuedMessages { - // Dump the lines we've queued up for printing + // Dump the lines we've queued up for printing. for _, line := range r.queuedMessageLines { + if ansi.StringWidth(line) < r.width { + // We only erase the rest of the line when the line is shorter than + // the width of the terminal. When the cursor reaches the end of + // the line, any escape sequences that follow will only affect the + // last cell of the line. + + // Removing previously rendered content at the end of line. + line = line + ansi.EraseLineRight + } + _, _ = buf.WriteString(line) _, _ = buf.WriteString("\r\n") } - // clear the queued message lines + // Clear the queued message lines. r.queuedMessageLines = []string{} } - // Paint new lines + // Paint new lines. for i := 0; i < len(newLines); i++ { - if _, skip := skipLines[i]; skip { + canSkip := !flushQueuedMessages && // Queuing messages triggers repaint -> we don't have access to previous frame content. + len(oldLines) > i && oldLines[i] == newLines[i] // Previously rendered line is the same. + + if _, ignore := r.ignoreLines[i]; ignore || canSkip { // Unless this is the last line, move the cursor down. if i < len(newLines)-1 { buf.WriteString(ansi.CursorDown1) } - } else { - if i == 0 && r.lastRender == "" { - // On first render, reset the cursor to the start of the line - // before writing anything. - buf.WriteByte('\r') - } + continue + } - line := newLines[i] - - // Truncate lines wider than the width of the window to avoid - // wrapping, which will mess up rendering. If we don't have the - // width of the window this will be ignored. - // - // Note that on Windows we only get the width of the window on - // program initialization, so after a resize this won't perform - // correctly (signal SIGWINCH is not supported on Windows). - if r.width > 0 { - line = ansi.Truncate(line, r.width, "") - } + if i == 0 && r.lastRender == "" { + // On first render, reset the cursor to the start of the line + // before writing anything. + buf.WriteByte('\r') + } - _, _ = buf.WriteString(line) + line := newLines[i] + + // Truncate lines wider than the width of the window to avoid + // wrapping, which will mess up rendering. If we don't have the + // width of the window this will be ignored. + // + // Note that on Windows we only get the width of the window on + // program initialization, so after a resize this won't perform + // correctly (signal SIGWINCH is not supported on Windows). + if r.width > 0 { + line = ansi.Truncate(line, r.width, "") + } - if i < len(newLines)-1 { - _, _ = buf.WriteString("\r\n") - } + if ansi.StringWidth(line) < r.width { + // We only erase the rest of the line when the line is shorter than + // the width of the terminal. When the cursor reaches the end of + // the line, any escape sequences that follow will only affect the + // last cell of the line. + + // Removing previously rendered content at the end of line. + line = line + ansi.EraseLineRight } + + _, _ = buf.WriteString(line) + + if i < len(newLines)-1 { + _, _ = buf.WriteString("\r\n") + } + } + + // Clearing left over content from last render. + if r.linesRendered > numLinesThisFlush { + buf.WriteString(ansi.EraseScreenBelow) } + r.linesRendered = numLinesThisFlush // Make sure the cursor is at the start of the last line to keep rendering @@ -313,7 +306,7 @@ func (r *standardRenderer) clearScreen() { defer r.mtx.Unlock() r.execute(ansi.EraseEntireScreen) - r.execute(ansi.CursorOrigin) + r.execute(ansi.HomeCursorPosition) r.repaint() } @@ -343,7 +336,7 @@ func (r *standardRenderer) enterAltScreen() { // Note: we can't use r.clearScreen() here because the mutex is already // locked. r.execute(ansi.EraseEntireScreen) - r.execute(ansi.CursorOrigin) + r.execute(ansi.HomeCursorPosition) // cmd.exe and other terminals keep separate cursor states for the AltScreen // and the main buffer. We have to explicitly reset the cursor visibility diff --git a/vendor/github.com/charmbracelet/lipgloss/.golangci-soft.yml b/vendor/github.com/charmbracelet/lipgloss/.golangci-soft.yml index 1b6824b..8783713 100644 --- a/vendor/github.com/charmbracelet/lipgloss/.golangci-soft.yml +++ b/vendor/github.com/charmbracelet/lipgloss/.golangci-soft.yml @@ -14,16 +14,13 @@ issues: linters: enable: - # - dupl - exhaustive - # - exhaustivestruct - goconst - godot - godox - - gomnd + - mnd - gomoddirectives - goprintffuncname - # - lll - misspell - nakedret - nestif @@ -34,13 +31,10 @@ linters: # disable default linters, they are already enabled in .golangci.yml disable: - - deadcode - errcheck - gosimple - govet - ineffassign - staticcheck - - structcheck - typecheck - unused - - varcheck diff --git a/vendor/github.com/charmbracelet/lipgloss/.golangci.yml b/vendor/github.com/charmbracelet/lipgloss/.golangci.yml index 3affce9..d6789e0 100644 --- a/vendor/github.com/charmbracelet/lipgloss/.golangci.yml +++ b/vendor/github.com/charmbracelet/lipgloss/.golangci.yml @@ -15,12 +15,10 @@ issues: linters: enable: - bodyclose - - exportloopref - gofumpt - goimports - gosec - nilerr - - predeclared - revive - rowserrcheck - sqlclosecheck diff --git a/vendor/github.com/charmbracelet/lipgloss/README.md b/vendor/github.com/charmbracelet/lipgloss/README.md index 42661d6..f171e7d 100644 --- a/vendor/github.com/charmbracelet/lipgloss/README.md +++ b/vendor/github.com/charmbracelet/lipgloss/README.md @@ -10,7 +10,7 @@ Style definitions for nice terminal layouts. Built with TUIs in mind. -![Lip Gloss example](https://stuff.charm.sh/lipgloss/lipgloss-example.png) +![Lip Gloss example](https://github.com/user-attachments/assets/99c5c015-551b-4897-8cd1-bcaafa0aad5a) Lip Gloss takes an expressive, declarative approach to terminal rendering. Users familiar with CSS will feel at home with Lip Gloss. @@ -402,7 +402,7 @@ block := lipgloss.Place(30, 80, lipgloss.Right, lipgloss.Bottom, fancyStyledPara You can also style the whitespace. For details, see [the docs][docs]. -### Rendering Tables +## Rendering Tables Lip Gloss ships with a table rendering sub-package. @@ -483,15 +483,15 @@ Lists have the ability to nest. ```go l := list.New( - "A", list.New("Artichoke"), - "B", list.New("Baking Flour", "Bananas", "Barley", "Bean Sprouts"), - "C", list.New("Cashew Apple", "Cashews", "Coconut Milk", "Curry Paste", "Currywurst"), - "D", list.New("Dill", "Dragonfruit", "Dried Shrimp"), - "E", list.New("Eggs"), - "F", list.New("Fish Cake", "Furikake"), - "J", list.New("Jicama"), - "K", list.New("Kohlrabi"), - "L", list.New("Leeks", "Lentils", "Licorice Root"), + "A", list.New("Artichoke"), + "B", list.New("Baking Flour", "Bananas", "Barley", "Bean Sprouts"), + "C", list.New("Cashew Apple", "Cashews", "Coconut Milk", "Curry Paste", "Currywurst"), + "D", list.New("Dill", "Dragonfruit", "Dried Shrimp"), + "E", list.New("Eggs"), + "F", list.New("Fish Cake", "Furikake"), + "J", list.New("Jicama"), + "K", list.New("Kohlrabi"), + "L", list.New("Leeks", "Lentils", "Licorice Root"), ) ``` @@ -513,15 +513,15 @@ enumeratorStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("99")).MarginRi itemStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("212")).MarginRight(1) l := list.New( - "Glossier", - "Claire’s Boutique", - "Nyx", - "Mac", - "Milk", -). - Enumerator(list.Roman). - EnumeratorStyle(enumeratorStyle). - ItemStyle(itemStyle) + "Glossier", + "Claire’s Boutique", + "Nyx", + "Mac", + "Milk", + ). + Enumerator(list.Roman). + EnumeratorStyle(enumeratorStyle). + ItemStyle(itemStyle) ``` Print the list. @@ -574,7 +574,7 @@ Define a new tree. ```go t := tree.Root("."). - Child("A", "B", "C") + Child("A", "B", "C") ``` Print the tree. @@ -592,18 +592,20 @@ Trees have the ability to nest. ```go t := tree.Root("."). - Child("Item 1"). - Child( - tree.Root("Item 2"). - Child("Item 2.1"). - Child("Item 2.2"). - Child("Item 2.3"), - ). - Child( - tree.Root("Item 3"). - Child("Item 3.1"). - Child("Item 3.2"), - ) + Child("macOS"). + Child( + tree.New(). + Root("Linux"). + Child("NixOS"). + Child("Arch Linux (btw)"). + Child("Void Linux"), + ). + Child( + tree.New(). + Root("BSD"). + Child("FreeBSD"). + Child("OpenBSD"), + ) ``` Print the tree. @@ -613,34 +615,40 @@ fmt.Println(t) ```

-Tree Example (simple) +Tree Example (simple)

Trees can be customized via their enumeration function as well as using `lipgloss.Style`s. ```go -enumeratorStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("99")).MarginRight(1) -itemStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("212")).MarginRight(1) - -t := tree.Root("Makeup"). - Child( - "Glossier", - "Claire’s Boutique", - "Nyx", - "Mac", - "Milk", - ). - Enumerator(tree.RoundedEnumerator). - EnumeratorStyle(enumeratorStyle). - ItemStyle(itemStyle). - RootStyle(lipgloss.NewStyle().Foreground(lipgloss.Color("#04B575"))) +enumeratorStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("63")).MarginRight(1) +rootStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("35")) +itemStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("212")) + +t := tree. + Root("⁜ Makeup"). + Child( + "Glossier", + "Fenty Beauty", + tree.New().Child( + "Gloss Bomb Universal Lip Luminizer", + "Hot Cheeks Velour Blushlighter", + ), + "Nyx", + "Mac", + "Milk", + ). + Enumerator(tree.RoundedEnumerator). + EnumeratorStyle(enumeratorStyle). + RootStyle(rootStyle). + ItemStyle(itemStyle) ``` Print the tree.

-Tree Example (makeup) +Tree Example (makeup)

The predefined enumerators for trees are `DefaultEnumerator` and `RoundedEnumerator`. @@ -726,6 +734,12 @@ the stylesheet-based Markdown renderer. [glamour]: https://github.com/charmbracelet/glamour +## Contributing + +See [contributing][contribute]. + +[contribute]: https://github.com/charmbracelet/lipgloss/contribute + ## Feedback We’d love to hear your thoughts on this project. Feel free to drop us a note! diff --git a/vendor/github.com/charmbracelet/lipgloss/style.go b/vendor/github.com/charmbracelet/lipgloss/style.go index 4343d3c..0eb5c01 100644 --- a/vendor/github.com/charmbracelet/lipgloss/style.go +++ b/vendor/github.com/charmbracelet/lipgloss/style.go @@ -353,6 +353,8 @@ func (s Style) Render(strs ...string) string { // Potentially convert tabs to spaces str = s.maybeConvertTabs(str) + // carriage returns can cause strange behaviour when rendering. + str = strings.ReplaceAll(str, "\r\n", "\n") // Strip newlines in single line mode if inline { @@ -562,14 +564,14 @@ func pad(str string, n int, style *termenv.Style) string { return b.String() } -func max(a, b int) int { //nolint:unparam +func max(a, b int) int { //nolint:unparam,predeclared if a > b { return a } return b } -func min(a, b int) int { +func min(a, b int) int { //nolint:predeclared if a < b { return a } diff --git a/vendor/github.com/charmbracelet/x/ansi/cursor.go b/vendor/github.com/charmbracelet/x/ansi/cursor.go index f79e1e7..da144b9 100644 --- a/vendor/github.com/charmbracelet/x/ansi/cursor.go +++ b/vendor/github.com/charmbracelet/x/ansi/cursor.go @@ -163,10 +163,34 @@ func SetCursorPosition(col, row int) string { return "\x1b[" + strconv.Itoa(row) + ";" + strconv.Itoa(col) + "H" } +// HomeCursorPosition is a sequence for moving the cursor to the upper left +// corner of the scrolling region. This is equivalent to `SetCursorPosition(1, 1)`. +const HomeCursorPosition = "\x1b[H" + +// MoveCursor (CUP) returns a sequence for setting the cursor to the +// given row and column. +// +// CSI n ; m H +// +// See: https://vt100.net/docs/vt510-rm/CUP.html +// +// Deprecated: use SetCursorPosition instead. +func MoveCursor(col, row int) string { + return SetCursorPosition(col, row) +} + // CursorOrigin is a sequence for moving the cursor to the upper left corner of // the display. This is equivalent to `SetCursorPosition(1, 1)`. +// +// Deprecated: use [HomeCursorPosition] instead. const CursorOrigin = "\x1b[1;1H" +// MoveCursorOrigin is a sequence for moving the cursor to the upper left +// corner of the display. This is equivalent to `SetCursorPosition(1, 1)`. +// +// Deprecated: use CursorOrigin instead. +const MoveCursorOrigin = CursorOrigin + // SaveCursorPosition (SCP or SCOSC) is a sequence for saving the cursor // position. // diff --git a/vendor/github.com/charmbracelet/x/ansi/notification.go b/vendor/github.com/charmbracelet/x/ansi/notification.go new file mode 100644 index 0000000..4943366 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/notification.go @@ -0,0 +1,13 @@ +package ansi + +// Notify sends a desktop notification using iTerm's OSC 9. +// +// OSC 9 ; Mc ST +// OSC 9 ; Mc BEL +// +// Where Mc is the notification body. +// +// See: https://iterm2.com/documentation-escape-codes.html +func Notify(s string) string { + return "\x1b]9;" + s + "\x07" +} diff --git a/vendor/github.com/charmbracelet/x/ansi/parser_decode.go b/vendor/github.com/charmbracelet/x/ansi/parser_decode.go index 5fa0ff4..0ed802c 100644 --- a/vendor/github.com/charmbracelet/x/ansi/parser_decode.go +++ b/vendor/github.com/charmbracelet/x/ansi/parser_decode.go @@ -248,15 +248,31 @@ func DecodeSequence[T string | []byte](b T, state byte, p *Parser) (seq T, width switch c { case BEL: if HasOscPrefix(b) { + parseOscCmd(p) return b[:i+1], 0, i + 1, NormalState } case CAN, SUB: + if HasOscPrefix(b) { + // Ensure we parse the OSC command number + parseOscCmd(p) + } + // Cancel the sequence return b[:i], 0, i, NormalState case ST: + if HasOscPrefix(b) { + // Ensure we parse the OSC command number + parseOscCmd(p) + } + return b[:i+1], 0, i + 1, NormalState case ESC: if HasStPrefix(b[i:]) { + if HasOscPrefix(b) { + // Ensure we parse the OSC command number + parseOscCmd(p) + } + // End of string 7-bit (ST) return b[:i+2], 0, i + 2, NormalState } @@ -270,18 +286,8 @@ func DecodeSequence[T string | []byte](b T, state byte, p *Parser) (seq T, width p.DataLen++ // Parse the OSC command number - if c == ';' && p.Cmd == parser.MissingCommand && HasOscPrefix(b) { - for j := 0; j < p.DataLen; j++ { - d := p.Data[j] - if d < '0' || d > '9' { - break - } - if p.Cmd == parser.MissingCommand { - p.Cmd = 0 - } - p.Cmd *= 10 - p.Cmd += int(d - '0') - } + if c == ';' && HasOscPrefix(b) { + parseOscCmd(p) } } } @@ -290,6 +296,23 @@ func DecodeSequence[T string | []byte](b T, state byte, p *Parser) (seq T, width return b, 0, len(b), state } +func parseOscCmd(p *Parser) { + if p == nil || p.Cmd != parser.MissingCommand { + return + } + for j := 0; j < p.DataLen; j++ { + d := p.Data[j] + if d < '0' || d > '9' { + break + } + if p.Cmd == parser.MissingCommand { + p.Cmd = 0 + } + p.Cmd *= 10 + p.Cmd += int(d - '0') + } +} + // Index returns the index of the first occurrence of the given byte slice in // the data. It returns -1 if the byte slice is not found. func Index[T string | []byte](data, b T) int { @@ -414,7 +437,11 @@ type Param int // Param returns the parameter at the given index. // It returns -1 if the parameter does not exist. func (s Param) Param() int { - return int(s) & parser.ParamMask + p := int(s) & parser.ParamMask + if p == parser.MissingParam { + return -1 + } + return p } // HasMore returns true if the parameter has more sub-parameters. diff --git a/vendor/github.com/charmbracelet/x/ansi/wrap.go b/vendor/github.com/charmbracelet/x/ansi/wrap.go index d080a77..77d239a 100644 --- a/vendor/github.com/charmbracelet/x/ansi/wrap.go +++ b/vendor/github.com/charmbracelet/x/ansi/wrap.go @@ -83,7 +83,9 @@ func Hardwrap(s string, limit int, preserveSpace bool) string { } buf.WriteByte(b[i]) - curWidth++ + if action == parser.PrintAction { + curWidth++ + } default: buf.WriteByte(b[i]) } diff --git a/vendor/modules.txt b/vendor/modules.txt index ce88f81..4393073 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -4,13 +4,13 @@ github.com/atotto/clipboard # github.com/aymanbagabas/go-osc52/v2 v2.0.1 ## explicit; go 1.16 github.com/aymanbagabas/go-osc52/v2 -# github.com/charmbracelet/bubbletea v1.1.2 +# github.com/charmbracelet/bubbletea v1.2.1 ## explicit; go 1.18 github.com/charmbracelet/bubbletea -# github.com/charmbracelet/lipgloss v0.13.0 +# github.com/charmbracelet/lipgloss v1.0.0 ## explicit; go 1.18 github.com/charmbracelet/lipgloss -# github.com/charmbracelet/x/ansi v0.4.0 +# github.com/charmbracelet/x/ansi v0.4.5 ## explicit; go 1.18 github.com/charmbracelet/x/ansi github.com/charmbracelet/x/ansi/parser