From 449736619c619beb62cefbfdd91aa342e31b878c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 May 2024 04:06:54 +0000 Subject: [PATCH] chore: bump github.com/charmbracelet/lipgloss from 0.10.0 to 0.11.0 Bumps [github.com/charmbracelet/lipgloss](https://github.com/charmbracelet/lipgloss) from 0.10.0 to 0.11.0. - [Release notes](https://github.com/charmbracelet/lipgloss/releases) - [Commits](https://github.com/charmbracelet/lipgloss/compare/v0.10.0...v0.11.0) --- updated-dependencies: - dependency-name: github.com/charmbracelet/lipgloss dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 5 +- go.sum | 10 +- .../charmbracelet/lipgloss/.golangci-soft.yml | 1 - .../charmbracelet/lipgloss/.golangci.yml | 1 + .../charmbracelet/lipgloss/README.md | 49 +-- .../charmbracelet/lipgloss/align.go | 4 +- .../charmbracelet/lipgloss/borders.go | 12 +- .../github.com/charmbracelet/lipgloss/get.go | 108 +++-- .../github.com/charmbracelet/lipgloss/join.go | 8 +- .../charmbracelet/lipgloss/position.go | 4 +- .../charmbracelet/lipgloss/renderer.go | 3 - .../github.com/charmbracelet/lipgloss/set.go | 169 +++++++- .../github.com/charmbracelet/lipgloss/size.go | 4 +- .../charmbracelet/lipgloss/style.go | 133 ++++-- .../charmbracelet/lipgloss/unset.go | 127 +++--- .../charmbracelet/lipgloss/whitespace.go | 6 +- .../github.com/charmbracelet/x/ansi/LICENSE | 21 + .../github.com/charmbracelet/x/ansi/ansi.go | 11 + .../github.com/charmbracelet/x/ansi/ascii.go | 8 + .../charmbracelet/x/ansi/background.go | 61 +++ vendor/github.com/charmbracelet/x/ansi/c0.go | 72 ++++ vendor/github.com/charmbracelet/x/ansi/c1.go | 72 ++++ .../charmbracelet/x/ansi/clipboard.go | 75 ++++ .../github.com/charmbracelet/x/ansi/color.go | 196 +++++++++ vendor/github.com/charmbracelet/x/ansi/csi.go | 141 ++++++ .../github.com/charmbracelet/x/ansi/ctrl.go | 17 + .../github.com/charmbracelet/x/ansi/cursor.go | 190 ++++++++ vendor/github.com/charmbracelet/x/ansi/dcs.go | 148 +++++++ vendor/github.com/charmbracelet/x/ansi/doc.go | 7 + .../charmbracelet/x/ansi/hyperlink.go | 28 ++ .../github.com/charmbracelet/x/ansi/kitty.go | 58 +++ .../github.com/charmbracelet/x/ansi/mode.go | 132 ++++++ vendor/github.com/charmbracelet/x/ansi/osc.go | 69 +++ .../github.com/charmbracelet/x/ansi/params.go | 45 ++ .../github.com/charmbracelet/x/ansi/parser.go | 357 +++++++++++++++ .../charmbracelet/x/ansi/parser/const.go | 78 ++++ .../charmbracelet/x/ansi/parser/seq.go | 136 ++++++ .../x/ansi/parser/transition_table.go | 269 ++++++++++++ .../charmbracelet/x/ansi/passthrough.go | 63 +++ .../github.com/charmbracelet/x/ansi/screen.go | 126 ++++++ .../charmbracelet/x/ansi/sequence.go | 199 +++++++++ .../github.com/charmbracelet/x/ansi/style.go | 290 +++++++++++++ .../charmbracelet/x/ansi/termcap.go | 31 ++ .../github.com/charmbracelet/x/ansi/title.go | 32 ++ .../charmbracelet/x/ansi/truncate.go | 108 +++++ .../github.com/charmbracelet/x/ansi/util.go | 29 ++ .../github.com/charmbracelet/x/ansi/width.go | 73 ++++ .../github.com/charmbracelet/x/ansi/wrap.go | 406 ++++++++++++++++++ .../github.com/charmbracelet/x/ansi/xterm.go | 33 ++ .../github.com/mattn/go-isatty/isatty_bsd.go | 3 +- .../mattn/go-isatty/isatty_others.go | 5 +- .../mattn/go-isatty/isatty_tcgets.go | 3 +- vendor/modules.txt | 8 +- 53 files changed, 4022 insertions(+), 222 deletions(-) create mode 100644 vendor/github.com/charmbracelet/x/ansi/LICENSE create mode 100644 vendor/github.com/charmbracelet/x/ansi/ansi.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/ascii.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/background.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/c0.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/c1.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/clipboard.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/color.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/csi.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/ctrl.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/cursor.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/dcs.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/doc.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/hyperlink.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/kitty.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/mode.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/osc.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/params.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/parser.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/parser/const.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/parser/seq.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/parser/transition_table.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/passthrough.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/screen.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/sequence.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/style.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/termcap.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/title.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/truncate.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/util.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/width.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/wrap.go create mode 100644 vendor/github.com/charmbracelet/x/ansi/xterm.go diff --git a/go.mod b/go.mod index c358fb1..76af54f 100644 --- a/go.mod +++ b/go.mod @@ -5,16 +5,17 @@ go 1.19 require ( github.com/charmbracelet/bubbles v0.18.0 github.com/charmbracelet/bubbletea v0.26.1 - github.com/charmbracelet/lipgloss v0.10.0 + github.com/charmbracelet/lipgloss v0.11.0 github.com/muesli/reflow v0.3.0 ) require ( github.com/atotto/clipboard v0.1.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/charmbracelet/x/ansi v0.1.1 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect - github.com/mattn/go-isatty v0.0.18 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect diff --git a/go.sum b/go.sum index 87963b6..1c90cdd 100644 --- a/go.sum +++ b/go.sum @@ -6,15 +6,17 @@ github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/ github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw= github.com/charmbracelet/bubbletea v0.26.1 h1:xujcQeF73rh4jwu3+zhfQsvV18x+7zIjlw7/CYbzGJ0= github.com/charmbracelet/bubbletea v0.26.1/go.mod h1:FzKr7sKoO8iFVcdIBM9J0sJOcQv5nDQaYwsee3kpbgo= -github.com/charmbracelet/lipgloss v0.10.0 h1:KWeXFSexGcfahHX+54URiZGkBFazf70JNMtwg/AFW3s= -github.com/charmbracelet/lipgloss v0.10.0/go.mod h1:Wig9DSfvANsxqkRsqj6x87irdy123SR4dOXlKa91ciE= +github.com/charmbracelet/lipgloss v0.11.0 h1:UoAcbQ6Qml8hDwSWs0Y1cB5TEQuZkDPH/ZqwWWYTG4g= +github.com/charmbracelet/lipgloss v0.11.0/go.mod h1:1UdRTH9gYgpcdNN5oBtjbu/IzNKtzVtb7sqN1t9LNn8= +github.com/charmbracelet/x/ansi v0.1.1 h1:CGAduulr6egay/YVbGc8Hsu8deMg1xZ/bkaXTPi1JDk= +github.com/charmbracelet/x/ansi v0.1.1/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= -github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= diff --git a/vendor/github.com/charmbracelet/lipgloss/.golangci-soft.yml b/vendor/github.com/charmbracelet/lipgloss/.golangci-soft.yml index ef456e0..1b6824b 100644 --- a/vendor/github.com/charmbracelet/lipgloss/.golangci-soft.yml +++ b/vendor/github.com/charmbracelet/lipgloss/.golangci-soft.yml @@ -23,7 +23,6 @@ linters: - gomnd - gomoddirectives - goprintffuncname - - ifshort # - lll - misspell - nakedret diff --git a/vendor/github.com/charmbracelet/lipgloss/.golangci.yml b/vendor/github.com/charmbracelet/lipgloss/.golangci.yml index a5a91d0..3affce9 100644 --- a/vendor/github.com/charmbracelet/lipgloss/.golangci.yml +++ b/vendor/github.com/charmbracelet/lipgloss/.golangci.yml @@ -16,6 +16,7 @@ linters: enable: - bodyclose - exportloopref + - gofumpt - goimports - gosec - nilerr diff --git a/vendor/github.com/charmbracelet/lipgloss/README.md b/vendor/github.com/charmbracelet/lipgloss/README.md index 21bc40c..1376c7c 100644 --- a/vendor/github.com/charmbracelet/lipgloss/README.md +++ b/vendor/github.com/charmbracelet/lipgloss/README.md @@ -1,11 +1,11 @@ -Lip Gloss -========= +# Lip Gloss

- Lip Gloss Title Treatment
+ Lip Gloss title treatment
Latest Release GoDoc Build Status + phorm.ai

Style definitions for nice terminal layouts. Built with TUIs in mind. @@ -64,7 +64,6 @@ The terminal's color profile will be automatically detected, and colors outside the gamut of the current palette will be automatically coerced to their closest available value. - ### Adaptive Colors You can also specify color options for light and dark backgrounds: @@ -115,7 +114,6 @@ var style = lipgloss.NewStyle(). Reverse(true) ``` - ## Block-Level Formatting Lip Gloss also supports rules for block-level formatting: @@ -154,7 +152,6 @@ lipgloss.NewStyle().Padding(1, 4, 2) lipgloss.NewStyle().Margin(2, 4, 3, 1) ``` - ## Aligning Text You can align paragraphs of text to the left, right, or center. @@ -167,7 +164,6 @@ var style = lipgloss.NewStyle(). Align(lipgloss.Center) // just kidding, align it in the center ``` - ## Width and Height Setting a minimum width and height is simple and straightforward. @@ -180,7 +176,6 @@ var style = lipgloss.NewStyle(). Foreground(lipgloss.Color("63")) ``` - ## Borders Adding borders is easy: @@ -228,21 +223,22 @@ lipgloss.NewStyle(). For more on borders see [the docs][docs]. - ## Copying Styles -Just use `Copy()`: +Just use assignment: ```go -var style = lipgloss.NewStyle().Foreground(lipgloss.Color("219")) +style := lipgloss.NewStyle().Foreground(lipgloss.Color("219")) -var wildStyle = style.Copy().Blink(true) -``` +copiedStyle := style // this is a true copy -`Copy()` performs a copy on the underlying data structure ensuring that you get -a true, dereferenced copy of a style. Without copying, it's possible to mutate -styles. +wildStyle := style.Blink(true) // this is also true copy, with blink added + +``` +Since `Style` data structures contains only primitive types, assigning a style +to another effectively creates a new copy of the style without mutating the +original. ## Inheritance @@ -261,7 +257,6 @@ var styleB = lipgloss.NewStyle(). Inherit(styleA) ``` - ## Unsetting Rules All rules can be unset: @@ -276,7 +271,6 @@ var style = lipgloss.NewStyle(). When a rule is unset, it won't be inherited or copied. - ## Enforcing Rules Sometimes, such as when developing a component, you want to make sure style @@ -353,7 +347,6 @@ For an example on using a custom renderer over SSH with [Wish][wish] see the In addition to pure styling, Lip Gloss also ships with some utilities to help assemble your layouts. - ### Joining Paragraphs Horizontally and vertically joining paragraphs is a cinch. @@ -370,7 +363,6 @@ lipgloss.JoinVertical(lipgloss.Center, paragraphA, paragraphB) lipgloss.JoinHorizontal(0.2, paragraphA, paragraphB, paragraphC) ``` - ### Measuring Width and Height Sometimes you’ll want to know the width and height of text blocks when building @@ -463,7 +455,7 @@ fmt.Println(t) For more on tables see [the docs](https://pkg.go.dev/github.com/charmbracelet/lipgloss?tab=doc) and [examples](https://github.com/charmbracelet/lipgloss/tree/master/examples/table). -*** +--- ## FAQ @@ -499,10 +491,11 @@ import ( lipgloss.SetColorProfile(termenv.TrueColor) ``` -*Note:* this option limits the flexibility of your application and can cause +_Note:_ this option limits the flexibility of your application and can cause ANSI escape codes to be output in cases where that might not be desired. Take careful note of your use case and environment before choosing to force a color profile. + ## What about [Bubble Tea][tea]? @@ -516,7 +509,6 @@ In simple terms, you can use Lip Gloss to help build your Bubble Tea views. [tea]: https://github.com/charmbracelet/tea - ## Under the Hood Lip Gloss is built on the excellent [Termenv][termenv] and [Reflow][reflow] @@ -526,7 +518,6 @@ For many use cases Termenv and Reflow will be sufficient for your needs. [termenv]: https://github.com/muesli/termenv [reflow]: https://github.com/muesli/reflow - ## Rendering Markdown For a more document-centric rendering solution with support for things like @@ -535,20 +526,19 @@ the stylesheet-based Markdown renderer. [glamour]: https://github.com/charmbracelet/glamour - ## Feedback We’d love to hear your thoughts on this project. Feel free to drop us a note! -* [Twitter](https://twitter.com/charmcli) -* [The Fediverse](https://mastodon.social/@charmcli) -* [Discord](https://charm.sh/chat) +- [Twitter](https://twitter.com/charmcli) +- [The Fediverse](https://mastodon.social/@charmcli) +- [Discord](https://charm.sh/chat) ## License [MIT](https://github.com/charmbracelet/lipgloss/raw/master/LICENSE) -*** +--- Part of [Charm](https://charm.sh). @@ -556,7 +546,6 @@ Part of [Charm](https://charm.sh). Charm热爱开源 • Charm loves open source - [docs]: https://pkg.go.dev/github.com/charmbracelet/lipgloss?tab=doc [wish]: https://github.com/charmbracelet/wish [ssh-example]: examples/ssh diff --git a/vendor/github.com/charmbracelet/lipgloss/align.go b/vendor/github.com/charmbracelet/lipgloss/align.go index 7ee549f..805d1e0 100644 --- a/vendor/github.com/charmbracelet/lipgloss/align.go +++ b/vendor/github.com/charmbracelet/lipgloss/align.go @@ -3,7 +3,7 @@ package lipgloss import ( "strings" - "github.com/muesli/reflow/ansi" + "github.com/charmbracelet/x/ansi" "github.com/muesli/termenv" ) @@ -15,7 +15,7 @@ func alignTextHorizontal(str string, pos Position, width int, style *termenv.Sty var b strings.Builder for i, l := range lines { - lineWidth := ansi.PrintableRuneWidth(l) + lineWidth := ansi.StringWidth(l) shortAmount := widestLine - lineWidth // difference from the widest line shortAmount += max(0, width-(shortAmount+lineWidth)) // difference from the total width, if set diff --git a/vendor/github.com/charmbracelet/lipgloss/borders.go b/vendor/github.com/charmbracelet/lipgloss/borders.go index 6ef90d5..deb6b35 100644 --- a/vendor/github.com/charmbracelet/lipgloss/borders.go +++ b/vendor/github.com/charmbracelet/lipgloss/borders.go @@ -3,7 +3,7 @@ package lipgloss import ( "strings" - "github.com/muesli/reflow/ansi" + "github.com/charmbracelet/x/ansi" "github.com/muesli/termenv" "github.com/rivo/uniseg" ) @@ -376,16 +376,12 @@ func (s Style) applyBorder(str string) string { // Render the horizontal (top or bottom) portion of a border. func renderHorizontalEdge(left, middle, right string, width int) string { - if width < 1 { - return "" - } - if middle == "" { middle = " " } - leftWidth := ansi.PrintableRuneWidth(left) - rightWidth := ansi.PrintableRuneWidth(right) + leftWidth := ansi.StringWidth(left) + rightWidth := ansi.StringWidth(right) runes := []rune(middle) j := 0 @@ -398,7 +394,7 @@ func renderHorizontalEdge(left, middle, right string, width int) string { if j >= len(runes) { j = 0 } - i += ansi.PrintableRuneWidth(string(runes[j])) + i += ansi.StringWidth(string(runes[j])) } out.WriteString(right) diff --git a/vendor/github.com/charmbracelet/lipgloss/get.go b/vendor/github.com/charmbracelet/lipgloss/get.go index 9be3d64..9c2f06f 100644 --- a/vendor/github.com/charmbracelet/lipgloss/get.go +++ b/vendor/github.com/charmbracelet/lipgloss/get.go @@ -3,7 +3,7 @@ package lipgloss import ( "strings" - "github.com/muesli/reflow/ansi" + "github.com/charmbracelet/x/ansi" ) // GetBold returns the style's bold value. If no value is set false is returned. @@ -416,74 +416,114 @@ func (s Style) GetTransform() func(string) string { // Returns whether or not the given property is set. func (s Style) isSet(k propKey) bool { - _, exists := s.rules[k] - return exists + return s.props.has(k) } func (s Style) getAsBool(k propKey, defaultVal bool) bool { - v, ok := s.rules[k] - if !ok { + if !s.isSet(k) { return defaultVal } - if b, ok := v.(bool); ok { - return b - } - return defaultVal + return s.attrs&int(k) != 0 } func (s Style) getAsColor(k propKey) TerminalColor { - v, ok := s.rules[k] - if !ok { + if !s.isSet(k) { return noColor } - if c, ok := v.(TerminalColor); ok { + + var c TerminalColor + switch k { //nolint:exhaustive + case foregroundKey: + c = s.fgColor + case backgroundKey: + c = s.bgColor + case marginBackgroundKey: + c = s.marginBgColor + case borderTopForegroundKey: + c = s.borderTopFgColor + case borderRightForegroundKey: + c = s.borderRightFgColor + case borderBottomForegroundKey: + c = s.borderBottomFgColor + case borderLeftForegroundKey: + c = s.borderLeftFgColor + case borderTopBackgroundKey: + c = s.borderTopBgColor + case borderRightBackgroundKey: + c = s.borderRightBgColor + case borderBottomBackgroundKey: + c = s.borderBottomBgColor + case borderLeftBackgroundKey: + c = s.borderLeftBgColor + } + + if c != nil { return c } + return noColor } func (s Style) getAsInt(k propKey) int { - v, ok := s.rules[k] - if !ok { + if !s.isSet(k) { return 0 } - if i, ok := v.(int); ok { - return i + switch k { //nolint:exhaustive + case widthKey: + return s.width + case heightKey: + return s.height + case paddingTopKey: + return s.paddingTop + case paddingRightKey: + return s.paddingRight + case paddingBottomKey: + return s.paddingBottom + case paddingLeftKey: + return s.paddingLeft + case marginTopKey: + return s.marginTop + case marginRightKey: + return s.marginRight + case marginBottomKey: + return s.marginBottom + case marginLeftKey: + return s.marginLeft + case maxWidthKey: + return s.maxWidth + case maxHeightKey: + return s.maxHeight + case tabWidthKey: + return s.tabWidth } return 0 } func (s Style) getAsPosition(k propKey) Position { - v, ok := s.rules[k] - if !ok { + if !s.isSet(k) { return Position(0) } - if p, ok := v.(Position); ok { - return p + switch k { //nolint:exhaustive + case alignHorizontalKey: + return s.alignHorizontal + case alignVerticalKey: + return s.alignVertical } return Position(0) } func (s Style) getBorderStyle() Border { - v, ok := s.rules[borderStyleKey] - if !ok { + if !s.isSet(borderStyleKey) { return noBorder } - if b, ok := v.(Border); ok { - return b - } - return noBorder + return s.borderStyle } -func (s Style) getAsTransform(k propKey) func(string) string { - v, ok := s.rules[k] - if !ok { +func (s Style) getAsTransform(propKey) func(string) string { + if !s.isSet(transformKey) { return nil } - if fn, ok := v.(func(string) string); ok { - return fn - } - return nil + return s.transform } // Split a string into lines, additionally returning the size of the widest @@ -492,7 +532,7 @@ func getLines(s string) (lines []string, widest int) { lines = strings.Split(s, "\n") for _, l := range lines { - w := ansi.PrintableRuneWidth(l) + w := ansi.StringWidth(l) if widest < w { widest = w } diff --git a/vendor/github.com/charmbracelet/lipgloss/join.go b/vendor/github.com/charmbracelet/lipgloss/join.go index f265976..b0a23a5 100644 --- a/vendor/github.com/charmbracelet/lipgloss/join.go +++ b/vendor/github.com/charmbracelet/lipgloss/join.go @@ -4,7 +4,7 @@ import ( "math" "strings" - "github.com/muesli/reflow/ansi" + "github.com/charmbracelet/x/ansi" ) // JoinHorizontal is a utility function for horizontally joining two @@ -12,7 +12,7 @@ import ( // the position, with 0 being all the way at the top and 1 being all the way // at the bottom. // -// If you just want to align to the left, right or center you may as well just +// If you just want to align to the top, center or bottom you may as well just // use the helper constants Top, Center, and Bottom. // // Example: @@ -85,7 +85,7 @@ func JoinHorizontal(pos Position, strs ...string) string { b.WriteString(block[i]) // Also make lines the same length - b.WriteString(strings.Repeat(" ", maxWidths[j]-ansi.PrintableRuneWidth(block[i]))) + b.WriteString(strings.Repeat(" ", maxWidths[j]-ansi.StringWidth(block[i]))) } if i < len(blocks[0])-1 { b.WriteRune('\n') @@ -137,7 +137,7 @@ func JoinVertical(pos Position, strs ...string) string { var b strings.Builder for i, block := range blocks { for j, line := range block { - w := maxWidth - ansi.PrintableRuneWidth(line) + w := maxWidth - ansi.StringWidth(line) switch pos { //nolint:exhaustive case Left: diff --git a/vendor/github.com/charmbracelet/lipgloss/position.go b/vendor/github.com/charmbracelet/lipgloss/position.go index 7d229e0..185f5af 100644 --- a/vendor/github.com/charmbracelet/lipgloss/position.go +++ b/vendor/github.com/charmbracelet/lipgloss/position.go @@ -4,7 +4,7 @@ import ( "math" "strings" - "github.com/muesli/reflow/ansi" + "github.com/charmbracelet/x/ansi" ) // Position represents a position along a horizontal or vertical axis. It's in @@ -66,7 +66,7 @@ func (r *Renderer) PlaceHorizontal(width int, pos Position, str string, opts ... var b strings.Builder for i, l := range lines { // Is this line shorter than the longest line? - short := max(0, contentWidth-ansi.PrintableRuneWidth(l)) + short := max(0, contentWidth-ansi.StringWidth(l)) switch pos { //nolint:exhaustive case Left: diff --git a/vendor/github.com/charmbracelet/lipgloss/renderer.go b/vendor/github.com/charmbracelet/lipgloss/renderer.go index 85ffd25..233aa7c 100644 --- a/vendor/github.com/charmbracelet/lipgloss/renderer.go +++ b/vendor/github.com/charmbracelet/lipgloss/renderer.go @@ -28,9 +28,6 @@ type Renderer struct { mtx sync.RWMutex } -// RendererOption is a function that can be used to configure a [Renderer]. -type RendererOption func(r *Renderer) - // DefaultRenderer returns the default renderer. func DefaultRenderer() *Renderer { return renderer diff --git a/vendor/github.com/charmbracelet/lipgloss/set.go b/vendor/github.com/charmbracelet/lipgloss/set.go index 5846b59..6f8b082 100644 --- a/vendor/github.com/charmbracelet/lipgloss/set.go +++ b/vendor/github.com/charmbracelet/lipgloss/set.go @@ -1,34 +1,161 @@ package lipgloss -// This could (should) probably just be moved into NewStyle(). We've broken it -// out, so we can call it in a lazy way. -func (s *Style) init() { - if s.rules == nil { - s.rules = make(rules) - } -} - // Set a value on the underlying rules map. func (s *Style) set(key propKey, value interface{}) { - s.init() - - switch v := value.(type) { - case int: + // We don't allow negative integers on any of our other values, so just keep + // them at zero or above. We could use uints instead, but the + // conversions are a little tedious, so we're sticking with ints for + // sake of usability. + switch key { //nolint:exhaustive + case foregroundKey: + s.fgColor = colorOrNil(value) + case backgroundKey: + s.bgColor = colorOrNil(value) + case widthKey: + s.width = max(0, value.(int)) + case heightKey: + s.height = max(0, value.(int)) + case alignHorizontalKey: + s.alignHorizontal = value.(Position) + case alignVerticalKey: + s.alignVertical = value.(Position) + case paddingTopKey: + s.paddingTop = max(0, value.(int)) + case paddingRightKey: + s.paddingRight = max(0, value.(int)) + case paddingBottomKey: + s.paddingBottom = max(0, value.(int)) + case paddingLeftKey: + s.paddingLeft = max(0, value.(int)) + case marginTopKey: + s.marginTop = max(0, value.(int)) + case marginRightKey: + s.marginRight = max(0, value.(int)) + case marginBottomKey: + s.marginBottom = max(0, value.(int)) + case marginLeftKey: + s.marginLeft = max(0, value.(int)) + case marginBackgroundKey: + s.marginBgColor = colorOrNil(value) + case borderStyleKey: + s.borderStyle = value.(Border) + case borderTopForegroundKey: + s.borderTopFgColor = colorOrNil(value) + case borderRightForegroundKey: + s.borderRightFgColor = colorOrNil(value) + case borderBottomForegroundKey: + s.borderBottomFgColor = colorOrNil(value) + case borderLeftForegroundKey: + s.borderLeftFgColor = colorOrNil(value) + case borderTopBackgroundKey: + s.borderTopBgColor = colorOrNil(value) + case borderRightBackgroundKey: + s.borderRightBgColor = colorOrNil(value) + case borderBottomBackgroundKey: + s.borderBottomBgColor = colorOrNil(value) + case borderLeftBackgroundKey: + s.borderLeftBgColor = colorOrNil(value) + case maxWidthKey: + s.maxWidth = max(0, value.(int)) + case maxHeightKey: + s.maxHeight = max(0, value.(int)) + case tabWidthKey: // TabWidth is the only property that may have a negative value (and // that negative value can be no less than -1). - if key == tabWidthKey { - s.rules[key] = v - break + s.tabWidth = value.(int) + case transformKey: + s.transform = value.(func(string) string) + default: + if v, ok := value.(bool); ok { //nolint:nestif + if v { + s.attrs |= int(key) + } else { + s.attrs &^= int(key) + } + } else if attrs, ok := value.(int); ok { + // bool attrs + if attrs&int(key) != 0 { + s.attrs |= int(key) + } else { + s.attrs &^= int(key) + } } + } - // We don't allow negative integers on any of our other values, so just keep - // them at zero or above. We could use uints instead, but the - // conversions are a little tedious, so we're sticking with ints for - // sake of usability. - s.rules[key] = max(0, v) + // Set the prop on + s.props = s.props.set(key) +} + +// setFrom sets the property from another style. +func (s *Style) setFrom(key propKey, i Style) { + switch key { //nolint:exhaustive + case foregroundKey: + s.set(foregroundKey, i.fgColor) + case backgroundKey: + s.set(backgroundKey, i.bgColor) + case widthKey: + s.set(widthKey, i.width) + case heightKey: + s.set(heightKey, i.height) + case alignHorizontalKey: + s.set(alignHorizontalKey, i.alignHorizontal) + case alignVerticalKey: + s.set(alignVerticalKey, i.alignVertical) + case paddingTopKey: + s.set(paddingTopKey, i.paddingTop) + case paddingRightKey: + s.set(paddingRightKey, i.paddingRight) + case paddingBottomKey: + s.set(paddingBottomKey, i.paddingBottom) + case paddingLeftKey: + s.set(paddingLeftKey, i.paddingLeft) + case marginTopKey: + s.set(marginTopKey, i.marginTop) + case marginRightKey: + s.set(marginRightKey, i.marginRight) + case marginBottomKey: + s.set(marginBottomKey, i.marginBottom) + case marginLeftKey: + s.set(marginLeftKey, i.marginLeft) + case marginBackgroundKey: + s.set(marginBackgroundKey, i.marginBgColor) + case borderStyleKey: + s.set(borderStyleKey, i.borderStyle) + case borderTopForegroundKey: + s.set(borderTopForegroundKey, i.borderTopFgColor) + case borderRightForegroundKey: + s.set(borderRightForegroundKey, i.borderRightFgColor) + case borderBottomForegroundKey: + s.set(borderBottomForegroundKey, i.borderBottomFgColor) + case borderLeftForegroundKey: + s.set(borderLeftForegroundKey, i.borderLeftFgColor) + case borderTopBackgroundKey: + s.set(borderTopBackgroundKey, i.borderTopBgColor) + case borderRightBackgroundKey: + s.set(borderRightBackgroundKey, i.borderRightBgColor) + case borderBottomBackgroundKey: + s.set(borderBottomBackgroundKey, i.borderBottomBgColor) + case borderLeftBackgroundKey: + s.set(borderLeftBackgroundKey, i.borderLeftBgColor) + case maxWidthKey: + s.set(maxWidthKey, i.maxWidth) + case maxHeightKey: + s.set(maxHeightKey, i.maxHeight) + case tabWidthKey: + s.set(tabWidthKey, i.tabWidth) + case transformKey: + s.set(transformKey, i.transform) default: - s.rules[key] = v + // Set attributes for set bool properties + s.set(key, i.attrs) + } +} + +func colorOrNil(c interface{}) TerminalColor { + if c, ok := c.(TerminalColor); ok { + return c } + return nil } // Bold sets a bold formatting rule. diff --git a/vendor/github.com/charmbracelet/lipgloss/size.go b/vendor/github.com/charmbracelet/lipgloss/size.go index 439a5cb..e169ff5 100644 --- a/vendor/github.com/charmbracelet/lipgloss/size.go +++ b/vendor/github.com/charmbracelet/lipgloss/size.go @@ -3,7 +3,7 @@ package lipgloss import ( "strings" - "github.com/muesli/reflow/ansi" + "github.com/charmbracelet/x/ansi" ) // Width returns the cell width of characters in the string. ANSI sequences are @@ -14,7 +14,7 @@ import ( // will give you accurate results. func Width(str string) (width int) { for _, l := range strings.Split(str, "\n") { - w := ansi.PrintableRuneWidth(l) + w := ansi.StringWidth(l) if w > width { width = w } diff --git a/vendor/github.com/charmbracelet/lipgloss/style.go b/vendor/github.com/charmbracelet/lipgloss/style.go index 58dcc0f..846b92f 100644 --- a/vendor/github.com/charmbracelet/lipgloss/style.go +++ b/vendor/github.com/charmbracelet/lipgloss/style.go @@ -4,26 +4,30 @@ import ( "strings" "unicode" - "github.com/muesli/reflow/truncate" - "github.com/muesli/reflow/wordwrap" - "github.com/muesli/reflow/wrap" + "github.com/charmbracelet/x/ansi" "github.com/muesli/termenv" ) const tabWidthDefault = 4 // Property for a key. -type propKey int +type propKey int64 // Available properties. const ( - boldKey propKey = iota + // Boolean props come first. + boldKey propKey = 1 << iota italicKey underlineKey strikethroughKey reverseKey blinkKey faintKey + underlineSpacesKey + strikethroughSpacesKey + colorWhitespaceKey + + // Non-boolean props. foregroundKey backgroundKey widthKey @@ -37,8 +41,6 @@ const ( paddingBottomKey paddingLeftKey - colorWhitespaceKey - // Margins. marginTopKey marginRightKey @@ -71,14 +73,27 @@ const ( maxWidthKey maxHeightKey tabWidthKey - underlineSpacesKey - strikethroughSpacesKey transformKey ) -// A set of properties. -type rules map[propKey]interface{} +// props is a set of properties. +type props int64 + +// set sets a property. +func (p props) set(k propKey) props { + return p | props(k) +} + +// unset unsets a property. +func (p props) unset(k propKey) props { + return p &^ props(k) +} + +// has checks if a property is set. +func (p props) has(k propKey) bool { + return p&props(k) != 0 +} // NewStyle returns a new, empty Style. While it's syntactic sugar for the // Style{} primitive, it's recommended to use this function for creating styles @@ -100,8 +115,48 @@ func (r *Renderer) NewStyle() Style { // Style contains a set of rules that comprise a style as a whole. type Style struct { r *Renderer - rules map[propKey]interface{} + props props value string + + // we store bool props values here + attrs int + + // props that have values + fgColor TerminalColor + bgColor TerminalColor + + width int + height int + + alignHorizontal Position + alignVertical Position + + paddingTop int + paddingRight int + paddingBottom int + paddingLeft int + + marginTop int + marginRight int + marginBottom int + marginLeft int + marginBgColor TerminalColor + + borderStyle Border + borderTopFgColor TerminalColor + borderRightFgColor TerminalColor + borderBottomFgColor TerminalColor + borderLeftFgColor TerminalColor + borderTopBgColor TerminalColor + borderRightBgColor TerminalColor + borderBottomBgColor TerminalColor + borderLeftBgColor TerminalColor + + maxWidth int + maxHeight int + tabWidth int + + transform func(string) string } // joinString joins a list of strings into a single string separated with a @@ -133,15 +188,10 @@ func (s Style) String() string { } // Copy returns a copy of this style, including any underlying string values. +// +// Deprecated: to copy just use assignment (i.e. a := b). All methods also return a new style. func (s Style) Copy() Style { - o := NewStyle() - o.init() - for k, v := range s.rules { - o.rules[k] = v - } - o.r = s.r - o.value = s.value - return o + return s } // Inherit overlays the style in the argument onto this style by copying each explicitly @@ -150,9 +200,11 @@ func (s Style) Copy() Style { // // Margins, padding, and underlying string values are not inherited. func (s Style) Inherit(i Style) Style { - s.init() + for k := boldKey; k <= transformKey; k <<= 1 { + if !i.isSet(k) { + continue + } - for k, v := range i.rules { switch k { //nolint:exhaustive case marginTopKey, marginRightKey, marginBottomKey, marginLeftKey: // Margins are not inherited @@ -163,14 +215,15 @@ func (s Style) Inherit(i Style) Style { case backgroundKey: // The margins also inherit the background color if !s.isSet(marginBackgroundKey) && !i.isSet(marginBackgroundKey) { - s.rules[marginBackgroundKey] = v + s.set(marginBackgroundKey, i.bgColor) } } - if _, exists := s.rules[k]; exists { + if s.isSet(k) { continue } - s.rules[k] = v + + s.setFrom(k, i) } return s } @@ -218,20 +271,24 @@ func (s Style) Render(strs ...string) string { maxWidth = s.getAsInt(maxWidthKey) maxHeight = s.getAsInt(maxHeightKey) - underlineSpaces = underline && s.getAsBool(underlineSpacesKey, true) - strikethroughSpaces = strikethrough && s.getAsBool(strikethroughSpacesKey, true) + underlineSpaces = s.getAsBool(underlineSpacesKey, false) || (underline && s.getAsBool(underlineSpacesKey, true)) + strikethroughSpaces = s.getAsBool(strikethroughSpacesKey, false) || (strikethrough && s.getAsBool(strikethroughSpacesKey, true)) // Do we need to style whitespace (padding and space outside // paragraphs) separately? styleWhitespace = reverse // Do we need to style spaces separately? - useSpaceStyler = underlineSpaces || strikethroughSpaces + useSpaceStyler = (underline && !underlineSpaces) || (strikethrough && !strikethroughSpaces) || underlineSpaces || strikethroughSpaces transform = s.getAsTransform(transformKey) ) - if len(s.rules) == 0 { + if transform != nil { + str = transform(str) + } + + if s.props == 0 { return s.maybeConvertTabs(str) } @@ -306,8 +363,7 @@ func (s Style) Render(strs ...string) string { // Word wrap if !inline && width > 0 { wrapAt := width - leftPadding - rightPadding - str = wordwrap.String(str, wrapAt) - str = wrap.String(str, wrapAt) // force-wrap long strings + str = ansi.Wrap(str, wrapAt, "") } // Render core text @@ -337,7 +393,7 @@ func (s Style) Render(strs ...string) string { } // Padding - if !inline { + if !inline { //nolint:nestif if leftPadding > 0 { var st *termenv.Style if colorWhitespace || styleWhitespace { @@ -393,7 +449,7 @@ func (s Style) Render(strs ...string) string { lines := strings.Split(str, "\n") for i := range lines { - lines[i] = truncate.String(lines[i], uint(maxWidth)) + lines[i] = ansi.Truncate(lines[i], maxWidth, "") } str = strings.Join(lines, "\n") @@ -402,11 +458,10 @@ func (s Style) Render(strs ...string) string { // Truncate according to MaxHeight if maxHeight > 0 { lines := strings.Split(str, "\n") - str = strings.Join(lines[:min(maxHeight, len(lines))], "\n") - } - - if transform != nil { - return transform(str) + height := min(maxHeight, len(lines)) + if len(lines) > 0 { + str = strings.Join(lines[:height], "\n") + } } return str @@ -508,7 +563,7 @@ func pad(str string, n int, style *termenv.Style) string { return b.String() } -func max(a, b int) int { +func max(a, b int) int { //nolint:unparam if a > b { return a } diff --git a/vendor/github.com/charmbracelet/lipgloss/unset.go b/vendor/github.com/charmbracelet/lipgloss/unset.go index 5387bcf..19d9337 100644 --- a/vendor/github.com/charmbracelet/lipgloss/unset.go +++ b/vendor/github.com/charmbracelet/lipgloss/unset.go @@ -1,159 +1,164 @@ package lipgloss +// unset unsets a property from a style. +func (s *Style) unset(key propKey) { + s.props = s.props.unset(key) +} + // UnsetBold removes the bold style rule, if set. func (s Style) UnsetBold() Style { - delete(s.rules, boldKey) + s.unset(boldKey) return s } // UnsetItalic removes the italic style rule, if set. func (s Style) UnsetItalic() Style { - delete(s.rules, italicKey) + s.unset(italicKey) return s } // UnsetUnderline removes the underline style rule, if set. func (s Style) UnsetUnderline() Style { - delete(s.rules, underlineKey) + s.unset(underlineKey) return s } // UnsetStrikethrough removes the strikethrough style rule, if set. func (s Style) UnsetStrikethrough() Style { - delete(s.rules, strikethroughKey) + s.unset(strikethroughKey) return s } // UnsetReverse removes the reverse style rule, if set. func (s Style) UnsetReverse() Style { - delete(s.rules, reverseKey) + s.unset(reverseKey) return s } // UnsetBlink removes the blink style rule, if set. func (s Style) UnsetBlink() Style { - delete(s.rules, blinkKey) + s.unset(blinkKey) return s } // UnsetFaint removes the faint style rule, if set. func (s Style) UnsetFaint() Style { - delete(s.rules, faintKey) + s.unset(faintKey) return s } // UnsetForeground removes the foreground style rule, if set. func (s Style) UnsetForeground() Style { - delete(s.rules, foregroundKey) + s.unset(foregroundKey) return s } // UnsetBackground removes the background style rule, if set. func (s Style) UnsetBackground() Style { - delete(s.rules, backgroundKey) + s.unset(backgroundKey) return s } // UnsetWidth removes the width style rule, if set. func (s Style) UnsetWidth() Style { - delete(s.rules, widthKey) + s.unset(widthKey) return s } // UnsetHeight removes the height style rule, if set. func (s Style) UnsetHeight() Style { - delete(s.rules, heightKey) + s.unset(heightKey) return s } // UnsetAlign removes the horizontal and vertical text alignment style rule, if set. func (s Style) UnsetAlign() Style { - delete(s.rules, alignHorizontalKey) - delete(s.rules, alignVerticalKey) + s.unset(alignHorizontalKey) + s.unset(alignVerticalKey) return s } // UnsetAlignHorizontal removes the horizontal text alignment style rule, if set. func (s Style) UnsetAlignHorizontal() Style { - delete(s.rules, alignHorizontalKey) + s.unset(alignHorizontalKey) return s } // UnsetAlignVertical removes the vertical text alignment style rule, if set. func (s Style) UnsetAlignVertical() Style { - delete(s.rules, alignVerticalKey) + s.unset(alignVerticalKey) return s } // UnsetPadding removes all padding style rules. func (s Style) UnsetPadding() Style { - delete(s.rules, paddingLeftKey) - delete(s.rules, paddingRightKey) - delete(s.rules, paddingTopKey) - delete(s.rules, paddingBottomKey) + s.unset(paddingLeftKey) + s.unset(paddingRightKey) + s.unset(paddingTopKey) + s.unset(paddingBottomKey) return s } // UnsetPaddingLeft removes the left padding style rule, if set. func (s Style) UnsetPaddingLeft() Style { - delete(s.rules, paddingLeftKey) + s.unset(paddingLeftKey) return s } // UnsetPaddingRight removes the right padding style rule, if set. func (s Style) UnsetPaddingRight() Style { - delete(s.rules, paddingRightKey) + s.unset(paddingRightKey) return s } // UnsetPaddingTop removes the top padding style rule, if set. func (s Style) UnsetPaddingTop() Style { - delete(s.rules, paddingTopKey) + s.unset(paddingTopKey) return s } // UnsetPaddingBottom removes the bottom padding style rule, if set. func (s Style) UnsetPaddingBottom() Style { - delete(s.rules, paddingBottomKey) + s.unset(paddingBottomKey) return s } // UnsetColorWhitespace removes the rule for coloring padding, if set. func (s Style) UnsetColorWhitespace() Style { - delete(s.rules, colorWhitespaceKey) + s.unset(colorWhitespaceKey) return s } // UnsetMargins removes all margin style rules. func (s Style) UnsetMargins() Style { - delete(s.rules, marginLeftKey) - delete(s.rules, marginRightKey) - delete(s.rules, marginTopKey) - delete(s.rules, marginBottomKey) + s.unset(marginLeftKey) + s.unset(marginRightKey) + s.unset(marginTopKey) + s.unset(marginBottomKey) return s } // UnsetMarginLeft removes the left margin style rule, if set. func (s Style) UnsetMarginLeft() Style { - delete(s.rules, marginLeftKey) + s.unset(marginLeftKey) return s } // UnsetMarginRight removes the right margin style rule, if set. func (s Style) UnsetMarginRight() Style { - delete(s.rules, marginRightKey) + s.unset(marginRightKey) return s } // UnsetMarginTop removes the top margin style rule, if set. func (s Style) UnsetMarginTop() Style { - delete(s.rules, marginTopKey) + s.unset(marginTopKey) return s } // UnsetMarginBottom removes the bottom margin style rule, if set. func (s Style) UnsetMarginBottom() Style { - delete(s.rules, marginBottomKey) + s.unset(marginBottomKey) return s } @@ -161,153 +166,153 @@ func (s Style) UnsetMarginBottom() Style { // margin's background color can be set from the background color of another // style during inheritance. func (s Style) UnsetMarginBackground() Style { - delete(s.rules, marginBackgroundKey) + s.unset(marginBackgroundKey) return s } // UnsetBorderStyle removes the border style rule, if set. func (s Style) UnsetBorderStyle() Style { - delete(s.rules, borderStyleKey) + s.unset(borderStyleKey) return s } // UnsetBorderTop removes the border top style rule, if set. func (s Style) UnsetBorderTop() Style { - delete(s.rules, borderTopKey) + s.unset(borderTopKey) return s } // UnsetBorderRight removes the border right style rule, if set. func (s Style) UnsetBorderRight() Style { - delete(s.rules, borderRightKey) + s.unset(borderRightKey) return s } // UnsetBorderBottom removes the border bottom style rule, if set. func (s Style) UnsetBorderBottom() Style { - delete(s.rules, borderBottomKey) + s.unset(borderBottomKey) return s } // UnsetBorderLeft removes the border left style rule, if set. func (s Style) UnsetBorderLeft() Style { - delete(s.rules, borderLeftKey) + s.unset(borderLeftKey) return s } // UnsetBorderForeground removes all border foreground color styles, if set. func (s Style) UnsetBorderForeground() Style { - delete(s.rules, borderTopForegroundKey) - delete(s.rules, borderRightForegroundKey) - delete(s.rules, borderBottomForegroundKey) - delete(s.rules, borderLeftForegroundKey) + s.unset(borderTopForegroundKey) + s.unset(borderRightForegroundKey) + s.unset(borderBottomForegroundKey) + s.unset(borderLeftForegroundKey) return s } // UnsetBorderTopForeground removes the top border foreground color rule, // if set. func (s Style) UnsetBorderTopForeground() Style { - delete(s.rules, borderTopForegroundKey) + s.unset(borderTopForegroundKey) return s } // UnsetBorderRightForeground removes the right border foreground color rule, // if set. func (s Style) UnsetBorderRightForeground() Style { - delete(s.rules, borderRightForegroundKey) + s.unset(borderRightForegroundKey) return s } // UnsetBorderBottomForeground removes the bottom border foreground color // rule, if set. func (s Style) UnsetBorderBottomForeground() Style { - delete(s.rules, borderBottomForegroundKey) + s.unset(borderBottomForegroundKey) return s } // UnsetBorderLeftForeground removes the left border foreground color rule, // if set. func (s Style) UnsetBorderLeftForeground() Style { - delete(s.rules, borderLeftForegroundKey) + s.unset(borderLeftForegroundKey) return s } // UnsetBorderBackground removes all border background color styles, if // set. func (s Style) UnsetBorderBackground() Style { - delete(s.rules, borderTopBackgroundKey) - delete(s.rules, borderRightBackgroundKey) - delete(s.rules, borderBottomBackgroundKey) - delete(s.rules, borderLeftBackgroundKey) + s.unset(borderTopBackgroundKey) + s.unset(borderRightBackgroundKey) + s.unset(borderBottomBackgroundKey) + s.unset(borderLeftBackgroundKey) return s } // UnsetBorderTopBackgroundColor removes the top border background color rule, // if set. func (s Style) UnsetBorderTopBackgroundColor() Style { - delete(s.rules, borderTopBackgroundKey) + s.unset(borderTopBackgroundKey) return s } // UnsetBorderRightBackground removes the right border background color // rule, if set. func (s Style) UnsetBorderRightBackground() Style { - delete(s.rules, borderRightBackgroundKey) + s.unset(borderRightBackgroundKey) return s } // UnsetBorderBottomBackground removes the bottom border background color // rule, if set. func (s Style) UnsetBorderBottomBackground() Style { - delete(s.rules, borderBottomBackgroundKey) + s.unset(borderBottomBackgroundKey) return s } // UnsetBorderLeftBackground removes the left border color rule, if set. func (s Style) UnsetBorderLeftBackground() Style { - delete(s.rules, borderLeftBackgroundKey) + s.unset(borderLeftBackgroundKey) return s } // UnsetInline removes the inline style rule, if set. func (s Style) UnsetInline() Style { - delete(s.rules, inlineKey) + s.unset(inlineKey) return s } // UnsetMaxWidth removes the max width style rule, if set. func (s Style) UnsetMaxWidth() Style { - delete(s.rules, maxWidthKey) + s.unset(maxWidthKey) return s } // UnsetMaxHeight removes the max height style rule, if set. func (s Style) UnsetMaxHeight() Style { - delete(s.rules, maxHeightKey) + s.unset(maxHeightKey) return s } // UnsetTabWidth removes the tab width style rule, if set. func (s Style) UnsetTabWidth() Style { - delete(s.rules, tabWidthKey) + s.unset(tabWidthKey) return s } // UnsetUnderlineSpaces removes the value set by UnderlineSpaces. func (s Style) UnsetUnderlineSpaces() Style { - delete(s.rules, underlineSpacesKey) + s.unset(underlineSpacesKey) return s } // UnsetStrikethroughSpaces removes the value set by StrikethroughSpaces. func (s Style) UnsetStrikethroughSpaces() Style { - delete(s.rules, strikethroughSpacesKey) + s.unset(strikethroughSpacesKey) return s } // UnsetTransform removes the value set by Transform. func (s Style) UnsetTransform() Style { - delete(s.rules, transformKey) + s.unset(transformKey) return s } diff --git a/vendor/github.com/charmbracelet/lipgloss/whitespace.go b/vendor/github.com/charmbracelet/lipgloss/whitespace.go index 78815fe..040dc98 100644 --- a/vendor/github.com/charmbracelet/lipgloss/whitespace.go +++ b/vendor/github.com/charmbracelet/lipgloss/whitespace.go @@ -3,7 +3,7 @@ package lipgloss import ( "strings" - "github.com/muesli/reflow/ansi" + "github.com/charmbracelet/x/ansi" "github.com/muesli/termenv" ) @@ -45,12 +45,12 @@ func (w whitespace) render(width int) string { if j >= len(r) { j = 0 } - i += ansi.PrintableRuneWidth(string(r[j])) + i += ansi.StringWidth(string(r[j])) } // Fill any extra gaps white spaces. This might be necessary if any runes // are more than one cell wide, which could leave a one-rune gap. - short := width - ansi.PrintableRuneWidth(b.String()) + short := width - ansi.StringWidth(b.String()) if short > 0 { b.WriteString(strings.Repeat(" ", short)) } diff --git a/vendor/github.com/charmbracelet/x/ansi/LICENSE b/vendor/github.com/charmbracelet/x/ansi/LICENSE new file mode 100644 index 0000000..65a5654 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Charmbracelet, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/charmbracelet/x/ansi/ansi.go b/vendor/github.com/charmbracelet/x/ansi/ansi.go new file mode 100644 index 0000000..48d873c --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/ansi.go @@ -0,0 +1,11 @@ +package ansi + +import "io" + +// Execute is a function that "execute" the given escape sequence by writing it +// to the provided output writter. +// +// This is a syntactic sugar over [io.WriteString]. +func Execute(w io.Writer, s string) (int, error) { + return io.WriteString(w, s) +} diff --git a/vendor/github.com/charmbracelet/x/ansi/ascii.go b/vendor/github.com/charmbracelet/x/ansi/ascii.go new file mode 100644 index 0000000..188582f --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/ascii.go @@ -0,0 +1,8 @@ +package ansi + +const ( + // SP is the space character (Char: \x20). + SP = 0x20 + // DEL is the delete character (Caret: ^?, Char: \x7f). + DEL = 0x7F +) diff --git a/vendor/github.com/charmbracelet/x/ansi/background.go b/vendor/github.com/charmbracelet/x/ansi/background.go new file mode 100644 index 0000000..f519af0 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/background.go @@ -0,0 +1,61 @@ +package ansi + +import ( + "image/color" +) + +// SetForegroundColor returns a sequence that sets the default terminal +// foreground color. +// +// OSC 10 ; color ST +// OSC 10 ; color BEL +// +// Where color is the encoded color number. +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands +func SetForegroundColor(c color.Color) string { + return "\x1b]10;" + colorToHexString(c) + "\x07" +} + +// RequestForegroundColor is a sequence that requests the current default +// terminal foreground color. +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands +const RequestForegroundColor = "\x1b]10;?\x07" + +// SetBackgroundColor returns a sequence that sets the default terminal +// background color. +// +// OSC 11 ; color ST +// OSC 11 ; color BEL +// +// Where color is the encoded color number. +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands +func SetBackgroundColor(c color.Color) string { + return "\x1b]11;" + colorToHexString(c) + "\x07" +} + +// RequestBackgroundColor is a sequence that requests the current default +// terminal background color. +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands +const RequestBackgroundColor = "\x1b]11;?\x07" + +// SetCursorColor returns a sequence that sets the terminal cursor color. +// +// OSC 12 ; color ST +// OSC 12 ; color BEL +// +// Where color is the encoded color number. +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands +func SetCursorColor(c color.Color) string { + return "\x1b]12;" + colorToHexString(c) + "\x07" +} + +// RequestCursorColor is a sequence that requests the current terminal cursor +// color. +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands +const RequestCursorColor = "\x1b]12;?\x07" diff --git a/vendor/github.com/charmbracelet/x/ansi/c0.go b/vendor/github.com/charmbracelet/x/ansi/c0.go new file mode 100644 index 0000000..13e3c6c --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/c0.go @@ -0,0 +1,72 @@ +package ansi + +// C0 control characters. +// +// These range from (0x00-0x1F) as defined in ISO 646 (ASCII). +// See: https://en.wikipedia.org/wiki/C0_and_C1_control_codes +const ( + // NUL is the null character (Caret: ^@, Char: \0). + NUL = 0x00 + // SOH is the start of heading character (Caret: ^A). + SOH = 0x01 + // STX is the start of text character (Caret: ^B). + STX = 0x02 + // ETX is the end of text character (Caret: ^C). + ETX = 0x03 + // EOT is the end of transmission character (Caret: ^D). + EOT = 0x04 + // ENQ is the enquiry character (Caret: ^E). + ENQ = 0x05 + // ACK is the acknowledge character (Caret: ^F). + ACK = 0x06 + // BEL is the bell character (Caret: ^G, Char: \a). + BEL = 0x07 + // BS is the backspace character (Caret: ^H, Char: \b). + BS = 0x08 + // HT is the horizontal tab character (Caret: ^I, Char: \t). + HT = 0x09 + // LF is the line feed character (Caret: ^J, Char: \n). + LF = 0x0A + // VT is the vertical tab character (Caret: ^K, Char: \v). + VT = 0x0B + // FF is the form feed character (Caret: ^L, Char: \f). + FF = 0x0C + // CR is the carriage return character (Caret: ^M, Char: \r). + CR = 0x0D + // SO is the shift out character (Caret: ^N). + SO = 0x0E + // SI is the shift in character (Caret: ^O). + SI = 0x0F + // DLE is the data link escape character (Caret: ^P). + DLE = 0x10 + // DC1 is the device control 1 character (Caret: ^Q). + DC1 = 0x11 + // DC2 is the device control 2 character (Caret: ^R). + DC2 = 0x12 + // DC3 is the device control 3 character (Caret: ^S). + DC3 = 0x13 + // DC4 is the device control 4 character (Caret: ^T). + DC4 = 0x14 + // NAK is the negative acknowledge character (Caret: ^U). + NAK = 0x15 + // SYN is the synchronous idle character (Caret: ^V). + SYN = 0x16 + // ETB is the end of transmission block character (Caret: ^W). + ETB = 0x17 + // CAN is the cancel character (Caret: ^X). + CAN = 0x18 + // EM is the end of medium character (Caret: ^Y). + EM = 0x19 + // SUB is the substitute character (Caret: ^Z). + SUB = 0x1A + // ESC is the escape character (Caret: ^[, Char: \e). + ESC = 0x1B + // FS is the file separator character (Caret: ^\). + FS = 0x1C + // GS is the group separator character (Caret: ^]). + GS = 0x1D + // RS is the record separator character (Caret: ^^). + RS = 0x1E + // US is the unit separator character (Caret: ^_). + US = 0x1F +) diff --git a/vendor/github.com/charmbracelet/x/ansi/c1.go b/vendor/github.com/charmbracelet/x/ansi/c1.go new file mode 100644 index 0000000..71058f5 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/c1.go @@ -0,0 +1,72 @@ +package ansi + +// C1 control characters. +// +// These range from (0x80-0x9F) as defined in ISO 6429 (ECMA-48). +// See: https://en.wikipedia.org/wiki/C0_and_C1_control_codes +const ( + // PAD is the padding character. + PAD = 0x80 + // HOP is the high octet preset character. + HOP = 0x81 + // BPH is the break permitted here character. + BPH = 0x82 + // NBH is the no break here character. + NBH = 0x83 + // IND is the index character. + IND = 0x84 + // NEL is the next line character. + NEL = 0x85 + // SSA is the start of selected area character. + SSA = 0x86 + // ESA is the end of selected area character. + ESA = 0x87 + // HTS is the horizontal tab set character. + HTS = 0x88 + // HTJ is the horizontal tab with justification character. + HTJ = 0x89 + // VTS is the vertical tab set character. + VTS = 0x8A + // PLD is the partial line forward character. + PLD = 0x8B + // PLU is the partial line backward character. + PLU = 0x8C + // RI is the reverse index character. + RI = 0x8D + // SS2 is the single shift 2 character. + SS2 = 0x8E + // SS3 is the single shift 3 character. + SS3 = 0x8F + // DCS is the device control string character. + DCS = 0x90 + // PU1 is the private use 1 character. + PU1 = 0x91 + // PU2 is the private use 2 character. + PU2 = 0x92 + // STS is the set transmit state character. + STS = 0x93 + // CCH is the cancel character. + CCH = 0x94 + // MW is the message waiting character. + MW = 0x95 + // SPA is the start of guarded area character. + SPA = 0x96 + // EPA is the end of guarded area character. + EPA = 0x97 + // SOS is the start of string character. + SOS = 0x98 + // SGCI is the single graphic character introducer character. + SGCI = 0x99 + // SCI is the single character introducer character. + SCI = 0x9A + // CSI is the control sequence introducer character. + CSI = 0x9B + // ST is the string terminator character. + ST = 0x9C + // OSC is the operating system command character. + OSC = 0x9D + // PM is the privacy message character. + PM = 0x9E + // APC is the application program command character. + APC = 0x9F +) diff --git a/vendor/github.com/charmbracelet/x/ansi/clipboard.go b/vendor/github.com/charmbracelet/x/ansi/clipboard.go new file mode 100644 index 0000000..94d26c3 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/clipboard.go @@ -0,0 +1,75 @@ +package ansi + +import "encoding/base64" + +// Clipboard names. +const ( + SystemClipboard = 'c' + PrimaryClipboard = 'p' +) + +// SetClipboard returns a sequence for manipulating the clipboard. +// +// OSC 52 ; Pc ; Pd ST +// OSC 52 ; Pc ; Pd BEL +// +// Where Pc is the clipboard name and Pd is the base64 encoded data. +// Empty data or invalid base64 data will reset the clipboard. +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands +func SetClipboard(c byte, d string) string { + if d != "" { + d = base64.StdEncoding.EncodeToString([]byte(d)) + } + return "\x1b]52;" + string(c) + ";" + d + "\x07" +} + +// SetSystemClipboard returns a sequence for setting the system clipboard. +// +// This is equivalent to SetClipboard(SystemClipboard, d). +func SetSystemClipboard(d string) string { + return SetClipboard(SystemClipboard, d) +} + +// SetPrimaryClipboard returns a sequence for setting the primary clipboard. +// +// This is equivalent to SetClipboard(PrimaryClipboard, d). +func SetPrimaryClipboard(d string) string { + return SetClipboard(PrimaryClipboard, d) +} + +// ResetClipboard returns a sequence for resetting the clipboard. +// +// This is equivalent to SetClipboard(c, ""). +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands +func ResetClipboard(c byte) string { + return SetClipboard(c, "") +} + +// ResetSystemClipboard is a sequence for resetting the system clipboard. +// +// This is equivalent to ResetClipboard(SystemClipboard). +const ResetSystemClipboard = "\x1b]52;c;\x07" + +// ResetPrimaryClipboard is a sequence for resetting the primary clipboard. +// +// This is equivalent to ResetClipboard(PrimaryClipboard). +const ResetPrimaryClipboard = "\x1b]52;p;\x07" + +// RequestClipboard returns a sequence for requesting the clipboard. +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands +func RequestClipboard(c byte) string { + return "\x1b]52;" + string(c) + ";?\x07" +} + +// RequestSystemClipboard is a sequence for requesting the system clipboard. +// +// This is equivalent to RequestClipboard(SystemClipboard). +const RequestSystemClipboard = "\x1b]52;c;?\x07" + +// RequestPrimaryClipboard is a sequence for requesting the primary clipboard. +// +// This is equivalent to RequestClipboard(PrimaryClipboard). +const RequestPrimaryClipboard = "\x1b]52;p;?\x07" diff --git a/vendor/github.com/charmbracelet/x/ansi/color.go b/vendor/github.com/charmbracelet/x/ansi/color.go new file mode 100644 index 0000000..2ff78bd --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/color.go @@ -0,0 +1,196 @@ +package ansi + +import ( + "image/color" +) + +// Technically speaking, the 16 basic ANSI colors are arbitrary and can be +// customized at the terminal level. Given that, we're returning what we feel +// are good defaults. +// +// This could also be a slice, but we use a map to make the mappings very +// explicit. +// +// See: https://www.ditig.com/publications/256-colors-cheat-sheet +var lowANSI = map[uint32]uint32{ + 0: 0x000000, // black + 1: 0x800000, // red + 2: 0x008000, // green + 3: 0x808000, // yellow + 4: 0x000080, // blue + 5: 0x800080, // magenta + 6: 0x008080, // cyan + 7: 0xc0c0c0, // white + 8: 0x808080, // bright black + 9: 0xff0000, // bright red + 10: 0x00ff00, // bright green + 11: 0xffff00, // bright yellow + 12: 0x0000ff, // bright blue + 13: 0xff00ff, // bright magenta + 14: 0x00ffff, // bright cyan + 15: 0xffffff, // bright white +} + +// Color is a color that can be used in a terminal. ANSI (including +// ANSI256) and 24-bit "true colors" fall under this category. +type Color interface { + color.Color +} + +// BasicColor is an ANSI 3-bit or 4-bit color with a value from 0 to 15. +type BasicColor uint8 + +var _ Color = BasicColor(0) + +const ( + // Black is the ANSI black color. + Black BasicColor = iota + + // Red is the ANSI red color. + Red + + // Green is the ANSI green color. + Green + + // Yellow is the ANSI yellow color. + Yellow + + // Blue is the ANSI blue color. + Blue + + // Magenta is the ANSI magenta color. + Magenta + + // Cyan is the ANSI cyan color. + Cyan + + // White is the ANSI white color. + White + + // BrightBlack is the ANSI bright black color. + BrightBlack + + // BrightRed is the ANSI bright red color. + BrightRed + + // BrightGreen is the ANSI bright green color. + BrightGreen + + // BrightYellow is the ANSI bright yellow color. + BrightYellow + + // BrightBlue is the ANSI bright blue color. + BrightBlue + + // BrightMagenta is the ANSI bright magenta color. + BrightMagenta + + // BrightCyan is the ANSI bright cyan color. + BrightCyan + + // BrightWhite is the ANSI bright white color. + BrightWhite +) + +// RGBA returns the red, green, blue and alpha components of the color. It +// satisfies the color.Color interface. +func (c BasicColor) RGBA() (uint32, uint32, uint32, uint32) { + ansi := uint32(c) + if ansi > 15 { + return 0, 0, 0, 0xffff + } + + r, g, b := ansiToRGB(ansi) + return toRGBA(r, g, b) +} + +// ExtendedColor is an ANSI 256 (8-bit) color with a value from 0 to 255. +type ExtendedColor uint8 + +var _ Color = ExtendedColor(0) + +// RGBA returns the red, green, blue and alpha components of the color. It +// satisfies the color.Color interface. +func (c ExtendedColor) RGBA() (uint32, uint32, uint32, uint32) { + r, g, b := ansiToRGB(uint32(c)) + return toRGBA(r, g, b) +} + +// TrueColor is a 24-bit color that can be used in the terminal. +// This can be used to represent RGB colors. +// +// For example, the color red can be represented as: +// +// TrueColor(0xff0000) +type TrueColor uint32 + +var _ Color = TrueColor(0) + +// RGBA returns the red, green, blue and alpha components of the color. It +// satisfies the color.Color interface. +func (c TrueColor) RGBA() (uint32, uint32, uint32, uint32) { + r, g, b := hexToRGB(uint32(c)) + return toRGBA(r, g, b) +} + +// ansiToRGB converts an ANSI color to a 24-bit RGB color. +// +// r, g, b := ansiToRGB(57) +func ansiToRGB(ansi uint32) (uint32, uint32, uint32) { + // For out-of-range values return black. + if ansi > 255 { + return 0, 0, 0 + } + + // Low ANSI. + if ansi < 16 { + h, ok := lowANSI[ansi] + if !ok { + return 0, 0, 0 + } + r, g, b := hexToRGB(h) + return r, g, b + } + + // Grays. + if ansi > 231 { + s := (ansi-232)*10 + 8 + return s, s, s + } + + // ANSI256. + n := ansi - 16 + b := n % 6 + g := (n - b) / 6 % 6 + r := (n - b - g*6) / 36 % 6 + for _, v := range []*uint32{&r, &g, &b} { + if *v > 0 { + c := *v*40 + 55 + *v = c + } + } + + return r, g, b +} + +// hexToRGB converts a number in hexadecimal format to red, green, and blue +// values. +// +// r, g, b := hexToRGB(0x0000FF) +func hexToRGB(hex uint32) (uint32, uint32, uint32) { + return hex >> 16, hex >> 8 & 0xff, hex & 0xff +} + +// toRGBA converts an RGB 8-bit color values to 32-bit color values suitable +// for color.Color. +// +// color.Color requires 16-bit color values, so we duplicate the 8-bit values +// to fill the 16-bit values. +// +// This always returns 0xffff (opaque) for the alpha channel. +func toRGBA(r, g, b uint32) (uint32, uint32, uint32, uint32) { + r |= r << 8 + g |= g << 8 + b |= b << 8 + return r, g, b, 0xffff +} diff --git a/vendor/github.com/charmbracelet/x/ansi/csi.go b/vendor/github.com/charmbracelet/x/ansi/csi.go new file mode 100644 index 0000000..b7e5bd2 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/csi.go @@ -0,0 +1,141 @@ +package ansi + +import ( + "bytes" + "strconv" + + "github.com/charmbracelet/x/ansi/parser" +) + +// CsiSequence represents a control sequence introducer (CSI) sequence. +// +// The sequence starts with a CSI sequence, CSI (0x9B) in a 8-bit environment +// or ESC [ (0x1B 0x5B) in a 7-bit environment, followed by any number of +// parameters in the range of 0x30-0x3F, then by any number of intermediate +// byte in the range of 0x20-0x2F, then finally with a single final byte in the +// range of 0x20-0x7E. +// +// CSI P..P I..I F +// +// See ECMA-48 § 5.4. +type CsiSequence struct { + // Params contains the raw parameters of the sequence. + // This is a slice of integers, where each integer is a 32-bit integer + // containing the parameter value in the lower 31 bits and a flag in the + // most significant bit indicating whether there are more sub-parameters. + Params []int + + // Cmd contains the raw command of the sequence. + // The command is a 32-bit integer containing the CSI command byte in the + // lower 8 bits, the private marker in the next 8 bits, and the intermediate + // byte in the next 8 bits. + // + // CSI ? u + // + // Is represented as: + // + // 'u' | '?' << 8 + Cmd int +} + +var _ Sequence = CsiSequence{} + +// Marker returns the marker byte of the CSI sequence. +// This is always gonna be one of the following '<' '=' '>' '?' and in the +// range of 0x3C-0x3F. +// Zero is returned if the sequence does not have a marker. +func (s CsiSequence) Marker() int { + return parser.Marker(s.Cmd) +} + +// Intermediate returns the intermediate byte of the CSI sequence. +// An intermediate byte is in the range of 0x20-0x2F. This includes these +// characters from ' ', '!', '"', '#', '$', '%', '&', ”', '(', ')', '*', '+', +// ',', '-', '.', '/'. +// Zero is returned if the sequence does not have an intermediate byte. +func (s CsiSequence) Intermediate() int { + return parser.Intermediate(s.Cmd) +} + +// Command returns the command byte of the CSI sequence. +func (s CsiSequence) Command() int { + return parser.Command(s.Cmd) +} + +// Param returns the parameter at the given index. +// It returns -1 if the parameter does not exist. +func (s CsiSequence) Param(i int) int { + return parser.Param(s.Params, i) +} + +// HasMore returns true if the parameter has more sub-parameters. +func (s CsiSequence) HasMore(i int) bool { + return parser.HasMore(s.Params, i) +} + +// Subparams returns the sub-parameters of the given parameter. +// It returns nil if the parameter does not exist. +func (s CsiSequence) Subparams(i int) []int { + return parser.Subparams(s.Params, i) +} + +// Len returns the number of parameters in the sequence. +// This will return the number of parameters in the sequence, excluding any +// sub-parameters. +func (s CsiSequence) Len() int { + return parser.Len(s.Params) +} + +// Range iterates over the parameters of the sequence and calls the given +// function for each parameter. +// The function should return false to stop the iteration. +func (s CsiSequence) Range(fn func(i int, param int, hasMore bool) bool) { + parser.Range(s.Params, fn) +} + +// Clone returns a copy of the CSI sequence. +func (s CsiSequence) Clone() Sequence { + return CsiSequence{ + Params: append([]int(nil), s.Params...), + Cmd: s.Cmd, + } +} + +// String returns a string representation of the sequence. +// The string will always be in the 7-bit format i.e (ESC [ P..P I..I F). +func (s CsiSequence) String() string { + return s.buffer().String() +} + +// buffer returns a buffer containing the sequence. +func (s CsiSequence) buffer() *bytes.Buffer { + var b bytes.Buffer + b.WriteString("\x1b[") + if m := s.Marker(); m != 0 { + b.WriteByte(byte(m)) + } + s.Range(func(i, param int, hasMore bool) bool { + if param >= 0 { + b.WriteString(strconv.Itoa(param)) + } + if i < len(s.Params)-1 { + if hasMore { + b.WriteByte(':') + } else { + b.WriteByte(';') + } + } + return true + }) + if i := s.Intermediate(); i != 0 { + b.WriteByte(byte(i)) + } + b.WriteByte(byte(s.Command())) + return &b +} + +// Bytes returns the byte representation of the sequence. +// The bytes will always be in the 7-bit format i.e (ESC [ P..P I..I F). +func (s CsiSequence) Bytes() []byte { + return s.buffer().Bytes() +} diff --git a/vendor/github.com/charmbracelet/x/ansi/ctrl.go b/vendor/github.com/charmbracelet/x/ansi/ctrl.go new file mode 100644 index 0000000..21beb9c --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/ctrl.go @@ -0,0 +1,17 @@ +package ansi + +// RequestXTVersion is a control sequence that requests the terminal's XTVERSION. It responds with a DSR sequence identifying the version. +// +// CSI > Ps q +// DCS > | text ST +// +// See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-PC-Style-Function-Keys +const RequestXTVersion = "\x1b[>0q" + +// RequestPrimaryDeviceAttributes is a control sequence that requests the +// terminal's primary device attributes (DA1). +// +// CSI c +// +// See https://vt100.net/docs/vt510-rm/DA1.html +const RequestPrimaryDeviceAttributes = "\x1b[c" diff --git a/vendor/github.com/charmbracelet/x/ansi/cursor.go b/vendor/github.com/charmbracelet/x/ansi/cursor.go new file mode 100644 index 0000000..5f010fd --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/cursor.go @@ -0,0 +1,190 @@ +package ansi + +import "strconv" + +// SaveCursor (DECSC) is an escape sequence that saves the current cursor +// position. +// +// ESC 7 +// +// See: https://vt100.net/docs/vt510-rm/DECSC.html +const SaveCursor = "\x1b7" + +// RestoreCursor (DECRC) is an escape sequence that restores the cursor +// position. +// +// ESC 8 +// +// See: https://vt100.net/docs/vt510-rm/DECRC.html +const RestoreCursor = "\x1b8" + +// RequestCursorPosition (CPR) is an escape sequence that requests the current +// cursor position. +// +// CSI 6 n +// +// The terminal will report the cursor position as a CSI sequence in the +// following format: +// +// CSI Pl ; Pc R +// +// Where Pl is the line number and Pc is the column number. +// See: https://vt100.net/docs/vt510-rm/CPR.html +const RequestCursorPosition = "\x1b[6n" + +// RequestExtendedCursorPosition (DECXCPR) is a sequence for requesting the +// cursor position report including the current page number. +// +// CSI ? 6 n +// +// The terminal will report the cursor position as a CSI sequence in the +// following format: +// +// CSI ? Pl ; Pc ; Pp R +// +// Where Pl is the line number, Pc is the column number, and Pp is the page +// number. +// See: https://vt100.net/docs/vt510-rm/DECXCPR.html +const RequestExtendedCursorPosition = "\x1b[?6n" + +// CursorUp (CUU) returns a sequence for moving the cursor up n cells. +// +// CSI n A +// +// See: https://vt100.net/docs/vt510-rm/CUU.html +func CursorUp(n int) string { + var s string + if n > 1 { + s = strconv.Itoa(n) + } + return "\x1b[" + s + "A" +} + +// CursorUp1 is a sequence for moving the cursor up one cell. +// +// This is equivalent to CursorUp(1). +const CursorUp1 = "\x1b[A" + +// CursorDown (CUD) returns a sequence for moving the cursor down n cells. +// +// CSI n B +// +// See: https://vt100.net/docs/vt510-rm/CUD.html +func CursorDown(n int) string { + var s string + if n > 1 { + s = strconv.Itoa(n) + } + return "\x1b[" + s + "B" +} + +// CursorDown1 is a sequence for moving the cursor down one cell. +// +// This is equivalent to CursorDown(1). +const CursorDown1 = "\x1b[B" + +// CursorRight (CUF) returns a sequence for moving the cursor right n cells. +// +// CSI n C +// +// See: https://vt100.net/docs/vt510-rm/CUF.html +func CursorRight(n int) string { + var s string + if n > 1 { + s = strconv.Itoa(n) + } + return "\x1b[" + s + "C" +} + +// CursorRight1 is a sequence for moving the cursor right one cell. +// +// This is equivalent to CursorRight(1). +const CursorRight1 = "\x1b[C" + +// CursorLeft (CUB) returns a sequence for moving the cursor left n cells. +// +// CSI n D +// +// See: https://vt100.net/docs/vt510-rm/CUB.html +func CursorLeft(n int) string { + var s string + if n > 1 { + s = strconv.Itoa(n) + } + return "\x1b[" + s + "D" +} + +// CursorLeft1 is a sequence for moving the cursor left one cell. +// +// This is equivalent to CursorLeft(1). +const CursorLeft1 = "\x1b[D" + +// CursorNextLine (CNL) returns a sequence for moving the cursor to the +// beginning of the next line n times. +// +// CSI n E +// +// See: https://vt100.net/docs/vt510-rm/CNL.html +func CursorNextLine(n int) string { + var s string + if n > 1 { + s = strconv.Itoa(n) + } + return "\x1b[" + s + "E" +} + +// CursorPreviousLine (CPL) returns a sequence for moving the cursor to the +// beginning of the previous line n times. +// +// CSI n F +// +// See: https://vt100.net/docs/vt510-rm/CPL.html +func CursorPreviousLine(n int) string { + var s string + if n > 1 { + s = strconv.Itoa(n) + } + return "\x1b[" + s + "F" +} + +// MoveCursor (CUP) returns a sequence for moving the cursor to the given row +// and column. +// +// CSI n ; m H +// +// See: https://vt100.net/docs/vt510-rm/CUP.html +func MoveCursor(row, col int) string { + if row < 0 { + row = 0 + } + if col < 0 { + col = 0 + } + return "\x1b[" + strconv.Itoa(row) + ";" + strconv.Itoa(col) + "H" +} + +// MoveCursorOrigin is a sequence for moving the cursor to the upper left +// corner of the screen. This is equivalent to MoveCursor(1, 1). +const MoveCursorOrigin = "\x1b[1;1H" + +// SaveCursorPosition (SCP or SCOSC) is a sequence for saving the cursor +// position. +// +// CSI s +// +// This acts like Save, except the page number where the cursor is located is +// not saved. +// +// See: https://vt100.net/docs/vt510-rm/SCOSC.html +const SaveCursorPosition = "\x1b[s" + +// RestoreCursorPosition (RCP or SCORC) is a sequence for restoring the cursor +// position. +// +// CSI u +// +// This acts like Restore, except the cursor stays on the same page where the +// cursor was saved. +// +// See: https://vt100.net/docs/vt510-rm/SCORC.html +const RestoreCursorPosition = "\x1b[u" diff --git a/vendor/github.com/charmbracelet/x/ansi/dcs.go b/vendor/github.com/charmbracelet/x/ansi/dcs.go new file mode 100644 index 0000000..185f0b5 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/dcs.go @@ -0,0 +1,148 @@ +package ansi + +import ( + "bytes" + "strconv" + + "github.com/charmbracelet/x/ansi/parser" +) + +// DcsSequence represents a Device Control String (DCS) escape sequence. +// +// The DCS sequence is used to send device control strings to the terminal. The +// sequence starts with the C1 control code character DCS (0x9B) or ESC P in +// 7-bit environments, followed by parameter bytes, intermediate bytes, a +// command byte, followed by data bytes, and ends with the C1 control code +// character ST (0x9C) or ESC \ in 7-bit environments. +// +// This follows the parameter string format. +// See ECMA-48 § 5.4.1 +type DcsSequence struct { + // Params contains the raw parameters of the sequence. + // This is a slice of integers, where each integer is a 32-bit integer + // containing the parameter value in the lower 31 bits and a flag in the + // most significant bit indicating whether there are more sub-parameters. + Params []int + + // Data contains the string raw data of the sequence. + // This is the data between the final byte and the escape sequence terminator. + Data []byte + + // Cmd contains the raw command of the sequence. + // The command is a 32-bit integer containing the DCS command byte in the + // lower 8 bits, the private marker in the next 8 bits, and the intermediate + // byte in the next 8 bits. + // + // DCS > 0 ; 1 $ r ST + // + // Is represented as: + // + // 'r' | '>' << 8 | '$' << 16 + Cmd int +} + +var _ Sequence = DcsSequence{} + +// Marker returns the marker byte of the DCS sequence. +// This is always gonna be one of the following '<' '=' '>' '?' and in the +// range of 0x3C-0x3F. +// Zero is returned if the sequence does not have a marker. +func (s DcsSequence) Marker() int { + return parser.Marker(s.Cmd) +} + +// Intermediate returns the intermediate byte of the DCS sequence. +// An intermediate byte is in the range of 0x20-0x2F. This includes these +// characters from ' ', '!', '"', '#', '$', '%', '&', ”', '(', ')', '*', '+', +// ',', '-', '.', '/'. +// Zero is returned if the sequence does not have an intermediate byte. +func (s DcsSequence) Intermediate() int { + return parser.Intermediate(s.Cmd) +} + +// Command returns the command byte of the CSI sequence. +func (s DcsSequence) Command() int { + return parser.Command(s.Cmd) +} + +// Param returns the parameter at the given index. +// It returns -1 if the parameter does not exist. +func (s DcsSequence) Param(i int) int { + return parser.Param(s.Params, i) +} + +// HasMore returns true if the parameter has more sub-parameters. +func (s DcsSequence) HasMore(i int) bool { + return parser.HasMore(s.Params, i) +} + +// Subparams returns the sub-parameters of the given parameter. +// It returns nil if the parameter does not exist. +func (s DcsSequence) Subparams(i int) []int { + return parser.Subparams(s.Params, i) +} + +// Len returns the number of parameters in the sequence. +// This will return the number of parameters in the sequence, excluding any +// sub-parameters. +func (s DcsSequence) Len() int { + return parser.Len(s.Params) +} + +// Range iterates over the parameters of the sequence and calls the given +// function for each parameter. +// The function should return false to stop the iteration. +func (s DcsSequence) Range(fn func(i int, param int, hasMore bool) bool) { + parser.Range(s.Params, fn) +} + +// Clone returns a copy of the DCS sequence. +func (s DcsSequence) Clone() Sequence { + return DcsSequence{ + Params: append([]int(nil), s.Params...), + Data: append([]byte(nil), s.Data...), + Cmd: s.Cmd, + } +} + +// String returns a string representation of the sequence. +// The string will always be in the 7-bit format i.e (ESC P p..p i..i f ESC \). +func (s DcsSequence) String() string { + return s.buffer().String() +} + +// buffer returns a buffer containing the sequence. +func (s DcsSequence) buffer() *bytes.Buffer { + var b bytes.Buffer + b.WriteString("\x1bP") + if m := s.Marker(); m != 0 { + b.WriteByte(byte(m)) + } + s.Range(func(i, param int, hasMore bool) bool { + if param >= -1 { + b.WriteString(strconv.Itoa(param)) + } + if i < len(s.Params)-1 { + if hasMore { + b.WriteByte(':') + } else { + b.WriteByte(';') + } + } + return true + }) + if i := s.Intermediate(); i != 0 { + b.WriteByte(byte(i)) + } + b.WriteByte(byte(s.Command())) + b.Write(s.Data) + b.WriteByte(ESC) + b.WriteByte('\\') + return &b +} + +// Bytes returns the byte representation of the sequence. +// The bytes will always be in the 7-bit format i.e (ESC P p..p i..i F ESC \). +func (s DcsSequence) Bytes() []byte { + return s.buffer().Bytes() +} diff --git a/vendor/github.com/charmbracelet/x/ansi/doc.go b/vendor/github.com/charmbracelet/x/ansi/doc.go new file mode 100644 index 0000000..e955e9f --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/doc.go @@ -0,0 +1,7 @@ +// Package ansi defines common ANSI escape sequences based on the ECMA-48 +// specs. +// +// All sequences use 7-bit C1 control codes, which are supported by most +// terminal emulators. OSC sequences are terminated by a BEL for wider +// compatibility with terminals. +package ansi diff --git a/vendor/github.com/charmbracelet/x/ansi/hyperlink.go b/vendor/github.com/charmbracelet/x/ansi/hyperlink.go new file mode 100644 index 0000000..323bfe9 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/hyperlink.go @@ -0,0 +1,28 @@ +package ansi + +import "strings" + +// SetHyperlink returns a sequence for starting a hyperlink. +// +// OSC 8 ; Params ; Uri ST +// OSC 8 ; Params ; Uri BEL +// +// To reset the hyperlink, omit the URI. +// +// See: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda +func SetHyperlink(uri string, params ...string) string { + var p string + if len(params) > 0 { + p = strings.Join(params, ":") + } + return "\x1b]8;" + p + ";" + uri + "\x07" +} + +// ResetHyperlink returns a sequence for resetting the hyperlink. +// +// This is equivalent to SetHyperlink("", params...). +// +// See: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda +func ResetHyperlink(params ...string) string { + return SetHyperlink("", params...) +} diff --git a/vendor/github.com/charmbracelet/x/ansi/kitty.go b/vendor/github.com/charmbracelet/x/ansi/kitty.go new file mode 100644 index 0000000..5bf8981 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/kitty.go @@ -0,0 +1,58 @@ +package ansi + +import "strconv" + +// Kitty keyboard protocol progressive enhancement flags. +// See: https://sw.kovidgoyal.net/kitty/keyboard-protocol/#progressive-enhancement +const ( + KittyDisambiguateEscapeCodes = 1 << iota + KittyReportEventTypes + KittyReportAlternateKeys + KittyReportAllKeys + KittyReportAssociatedKeys + + KittyAllFlags = KittyDisambiguateEscapeCodes | KittyReportEventTypes | + KittyReportAlternateKeys | KittyReportAllKeys | KittyReportAssociatedKeys +) + +// RequestKittyKeyboard is a sequence to request the terminal Kitty keyboard +// protocol enabled flags. +// +// See: https://sw.kovidgoyal.net/kitty/keyboard-protocol/ +const RequestKittyKeyboard = "\x1b[?u" + +// PushKittyKeyboard returns a sequence to push the given flags to the terminal +// Kitty Keyboard stack. +// +// CSI > flags u +// +// See https://sw.kovidgoyal.net/kitty/keyboard-protocol/#progressive-enhancement +func PushKittyKeyboard(flags int) string { + var f string + if flags > 0 { + f = strconv.Itoa(flags) + } + + return "\x1b[>" + f + "u" +} + +// DisableKittyKeyboard is a sequence to push zero into the terminal Kitty +// Keyboard stack to disable the protocol. +// +// This is equivalent to PushKittyKeyboard(0). +const DisableKittyKeyboard = "\x1b[>0u" + +// PopKittyKeyboard returns a sequence to pop n number of flags from the +// terminal Kitty Keyboard stack. +// +// CSI < flags u +// +// See https://sw.kovidgoyal.net/kitty/keyboard-protocol/#progressive-enhancement +func PopKittyKeyboard(n int) string { + var num string + if n > 0 { + num = strconv.Itoa(n) + } + + return "\x1b[<" + num + "u" +} diff --git a/vendor/github.com/charmbracelet/x/ansi/mode.go b/vendor/github.com/charmbracelet/x/ansi/mode.go new file mode 100644 index 0000000..4c39e78 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/mode.go @@ -0,0 +1,132 @@ +package ansi + +// This file define uses multiple sequences to set (SM), reset (RM), and request +// (DECRQM) different ANSI and DEC modes. +// +// See: https://vt100.net/docs/vt510-rm/SM.html +// See: https://vt100.net/docs/vt510-rm/RM.html +// See: https://vt100.net/docs/vt510-rm/DECRQM.html +// +// The terminal then responds to the request with a Report Mode function +// (DECRPM) in the format: +// +// ANSI format: +// +// CSI Pa ; Ps ; $ y +// +// DEC format: +// +// CSI ? Pa ; Ps $ y +// +// Where Pa is the mode number, and Ps is the mode value. +// See: https://vt100.net/docs/vt510-rm/DECRPM.html + +// Application Cursor Keys (DECCKM) is a mode that determines whether the +// cursor keys send ANSI cursor sequences or application sequences. +// +// See: https://vt100.net/docs/vt510-rm/DECCKM.html +const ( + EnableCursorKeys = "\x1b[?1h" + DisableCursorKeys = "\x1b[?1l" + RequestCursorKeys = "\x1b[?1$p" +) + +// Text Cursor Enable Mode (DECTCEM) is a mode that shows/hides the cursor. +// +// See: https://vt100.net/docs/vt510-rm/DECTCEM.html +const ( + ShowCursor = "\x1b[?25h" + HideCursor = "\x1b[?25l" + RequestCursorVisibility = "\x1b[?25$p" +) + +// VT Mouse Tracking is a mode that determines whether the mouse reports on +// button press and release. +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking +const ( + EnableMouse = "\x1b[?1000h" + DisableMouse = "\x1b[?1000l" + RequestMouse = "\x1b[?1000$p" +) + +// VT Hilite Mouse Tracking is a mode that determines whether the mouse reports on +// button presses, releases, and highlighted cells. +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking +const ( + EnableMouseHilite = "\x1b[?1001h" + DisableMouseHilite = "\x1b[?1001l" + RequestMouseHilite = "\x1b[?1001$p" +) + +// Cell Motion Mouse Tracking is a mode that determines whether the mouse +// reports on button press, release, and motion events. +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking +const ( + EnableMouseCellMotion = "\x1b[?1002h" + DisableMouseCellMotion = "\x1b[?1002l" + RequestMouseCellMotion = "\x1b[?1002$p" +) + +// All Mouse Tracking is a mode that determines whether the mouse reports on +// button press, release, motion, and highlight events. +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking +const ( + EnableMouseAllMotion = "\x1b[?1003h" + DisableMouseAllMotion = "\x1b[?1003l" + RequestMouseAllMotion = "\x1b[?1003$p" +) + +// SGR Mouse Extension is a mode that determines whether the mouse reports events +// formatted with SGR parameters. +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking +const ( + EnableMouseSgrExt = "\x1b[?1006h" + DisableMouseSgrExt = "\x1b[?1006l" + RequestMouseSgrExt = "\x1b[?1006$p" +) + +// Alternate Screen Buffer is a mode that determines whether the alternate screen +// buffer is active. +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer +const ( + EnableAltScreenBuffer = "\x1b[?1049h" + DisableAltScreenBuffer = "\x1b[?1049l" + RequestAltScreenBuffer = "\x1b[?1049$p" +) + +// Bracketed Paste Mode is a mode that determines whether pasted text is +// bracketed with escape sequences. +// +// See: https://cirw.in/blog/bracketed-paste +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Bracketed-Paste-Mode +const ( + EnableBracketedPaste = "\x1b[?2004h" + DisableBracketedPaste = "\x1b[?2004l" + RequestBracketedPaste = "\x1b[?2004$p" +) + +// Synchronized Output Mode is a mode that determines whether output is +// synchronized with the terminal. +// +// See: https://gist.github.com/christianparpart/d8a62cc1ab659194337d73e399004036 +const ( + EnableSyncdOutput = "\x1b[?2026h" + DisableSyncdOutput = "\x1b[?2026l" + RequestSyncdOutput = "\x1b[?2026$p" +) + +// Win32Input is a mode that determines whether input is processed by the +// Win32 console and Conpty. +// +// See: https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md +const ( + EnableWin32Input = "\x1b[?9001h" + DisableWin32Input = "\x1b[?9001l" + RequestWin32Input = "\x1b[?9001$p" +) diff --git a/vendor/github.com/charmbracelet/x/ansi/osc.go b/vendor/github.com/charmbracelet/x/ansi/osc.go new file mode 100644 index 0000000..40b543c --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/osc.go @@ -0,0 +1,69 @@ +package ansi + +import ( + "bytes" + "strings" +) + +// OscSequence represents an OSC sequence. +// +// The sequence starts with a OSC sequence, OSC (0x9D) in a 8-bit environment +// or ESC ] (0x1B 0x5D) in a 7-bit environment, followed by positive integer identifier, +// then by arbitrary data terminated by a ST (0x9C) in a 8-bit environment, +// ESC \ (0x1B 0x5C) in a 7-bit environment, or BEL (0x07) for backwards compatibility. +// +// OSC Ps ; Pt ST +// OSC Ps ; Pt BEL +// +// See ECMA-48 § 5.7. +type OscSequence struct { + // Data contains the raw data of the sequence including the identifier + // command. + Data []byte + + // Cmd contains the raw command of the sequence. + Cmd int +} + +var _ Sequence = OscSequence{} + +// Command returns the command of the OSC sequence. +func (s OscSequence) Command() int { + return s.Cmd +} + +// Params returns the parameters of the OSC sequence split by ';'. +// The first element is the identifier command. +func (s OscSequence) Params() []string { + return strings.Split(string(s.Data), ";") +} + +// Clone returns a copy of the OSC sequence. +func (s OscSequence) Clone() Sequence { + return OscSequence{ + Data: append([]byte(nil), s.Data...), + Cmd: s.Cmd, + } +} + +// String returns the string representation of the OSC sequence. +// To be more compatible with different terminal, this will always return a +// 7-bit formatted sequence, terminated by BEL. +func (s OscSequence) String() string { + return s.buffer().String() +} + +// Bytes returns the byte representation of the OSC sequence. +// To be more compatible with different terminal, this will always return a +// 7-bit formatted sequence, terminated by BEL. +func (s OscSequence) Bytes() []byte { + return s.buffer().Bytes() +} + +func (s OscSequence) buffer() *bytes.Buffer { + var b bytes.Buffer + b.WriteString("\x1b]") + b.Write(s.Data) + b.WriteByte(BEL) + return &b +} diff --git a/vendor/github.com/charmbracelet/x/ansi/params.go b/vendor/github.com/charmbracelet/x/ansi/params.go new file mode 100644 index 0000000..a1bb424 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/params.go @@ -0,0 +1,45 @@ +package ansi + +import ( + "bytes" +) + +// Params parses and returns a list of control sequence parameters. +// +// Parameters are positive integers separated by semicolons. Empty parameters +// default to zero. Parameters can have sub-parameters separated by colons. +// +// Any non-parameter bytes are ignored. This includes bytes that are not in the +// range of 0x30-0x3B. +// +// See ECMA-48 § 5.4.1. +func Params(p []byte) [][]uint { + if len(p) == 0 { + return [][]uint{} + } + + // Filter out non-parameter bytes i.e. non 0x30-0x3B. + p = bytes.TrimFunc(p, func(r rune) bool { + return r < 0x30 || r > 0x3B + }) + + parts := bytes.Split(p, []byte{';'}) + params := make([][]uint, len(parts)) + for i, part := range parts { + sparts := bytes.Split(part, []byte{':'}) + params[i] = make([]uint, len(sparts)) + for j, spart := range sparts { + params[i][j] = bytesToUint16(spart) + } + } + + return params +} + +func bytesToUint16(b []byte) uint { + var n uint + for _, c := range b { + n = n*10 + uint(c-'0') + } + return n +} diff --git a/vendor/github.com/charmbracelet/x/ansi/parser.go b/vendor/github.com/charmbracelet/x/ansi/parser.go new file mode 100644 index 0000000..4595b51 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/parser.go @@ -0,0 +1,357 @@ +package ansi + +import ( + "unicode/utf8" + + "github.com/charmbracelet/x/ansi/parser" +) + +// ParserDispatcher is a function that dispatches a sequence. +type ParserDispatcher func(Sequence) + +// Parser represents a DEC ANSI compatible sequence parser. +// +// It uses a state machine to parse ANSI escape sequences and control +// characters. The parser is designed to be used with a terminal emulator or +// similar application that needs to parse ANSI escape sequences and control +// characters. +// See package [parser] for more information. +// +//go:generate go run ./gen.go +type Parser struct { + // Params contains the raw parameters of the sequence. + // These parameters used when constructing CSI and DCS sequences. + Params []int + + // Data contains the raw data of the sequence. + // These data used when constructing OSC, DCS, SOS, PM, and APC sequences. + Data []byte + + // DataLen keeps track of the length of the data buffer. + // If DataLen is -1, the data buffer is unlimited and will grow as needed. + // Otherwise, DataLen is limited by the size of the Data buffer. + DataLen int + + // ParamsLen keeps track of the number of parameters. + // This is limited by the size of the Params buffer. + ParamsLen int + + // Cmd contains the raw command along with the private marker and + // intermediate bytes of the sequence. + // The first lower byte contains the command byte, the next byte contains + // the private marker, and the next byte contains the intermediate byte. + Cmd int + + // RuneLen keeps track of the number of bytes collected for a UTF-8 rune. + RuneLen int + + // RuneBuf contains the bytes collected for a UTF-8 rune. + RuneBuf [utf8.MaxRune]byte + + // State is the current state of the parser. + State byte +} + +// NewParser returns a new parser with the given sizes allocated. +// If dataSize is zero, the underlying data buffer will be unlimited and will +// grow as needed. +func NewParser(paramsSize, dataSize int) *Parser { + s := &Parser{ + Params: make([]int, paramsSize), + Data: make([]byte, dataSize), + } + if dataSize <= 0 { + s.DataLen = -1 + } + return s +} + +// Reset resets the parser to its initial state. +func (p *Parser) Reset() { + p.clear() + p.State = parser.GroundState +} + +// clear clears the parser parameters and command. +func (p *Parser) clear() { + if len(p.Params) > 0 { + p.Params[0] = parser.MissingParam + } + p.ParamsLen = 0 + p.Cmd = 0 + p.RuneLen = 0 +} + +// StateName returns the name of the current state. +func (p *Parser) StateName() string { + return parser.StateNames[p.State] +} + +// Parse parses the given dispatcher and byte buffer. +func (p *Parser) Parse(dispatcher ParserDispatcher, b []byte) { + for i := 0; i < len(b); i++ { + p.Advance(dispatcher, b[i], i < len(b)-1) + } +} + +// Advance advances the parser with the given dispatcher and byte. +func (p *Parser) Advance(dispatcher ParserDispatcher, b byte, more bool) parser.Action { + switch p.State { + case parser.Utf8State: + // We handle UTF-8 here. + return p.advanceUtf8(dispatcher, b) + default: + return p.advance(dispatcher, b, more) + } +} + +func (p *Parser) collectRune(b byte) { + if p.RuneLen < utf8.UTFMax { + p.RuneBuf[p.RuneLen] = b + p.RuneLen++ + } +} + +func (p *Parser) advanceUtf8(dispatcher ParserDispatcher, b byte) parser.Action { + // Collect UTF-8 rune bytes. + p.collectRune(b) + rw := utf8ByteLen(p.RuneBuf[0]) + if rw == -1 { + // We panic here because the first byte comes from the state machine, + // if this panics, it means there is a bug in the state machine! + panic("invalid rune") // unreachable + } + + if p.RuneLen < rw { + return parser.NoneAction + } + + // We have enough bytes to decode the rune + bts := p.RuneBuf[:rw] + r, _ := utf8.DecodeRune(bts) + if dispatcher != nil { + dispatcher(Rune(r)) + } + + p.State = parser.GroundState + p.RuneLen = 0 + + return parser.NoneAction +} + +func (p *Parser) advance(d ParserDispatcher, b byte, more bool) parser.Action { + state, action := parser.Table.Transition(p.State, b) + + // We need to clear the parser state if the state changes from EscapeState. + // This is because when we enter the EscapeState, we don't get a chance to + // clear the parser state. For example, when a sequence terminates with a + // ST (\x1b\\ or \x9c), we dispatch the current sequence and transition to + // EscapeState. However, the parser state is not cleared in this case and + // we need to clear it here before dispatching the esc sequence. + if p.State != state { + switch p.State { + case parser.EscapeState: + p.performAction(d, parser.ClearAction, b) + } + if action == parser.PutAction && + p.State == parser.DcsEntryState && state == parser.DcsStringState { + // XXX: This is a special case where we need to start collecting + // non-string parameterized data i.e. doesn't follow the ECMA-48 § + // 5.4.1 string parameters format. + p.performAction(d, parser.StartAction, 0) + } + } + + // Handle special cases + switch { + case b == ESC && p.State == parser.EscapeState: + // Two ESCs in a row + p.performAction(d, parser.ExecuteAction, b) + if !more { + // Two ESCs at the end of the buffer + p.performAction(d, parser.ExecuteAction, b) + } + case b == ESC && !more: + // Last byte is an ESC + p.performAction(d, parser.ExecuteAction, b) + case p.State == parser.EscapeState && b == 'P' && !more: + // ESC P (DCS) at the end of the buffer + p.performAction(d, parser.DispatchAction, b) + case p.State == parser.EscapeState && b == 'X' && !more: + // ESC X (SOS) at the end of the buffer + p.performAction(d, parser.DispatchAction, b) + case p.State == parser.EscapeState && b == '[' && !more: + // ESC [ (CSI) at the end of the buffer + p.performAction(d, parser.DispatchAction, b) + case p.State == parser.EscapeState && b == ']' && !more: + // ESC ] (OSC) at the end of the buffer + p.performAction(d, parser.DispatchAction, b) + case p.State == parser.EscapeState && b == '^' && !more: + // ESC ^ (PM) at the end of the buffer + p.performAction(d, parser.DispatchAction, b) + case p.State == parser.EscapeState && b == '_' && !more: + // ESC _ (APC) at the end of the buffer + p.performAction(d, parser.DispatchAction, b) + default: + p.performAction(d, action, b) + } + + p.State = state + + return action +} + +func (p *Parser) performAction(dispatcher ParserDispatcher, action parser.Action, b byte) { + switch action { + case parser.IgnoreAction: + break + + case parser.ClearAction: + p.clear() + + case parser.PrintAction: + if utf8ByteLen(b) > 1 { + p.collectRune(b) + } else if dispatcher != nil { + dispatcher(Rune(b)) + } + + case parser.ExecuteAction: + if dispatcher != nil { + dispatcher(ControlCode(b)) + } + + case parser.MarkerAction: + // Collect private marker + // we only store the last marker + p.Cmd &^= 0xff << parser.MarkerShift + p.Cmd |= int(b) << parser.MarkerShift + + case parser.CollectAction: + // Collect intermediate bytes + // we only store the last intermediate byte + p.Cmd &^= 0xff << parser.IntermedShift + p.Cmd |= int(b) << parser.IntermedShift + + case parser.ParamAction: + // Collect parameters + if p.ParamsLen >= len(p.Params) { + break + } + + if b >= '0' && b <= '9' { + if p.Params[p.ParamsLen] == parser.MissingParam { + p.Params[p.ParamsLen] = 0 + } + + p.Params[p.ParamsLen] *= 10 + p.Params[p.ParamsLen] += int(b - '0') + } + + if b == ':' { + p.Params[p.ParamsLen] |= parser.HasMoreFlag + } + + if b == ';' || b == ':' { + p.ParamsLen++ + if p.ParamsLen < len(p.Params) { + p.Params[p.ParamsLen] = parser.MissingParam + } + } + + case parser.StartAction: + if p.DataLen < 0 { + p.Data = make([]byte, 0) + } else { + p.DataLen = 0 + } + if p.State >= parser.DcsEntryState && p.State <= parser.DcsStringState { + // Collect the command byte for DCS + p.Cmd |= int(b) + } else { + p.Cmd = parser.MissingCommand + } + + case parser.PutAction: + switch p.State { + case parser.OscStringState: + if b == ';' && p.Cmd == parser.MissingCommand { + // Try to parse the command + datalen := len(p.Data) + if p.DataLen >= 0 { + datalen = p.DataLen + } + for i := 0; i < datalen; i++ { + d := p.Data[i] + if d < '0' || d > '9' { + break + } + if p.Cmd == parser.MissingCommand { + p.Cmd = 0 + } + p.Cmd *= 10 + p.Cmd += int(d - '0') + } + } + } + + if p.DataLen < 0 { + p.Data = append(p.Data, b) + } else { + if p.DataLen < len(p.Data) { + p.Data[p.DataLen] = b + p.DataLen++ + } + } + + case parser.DispatchAction: + // Increment the last parameter + if p.ParamsLen > 0 && p.ParamsLen < len(p.Params)-1 || + p.ParamsLen == 0 && len(p.Params) > 0 && p.Params[0] != parser.MissingParam { + p.ParamsLen++ + } + + if dispatcher == nil { + break + } + + var seq Sequence + data := p.Data + if p.DataLen >= 0 { + data = data[:p.DataLen] + } + switch p.State { + case parser.CsiEntryState, parser.CsiParamState, parser.CsiIntermediateState: + p.Cmd |= int(b) + seq = CsiSequence{Cmd: p.Cmd, Params: p.Params[:p.ParamsLen]} + case parser.EscapeState, parser.EscapeIntermediateState: + p.Cmd |= int(b) + seq = EscSequence(p.Cmd) + case parser.DcsEntryState, parser.DcsParamState, parser.DcsIntermediateState, parser.DcsStringState: + seq = DcsSequence{Cmd: p.Cmd, Params: p.Params[:p.ParamsLen], Data: data} + case parser.OscStringState: + seq = OscSequence{Cmd: p.Cmd, Data: data} + case parser.SosStringState: + seq = SosSequence{Data: data} + case parser.PmStringState: + seq = PmSequence{Data: data} + case parser.ApcStringState: + seq = ApcSequence{Data: data} + } + + dispatcher(seq) + } +} + +func utf8ByteLen(b byte) int { + if b <= 0b0111_1111 { // 0x00-0x7F + return 1 + } else if b >= 0b1100_0000 && b <= 0b1101_1111 { // 0xC0-0xDF + return 2 + } else if b >= 0b1110_0000 && b <= 0b1110_1111 { // 0xE0-0xEF + return 3 + } else if b >= 0b1111_0000 && b <= 0b1111_0111 { // 0xF0-0xF7 + return 4 + } + return -1 +} diff --git a/vendor/github.com/charmbracelet/x/ansi/parser/const.go b/vendor/github.com/charmbracelet/x/ansi/parser/const.go new file mode 100644 index 0000000..54b7383 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/parser/const.go @@ -0,0 +1,78 @@ +package parser + +// Action is a DEC ANSI parser action. +type Action = byte + +// These are the actions that the parser can take. +const ( + NoneAction Action = iota + ClearAction + CollectAction + MarkerAction + DispatchAction + ExecuteAction + StartAction // Start of a data string + PutAction // Put into the data string + ParamAction + PrintAction + + IgnoreAction = NoneAction +) + +// nolint: unused +var ActionNames = []string{ + "NoneAction", + "ClearAction", + "CollectAction", + "MarkerAction", + "DispatchAction", + "ExecuteAction", + "StartAction", + "PutAction", + "ParamAction", + "PrintAction", +} + +// State is a DEC ANSI parser state. +type State = byte + +// These are the states that the parser can be in. +const ( + GroundState State = iota + CsiEntryState + CsiIntermediateState + CsiParamState + DcsEntryState + DcsIntermediateState + DcsParamState + DcsStringState + EscapeState + EscapeIntermediateState + OscStringState + SosStringState + PmStringState + ApcStringState + + // Utf8State is not part of the DEC ANSI standard. It is used to handle + // UTF-8 sequences. + Utf8State +) + +// nolint: unused +var StateNames = []string{ + "GroundState", + "CsiEntryState", + "CsiIntermediateState", + "CsiParamState", + "DcsEntryState", + "DcsIntermediateState", + "DcsParamState", + "DcsStringState", + "EscapeState", + "EscapeIntermediateState", + "OscStringState", + "SosStringState", + "PmStringState", + "ApcStringState", + "Utf8State", +} diff --git a/vendor/github.com/charmbracelet/x/ansi/parser/seq.go b/vendor/github.com/charmbracelet/x/ansi/parser/seq.go new file mode 100644 index 0000000..c99f163 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/parser/seq.go @@ -0,0 +1,136 @@ +package parser + +import "math" + +// Shift and masks for sequence parameters and intermediates. +const ( + MarkerShift = 8 + IntermedShift = 16 + CommandMask = 0xff + HasMoreFlag = math.MinInt32 + ParamMask = ^HasMoreFlag + MissingParam = ParamMask + MissingCommand = MissingParam + MaxParam = math.MaxUint16 // the maximum value a parameter can have +) + +const ( + // MaxParamsSize is the maximum number of parameters a sequence can have. + MaxParamsSize = 32 + + // DefaultParamValue is the default value used for missing parameters. + DefaultParamValue = 0 +) + +// Marker returns the marker byte of the sequence. +// This is always gonna be one of the following '<' '=' '>' '?' and in the +// range of 0x3C-0x3F. +// Zero is returned if the sequence does not have a marker. +func Marker(cmd int) int { + return (cmd >> MarkerShift) & CommandMask +} + +// Intermediate returns the intermediate byte of the sequence. +// An intermediate byte is in the range of 0x20-0x2F. This includes these +// characters from ' ', '!', '"', '#', '$', '%', '&', ”', '(', ')', '*', '+', +// ',', '-', '.', '/'. +// Zero is returned if the sequence does not have an intermediate byte. +func Intermediate(cmd int) int { + return (cmd >> IntermedShift) & CommandMask +} + +// Command returns the command byte of the CSI sequence. +func Command(cmd int) int { + return cmd & CommandMask +} + +// Param returns the parameter at the given index. +// It returns -1 if the parameter does not exist. +func Param(params []int, i int) int { + if len(params) == 0 || i < 0 || i >= len(params) { + return -1 + } + + p := params[i] & ParamMask + if p == MissingParam { + return -1 + } + + return p +} + +// HasMore returns true if the parameter has more sub-parameters. +func HasMore(params []int, i int) bool { + if len(params) == 0 || i >= len(params) { + return false + } + + return params[i]&HasMoreFlag != 0 +} + +// Subparams returns the sub-parameters of the given parameter. +// It returns nil if the parameter does not exist. +func Subparams(params []int, i int) []int { + if len(params) == 0 || i < 0 || i >= len(params) { + return nil + } + + // Count the number of parameters before the given parameter index. + var count int + var j int + for j = 0; j < len(params); j++ { + if count == i { + break + } + if !HasMore(params, j) { + count++ + } + } + + if count > i || j >= len(params) { + return nil + } + + var subs []int + for ; j < len(params); j++ { + if !HasMore(params, j) { + break + } + p := Param(params, j) + if p == -1 { + p = DefaultParamValue + } + subs = append(subs, p) + } + + p := Param(params, j) + if p == -1 { + p = DefaultParamValue + } + + return append(subs, p) +} + +// Len returns the number of parameters in the sequence. +// This will return the number of parameters in the sequence, excluding any +// sub-parameters. +func Len(params []int) int { + var n int + for i := 0; i < len(params); i++ { + if !HasMore(params, i) { + n++ + } + } + return n +} + +// Range iterates over the parameters of the sequence and calls the given +// function for each parameter. +// The function should return false to stop the iteration. +func Range(params []int, fn func(i int, param int, hasMore bool) bool) { + for i := 0; i < len(params); i++ { + if !fn(i, Param(params, i), HasMore(params, i)) { + break + } + } +} diff --git a/vendor/github.com/charmbracelet/x/ansi/parser/transition_table.go b/vendor/github.com/charmbracelet/x/ansi/parser/transition_table.go new file mode 100644 index 0000000..febde15 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/parser/transition_table.go @@ -0,0 +1,269 @@ +package parser + +// Table values are generated like this: +// +// index: currentState << IndexStateShift | charCode +// value: action << TransitionActionShift | nextState +const ( + TransitionActionShift = 4 + TransitionStateMask = 15 + IndexStateShift = 8 + + // DefaultTableSize is the default size of the transition table. + DefaultTableSize = 4096 +) + +// Table is a DEC ANSI transition table. +var Table = GenerateTransitionTable() + +// TransitionTable is a DEC ANSI transition table. +// https://vt100.net/emu/dec_ansi_parser +type TransitionTable []byte + +// NewTransitionTable returns a new DEC ANSI transition table. +func NewTransitionTable(size int) TransitionTable { + if size <= 0 { + size = DefaultTableSize + } + return TransitionTable(make([]byte, size)) +} + +// SetDefault sets default transition. +func (t TransitionTable) SetDefault(action Action, state State) { + for i := 0; i < len(t); i++ { + t[i] = action<> TransitionActionShift +} + +// byte range macro +func r(start, end byte) []byte { + var a []byte + for i := int(start); i <= int(end); i++ { + a = append(a, byte(i)) + } + return a +} + +// GenerateTransitionTable generates a DEC ANSI transition table compatible +// with the VT500-series of terminals. This implementation includes a few +// modifications that include: +// - A new Utf8State is introduced to handle UTF8 sequences. +// - Osc and Dcs data accept UTF8 sequences by extending the printable range +// to 0xFF and 0xFE respectively. +// - We don't ignore 0x3A (':') when building Csi and Dcs parameters and +// instead use it to denote sub-parameters. +// - Support dispatching SosPmApc sequences. +func GenerateTransitionTable() TransitionTable { + table := NewTransitionTable(DefaultTableSize) + table.SetDefault(NoneAction, GroundState) + + // Anywhere + for _, state := range r(GroundState, Utf8State) { + // Anywhere -> Ground + table.AddMany([]byte{0x18, 0x1a, 0x99, 0x9a}, state, ExecuteAction, GroundState) + table.AddRange(0x80, 0x8F, state, ExecuteAction, GroundState) + table.AddRange(0x90, 0x97, state, ExecuteAction, GroundState) + table.AddOne(0x9C, state, IgnoreAction, GroundState) + // Anywhere -> Escape + table.AddOne(0x1B, state, ClearAction, EscapeState) + // Anywhere -> SosStringState + table.AddOne(0x98, state, StartAction, SosStringState) + // Anywhere -> PmStringState + table.AddOne(0x9E, state, StartAction, PmStringState) + // Anywhere -> ApcStringState + table.AddOne(0x9F, state, StartAction, ApcStringState) + // Anywhere -> CsiEntry + table.AddOne(0x9B, state, ClearAction, CsiEntryState) + // Anywhere -> DcsEntry + table.AddOne(0x90, state, ClearAction, DcsEntryState) + // Anywhere -> OscString + table.AddOne(0x9D, state, StartAction, OscStringState) + // Anywhere -> Utf8 + table.AddRange(0xC2, 0xDF, state, PrintAction, Utf8State) // UTF8 2 byte sequence + table.AddRange(0xE0, 0xEF, state, PrintAction, Utf8State) // UTF8 3 byte sequence + table.AddRange(0xF0, 0xF4, state, PrintAction, Utf8State) // UTF8 4 byte sequence + } + + // Ground + table.AddRange(0x00, 0x17, GroundState, ExecuteAction, GroundState) + table.AddOne(0x19, GroundState, ExecuteAction, GroundState) + table.AddRange(0x1C, 0x1F, GroundState, ExecuteAction, GroundState) + table.AddRange(0x20, 0x7F, GroundState, PrintAction, GroundState) + + // EscapeIntermediate + table.AddRange(0x00, 0x17, EscapeIntermediateState, ExecuteAction, EscapeIntermediateState) + table.AddOne(0x19, EscapeIntermediateState, ExecuteAction, EscapeIntermediateState) + table.AddRange(0x1C, 0x1F, EscapeIntermediateState, ExecuteAction, EscapeIntermediateState) + table.AddRange(0x20, 0x2F, EscapeIntermediateState, CollectAction, EscapeIntermediateState) + table.AddOne(0x7F, EscapeIntermediateState, IgnoreAction, EscapeIntermediateState) + // EscapeIntermediate -> Ground + table.AddRange(0x30, 0x7E, EscapeIntermediateState, DispatchAction, GroundState) + + // Escape + table.AddRange(0x00, 0x17, EscapeState, ExecuteAction, EscapeState) + table.AddOne(0x19, EscapeState, ExecuteAction, EscapeState) + table.AddRange(0x1C, 0x1F, EscapeState, ExecuteAction, EscapeState) + table.AddOne(0x7F, EscapeState, IgnoreAction, EscapeState) + // Escape -> Ground + table.AddRange(0x30, 0x4F, EscapeState, DispatchAction, GroundState) + table.AddRange(0x51, 0x57, EscapeState, DispatchAction, GroundState) + table.AddOne(0x59, EscapeState, DispatchAction, GroundState) + table.AddOne(0x5A, EscapeState, DispatchAction, GroundState) + table.AddOne(0x5C, EscapeState, DispatchAction, GroundState) + table.AddRange(0x60, 0x7E, EscapeState, DispatchAction, GroundState) + // Escape -> Escape_intermediate + table.AddRange(0x20, 0x2F, EscapeState, CollectAction, EscapeIntermediateState) + // Escape -> Sos_pm_apc_string + table.AddOne('X', EscapeState, StartAction, SosStringState) // SOS + table.AddOne('^', EscapeState, StartAction, PmStringState) // PM + table.AddOne('_', EscapeState, StartAction, ApcStringState) // APC + // Escape -> Dcs_entry + table.AddOne('P', EscapeState, ClearAction, DcsEntryState) + // Escape -> Csi_entry + table.AddOne('[', EscapeState, ClearAction, CsiEntryState) + // Escape -> Osc_string + table.AddOne(']', EscapeState, StartAction, OscStringState) + + // Sos_pm_apc_string + for _, state := range r(SosStringState, ApcStringState) { + table.AddRange(0x00, 0x17, state, PutAction, state) + table.AddOne(0x19, state, PutAction, state) + table.AddRange(0x1C, 0x1F, state, PutAction, state) + table.AddRange(0x20, 0x7F, state, PutAction, state) + // ESC, ST, CAN, and SUB terminate the sequence + table.AddOne(0x1B, state, DispatchAction, EscapeState) + table.AddOne(0x9C, state, DispatchAction, GroundState) + table.AddMany([]byte{0x18, 0x1A}, state, IgnoreAction, GroundState) + } + + // Dcs_entry + table.AddRange(0x00, 0x07, DcsEntryState, IgnoreAction, DcsEntryState) + table.AddRange(0x0E, 0x17, DcsEntryState, IgnoreAction, DcsEntryState) + table.AddOne(0x19, DcsEntryState, IgnoreAction, DcsEntryState) + table.AddRange(0x1C, 0x1F, DcsEntryState, IgnoreAction, DcsEntryState) + table.AddOne(0x7F, DcsEntryState, IgnoreAction, DcsEntryState) + // Dcs_entry -> Dcs_intermediate + table.AddRange(0x20, 0x2F, DcsEntryState, CollectAction, DcsIntermediateState) + // Dcs_entry -> Dcs_param + table.AddRange(0x30, 0x3B, DcsEntryState, ParamAction, DcsParamState) + table.AddRange(0x3C, 0x3F, DcsEntryState, MarkerAction, DcsParamState) + // Dcs_entry -> Dcs_passthrough + table.AddRange(0x08, 0x0D, DcsEntryState, PutAction, DcsStringState) // Follows ECMA-48 § 8.3.27 + // XXX: allows passing ESC (not a ECMA-48 standard) this to allow for + // passthrough of ANSI sequences like in Screen or Tmux passthrough mode. + table.AddOne(0x1B, DcsEntryState, PutAction, DcsStringState) + table.AddRange(0x40, 0x7E, DcsEntryState, StartAction, DcsStringState) + + // Dcs_intermediate + table.AddRange(0x00, 0x17, DcsIntermediateState, IgnoreAction, DcsIntermediateState) + table.AddOne(0x19, DcsIntermediateState, IgnoreAction, DcsIntermediateState) + table.AddRange(0x1C, 0x1F, DcsIntermediateState, IgnoreAction, DcsIntermediateState) + table.AddRange(0x20, 0x2F, DcsIntermediateState, CollectAction, DcsIntermediateState) + table.AddOne(0x7F, DcsIntermediateState, IgnoreAction, DcsIntermediateState) + // Dcs_intermediate -> Dcs_passthrough + table.AddRange(0x30, 0x3F, DcsIntermediateState, StartAction, DcsStringState) + table.AddRange(0x40, 0x7E, DcsIntermediateState, StartAction, DcsStringState) + + // Dcs_param + table.AddRange(0x00, 0x17, DcsParamState, IgnoreAction, DcsParamState) + table.AddOne(0x19, DcsParamState, IgnoreAction, DcsParamState) + table.AddRange(0x1C, 0x1F, DcsParamState, IgnoreAction, DcsParamState) + table.AddRange(0x30, 0x3B, DcsParamState, ParamAction, DcsParamState) + table.AddOne(0x7F, DcsParamState, IgnoreAction, DcsParamState) + table.AddRange(0x3C, 0x3F, DcsParamState, IgnoreAction, DcsParamState) + // Dcs_param -> Dcs_intermediate + table.AddRange(0x20, 0x2F, DcsParamState, CollectAction, DcsIntermediateState) + // Dcs_param -> Dcs_passthrough + table.AddRange(0x40, 0x7E, DcsParamState, StartAction, DcsStringState) + + // Dcs_passthrough + table.AddRange(0x00, 0x17, DcsStringState, PutAction, DcsStringState) + table.AddOne(0x19, DcsStringState, PutAction, DcsStringState) + table.AddRange(0x1C, 0x1F, DcsStringState, PutAction, DcsStringState) + table.AddRange(0x20, 0x7E, DcsStringState, PutAction, DcsStringState) + table.AddOne(0x7F, DcsStringState, IgnoreAction, DcsStringState) + table.AddRange(0x80, 0xFF, DcsStringState, PutAction, DcsStringState) // Allow Utf8 characters by extending the printable range from 0x7F to 0xFF + // ST, CAN, SUB, and ESC terminate the sequence + table.AddOne(0x1B, DcsStringState, DispatchAction, EscapeState) + table.AddOne(0x9C, DcsStringState, DispatchAction, GroundState) + table.AddMany([]byte{0x18, 0x1A}, DcsStringState, IgnoreAction, GroundState) + + // Csi_param + table.AddRange(0x00, 0x17, CsiParamState, ExecuteAction, CsiParamState) + table.AddOne(0x19, CsiParamState, ExecuteAction, CsiParamState) + table.AddRange(0x1C, 0x1F, CsiParamState, ExecuteAction, CsiParamState) + table.AddRange(0x30, 0x3B, CsiParamState, ParamAction, CsiParamState) + table.AddOne(0x7F, CsiParamState, IgnoreAction, CsiParamState) + table.AddRange(0x3C, 0x3F, CsiParamState, IgnoreAction, CsiParamState) + // Csi_param -> Ground + table.AddRange(0x40, 0x7E, CsiParamState, DispatchAction, GroundState) + // Csi_param -> Csi_intermediate + table.AddRange(0x20, 0x2F, CsiParamState, CollectAction, CsiIntermediateState) + + // Csi_intermediate + table.AddRange(0x00, 0x17, CsiIntermediateState, ExecuteAction, CsiIntermediateState) + table.AddOne(0x19, CsiIntermediateState, ExecuteAction, CsiIntermediateState) + table.AddRange(0x1C, 0x1F, CsiIntermediateState, ExecuteAction, CsiIntermediateState) + table.AddRange(0x20, 0x2F, CsiIntermediateState, CollectAction, CsiIntermediateState) + table.AddOne(0x7F, CsiIntermediateState, IgnoreAction, CsiIntermediateState) + // Csi_intermediate -> Ground + table.AddRange(0x40, 0x7E, CsiIntermediateState, DispatchAction, GroundState) + // Csi_intermediate -> Csi_ignore + table.AddRange(0x30, 0x3F, CsiIntermediateState, IgnoreAction, GroundState) + + // Csi_entry + table.AddRange(0x00, 0x17, CsiEntryState, ExecuteAction, CsiEntryState) + table.AddOne(0x19, CsiEntryState, ExecuteAction, CsiEntryState) + table.AddRange(0x1C, 0x1F, CsiEntryState, ExecuteAction, CsiEntryState) + table.AddOne(0x7F, CsiEntryState, IgnoreAction, CsiEntryState) + // Csi_entry -> Ground + table.AddRange(0x40, 0x7E, CsiEntryState, DispatchAction, GroundState) + // Csi_entry -> Csi_intermediate + table.AddRange(0x20, 0x2F, CsiEntryState, CollectAction, CsiIntermediateState) + // Csi_entry -> Csi_param + table.AddRange(0x30, 0x3B, CsiEntryState, ParamAction, CsiParamState) + table.AddRange(0x3C, 0x3F, CsiEntryState, MarkerAction, CsiParamState) + + // Osc_string + table.AddRange(0x00, 0x06, OscStringState, IgnoreAction, OscStringState) + table.AddRange(0x08, 0x17, OscStringState, IgnoreAction, OscStringState) + table.AddOne(0x19, OscStringState, IgnoreAction, OscStringState) + table.AddRange(0x1C, 0x1F, OscStringState, IgnoreAction, OscStringState) + table.AddRange(0x20, 0xFF, OscStringState, PutAction, OscStringState) // Allow Utf8 characters by extending the printable range from 0x7F to 0xFF + + // ST, CAN, SUB, ESC, and BEL terminate the sequence + table.AddOne(0x1B, OscStringState, DispatchAction, EscapeState) + table.AddOne(0x07, OscStringState, DispatchAction, GroundState) + table.AddOne(0x9C, OscStringState, DispatchAction, GroundState) + table.AddMany([]byte{0x18, 0x1A}, OscStringState, IgnoreAction, GroundState) + + return table +} diff --git a/vendor/github.com/charmbracelet/x/ansi/passthrough.go b/vendor/github.com/charmbracelet/x/ansi/passthrough.go new file mode 100644 index 0000000..14a7452 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/passthrough.go @@ -0,0 +1,63 @@ +package ansi + +import ( + "bytes" +) + +// ScreenPassthrough wraps the given ANSI sequence in a DCS passthrough +// sequence to be sent to the outer terminal. This is used to send raw escape +// sequences to the outer terminal when running inside GNU Screen. +// +// DCS ST +// +// Note: Screen limits the length of string sequences to 768 bytes (since 2014). +// Use zero to indicate no limit, otherwise, this will chunk the returned +// string into limit sized chunks. +// +// See: https://www.gnu.org/software/screen/manual/screen.html#String-Escapes +// See: https://git.savannah.gnu.org/cgit/screen.git/tree/src/screen.h?id=c184c6ec27683ff1a860c45be5cf520d896fd2ef#n44 +func ScreenPassthrough(seq string, limit int) string { + var b bytes.Buffer + b.WriteString("\x1bP") + if limit > 0 { + for i := 0; i < len(seq); i += limit { + end := i + limit + if end > len(seq) { + end = len(seq) + } + b.WriteString(seq[i:end]) + if end < len(seq) { + b.WriteString("\x1b\\\x1bP") + } + } + } else { + b.WriteString(seq) + } + b.WriteString("\x1b\\") + return b.String() +} + +// TmuxPassthrough wraps the given ANSI sequence in a special DCS passthrough +// sequence to be sent to the outer terminal. This is used to send raw escape +// sequences to the outer terminal when running inside Tmux. +// +// DCS tmux ; ST +// +// Where is the given sequence in which all occurrences of ESC +// (0x1b) are doubled i.e. replaced with ESC ESC (0x1b 0x1b). +// +// Note: this needs the `allow-passthrough` option to be set to `on`. +// +// See: https://github.com/tmux/tmux/wiki/FAQ#what-is-the-passthrough-escape-sequence-and-how-do-i-use-it +func TmuxPassthrough(seq string) string { + var b bytes.Buffer + b.WriteString("\x1bPtmux;") + for i := 0; i < len(seq); i++ { + if seq[i] == ESC { + b.WriteByte(ESC) + } + b.WriteByte(seq[i]) + } + b.WriteString("\x1b\\") + return b.String() +} diff --git a/vendor/github.com/charmbracelet/x/ansi/screen.go b/vendor/github.com/charmbracelet/x/ansi/screen.go new file mode 100644 index 0000000..4909cf0 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/screen.go @@ -0,0 +1,126 @@ +package ansi + +import "strconv" + +// EraseDisplay (ED) clears the screen or parts of the screen. Possible values: +// +// 0: Clear from cursor to end of screen. +// 1: Clear from cursor to beginning of the screen. +// 2: Clear entire screen (and moves cursor to upper left on DOS). +// 3: Clear entire screen and delete all lines saved in the scrollback buffer. +// +// CSI J +// +// See: https://vt100.net/docs/vt510-rm/ED.html +func EraseDisplay(n int) string { + if n < 0 { + n = 0 + } + return "\x1b[" + strconv.Itoa(n) + "J" +} + +// EraseDisplay constants. +// These are the possible values for the EraseDisplay function. +const ( + EraseDisplayRight = "\x1b[0J" + EraseDisplayLeft = "\x1b[1J" + EraseEntireDisplay = "\x1b[2J" +) + +// EraseLine (EL) clears the current line or parts of the line. Possible values: +// +// 0: Clear from cursor to end of line. +// 1: Clear from cursor to beginning of the line. +// 2: Clear entire line. +// +// The cursor position is not affected. +// +// CSI K +// +// See: https://vt100.net/docs/vt510-rm/EL.html +func EraseLine(n int) string { + if n < 0 { + n = 0 + } + return "\x1b[" + strconv.Itoa(n) + "K" +} + +// EraseLine constants. +// These are the possible values for the EraseLine function. +const ( + EraseLineRight = "\x1b[0K" + EraseLineLeft = "\x1b[1K" + EraseEntireLine = "\x1b[2K" +) + +// ScrollUp (SU) scrolls the screen up n lines. New lines are added at the +// bottom of the screen. +// +// CSI S +// +// See: https://vt100.net/docs/vt510-rm/SU.html +func ScrollUp(n int) string { + var s string + if n > 1 { + s = strconv.Itoa(n) + } + return "\x1b[" + s + "S" +} + +// ScrollDown (SD) scrolls the screen down n lines. New lines are added at the +// top of the screen. +// +// CSI T +// +// See: https://vt100.net/docs/vt510-rm/SD.html +func ScrollDown(n int) string { + var s string + if n > 1 { + s = strconv.Itoa(n) + } + return "\x1b[" + s + "T" +} + +// InsertLine (IL) inserts n blank lines at the current cursor position. +// Existing lines are moved down. +// +// CSI L +// +// See: https://vt100.net/docs/vt510-rm/IL.html +func InsertLine(n int) string { + var s string + if n > 1 { + s = strconv.Itoa(n) + } + return "\x1b[" + s + "L" +} + +// DeleteLine (DL) deletes n lines at the current cursor position. Existing +// lines are moved up. +// +// CSI M +// +// See: https://vt100.net/docs/vt510-rm/DL.html +func DeleteLine(n int) string { + var s string + if n > 1 { + s = strconv.Itoa(n) + } + return "\x1b[" + s + "M" +} + +// SetScrollingRegion (DECSTBM) sets the top and bottom margins for the scrolling +// region. The default is the entire screen. +// +// CSI ; r +// +// See: https://vt100.net/docs/vt510-rm/DECSTBM.html +func SetScrollingRegion(t, b int) string { + if t < 0 { + t = 0 + } + if b < 0 { + b = 0 + } + return "\x1b[" + strconv.Itoa(t) + ";" + strconv.Itoa(b) + "r" +} diff --git a/vendor/github.com/charmbracelet/x/ansi/sequence.go b/vendor/github.com/charmbracelet/x/ansi/sequence.go new file mode 100644 index 0000000..f294a22 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/sequence.go @@ -0,0 +1,199 @@ +package ansi + +import ( + "bytes" + + "github.com/charmbracelet/x/ansi/parser" +) + +// Sequence represents an ANSI sequence. This can be a control sequence, escape +// sequence, a printable character, etc. +type Sequence interface { + // String returns the string representation of the sequence. + String() string + // Bytes returns the byte representation of the sequence. + Bytes() []byte + // Clone returns a copy of the sequence. + Clone() Sequence +} + +// Rune represents a printable character. +type Rune rune + +var _ Sequence = Rune(0) + +// Bytes implements Sequence. +func (r Rune) Bytes() []byte { + return []byte(string(r)) +} + +// String implements Sequence. +func (r Rune) String() string { + return string(r) +} + +// Clone implements Sequence. +func (r Rune) Clone() Sequence { + return r +} + +// ControlCode represents a control code character. This is a character that +// is not printable and is used to control the terminal. This would be a +// character in the C0 or C1 set in the range of 0x00-0x1F and 0x80-0x9F. +type ControlCode byte + +var _ Sequence = ControlCode(0) + +// Bytes implements Sequence. +func (c ControlCode) Bytes() []byte { + return []byte{byte(c)} +} + +// String implements Sequence. +func (c ControlCode) String() string { + return string(c) +} + +// Clone implements Sequence. +func (c ControlCode) Clone() Sequence { + return c +} + +// EscSequence represents an escape sequence. +type EscSequence int + +var _ Sequence = EscSequence(0) + +// buffer returns the buffer of the escape sequence. +func (e EscSequence) buffer() *bytes.Buffer { + var b bytes.Buffer + b.WriteByte('\x1b') + if i := parser.Intermediate(int(e)); i != 0 { + b.WriteByte(byte(i)) + } + b.WriteByte(byte(e.Command())) + return &b +} + +// Bytes implements Sequence. +func (e EscSequence) Bytes() []byte { + return e.buffer().Bytes() +} + +// String implements Sequence. +func (e EscSequence) String() string { + return e.buffer().String() +} + +// Clone implements Sequence. +func (e EscSequence) Clone() Sequence { + return e +} + +// Command returns the command byte of the escape sequence. +func (e EscSequence) Command() int { + return parser.Command(int(e)) +} + +// Intermediate returns the intermediate byte of the escape sequence. +func (e EscSequence) Intermediate() int { + return parser.Intermediate(int(e)) +} + +// SosSequence represents a SOS sequence. +type SosSequence struct { + // Data contains the raw data of the sequence. + Data []byte +} + +var _ Sequence = &SosSequence{} + +// Clone implements Sequence. +func (s SosSequence) Clone() Sequence { + return SosSequence{Data: append([]byte(nil), s.Data...)} +} + +// Bytes implements Sequence. +func (s SosSequence) Bytes() []byte { + return s.buffer().Bytes() +} + +// String implements Sequence. +func (s SosSequence) String() string { + return s.buffer().String() +} + +func (s SosSequence) buffer() *bytes.Buffer { + var b bytes.Buffer + b.WriteByte('\x1b') + b.WriteByte('X') + b.Write(s.Data) + b.WriteString("\x1b\\") + return &b +} + +// PmSequence represents a PM sequence. +type PmSequence struct { + // Data contains the raw data of the sequence. + Data []byte +} + +var _ Sequence = &PmSequence{} + +// Clone implements Sequence. +func (s PmSequence) Clone() Sequence { + return PmSequence{Data: append([]byte(nil), s.Data...)} +} + +// Bytes implements Sequence. +func (s PmSequence) Bytes() []byte { + return s.buffer().Bytes() +} + +// String implements Sequence. +func (s PmSequence) String() string { + return s.buffer().String() +} + +// buffer returns the buffer of the PM sequence. +func (s PmSequence) buffer() *bytes.Buffer { + var b bytes.Buffer + b.WriteByte('\x1b') + b.WriteByte('^') + b.Write(s.Data) + b.WriteString("\x1b\\") + return &b +} + +// ApcSequence represents an APC sequence. +type ApcSequence struct { + // Data contains the raw data of the sequence. + Data []byte +} + +var _ Sequence = &ApcSequence{} + +// Clone implements Sequence. +func (s ApcSequence) Clone() Sequence { + return ApcSequence{Data: append([]byte(nil), s.Data...)} +} + +// Bytes implements Sequence. +func (s ApcSequence) Bytes() []byte { + return s.buffer().Bytes() +} + +// String implements Sequence. +func (s ApcSequence) String() string { + return s.buffer().String() +} + +// buffer returns the buffer of the APC sequence. +func (s ApcSequence) buffer() *bytes.Buffer { + var b bytes.Buffer + b.WriteByte('\x1b') + b.WriteByte('_') + b.Write(s.Data) + b.WriteString("\x1b\\") + return &b +} diff --git a/vendor/github.com/charmbracelet/x/ansi/style.go b/vendor/github.com/charmbracelet/x/ansi/style.go new file mode 100644 index 0000000..3342185 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/style.go @@ -0,0 +1,290 @@ +package ansi + +import ( + "image/color" + "strconv" + "strings" +) + +// ResetStyle is a SGR (Select Graphic Rendition) style sequence that resets +// all attributes. +// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters +const ResetStyle = "\x1b[m" + +// Attr is a SGR (Select Graphic Rendition) style attribute. +type Attr = string + +// Style represents an ANSI SGR (Select Graphic Rendition) style. +type Style []Attr + +// String returns the ANSI SGR (Select Graphic Rendition) style sequence for +// the given style. +func (s Style) String() string { + if len(s) == 0 { + return ResetStyle + } + return "\x1b[" + strings.Join(s, ";") + "m" +} + +// Styled returns a styled string with the given style applied. +func (s Style) Styled(str string) string { + if len(s) == 0 { + return str + } + return s.String() + str + ResetStyle +} + +// Reset appends the reset style attribute to the style. +func (s Style) Reset() Style { + return append(s, ResetAttr) +} + +// Bold appends the bold style attribute to the style. +func (s Style) Bold() Style { + return append(s, BoldAttr) +} + +// Faint appends the faint style attribute to the style. +func (s Style) Faint() Style { + return append(s, FaintAttr) +} + +// Italic appends the italic style attribute to the style. +func (s Style) Italic() Style { + return append(s, ItalicAttr) +} + +// Underline appends the underline style attribute to the style. +func (s Style) Underline() Style { + return append(s, UnderlineAttr) +} + +// DoubleUnderline appends the double underline style attribute to the style. +func (s Style) DoubleUnderline() Style { + return append(s, DoubleUnderlineAttr) +} + +// CurlyUnderline appends the curly underline style attribute to the style. +func (s Style) CurlyUnderline() Style { + return append(s, CurlyUnderlineAttr) +} + +// DottedUnderline appends the dotted underline style attribute to the style. +func (s Style) DottedUnderline() Style { + return append(s, DottedUnderlineAttr) +} + +// DashedUnderline appends the dashed underline style attribute to the style. +func (s Style) DashedUnderline() Style { + return append(s, DashedUnderlineAttr) +} + +// SlowBlink appends the slow blink style attribute to the style. +func (s Style) SlowBlink() Style { + return append(s, SlowBlinkAttr) +} + +// RapidBlink appends the rapid blink style attribute to the style. +func (s Style) RapidBlink() Style { + return append(s, RapidBlinkAttr) +} + +// Reverse appends the reverse style attribute to the style. +func (s Style) Reverse() Style { + return append(s, ReverseAttr) +} + +// Conceal appends the conceal style attribute to the style. +func (s Style) Conceal() Style { + return append(s, ConcealAttr) +} + +// Strikethrough appends the strikethrough style attribute to the style. +func (s Style) Strikethrough() Style { + return append(s, StrikethroughAttr) +} + +// NoBold appends the no bold style attribute to the style. +func (s Style) NoBold() Style { + return append(s, NoBoldAttr) +} + +// NormalIntensity appends the normal intensity style attribute to the style. +func (s Style) NormalIntensity() Style { + return append(s, NormalIntensityAttr) +} + +// NoItalic appends the no italic style attribute to the style. +func (s Style) NoItalic() Style { + return append(s, NoItalicAttr) +} + +// NoUnderline appends the no underline style attribute to the style. +func (s Style) NoUnderline() Style { + return append(s, NoUnderlineAttr) +} + +// NoBlink appends the no blink style attribute to the style. +func (s Style) NoBlink() Style { + return append(s, NoBlinkAttr) +} + +// NoReverse appends the no reverse style attribute to the style. +func (s Style) NoReverse() Style { + return append(s, NoReverseAttr) +} + +// NoStrikethrough appends the no strikethrough style attribute to the style. +func (s Style) NoStrikethrough() Style { + return append(s, NoStrikethroughAttr) +} + +// DefaultForegroundColor appends the default foreground color style attribute to the style. +func (s Style) DefaultForegroundColor() Style { + return append(s, DefaultForegroundColorAttr) +} + +// DefaultBackgroundColor appends the default background color style attribute to the style. +func (s Style) DefaultBackgroundColor() Style { + return append(s, DefaultBackgroundColorAttr) +} + +// DefaultUnderlineColor appends the default underline color style attribute to the style. +func (s Style) DefaultUnderlineColor() Style { + return append(s, DefaultUnderlineColorAttr) +} + +// ForegroundColor appends the foreground color style attribute to the style. +func (s Style) ForegroundColor(c Color) Style { + return append(s, ForegroundColorAttr(c)) +} + +// BackgroundColor appends the background color style attribute to the style. +func (s Style) BackgroundColor(c Color) Style { + return append(s, BackgroundColorAttr(c)) +} + +// UnderlineColor appends the underline color style attribute to the style. +func (s Style) UnderlineColor(c Color) Style { + return append(s, UnderlineColorAttr(c)) +} + +// SGR (Select Graphic Rendition) style attributes. +// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters +const ( + ResetAttr Attr = "0" + BoldAttr Attr = "1" + FaintAttr Attr = "2" + ItalicAttr Attr = "3" + UnderlineAttr Attr = "4" + DoubleUnderlineAttr Attr = "4:2" + CurlyUnderlineAttr Attr = "4:3" + DottedUnderlineAttr Attr = "4:4" + DashedUnderlineAttr Attr = "4:5" + SlowBlinkAttr Attr = "5" + RapidBlinkAttr Attr = "6" + ReverseAttr Attr = "7" + ConcealAttr Attr = "8" + StrikethroughAttr Attr = "9" + NoBoldAttr Attr = "21" // Some terminals treat this as double underline. + NormalIntensityAttr Attr = "22" + NoItalicAttr Attr = "23" + NoUnderlineAttr Attr = "24" + NoBlinkAttr Attr = "25" + NoReverseAttr Attr = "27" + NoStrikethroughAttr Attr = "29" + DefaultForegroundColorAttr Attr = "39" + DefaultBackgroundColorAttr Attr = "49" + DefaultUnderlineColorAttr Attr = "59" +) + +// ForegroundColorAttr returns the style SGR attribute for the given foreground +// color. +// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters +func ForegroundColorAttr(c Color) Attr { + switch c := c.(type) { + case BasicColor: + // 3-bit or 4-bit ANSI foreground + // "3" or "9" where n is the color number from 0 to 7 + if c < 8 { + return "3" + string('0'+c) + } else if c < 16 { + return "9" + string('0'+c-8) + } + case ExtendedColor: + // 256-color ANSI foreground + // "38;5;" + return "38;5;" + strconv.FormatUint(uint64(c), 10) + case TrueColor, color.Color: + // 24-bit "true color" foreground + // "38;2;;;" + r, g, b, _ := c.RGBA() + return "38;2;" + + strconv.FormatUint(uint64(shift(r)), 10) + ";" + + strconv.FormatUint(uint64(shift(g)), 10) + ";" + + strconv.FormatUint(uint64(shift(b)), 10) + } + return DefaultForegroundColorAttr +} + +// BackgroundColorAttr returns the style SGR attribute for the given background +// color. +// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters +func BackgroundColorAttr(c Color) Attr { + switch c := c.(type) { + case BasicColor: + // 3-bit or 4-bit ANSI foreground + // "4" or "10" where n is the color number from 0 to 7 + if c < 8 { + return "4" + string('0'+c) + } else { + return "10" + string('0'+c-8) + } + case ExtendedColor: + // 256-color ANSI foreground + // "48;5;" + return "48;5;" + strconv.FormatUint(uint64(c), 10) + case TrueColor, color.Color: + // 24-bit "true color" foreground + // "38;2;;;" + r, g, b, _ := c.RGBA() + return "48;2;" + + strconv.FormatUint(uint64(shift(r)), 10) + ";" + + strconv.FormatUint(uint64(shift(g)), 10) + ";" + + strconv.FormatUint(uint64(shift(b)), 10) + } + return DefaultBackgroundColorAttr +} + +// UnderlineColorAttr returns the style SGR attribute for the given underline +// color. +// See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters +func UnderlineColorAttr(c Color) Attr { + switch c := c.(type) { + // NOTE: we can't use 3-bit and 4-bit ANSI color codes with underline + // color, use 256-color instead. + // + // 256-color ANSI underline color + // "58;5;" + case BasicColor: + return "58;5;" + strconv.FormatUint(uint64(c), 10) + case ExtendedColor: + return "58;5;" + strconv.FormatUint(uint64(c), 10) + case TrueColor, color.Color: + // 24-bit "true color" foreground + // "38;2;;;" + r, g, b, _ := c.RGBA() + return "58;2;" + + strconv.FormatUint(uint64(shift(r)), 10) + ";" + + strconv.FormatUint(uint64(shift(g)), 10) + ";" + + strconv.FormatUint(uint64(shift(b)), 10) + } + return DefaultUnderlineColorAttr +} + +func shift(v uint32) uint32 { + if v > 0xff { + return v >> 8 + } + return v +} diff --git a/vendor/github.com/charmbracelet/x/ansi/termcap.go b/vendor/github.com/charmbracelet/x/ansi/termcap.go new file mode 100644 index 0000000..1dfc52a --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/termcap.go @@ -0,0 +1,31 @@ +package ansi + +import ( + "encoding/hex" + "strings" +) + +// RequestTermcap (XTGETTCAP) requests Termcap/Terminfo strings. +// +// DCS + q ST +// +// Where is a list of Termcap/Terminfo capabilities, encoded in 2-digit +// hexadecimals, separated by semicolons. +// +// See: https://man7.org/linux/man-pages/man5/terminfo.5.html +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands +func RequestTermcap(caps ...string) string { + if len(caps) == 0 { + return "" + } + + s := "\x1bP+q" + for i, c := range caps { + if i > 0 { + s += ";" + } + s += strings.ToUpper(hex.EncodeToString([]byte(c))) + } + + return s + "\x1b\\" +} diff --git a/vendor/github.com/charmbracelet/x/ansi/title.go b/vendor/github.com/charmbracelet/x/ansi/title.go new file mode 100644 index 0000000..8fd8bf9 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/title.go @@ -0,0 +1,32 @@ +package ansi + +// SetIconNameWindowTitle returns a sequence for setting the icon name and +// window title. +// +// OSC 0 ; title ST +// OSC 0 ; title BEL +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands +func SetIconNameWindowTitle(s string) string { + return "\x1b]0;" + s + "\x07" +} + +// SetIconName returns a sequence for setting the icon name. +// +// OSC 1 ; title ST +// OSC 1 ; title BEL +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands +func SetIconName(s string) string { + return "\x1b]1;" + s + "\x07" +} + +// SetWindowTitle returns a sequence for setting the window title. +// +// OSC 2 ; title ST +// OSC 2 ; title BEL +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands +func SetWindowTitle(s string) string { + return "\x1b]2;" + s + "\x07" +} diff --git a/vendor/github.com/charmbracelet/x/ansi/truncate.go b/vendor/github.com/charmbracelet/x/ansi/truncate.go new file mode 100644 index 0000000..03d0a12 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/truncate.go @@ -0,0 +1,108 @@ +package ansi + +import ( + "bytes" + + "github.com/charmbracelet/x/ansi/parser" + "github.com/rivo/uniseg" +) + +// Truncate truncates a string to a given length, adding a tail to the +// end if the string is longer than the given length. +// This function is aware of ANSI escape codes and will not break them, and +// accounts for wide-characters (such as East Asians and emojis). +func Truncate(s string, length int, tail string) string { + tw := StringWidth(tail) + length -= tw + if length < 0 { + return "" + } + + var cluster []byte + var buf bytes.Buffer + curWidth := 0 + ignoring := false + gstate := -1 + pstate := parser.GroundState // initial state + b := []byte(s) + i := 0 + + // Here we iterate over the bytes of the string and collect printable + // characters and runes. We also keep track of the width of the string + // in cells. + // Once we reach the given length, we start ignoring characters and only + // collect ANSI escape codes until we reach the end of string. + for i < len(b) { + state, action := parser.Table.Transition(pstate, b[i]) + + switch action { + case parser.PrintAction: + if utf8ByteLen(b[i]) > 1 { + // This action happens when we transition to the Utf8State. + var width int + cluster, _, width, gstate = uniseg.FirstGraphemeCluster(b[i:], gstate) + + // increment the index by the length of the cluster + i += len(cluster) + + // Are we ignoring? Skip to the next byte + if ignoring { + continue + } + + // Is this gonna be too wide? + // If so write the tail and stop collecting. + if curWidth+width > length && !ignoring { + ignoring = true + buf.WriteString(tail) + } + + if curWidth+width > length { + continue + } + + curWidth += width + for _, r := range cluster { + buf.WriteByte(r) + } + + gstate = -1 // reset grapheme state otherwise, width calculation might be off + // Done collecting, now we're back in the ground state. + pstate = parser.GroundState + continue + } + + // Is this gonna be too wide? + // If so write the tail and stop collecting. + if curWidth >= length && !ignoring { + ignoring = true + buf.WriteString(tail) + } + + // Skip to the next byte if we're ignoring + if ignoring { + i++ + continue + } + + // collects printable ASCII + curWidth++ + fallthrough + default: + buf.WriteByte(b[i]) + i++ + } + + // Transition to the next state. + pstate = state + + // Once we reach the given length, we start ignoring runes and write + // the tail to the buffer. + if curWidth > length && !ignoring { + ignoring = true + buf.WriteString(tail) + } + } + + return buf.String() +} diff --git a/vendor/github.com/charmbracelet/x/ansi/util.go b/vendor/github.com/charmbracelet/x/ansi/util.go new file mode 100644 index 0000000..767093f --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/util.go @@ -0,0 +1,29 @@ +package ansi + +import ( + "fmt" + "image/color" +) + +// colorToHexString returns a hex string representation of a color. +func colorToHexString(c color.Color) string { + if c == nil { + return "" + } + shift := func(v uint32) uint32 { + if v > 0xff { + return v >> 8 + } + return v + } + r, g, b, _ := c.RGBA() + r, g, b = shift(r), shift(g), shift(b) + return fmt.Sprintf("#%02x%02x%02x", r, g, b) +} + +// rgbToHex converts red, green, and blue values to a hexadecimal value. +// +// hex := rgbToHex(0, 0, 255) // 0x0000FF +func rgbToHex(r, g, b uint32) uint32 { + return r<<16 + g<<8 + b +} diff --git a/vendor/github.com/charmbracelet/x/ansi/width.go b/vendor/github.com/charmbracelet/x/ansi/width.go new file mode 100644 index 0000000..4da3959 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/width.go @@ -0,0 +1,73 @@ +package ansi + +import ( + "bytes" + + "github.com/charmbracelet/x/ansi/parser" + "github.com/rivo/uniseg" +) + +// Strip removes ANSI escape codes from a string. +func Strip(s string) string { + var ( + buf bytes.Buffer // buffer for collecting printable characters + ri int // rune index + rw int // rune width + pstate = parser.GroundState // initial state + ) + + // This implements a subset of the Parser to only collect runes and + // printable characters. + for i := 0; i < len(s); i++ { + var state, action byte + if pstate != parser.Utf8State { + state, action = parser.Table.Transition(pstate, s[i]) + } + + switch { + case pstate == parser.Utf8State: + // During this state, collect rw bytes to form a valid rune in the + // buffer. After getting all the rune bytes into the buffer, + // transition to GroundState and reset the counters. + buf.WriteByte(s[i]) + ri++ + if ri < rw { + continue + } + pstate = parser.GroundState + ri = 0 + rw = 0 + case action == parser.PrintAction: + // This action happens when we transition to the Utf8State. + if w := utf8ByteLen(s[i]); w > 1 { + rw = w + buf.WriteByte(s[i]) + ri++ + break + } + fallthrough + case action == parser.ExecuteAction: + // collects printable ASCII and non-printable characters + buf.WriteByte(s[i]) + } + + // Transition to the next state. + // The Utf8State is managed separately above. + if pstate != parser.Utf8State { + pstate = state + } + } + + return buf.String() +} + +// StringWidth returns the width of a string in cells. This is the number of +// cells that the string will occupy when printed in a terminal. ANSI escape +// codes are ignored and wide characters (such as East Asians and emojis) are +// accounted for. +func StringWidth(s string) int { + if s == "" { + return 0 + } + return uniseg.StringWidth(Strip(s)) +} diff --git a/vendor/github.com/charmbracelet/x/ansi/wrap.go b/vendor/github.com/charmbracelet/x/ansi/wrap.go new file mode 100644 index 0000000..9aa9b64 --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/wrap.go @@ -0,0 +1,406 @@ +package ansi + +import ( + "bytes" + "unicode" + "unicode/utf8" + + "github.com/charmbracelet/x/ansi/parser" + "github.com/rivo/uniseg" +) + +// nbsp is a non-breaking space +const nbsp = 0xA0 + +// Hardwrap wraps a string or a block of text to a given line length, breaking +// word boundaries. This will preserve ANSI escape codes and will account for +// wide-characters in the string. +// When preserveSpace is true, spaces at the beginning of a line will be +// preserved. +func Hardwrap(s string, limit int, preserveSpace bool) string { + if limit < 1 { + return s + } + + var ( + cluster []byte + buf bytes.Buffer + curWidth int + forceNewline bool + gstate = -1 + pstate = parser.GroundState // initial state + b = []byte(s) + ) + + addNewline := func() { + buf.WriteByte('\n') + curWidth = 0 + } + + i := 0 + for i < len(b) { + state, action := parser.Table.Transition(pstate, b[i]) + + switch action { + case parser.PrintAction: + if utf8ByteLen(b[i]) > 1 { + var width int + cluster, _, width, gstate = uniseg.FirstGraphemeCluster(b[i:], gstate) + i += len(cluster) + + if curWidth+width > limit { + addNewline() + } + if !preserveSpace && curWidth == 0 && len(cluster) <= 4 { + // Skip spaces at the beginning of a line + if r, _ := utf8.DecodeRune(cluster); r != utf8.RuneError && unicode.IsSpace(r) { + pstate = parser.GroundState + continue + } + } + + buf.Write(cluster) + curWidth += width + gstate = -1 // reset grapheme state otherwise, width calculation might be off + pstate = parser.GroundState + continue + } + fallthrough + case parser.ExecuteAction: + if b[i] == '\n' { + addNewline() + forceNewline = false + break + } + + if curWidth+1 > limit { + addNewline() + forceNewline = true + } + + // Skip spaces at the beginning of a line + if curWidth == 0 { + if !preserveSpace && forceNewline && unicode.IsSpace(rune(b[i])) { + break + } + forceNewline = false + } + + buf.WriteByte(b[i]) + curWidth++ + default: + buf.WriteByte(b[i]) + } + + // We manage the UTF8 state separately manually above. + if pstate != parser.Utf8State { + pstate = state + } + i++ + } + + return buf.String() +} + +// Wordwrap wraps a string or a block of text to a given line length, not +// breaking word boundaries. This will preserve ANSI escape codes and will +// account for wide-characters in the string. +// The breakpoints string is a list of characters that are considered +// breakpoints for word wrapping. A hyphen (-) is always considered a +// breakpoint. +// +// Note: breakpoints must be a string of 1-cell wide rune characters. +func Wordwrap(s string, limit int, breakpoints string) string { + if limit < 1 { + return s + } + + var ( + cluster []byte + buf bytes.Buffer + word bytes.Buffer + space bytes.Buffer + curWidth int + wordLen int + gstate = -1 + pstate = parser.GroundState // initial state + b = []byte(s) + ) + + addSpace := func() { + curWidth += space.Len() + buf.Write(space.Bytes()) + space.Reset() + } + + addWord := func() { + if word.Len() == 0 { + return + } + + addSpace() + curWidth += wordLen + buf.Write(word.Bytes()) + word.Reset() + wordLen = 0 + } + + addNewline := func() { + buf.WriteByte('\n') + curWidth = 0 + space.Reset() + } + + i := 0 + for i < len(b) { + state, action := parser.Table.Transition(pstate, b[i]) + + switch action { + case parser.PrintAction: + if utf8ByteLen(b[i]) > 1 { + var width int + cluster, _, width, gstate = uniseg.FirstGraphemeCluster(b[i:], gstate) + i += len(cluster) + + r, _ := utf8.DecodeRune(cluster) + if r != utf8.RuneError && unicode.IsSpace(r) && r != nbsp { + addWord() + space.WriteRune(r) + } else if bytes.ContainsAny(cluster, breakpoints) { + addSpace() + addWord() + buf.Write(cluster) + curWidth++ + } else { + word.Write(cluster) + wordLen += width + if curWidth+space.Len()+wordLen > limit && + wordLen < limit { + addNewline() + } + } + + pstate = parser.GroundState + continue + } + fallthrough + case parser.ExecuteAction: + r := rune(b[i]) + switch { + case r == '\n': + if wordLen == 0 { + if curWidth+space.Len() > limit { + curWidth = 0 + } else { + buf.Write(space.Bytes()) + } + space.Reset() + } + + addWord() + addNewline() + case unicode.IsSpace(r): + addWord() + space.WriteByte(b[i]) + case r == '-': + fallthrough + case runeContainsAny(r, breakpoints): + addSpace() + addWord() + buf.WriteByte(b[i]) + curWidth++ + default: + word.WriteByte(b[i]) + wordLen++ + if curWidth+space.Len()+wordLen > limit && + wordLen < limit { + addNewline() + } + } + + default: + word.WriteByte(b[i]) + } + + // We manage the UTF8 state separately manually above. + if pstate != parser.Utf8State { + pstate = state + } + i++ + } + + addWord() + + return buf.String() +} + +// Wrap wraps a string or a block of text to a given line length, breaking word +// boundaries if necessary. This will preserve ANSI escape codes and will +// account for wide-characters in the string. The breakpoints string is a list +// of characters that are considered breakpoints for word wrapping. A hyphen +// (-) is always considered a breakpoint. +// +// Note: breakpoints must be a string of 1-cell wide rune characters. +func Wrap(s string, limit int, breakpoints string) string { + if limit < 1 { + return s + } + + var ( + cluster []byte + buf bytes.Buffer + word bytes.Buffer + space bytes.Buffer + curWidth int // written width of the line + wordLen int // word buffer len without ANSI escape codes + gstate = -1 + pstate = parser.GroundState // initial state + b = []byte(s) + ) + + addSpace := func() { + curWidth += space.Len() + buf.Write(space.Bytes()) + space.Reset() + } + + addWord := func() { + if word.Len() == 0 { + return + } + + addSpace() + curWidth += wordLen + buf.Write(word.Bytes()) + word.Reset() + wordLen = 0 + } + + addNewline := func() { + buf.WriteByte('\n') + curWidth = 0 + space.Reset() + } + + i := 0 + for i < len(b) { + state, action := parser.Table.Transition(pstate, b[i]) + + switch action { + case parser.PrintAction: + if utf8ByteLen(b[i]) > 1 { + var width int + cluster, _, width, gstate = uniseg.FirstGraphemeCluster(b[i:], gstate) + i += len(cluster) + + r, _ := utf8.DecodeRune(cluster) + switch { + case r != utf8.RuneError && unicode.IsSpace(r) && r != nbsp: // nbsp is a non-breaking space + addWord() + space.WriteRune(r) + case bytes.ContainsAny(cluster, breakpoints): + addSpace() + if curWidth+wordLen+width > limit { + word.Write(cluster) + wordLen += width + } else { + addWord() + buf.Write(cluster) + curWidth += width + } + default: + if wordLen+width > limit { + // Hardwrap the word if it's too long + addWord() + } + + word.Write(cluster) + wordLen += width + + if curWidth+wordLen+space.Len() > limit { + addNewline() + } + } + + pstate = parser.GroundState + continue + } + + fallthrough + case parser.ExecuteAction: + switch r := rune(b[i]); { + case r == '\n': + if wordLen == 0 { + if curWidth+space.Len() > limit { + curWidth = 0 + } else { + // preserve whitespaces + buf.Write(space.Bytes()) + } + space.Reset() + } + + addWord() + addNewline() + case unicode.IsSpace(r): + addWord() + space.WriteRune(r) + case r == '-': + fallthrough + case runeContainsAny(r, breakpoints): + addSpace() + if curWidth+wordLen >= limit { + // We can't fit the breakpoint in the current line, treat + // it as part of the word. + word.WriteRune(r) + wordLen++ + } else { + addWord() + buf.WriteRune(r) + curWidth++ + } + default: + word.WriteRune(r) + wordLen++ + + if wordLen == limit { + // Hardwrap the word if it's too long + addWord() + } + + if curWidth+wordLen+space.Len() > limit { + addNewline() + } + } + + default: + word.WriteByte(b[i]) + } + + // We manage the UTF8 state separately manually above. + if pstate != parser.Utf8State { + pstate = state + } + i++ + } + + if word.Len() != 0 { + // Preserve ANSI wrapped spaces at the end of string + if curWidth+space.Len() > limit { + buf.WriteByte('\n') + } + addSpace() + } + buf.Write(word.Bytes()) + + return buf.String() +} + +func runeContainsAny(r rune, s string) bool { + for _, c := range s { + if c == r { + return true + } + } + return false +} diff --git a/vendor/github.com/charmbracelet/x/ansi/xterm.go b/vendor/github.com/charmbracelet/x/ansi/xterm.go new file mode 100644 index 0000000..e2eb10a --- /dev/null +++ b/vendor/github.com/charmbracelet/x/ansi/xterm.go @@ -0,0 +1,33 @@ +package ansi + +// DisableModifyOtherKeys disables the modifyOtherKeys mode. +// +// CSI > 4 ; 0 m +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_ +// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys +const DisableModifyOtherKeys = "\x1b[>4;0m" + +// EnableModifyOtherKeys1 enables the modifyOtherKeys mode 1. +// +// CSI > 4 ; 1 m +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_ +// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys +const EnableModifyOtherKeys1 = "\x1b[>4;1m" + +// EnableModifyOtherKeys2 enables the modifyOtherKeys mode 2. +// +// CSI > 4 ; 2 m +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_ +// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys +const EnableModifyOtherKeys2 = "\x1b[>4;2m" + +// RequestModifyOtherKeys requests the modifyOtherKeys mode. +// +// CSI ? 4 m +// +// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_ +// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys +const RequestModifyOtherKeys = "\x1b[?4m" diff --git a/vendor/github.com/mattn/go-isatty/isatty_bsd.go b/vendor/github.com/mattn/go-isatty/isatty_bsd.go index d569c0c..d0ea68f 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_bsd.go +++ b/vendor/github.com/mattn/go-isatty/isatty_bsd.go @@ -1,6 +1,7 @@ -//go:build (darwin || freebsd || openbsd || netbsd || dragonfly || hurd) && !appengine +//go:build (darwin || freebsd || openbsd || netbsd || dragonfly || hurd) && !appengine && !tinygo // +build darwin freebsd openbsd netbsd dragonfly hurd // +build !appengine +// +build !tinygo package isatty diff --git a/vendor/github.com/mattn/go-isatty/isatty_others.go b/vendor/github.com/mattn/go-isatty/isatty_others.go index 3150322..7402e06 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_others.go +++ b/vendor/github.com/mattn/go-isatty/isatty_others.go @@ -1,5 +1,6 @@ -//go:build appengine || js || nacl || wasm -// +build appengine js nacl wasm +//go:build (appengine || js || nacl || tinygo || wasm) && !windows +// +build appengine js nacl tinygo wasm +// +build !windows package isatty diff --git a/vendor/github.com/mattn/go-isatty/isatty_tcgets.go b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go index 6778765..0337d8c 100644 --- a/vendor/github.com/mattn/go-isatty/isatty_tcgets.go +++ b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go @@ -1,6 +1,7 @@ -//go:build (linux || aix || zos) && !appengine +//go:build (linux || aix || zos) && !appengine && !tinygo // +build linux aix zos // +build !appengine +// +build !tinygo package isatty diff --git a/vendor/modules.txt b/vendor/modules.txt index 4f64cc6..54284c2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -18,16 +18,20 @@ github.com/charmbracelet/bubbles/viewport # github.com/charmbracelet/bubbletea v0.26.1 ## explicit; go 1.18 github.com/charmbracelet/bubbletea -# github.com/charmbracelet/lipgloss v0.10.0 +# github.com/charmbracelet/lipgloss v0.11.0 ## explicit; go 1.18 github.com/charmbracelet/lipgloss +# github.com/charmbracelet/x/ansi v0.1.1 +## explicit; go 1.18 +github.com/charmbracelet/x/ansi +github.com/charmbracelet/x/ansi/parser # github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f ## explicit; go 1.16 github.com/erikgeiser/coninput # github.com/lucasb-eyer/go-colorful v1.2.0 ## explicit; go 1.12 github.com/lucasb-eyer/go-colorful -# github.com/mattn/go-isatty v0.0.18 +# github.com/mattn/go-isatty v0.0.20 ## explicit; go 1.15 github.com/mattn/go-isatty # github.com/mattn/go-localereader v0.0.1