diff options
Diffstat (limited to 'vendor/github.com/muesli')
26 files changed, 2931 insertions, 0 deletions
diff --git a/vendor/github.com/muesli/termenv/.gitignore b/vendor/github.com/muesli/termenv/.gitignore new file mode 100644 index 0000000..66fd13c --- /dev/null +++ b/vendor/github.com/muesli/termenv/.gitignore @@ -0,0 +1,15 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ diff --git a/vendor/github.com/muesli/termenv/.golangci-soft.yml b/vendor/github.com/muesli/termenv/.golangci-soft.yml new file mode 100644 index 0000000..84e3d41 --- /dev/null +++ b/vendor/github.com/muesli/termenv/.golangci-soft.yml @@ -0,0 +1,43 @@ +run: + tests: false + +issues: + include: + - EXC0001 + - EXC0005 + - EXC0011 + - EXC0012 + - EXC0013 + + max-issues-per-linter: 0 + max-same-issues: 0 + +linters: + enable: + # - dupl + - exhaustive + # - exhaustivestruct + - goconst + - godot + - godox + - mnd + - gomoddirectives + - goprintffuncname + # - lll + - misspell + - nakedret + - nestif + - noctx + - nolintlint + - prealloc + - wrapcheck + + # disable default linters, they are already enabled in .golangci.yml + disable: + - errcheck + - gosimple + - govet + - ineffassign + - staticcheck + - typecheck + - unused diff --git a/vendor/github.com/muesli/termenv/.golangci.yml b/vendor/github.com/muesli/termenv/.golangci.yml new file mode 100644 index 0000000..684d54b --- /dev/null +++ b/vendor/github.com/muesli/termenv/.golangci.yml @@ -0,0 +1,28 @@ +run: + tests: false + +issues: + include: + - EXC0001 + - EXC0005 + - EXC0011 + - EXC0012 + - EXC0013 + + max-issues-per-linter: 0 + max-same-issues: 0 + +linters: + enable: + - bodyclose + - goimports + - gosec + - nilerr + - predeclared + - revive + - rowserrcheck + - sqlclosecheck + - tparallel + - unconvert + - unparam + - whitespace diff --git a/vendor/github.com/muesli/termenv/LICENSE b/vendor/github.com/muesli/termenv/LICENSE new file mode 100644 index 0000000..8532c45 --- /dev/null +++ b/vendor/github.com/muesli/termenv/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Christian Muehlhaeuser + +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/muesli/termenv/README.md b/vendor/github.com/muesli/termenv/README.md new file mode 100644 index 0000000..fa7929d --- /dev/null +++ b/vendor/github.com/muesli/termenv/README.md @@ -0,0 +1,431 @@ +<p align="center"> + <img src="https://stuff.charm.sh/termenv.png" width="480" alt="termenv Logo"> + <br /> + <a href="https://github.com/muesli/termenv/releases"><img src="https://img.shields.io/github/release/muesli/termenv.svg" alt="Latest Release"></a> + <a href="https://godoc.org/github.com/muesli/termenv"><img src="https://godoc.org/github.com/golang/gddo?status.svg" alt="GoDoc"></a> + <a href="https://github.com/muesli/termenv/actions"><img src="https://github.com/muesli/termenv/workflows/build/badge.svg" alt="Build Status"></a> + <a href="https://coveralls.io/github/muesli/termenv?branch=master"><img src="https://coveralls.io/repos/github/muesli/termenv/badge.svg?branch=master" alt="Coverage Status"></a> + <a href="https://goreportcard.com/report/muesli/termenv"><img src="https://goreportcard.com/badge/muesli/termenv" alt="Go ReportCard"></a> + <br /> + <img src="https://github.com/muesli/termenv/raw/master/examples/hello-world/hello-world.png" alt="Example terminal output"> +</p> + +`termenv` lets you safely use advanced styling options on the terminal. It +gathers information about the terminal environment in terms of its ANSI & color +support and offers you convenient methods to colorize and style your output, +without you having to deal with all kinds of weird ANSI escape sequences and +color conversions. + +## Features + +- RGB/TrueColor support +- Detects the supported color range of your terminal +- Automatically converts colors to the best matching, available colors +- Terminal theme (light/dark) detection +- Chainable syntax +- Nested styles + +## Installation + +```bash +go get github.com/muesli/termenv +``` + +## Usage + +```go +output := termenv.NewOutput(os.Stdout) +``` + +`termenv` queries the terminal's capabilities it is running in, so you can +safely use advanced features, like RGB colors or ANSI styles. `output.Profile` +returns the supported profile: + +- `termenv.Ascii` - no ANSI support detected, ASCII only +- `termenv.ANSI` - 16 color ANSI support +- `termenv.ANSI256` - Extended 256 color ANSI support +- `termenv.TrueColor` - RGB/TrueColor support + +Alternatively, you can use `termenv.EnvColorProfile` which evaluates the +terminal like `ColorProfile`, but also respects the `NO_COLOR` and +`CLICOLOR_FORCE` environment variables. + +You can also query the terminal for its color scheme, so you know whether your +app is running in a light- or dark-themed environment: + +```go +// Returns terminal's foreground color +color := output.ForegroundColor() + +// Returns terminal's background color +color := output.BackgroundColor() + +// Returns whether terminal uses a dark-ish background +darkTheme := output.HasDarkBackground() +``` + +### Manual Profile Selection + +If you don't want to rely on the automatic detection, you can manually select +the profile you want to use: + +```go +output := termenv.NewOutput(os.Stdout, termenv.WithProfile(termenv.TrueColor)) +``` + +## Colors + +`termenv` supports multiple color profiles: Ascii (black & white only), +ANSI (16 colors), ANSI Extended (256 colors), and TrueColor (24-bit RGB). Colors +will automatically be degraded to the best matching available color in the +desired profile: + +`TrueColor` => `ANSI 256 Colors` => `ANSI 16 Colors` => `Ascii` + +```go +s := output.String("Hello World") + +// Supports hex values +// Will automatically degrade colors on terminals not supporting RGB +s.Foreground(output.Color("#abcdef")) +// but also supports ANSI colors (0-255) +s.Background(output.Color("69")) +// ...or the color.Color interface +s.Foreground(output.FromColor(color.RGBA{255, 128, 0, 255})) + +// Combine fore- & background colors +s.Foreground(output.Color("#ffffff")).Background(output.Color("#0000ff")) + +// Supports the fmt.Stringer interface +fmt.Println(s) +``` + +## Styles + +You can use a chainable syntax to compose your own styles: + +```go +s := output.String("foobar") + +// Text styles +s.Bold() +s.Faint() +s.Italic() +s.CrossOut() +s.Underline() +s.Overline() + +// Reverse swaps current fore- & background colors +s.Reverse() + +// Blinking text +s.Blink() + +// Combine multiple options +s.Bold().Underline() +``` + +## Template Helpers + +`termenv` provides a set of helper functions to style your Go templates: + +```go +// load template helpers +f := output.TemplateFuncs() +tpl := template.New("tpl").Funcs(f) + +// apply bold style in a template +bold := `{{ Bold "Hello World" }}` + +// examples for colorized templates +col := `{{ Color "#ff0000" "#0000ff" "Red on Blue" }}` +fg := `{{ Foreground "#ff0000" "Red Foreground" }}` +bg := `{{ Background "#0000ff" "Blue Background" }}` + +// wrap styles +wrap := `{{ Bold (Underline "Hello World") }}` + +// parse and render +tpl, err = tpl.Parse(bold) + +var buf bytes.Buffer +tpl.Execute(&buf, nil) +fmt.Println(&buf) +``` + +Other available helper functions are: `Faint`, `Italic`, `CrossOut`, +`Underline`, `Overline`, `Reverse`, and `Blink`. + +## Positioning + +```go +// Move the cursor to a given position +output.MoveCursor(row, column) + +// Save the cursor position +output.SaveCursorPosition() + +// Restore a saved cursor position +output.RestoreCursorPosition() + +// Move the cursor up a given number of lines +output.CursorUp(n) + +// Move the cursor down a given number of lines +output.CursorDown(n) + +// Move the cursor up a given number of lines +output.CursorForward(n) + +// Move the cursor backwards a given number of cells +output.CursorBack(n) + +// Move the cursor down a given number of lines and place it at the beginning +// of the line +output.CursorNextLine(n) + +// Move the cursor up a given number of lines and place it at the beginning of +// the line +output.CursorPrevLine(n) +``` + +## Screen + +```go +// Reset the terminal to its default style, removing any active styles +output.Reset() + +// RestoreScreen restores a previously saved screen state +output.RestoreScreen() + +// SaveScreen saves the screen state +output.SaveScreen() + +// Switch to the altscreen. The former view can be restored with ExitAltScreen() +output.AltScreen() + +// Exit the altscreen and return to the former terminal view +output.ExitAltScreen() + +// Clear the visible portion of the terminal +output.ClearScreen() + +// Clear the current line +output.ClearLine() + +// Clear a given number of lines +output.ClearLines(n) + +// Set the scrolling region of the terminal +output.ChangeScrollingRegion(top, bottom) + +// Insert the given number of lines at the top of the scrollable region, pushing +// lines below down +output.InsertLines(n) + +// Delete the given number of lines, pulling any lines in the scrollable region +// below up +output.DeleteLines(n) +``` + +## Session + +```go +// SetWindowTitle sets the terminal window title +output.SetWindowTitle(title) + +// SetForegroundColor sets the default foreground color +output.SetForegroundColor(color) + +// SetBackgroundColor sets the default background color +output.SetBackgroundColor(color) + +// SetCursorColor sets the cursor color +output.SetCursorColor(color) + +// Hide the cursor +output.HideCursor() + +// Show the cursor +output.ShowCursor() + +// Copy to clipboard +output.Copy(message) + +// Copy to primary clipboard (X11) +output.CopyPrimary(message) + +// Trigger notification +output.Notify(title, body) +``` + +## Mouse + +```go +// Enable X10 mouse mode, only button press events are sent +output.EnableMousePress() + +// Disable X10 mouse mode +output.DisableMousePress() + +// Enable Mouse Tracking mode +output.EnableMouse() + +// Disable Mouse Tracking mode +output.DisableMouse() + +// Enable Hilite Mouse Tracking mode +output.EnableMouseHilite() + +// Disable Hilite Mouse Tracking mode +output.DisableMouseHilite() + +// Enable Cell Motion Mouse Tracking mode +output.EnableMouseCellMotion() + +// Disable Cell Motion Mouse Tracking mode +output.DisableMouseCellMotion() + +// Enable All Motion Mouse mode +output.EnableMouseAllMotion() + +// Disable All Motion Mouse mode +output.DisableMouseAllMotion() +``` + +## Bracketed Paste + +```go +// Enables bracketed paste mode +termenv.EnableBracketedPaste() + +// Disables bracketed paste mode +termenv.DisableBracketedPaste() +``` + +## Terminal Feature Support + +### Color Support + +- 24-bit (RGB): alacritty, foot, iTerm, kitty, Konsole, st, tmux, vte-based, wezterm, Ghostty, Windows Terminal +- 8-bit (256): rxvt, screen, xterm, Apple Terminal +- 4-bit (16): Linux Console + +### Control Sequences + +<details> +<summary>Click to show feature matrix</summary> + +| Terminal | Query Color Scheme | Query Cursor Position | Set Window Title | Change Cursor Color | Change Default Foreground Setting | Change Default Background Setting | Bracketed Paste | Extended Mouse (SGR) | Pixels Mouse (SGR-Pixels) | +| ---------------- | :----------------: | :-------------------: | :--------------: | :-----------------: | :-------------------------------: | :-------------------------------: | :-------------: | :------------------: | :-----------------------: | +| alacritty | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| foot | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| kitty | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| Konsole | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | +| rxvt | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | +| urxvt | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| screen | ⛔[^mux] | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | +| st | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| tmux | ⛔[^mux] | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| vte-based[^vte] | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | +| wezterm | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| xterm | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | +| Linux Console | ❌ | ✅ | ⛔ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | +| Apple Terminal | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ❌ | +| iTerm | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | +| Windows cmd | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | +| Windows Terminal | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | + +[^vte]: This covers all vte-based terminals, including Gnome Terminal, guake, Pantheon Terminal, Terminator, Tilix, XFCE Terminal. +[^mux]: Unavailable as multiplexers (like tmux or screen) can be connected to multiple terminals (with different color settings) at the same time. + +You can help improve this list! Check out [how to](ansi_compat.md) and open an issue or pull request. + +</details> + +### System Commands + +<details> +<summary>Click to show feature matrix</summary> + +| Terminal | Copy to Clipboard (OSC52) | Hyperlinks (OSC8) | Notifications (OSC777) | +| ---------------- | :-----------------------: | :---------------: | :--------------------: | +| alacritty | ✅ | ✅[^alacritty] | ❌ | +| foot | ✅ | ✅ | ✅ | +| kitty | ✅ | ✅ | ✅ | +| Konsole | ❌[^konsole] | ✅ | ❌ | +| rxvt | ❌ | ❌ | ❌ | +| urxvt | ✅[^urxvt] | ❌ | ✅ | +| screen | ✅ | ❌[^screen] | ❌ | +| st | ✅ | ❌ | ❌ | +| tmux | ✅ | ❌[^tmux] | ❌ | +| vte-based[^vte] | ❌[^vte] | ✅ | ❌ | +| wezterm | ✅ | ✅ | ❌ | +| xterm | ✅ | ❌ | ❌ | +| Linux Console | ⛔ | ⛔ | ❌ | +| Apple Terminal | ✅[^apple] | ❌ | ❌ | +| iTerm | ✅ | ✅ | ❌ | +| Windows cmd | ❌ | ❌ | ❌ | +| Windows Terminal | ✅ | ✅ | ❌ | + +[^vte]: This covers all vte-based terminals, including Gnome Terminal, guake, Pantheon Terminal, Terminator, Tilix, XFCE Terminal. OSC52 is not supported, see [issue#2495](https://gitlab.gnome.org/GNOME/vte/-/issues/2495). +[^urxvt]: Workaround for urxvt not supporting OSC52. See [this](https://unix.stackexchange.com/a/629485) for more information. +[^konsole]: OSC52 is not supported, for more info see [bug#372116](https://bugs.kde.org/show_bug.cgi?id=372116). +[^apple]: OSC52 works with a [workaround](https://github.com/roy2220/osc52pty). +[^tmux]: OSC8 is not supported, for more info see [issue#911](https://github.com/tmux/tmux/issues/911). +[^screen]: OSC8 is not supported, for more info see [bug#50952](https://savannah.gnu.org/bugs/index.php?50952). +[^alacritty]: OSC8 is supported since [v0.11.0](https://github.com/alacritty/alacritty/releases/tag/v0.11.0) + +</details> + +## Platform Support + +`termenv` works on Unix systems (like Linux, macOS, or BSD) and Windows. While +terminal applications on Unix support ANSI styling out-of-the-box, on Windows +you need to enable ANSI processing in your application first: + +```go + restoreConsole, err := termenv.EnableVirtualTerminalProcessing(termenv.DefaultOutput()) + if err != nil { + panic(err) + } + defer restoreConsole() +``` + +The above code is safe to include on non-Windows systems or when os.Stdout does +not refer to a terminal (e.g. in tests). + +## Color Chart + + + +You can find the source code used to create this chart in `termenv`'s examples. + +## Related Projects + +- [reflow](https://github.com/muesli/reflow) - ANSI-aware text operations +- [Lip Gloss](https://github.com/charmbracelet/lipgloss) - style definitions for nice terminal layouts 👄 +- [ansi](https://github.com/muesli/ansi) - ANSI sequence helpers + +## termenv in the Wild + +Need some inspiration or just want to see how others are using `termenv`? Check +out these projects: + +- [Bubble Tea](https://github.com/charmbracelet/bubbletea) - a powerful little TUI framework 🏗 +- [Glamour](https://github.com/charmbracelet/glamour) - stylesheet-based markdown rendering for your CLI apps 💇🏻♀️ +- [Glow](https://github.com/charmbracelet/glow) - a markdown renderer for the command-line 💅🏻 +- [duf](https://github.com/muesli/duf) - Disk Usage/Free Utility - a better 'df' alternative +- [gitty](https://github.com/muesli/gitty) - contextual information about your git projects +- [slides](https://github.com/maaslalani/slides) - terminal-based presentation tool + +## Feedback + +Got some feedback or suggestions? Please open an issue or drop me a note! + +- [Twitter](https://twitter.com/mueslix) +- [The Fediverse](https://mastodon.social/@fribbledom) + +## License + +[MIT](https://github.com/muesli/termenv/raw/master/LICENSE) diff --git a/vendor/github.com/muesli/termenv/ansi_compat.md b/vendor/github.com/muesli/termenv/ansi_compat.md new file mode 100644 index 0000000..6b68a3a --- /dev/null +++ b/vendor/github.com/muesli/termenv/ansi_compat.md @@ -0,0 +1,65 @@ +## Change Foreground Color + +This command should enable a blue foreground color: + +```bash +echo -ne "\033]10;#0000ff\007" +``` + +## Change Background Color + +This command should enable a green background color: + +```bash +echo -ne "\033]11;#00ff00\007" +``` + +## Change Cursor Color + +This command should enable a red cursor color: + +```bash +echo -ne "\033]12;#ff0000\007" +``` + +## Query Color Scheme + +These two commands should print out the currently active color scheme: + +```bash +echo -ne "\033]10;?\033\\" +echo -ne "\033]11;?\033\\" +``` + +## Query Cursor Position + +This command should print out the current cursor position: + +```bash +echo -ne "\033[6n" +``` + +## Set Window Title + +This command should set the window title to "Test": + +```bash +echo -ne "\033]2;Test\007" && sleep 10 +``` + +## Bracketed paste + +Enter this command, then paste a word from the clipboard. The text +displayed on the terminal should contain the codes `200~` and `201~`: + +```bash +echo -ne "\033[?2004h" && sleep 10 +``` + +## Trigger Notification + +This command should trigger a notification: + +```bash +echo -ne "\033]777;notify;Title;Body\033\\" +``` diff --git a/vendor/github.com/muesli/termenv/ansicolors.go b/vendor/github.com/muesli/termenv/ansicolors.go new file mode 100644 index 0000000..1a301b0 --- /dev/null +++ b/vendor/github.com/muesli/termenv/ansicolors.go @@ -0,0 +1,281 @@ +package termenv + +// ANSI color codes. +const ( + ANSIBlack ANSIColor = iota + ANSIRed + ANSIGreen + ANSIYellow + ANSIBlue + ANSIMagenta + ANSICyan + ANSIWhite + ANSIBrightBlack + ANSIBrightRed + ANSIBrightGreen + ANSIBrightYellow + ANSIBrightBlue + ANSIBrightMagenta + ANSIBrightCyan + ANSIBrightWhite +) + +// RGB values of ANSI colors (0-255). +var ansiHex = []string{ + "#000000", + "#800000", + "#008000", + "#808000", + "#000080", + "#800080", + "#008080", + "#c0c0c0", + "#808080", + "#ff0000", + "#00ff00", + "#ffff00", + "#0000ff", + "#ff00ff", + "#00ffff", + "#ffffff", + "#000000", + "#00005f", + "#000087", + "#0000af", + "#0000d7", + "#0000ff", + "#005f00", + "#005f5f", + "#005f87", + "#005faf", + "#005fd7", + "#005fff", + "#008700", + "#00875f", + "#008787", + "#0087af", + "#0087d7", + "#0087ff", + "#00af00", + "#00af5f", + "#00af87", + "#00afaf", + "#00afd7", + "#00afff", + "#00d700", + "#00d75f", + "#00d787", + "#00d7af", + "#00d7d7", + "#00d7ff", + "#00ff00", + "#00ff5f", + "#00ff87", + "#00ffaf", + "#00ffd7", + "#00ffff", + "#5f0000", + "#5f005f", + "#5f0087", + "#5f00af", + "#5f00d7", + "#5f00ff", + "#5f5f00", + "#5f5f5f", + "#5f5f87", + "#5f5faf", + "#5f5fd7", + "#5f5fff", + "#5f8700", + "#5f875f", + "#5f8787", + "#5f87af", + "#5f87d7", + "#5f87ff", + "#5faf00", + "#5faf5f", + "#5faf87", + "#5fafaf", + "#5fafd7", + "#5fafff", + "#5fd700", + "#5fd75f", + "#5fd787", + "#5fd7af", + "#5fd7d7", + "#5fd7ff", + "#5fff00", + "#5fff5f", + "#5fff87", + "#5fffaf", + "#5fffd7", + "#5fffff", + "#870000", + "#87005f", + "#870087", + "#8700af", + "#8700d7", + "#8700ff", + "#875f00", + "#875f5f", + "#875f87", + "#875faf", + "#875fd7", + "#875fff", + "#878700", + "#87875f", + "#878787", + "#8787af", + "#8787d7", + "#8787ff", + "#87af00", + "#87af5f", + "#87af87", + "#87afaf", + "#87afd7", + "#87afff", + "#87d700", + "#87d75f", + "#87d787", + "#87d7af", + "#87d7d7", + "#87d7ff", + "#87ff00", + "#87ff5f", + "#87ff87", + "#87ffaf", + "#87ffd7", + "#87ffff", + "#af0000", + "#af005f", + "#af0087", + "#af00af", + "#af00d7", + "#af00ff", + "#af5f00", + "#af5f5f", + "#af5f87", + "#af5faf", + "#af5fd7", + "#af5fff", + "#af8700", + "#af875f", + "#af8787", + "#af87af", + "#af87d7", + "#af87ff", + "#afaf00", + "#afaf5f", + "#afaf87", + "#afafaf", + "#afafd7", + "#afafff", + "#afd700", + "#afd75f", + "#afd787", + "#afd7af", + "#afd7d7", + "#afd7ff", + "#afff00", + "#afff5f", + "#afff87", + "#afffaf", + "#afffd7", + "#afffff", + "#d70000", + "#d7005f", + "#d70087", + "#d700af", + "#d700d7", + "#d700ff", + "#d75f00", + "#d75f5f", + "#d75f87", + "#d75faf", + "#d75fd7", + "#d75fff", + "#d78700", + "#d7875f", + "#d78787", + "#d787af", + "#d787d7", + "#d787ff", + "#d7af00", + "#d7af5f", + "#d7af87", + "#d7afaf", + "#d7afd7", + "#d7afff", + "#d7d700", + "#d7d75f", + "#d7d787", + "#d7d7af", + "#d7d7d7", + "#d7d7ff", + "#d7ff00", + "#d7ff5f", + "#d7ff87", + "#d7ffaf", + "#d7ffd7", + "#d7ffff", + "#ff0000", + "#ff005f", + "#ff0087", + "#ff00af", + "#ff00d7", + "#ff00ff", + "#ff5f00", + "#ff5f5f", + "#ff5f87", + "#ff5faf", + "#ff5fd7", + "#ff5fff", + "#ff8700", + "#ff875f", + "#ff8787", + "#ff87af", + "#ff87d7", + "#ff87ff", + "#ffaf00", + "#ffaf5f", + "#ffaf87", + "#ffafaf", + "#ffafd7", + "#ffafff", + "#ffd700", + "#ffd75f", + "#ffd787", + "#ffd7af", + "#ffd7d7", + "#ffd7ff", + "#ffff00", + "#ffff5f", + "#ffff87", + "#ffffaf", + "#ffffd7", + "#ffffff", + "#080808", + "#121212", + "#1c1c1c", + "#262626", + "#303030", + "#3a3a3a", + "#444444", + "#4e4e4e", + "#585858", + "#626262", + "#6c6c6c", + "#767676", + "#808080", + "#8a8a8a", + "#949494", + "#9e9e9e", + "#a8a8a8", + "#b2b2b2", + "#bcbcbc", + "#c6c6c6", + "#d0d0d0", + "#dadada", + "#e4e4e4", + "#eeeeee", +} diff --git a/vendor/github.com/muesli/termenv/color.go b/vendor/github.com/muesli/termenv/color.go new file mode 100644 index 0000000..59e639b --- /dev/null +++ b/vendor/github.com/muesli/termenv/color.go @@ -0,0 +1,205 @@ +package termenv + +import ( + "errors" + "fmt" + "math" + "strings" + + "github.com/lucasb-eyer/go-colorful" +) + +// ErrInvalidColor gets returned when a color is invalid. +var ErrInvalidColor = errors.New("invalid color") + +// Foreground and Background sequence codes. +const ( + Foreground = "38" + Background = "48" +) + +// Color is an interface implemented by all colors that can be converted to an +// ANSI sequence. +type Color interface { + // Sequence returns the ANSI Sequence for the color. + Sequence(bg bool) string +} + +// NoColor is a nop for terminals that don't support colors. +type NoColor struct{} + +func (c NoColor) String() string { + return "" +} + +// ANSIColor is a color (0-15) as defined by the ANSI Standard. +type ANSIColor int + +func (c ANSIColor) String() string { + return ansiHex[c] +} + +// ANSI256Color is a color (16-255) as defined by the ANSI Standard. +type ANSI256Color int + +func (c ANSI256Color) String() string { + return ansiHex[c] +} + +// RGBColor is a hex-encoded color, e.g. "#abcdef". +type RGBColor string + +// ConvertToRGB converts a Color to a colorful.Color. +func ConvertToRGB(c Color) colorful.Color { + var hex string + switch v := c.(type) { + case RGBColor: + hex = string(v) + case ANSIColor: + hex = ansiHex[v] + case ANSI256Color: + hex = ansiHex[v] + } + + ch, _ := colorful.Hex(hex) + return ch +} + +// Sequence returns the ANSI Sequence for the color. +func (c NoColor) Sequence(_ bool) string { + return "" +} + +// Sequence returns the ANSI Sequence for the color. +// +//nolint:mnd +func (c ANSIColor) Sequence(bg bool) string { + col := int(c) + bgMod := func(c int) int { + if bg { + return c + 10 + } + return c + } + + if col < 8 { + return fmt.Sprintf("%d", bgMod(col)+30) //nolint:mnd + } + return fmt.Sprintf("%d", bgMod(col-8)+90) //nolint:mnd +} + +// Sequence returns the ANSI Sequence for the color. +func (c ANSI256Color) Sequence(bg bool) string { + prefix := Foreground + if bg { + prefix = Background + } + return fmt.Sprintf("%s;5;%d", prefix, c) +} + +// Sequence returns the ANSI Sequence for the color. +func (c RGBColor) Sequence(bg bool) string { + f, err := colorful.Hex(string(c)) + if err != nil { + return "" + } + + prefix := Foreground + if bg { + prefix = Background + } + return fmt.Sprintf("%s;2;%d;%d;%d", prefix, uint8(f.R*255), uint8(f.G*255), uint8(f.B*255)) //nolint:mnd +} + +func xTermColor(s string) (RGBColor, error) { + if len(s) < 24 || len(s) > 25 { + return RGBColor(""), ErrInvalidColor + } + + switch { + case strings.HasSuffix(s, string(BEL)): + s = strings.TrimSuffix(s, string(BEL)) + case strings.HasSuffix(s, string(ESC)): + s = strings.TrimSuffix(s, string(ESC)) + case strings.HasSuffix(s, ST): + s = strings.TrimSuffix(s, ST) + default: + return RGBColor(""), ErrInvalidColor + } + + s = s[4:] + + prefix := ";rgb:" + if !strings.HasPrefix(s, prefix) { + return RGBColor(""), ErrInvalidColor + } + s = strings.TrimPrefix(s, prefix) + + h := strings.Split(s, "/") + hex := fmt.Sprintf("#%s%s%s", h[0][:2], h[1][:2], h[2][:2]) + return RGBColor(hex), nil +} + +func ansi256ToANSIColor(c ANSI256Color) ANSIColor { + var r int + md := math.MaxFloat64 + + h, _ := colorful.Hex(ansiHex[c]) + for i := 0; i <= 15; i++ { + hb, _ := colorful.Hex(ansiHex[i]) + d := h.DistanceHSLuv(hb) + + if d < md { + md = d + r = i + } + } + + return ANSIColor(r) +} + +//nolint:mnd +func hexToANSI256Color(c colorful.Color) ANSI256Color { + v2ci := func(v float64) int { + if v < 48 { + return 0 + } + if v < 115 { + return 1 + } + return int((v - 35) / 40) + } + + // Calculate the nearest 0-based color index at 16..231 + r := v2ci(c.R * 255.0) // 0..5 each + g := v2ci(c.G * 255.0) + b := v2ci(c.B * 255.0) + ci := 36*r + 6*g + b /* 0..215 */ + + // Calculate the represented colors back from the index + i2cv := [6]int{0, 0x5f, 0x87, 0xaf, 0xd7, 0xff} + cr := i2cv[r] // r/g/b, 0..255 each + cg := i2cv[g] + cb := i2cv[b] + + // Calculate the nearest 0-based gray index at 232..255 + var grayIdx int + average := (r + g + b) / 3 + if average > 238 { + grayIdx = 23 + } else { + grayIdx = (average - 3) / 10 // 0..23 + } + gv := 8 + 10*grayIdx // same value for r/g/b, 0..255 + + // Return the one which is nearer to the original input rgb value + c2 := colorful.Color{R: float64(cr) / 255.0, G: float64(cg) / 255.0, B: float64(cb) / 255.0} + g2 := colorful.Color{R: float64(gv) / 255.0, G: float64(gv) / 255.0, B: float64(gv) / 255.0} + colorDist := c.DistanceHSLuv(c2) + grayDist := c.DistanceHSLuv(g2) + + if colorDist <= grayDist { + return ANSI256Color(16 + ci) + } + return ANSI256Color(232 + grayIdx) +} diff --git a/vendor/github.com/muesli/termenv/constants_linux.go b/vendor/github.com/muesli/termenv/constants_linux.go new file mode 100644 index 0000000..4262f03 --- /dev/null +++ b/vendor/github.com/muesli/termenv/constants_linux.go @@ -0,0 +1,8 @@ +package termenv + +import "golang.org/x/sys/unix" + +const ( + tcgetattr = unix.TCGETS + tcsetattr = unix.TCSETS +) diff --git a/vendor/github.com/muesli/termenv/constants_solaris.go b/vendor/github.com/muesli/termenv/constants_solaris.go new file mode 100644 index 0000000..4262f03 --- /dev/null +++ b/vendor/github.com/muesli/termenv/constants_solaris.go @@ -0,0 +1,8 @@ +package termenv + +import "golang.org/x/sys/unix" + +const ( + tcgetattr = unix.TCGETS + tcsetattr = unix.TCSETS +) diff --git a/vendor/github.com/muesli/termenv/constants_unix.go b/vendor/github.com/muesli/termenv/constants_unix.go new file mode 100644 index 0000000..5d66424 --- /dev/null +++ b/vendor/github.com/muesli/termenv/constants_unix.go @@ -0,0 +1,13 @@ +//go:build (darwin || dragonfly || freebsd || netbsd || openbsd) && !solaris && !illumos +// +build darwin dragonfly freebsd netbsd openbsd +// +build !solaris +// +build !illumos + +package termenv + +import "golang.org/x/sys/unix" + +const ( + tcgetattr = unix.TIOCGETA + tcsetattr = unix.TIOCSETA +) diff --git a/vendor/github.com/muesli/termenv/constants_zos.go b/vendor/github.com/muesli/termenv/constants_zos.go new file mode 100644 index 0000000..4262f03 --- /dev/null +++ b/vendor/github.com/muesli/termenv/constants_zos.go @@ -0,0 +1,8 @@ +package termenv + +import "golang.org/x/sys/unix" + +const ( + tcgetattr = unix.TCGETS + tcsetattr = unix.TCSETS +) diff --git a/vendor/github.com/muesli/termenv/copy.go b/vendor/github.com/muesli/termenv/copy.go new file mode 100644 index 0000000..4bf5c9f --- /dev/null +++ b/vendor/github.com/muesli/termenv/copy.go @@ -0,0 +1,37 @@ +package termenv + +import ( + "strings" + + "github.com/aymanbagabas/go-osc52/v2" +) + +// Copy copies text to clipboard using OSC 52 escape sequence. +func (o Output) Copy(str string) { + s := osc52.New(str) + if strings.HasPrefix(o.environ.Getenv("TERM"), "screen") { + s = s.Screen() + } + _, _ = s.WriteTo(o) +} + +// CopyPrimary copies text to primary clipboard (X11) using OSC 52 escape +// sequence. +func (o Output) CopyPrimary(str string) { + s := osc52.New(str).Primary() + if strings.HasPrefix(o.environ.Getenv("TERM"), "screen") { + s = s.Screen() + } + _, _ = s.WriteTo(o) +} + +// Copy copies text to clipboard using OSC 52 escape sequence. +func Copy(str string) { + output.Copy(str) +} + +// CopyPrimary copies text to primary clipboard (X11) using OSC 52 escape +// sequence. +func CopyPrimary(str string) { + output.CopyPrimary(str) +} diff --git a/vendor/github.com/muesli/termenv/hyperlink.go b/vendor/github.com/muesli/termenv/hyperlink.go new file mode 100644 index 0000000..97e760a --- /dev/null +++ b/vendor/github.com/muesli/termenv/hyperlink.go @@ -0,0 +1,11 @@ +package termenv + +// Hyperlink creates a hyperlink using OSC8. +func Hyperlink(link, name string) string { + return output.Hyperlink(link, name) +} + +// Hyperlink creates a hyperlink using OSC8. +func (o *Output) Hyperlink(link, name string) string { + return OSC + "8;;" + link + ST + name + OSC + "8;;" + ST +} diff --git a/vendor/github.com/muesli/termenv/notification.go b/vendor/github.com/muesli/termenv/notification.go new file mode 100644 index 0000000..2a8cf06 --- /dev/null +++ b/vendor/github.com/muesli/termenv/notification.go @@ -0,0 +1,11 @@ +package termenv + +// Notify triggers a notification using OSC777. +func Notify(title, body string) { + output.Notify(title, body) +} + +// Notify triggers a notification using OSC777. +func (o *Output) Notify(title, body string) { + _, _ = o.WriteString(OSC + "777;notify;" + title + ";" + body + ST) +} diff --git a/vendor/github.com/muesli/termenv/output.go b/vendor/github.com/muesli/termenv/output.go new file mode 100644 index 0000000..e4434de --- /dev/null +++ b/vendor/github.com/muesli/termenv/output.go @@ -0,0 +1,205 @@ +package termenv + +import ( + "io" + "os" + "sync" +) + +// output is the default global output. +var output = NewOutput(os.Stdout) + +// File represents a file descriptor. +// +// Deprecated: Use *os.File instead. +type File interface { + io.ReadWriter + Fd() uintptr +} + +// OutputOption sets an option on Output. +type OutputOption = func(*Output) + +// Output is a terminal output. +type Output struct { + Profile + w io.Writer + environ Environ + + assumeTTY bool + unsafe bool + cache bool + fgSync *sync.Once + fgColor Color + bgSync *sync.Once + bgColor Color +} + +// Environ is an interface for getting environment variables. +type Environ interface { + Environ() []string + Getenv(string) string +} + +type osEnviron struct{} + +func (oe *osEnviron) Environ() []string { + return os.Environ() +} + +func (oe *osEnviron) Getenv(key string) string { + return os.Getenv(key) +} + +// DefaultOutput returns the default global output. +func DefaultOutput() *Output { + return output +} + +// SetDefaultOutput sets the default global output. +func SetDefaultOutput(o *Output) { + output = o +} + +// NewOutput returns a new Output for the given writer. +func NewOutput(w io.Writer, opts ...OutputOption) *Output { + o := &Output{ + w: w, + environ: &osEnviron{}, + Profile: -1, + fgSync: &sync.Once{}, + fgColor: NoColor{}, + bgSync: &sync.Once{}, + bgColor: NoColor{}, + } + + if o.w == nil { + o.w = os.Stdout + } + for _, opt := range opts { + opt(o) + } + if o.Profile < 0 { + o.Profile = o.EnvColorProfile() + } + + return o +} + +// WithEnvironment returns a new OutputOption for the given environment. +func WithEnvironment(environ Environ) OutputOption { + return func(o *Output) { + o.environ = environ + } +} + +// WithProfile returns a new OutputOption for the given profile. +func WithProfile(profile Profile) OutputOption { + return func(o *Output) { + o.Profile = profile + } +} + +// WithColorCache returns a new OutputOption with fore- and background color values +// pre-fetched and cached. +func WithColorCache(v bool) OutputOption { + return func(o *Output) { + o.cache = v + + // cache the values now + _ = o.ForegroundColor() + _ = o.BackgroundColor() + } +} + +// WithTTY returns a new OutputOption to assume whether or not the output is a TTY. +// This is useful when mocking console output. +func WithTTY(v bool) OutputOption { + return func(o *Output) { + o.assumeTTY = v + } +} + +// WithUnsafe returns a new OutputOption with unsafe mode enabled. Unsafe mode doesn't +// check whether or not the terminal is a TTY. +// +// This option supersedes WithTTY. +// +// This is useful when mocking console output and enforcing ANSI escape output +// e.g. on SSH sessions. +func WithUnsafe() OutputOption { + return func(o *Output) { + o.unsafe = true + } +} + +// ForegroundColor returns the terminal's default foreground color. +func (o *Output) ForegroundColor() Color { + f := func() { + if !o.isTTY() { + return + } + + o.fgColor = o.foregroundColor() + } + + if o.cache { + o.fgSync.Do(f) + } else { + f() + } + + return o.fgColor +} + +// BackgroundColor returns the terminal's default background color. +func (o *Output) BackgroundColor() Color { + f := func() { + if !o.isTTY() { + return + } + + o.bgColor = o.backgroundColor() + } + + if o.cache { + o.bgSync.Do(f) + } else { + f() + } + + return o.bgColor +} + +// HasDarkBackground returns whether terminal uses a dark-ish background. +func (o *Output) HasDarkBackground() bool { + c := ConvertToRGB(o.BackgroundColor()) + _, _, l := c.Hsl() + return l < 0.5 //nolint:mnd +} + +// TTY returns the terminal's file descriptor. This may be nil if the output is +// not a terminal. +// +// Deprecated: Use Writer() instead. +func (o Output) TTY() File { + if f, ok := o.w.(File); ok { + return f + } + return nil +} + +// Writer returns the underlying writer. This may be of type io.Writer, +// io.ReadWriter, or *os.File. +func (o Output) Writer() io.Writer { + return o.w +} + +func (o Output) Write(p []byte) (int, error) { + return o.w.Write(p) //nolint:wrapcheck +} + +// WriteString writes the given string to the output. +func (o Output) WriteString(s string) (int, error) { + return o.Write([]byte(s)) +} diff --git a/vendor/github.com/muesli/termenv/profile.go b/vendor/github.com/muesli/termenv/profile.go new file mode 100644 index 0000000..7d38f5f --- /dev/null +++ b/vendor/github.com/muesli/termenv/profile.go @@ -0,0 +1,112 @@ +package termenv + +import ( + "image/color" + "strconv" + "strings" + + "github.com/lucasb-eyer/go-colorful" +) + +// Profile is a color profile: Ascii, ANSI, ANSI256, or TrueColor. +type Profile int + +const ( + // TrueColor, 24-bit color profile. + TrueColor = Profile(iota) + // ANSI256, 8-bit color profile. + ANSI256 + // ANSI, 4-bit color profile. + ANSI + // Ascii, uncolored profile. + Ascii //nolint:revive +) + +// Name returns the profile name as a string. +func (p Profile) Name() string { + switch p { + case Ascii: + return "Ascii" + case ANSI: + return "ANSI" + case ANSI256: + return "ANSI256" + case TrueColor: + return "TrueColor" + } + return "Unknown" +} + +// String returns a new Style. +func (p Profile) String(s ...string) Style { + return Style{ + profile: p, + string: strings.Join(s, " "), + } +} + +// Convert transforms a given Color to a Color supported within the Profile. +func (p Profile) Convert(c Color) Color { + if p == Ascii { + return NoColor{} + } + + switch v := c.(type) { + case ANSIColor: + return v + + case ANSI256Color: + if p == ANSI { + return ansi256ToANSIColor(v) + } + return v + + case RGBColor: + h, err := colorful.Hex(string(v)) + if err != nil { + return nil + } + if p != TrueColor { + ac := hexToANSI256Color(h) + if p == ANSI { + return ansi256ToANSIColor(ac) + } + return ac + } + return v + } + + return c +} + +// Color creates a Color from a string. Valid inputs are hex colors, as well as +// ANSI color codes (0-15, 16-255). +func (p Profile) Color(s string) Color { + if len(s) == 0 { + return nil + } + + var c Color + if strings.HasPrefix(s, "#") { + c = RGBColor(s) + } else { + i, err := strconv.Atoi(s) + if err != nil { + return nil + } + + if i < 16 { //nolint:mnd + c = ANSIColor(i) + } else { + c = ANSI256Color(i) + } + } + + return p.Convert(c) +} + +// FromColor creates a Color from a color.Color. +func (p Profile) FromColor(c color.Color) Color { + col, _ := colorful.MakeColor(c) + return p.Color(col.Hex()) +} diff --git a/vendor/github.com/muesli/termenv/screen.go b/vendor/github.com/muesli/termenv/screen.go new file mode 100644 index 0000000..75c11d0 --- /dev/null +++ b/vendor/github.com/muesli/termenv/screen.go @@ -0,0 +1,590 @@ +package termenv + +import ( + "fmt" + "strings" +) + +// Sequence definitions. +const ( + // Cursor positioning. + CursorUpSeq = "%dA" + CursorDownSeq = "%dB" + CursorForwardSeq = "%dC" + CursorBackSeq = "%dD" + CursorNextLineSeq = "%dE" + CursorPreviousLineSeq = "%dF" + CursorHorizontalSeq = "%dG" + CursorPositionSeq = "%d;%dH" + EraseDisplaySeq = "%dJ" + EraseLineSeq = "%dK" + ScrollUpSeq = "%dS" + ScrollDownSeq = "%dT" + SaveCursorPositionSeq = "s" + RestoreCursorPositionSeq = "u" + ChangeScrollingRegionSeq = "%d;%dr" + InsertLineSeq = "%dL" + DeleteLineSeq = "%dM" + + // Explicit values for EraseLineSeq. + EraseLineRightSeq = "0K" + EraseLineLeftSeq = "1K" + EraseEntireLineSeq = "2K" + + // Mouse. + EnableMousePressSeq = "?9h" // press only (X10) + DisableMousePressSeq = "?9l" + EnableMouseSeq = "?1000h" // press, release, wheel + DisableMouseSeq = "?1000l" + EnableMouseHiliteSeq = "?1001h" // highlight + DisableMouseHiliteSeq = "?1001l" + EnableMouseCellMotionSeq = "?1002h" // press, release, move on pressed, wheel + DisableMouseCellMotionSeq = "?1002l" + EnableMouseAllMotionSeq = "?1003h" // press, release, move, wheel + DisableMouseAllMotionSeq = "?1003l" + EnableMouseExtendedModeSeq = "?1006h" // press, release, move, wheel, extended coordinates + DisableMouseExtendedModeSeq = "?1006l" + EnableMousePixelsModeSeq = "?1016h" // press, release, move, wheel, extended pixel coordinates + DisableMousePixelsModeSeq = "?1016l" + + // Screen. + RestoreScreenSeq = "?47l" + SaveScreenSeq = "?47h" + AltScreenSeq = "?1049h" + ExitAltScreenSeq = "?1049l" + + // Bracketed paste. + // https://en.wikipedia.org/wiki/Bracketed-paste + EnableBracketedPasteSeq = "?2004h" + DisableBracketedPasteSeq = "?2004l" + StartBracketedPasteSeq = "200~" + EndBracketedPasteSeq = "201~" + + // Session. + SetWindowTitleSeq = "2;%s" + string(BEL) + SetForegroundColorSeq = "10;%s" + string(BEL) + SetBackgroundColorSeq = "11;%s" + string(BEL) + SetCursorColorSeq = "12;%s" + string(BEL) + ShowCursorSeq = "?25h" + HideCursorSeq = "?25l" +) + +// Reset the terminal to its default style, removing any active styles. +func (o Output) Reset() { + fmt.Fprint(o.w, CSI+ResetSeq+"m") //nolint:errcheck +} + +// SetForegroundColor sets the default foreground color. +func (o Output) SetForegroundColor(color Color) { + fmt.Fprintf(o.w, OSC+SetForegroundColorSeq, color) //nolint:errcheck +} + +// SetBackgroundColor sets the default background color. +func (o Output) SetBackgroundColor(color Color) { + fmt.Fprintf(o.w, OSC+SetBackgroundColorSeq, color) //nolint:errcheck +} + +// SetCursorColor sets the cursor color. +func (o Output) SetCursorColor(color Color) { + fmt.Fprintf(o.w, OSC+SetCursorColorSeq, color) //nolint:errcheck +} + +// RestoreScreen restores a previously saved screen state. +func (o Output) RestoreScreen() { + fmt.Fprint(o.w, CSI+RestoreScreenSeq) //nolint:errcheck +} + +// SaveScreen saves the screen state. +func (o Output) SaveScreen() { + fmt.Fprint(o.w, CSI+SaveScreenSeq) //nolint:errcheck +} + +// AltScreen switches to the alternate screen buffer. The former view can be +// restored with ExitAltScreen(). +func (o Output) AltScreen() { + fmt.Fprint(o.w, CSI+AltScreenSeq) //nolint:errcheck +} + +// ExitAltScreen exits the alternate screen buffer and returns to the former +// terminal view. +func (o Output) ExitAltScreen() { + fmt.Fprint(o.w, CSI+ExitAltScreenSeq) //nolint:errcheck +} + +// ClearScreen clears the visible portion of the terminal. +func (o Output) ClearScreen() { + fmt.Fprintf(o.w, CSI+EraseDisplaySeq, 2) //nolint:errcheck,mnd + o.MoveCursor(1, 1) +} + +// MoveCursor moves the cursor to a given position. +func (o Output) MoveCursor(row int, column int) { + fmt.Fprintf(o.w, CSI+CursorPositionSeq, row, column) //nolint:errcheck +} + +// HideCursor hides the cursor. +func (o Output) HideCursor() { + fmt.Fprint(o.w, CSI+HideCursorSeq) //nolint:errcheck +} + +// ShowCursor shows the cursor. +func (o Output) ShowCursor() { + fmt.Fprint(o.w, CSI+ShowCursorSeq) //nolint:errcheck +} + +// SaveCursorPosition saves the cursor position. +func (o Output) SaveCursorPosition() { + fmt.Fprint(o.w, CSI+SaveCursorPositionSeq) //nolint:errcheck +} + +// RestoreCursorPosition restores a saved cursor position. +func (o Output) RestoreCursorPosition() { + fmt.Fprint(o.w, CSI+RestoreCursorPositionSeq) //nolint:errcheck +} + +// CursorUp moves the cursor up a given number of lines. +func (o Output) CursorUp(n int) { + fmt.Fprintf(o.w, CSI+CursorUpSeq, n) //nolint:errcheck +} + +// CursorDown moves the cursor down a given number of lines. +func (o Output) CursorDown(n int) { + fmt.Fprintf(o.w, CSI+CursorDownSeq, n) //nolint:errcheck +} + +// CursorForward moves the cursor up a given number of lines. +func (o Output) CursorForward(n int) { + fmt.Fprintf(o.w, CSI+CursorForwardSeq, n) //nolint:errcheck +} + +// CursorBack moves the cursor backwards a given number of cells. +func (o Output) CursorBack(n int) { + fmt.Fprintf(o.w, CSI+CursorBackSeq, n) //nolint:errcheck +} + +// CursorNextLine moves the cursor down a given number of lines and places it at +// the beginning of the line. +func (o Output) CursorNextLine(n int) { + fmt.Fprintf(o.w, CSI+CursorNextLineSeq, n) //nolint:errcheck +} + +// CursorPrevLine moves the cursor up a given number of lines and places it at +// the beginning of the line. +func (o Output) CursorPrevLine(n int) { + fmt.Fprintf(o.w, CSI+CursorPreviousLineSeq, n) //nolint:errcheck +} + +// ClearLine clears the current line. +func (o Output) ClearLine() { + fmt.Fprint(o.w, CSI+EraseEntireLineSeq) //nolint:errcheck +} + +// ClearLineLeft clears the line to the left of the cursor. +func (o Output) ClearLineLeft() { + fmt.Fprint(o.w, CSI+EraseLineLeftSeq) //nolint:errcheck +} + +// ClearLineRight clears the line to the right of the cursor. +func (o Output) ClearLineRight() { + fmt.Fprint(o.w, CSI+EraseLineRightSeq) //nolint:errcheck +} + +// ClearLines clears a given number of lines. +func (o Output) ClearLines(n int) { + clearLine := fmt.Sprintf(CSI+EraseLineSeq, 2) //nolint:mnd + cursorUp := fmt.Sprintf(CSI+CursorUpSeq, 1) + fmt.Fprint(o.w, clearLine+strings.Repeat(cursorUp+clearLine, n)) //nolint:errcheck +} + +// ChangeScrollingRegion sets the scrolling region of the terminal. +func (o Output) ChangeScrollingRegion(top, bottom int) { + fmt.Fprintf(o.w, CSI+ChangeScrollingRegionSeq, top, bottom) //nolint:errcheck +} + +// InsertLines inserts the given number of lines at the top of the scrollable +// region, pushing lines below down. +func (o Output) InsertLines(n int) { + fmt.Fprintf(o.w, CSI+InsertLineSeq, n) //nolint:errcheck +} + +// DeleteLines deletes the given number of lines, pulling any lines in +// the scrollable region below up. +func (o Output) DeleteLines(n int) { + fmt.Fprintf(o.w, CSI+DeleteLineSeq, n) //nolint:errcheck +} + +// EnableMousePress enables X10 mouse mode. Button press events are sent only. +func (o Output) EnableMousePress() { + fmt.Fprint(o.w, CSI+EnableMousePressSeq) //nolint:errcheck +} + +// DisableMousePress disables X10 mouse mode. +func (o Output) DisableMousePress() { + fmt.Fprint(o.w, CSI+DisableMousePressSeq) //nolint:errcheck +} + +// EnableMouse enables Mouse Tracking mode. +func (o Output) EnableMouse() { + fmt.Fprint(o.w, CSI+EnableMouseSeq) //nolint:errcheck +} + +// DisableMouse disables Mouse Tracking mode. +func (o Output) DisableMouse() { + fmt.Fprint(o.w, CSI+DisableMouseSeq) //nolint:errcheck +} + +// EnableMouseHilite enables Hilite Mouse Tracking mode. +func (o Output) EnableMouseHilite() { + fmt.Fprint(o.w, CSI+EnableMouseHiliteSeq) //nolint:errcheck +} + +// DisableMouseHilite disables Hilite Mouse Tracking mode. +func (o Output) DisableMouseHilite() { + fmt.Fprint(o.w, CSI+DisableMouseHiliteSeq) //nolint:errcheck +} + +// EnableMouseCellMotion enables Cell Motion Mouse Tracking mode. +func (o Output) EnableMouseCellMotion() { + fmt.Fprint(o.w, CSI+EnableMouseCellMotionSeq) //nolint:errcheck +} + +// DisableMouseCellMotion disables Cell Motion Mouse Tracking mode. +func (o Output) DisableMouseCellMotion() { + fmt.Fprint(o.w, CSI+DisableMouseCellMotionSeq) //nolint:errcheck +} + +// EnableMouseAllMotion enables All Motion Mouse mode. +func (o Output) EnableMouseAllMotion() { + fmt.Fprint(o.w, CSI+EnableMouseAllMotionSeq) //nolint:errcheck +} + +// DisableMouseAllMotion disables All Motion Mouse mode. +func (o Output) DisableMouseAllMotion() { + fmt.Fprint(o.w, CSI+DisableMouseAllMotionSeq) //nolint:errcheck +} + +// EnableMouseExtendedMotion enables Extended Mouse mode (SGR). This should be +// enabled in conjunction with EnableMouseCellMotion, and EnableMouseAllMotion. +func (o Output) EnableMouseExtendedMode() { + fmt.Fprint(o.w, CSI+EnableMouseExtendedModeSeq) //nolint:errcheck +} + +// DisableMouseExtendedMotion disables Extended Mouse mode (SGR). +func (o Output) DisableMouseExtendedMode() { + fmt.Fprint(o.w, CSI+DisableMouseExtendedModeSeq) //nolint:errcheck +} + +// EnableMousePixelsMotion enables Pixel Motion Mouse mode (SGR-Pixels). This +// should be enabled in conjunction with EnableMouseCellMotion, and +// EnableMouseAllMotion. +func (o Output) EnableMousePixelsMode() { + fmt.Fprint(o.w, CSI+EnableMousePixelsModeSeq) //nolint:errcheck +} + +// DisableMousePixelsMotion disables Pixel Motion Mouse mode (SGR-Pixels). +func (o Output) DisableMousePixelsMode() { + fmt.Fprint(o.w, CSI+DisableMousePixelsModeSeq) //nolint:errcheck +} + +// SetWindowTitle sets the terminal window title. +func (o Output) SetWindowTitle(title string) { + fmt.Fprintf(o.w, OSC+SetWindowTitleSeq, title) //nolint:errcheck +} + +// EnableBracketedPaste enables bracketed paste. +func (o Output) EnableBracketedPaste() { + fmt.Fprintf(o.w, CSI+EnableBracketedPasteSeq) //nolint:errcheck +} + +// DisableBracketedPaste disables bracketed paste. +func (o Output) DisableBracketedPaste() { + fmt.Fprintf(o.w, CSI+DisableBracketedPasteSeq) //nolint:errcheck +} + +// Legacy functions. + +// Reset the terminal to its default style, removing any active styles. +// +// Deprecated: please use termenv.Output instead. +func Reset() { + output.Reset() +} + +// SetForegroundColor sets the default foreground color. +// +// Deprecated: please use termenv.Output instead. +func SetForegroundColor(color Color) { + output.SetForegroundColor(color) +} + +// SetBackgroundColor sets the default background color. +// +// Deprecated: please use termenv.Output instead. +func SetBackgroundColor(color Color) { + output.SetBackgroundColor(color) +} + +// SetCursorColor sets the cursor color. +// +// Deprecated: please use termenv.Output instead. +func SetCursorColor(color Color) { + output.SetCursorColor(color) +} + +// RestoreScreen restores a previously saved screen state. +// +// Deprecated: please use termenv.Output instead. +func RestoreScreen() { + output.RestoreScreen() +} + +// SaveScreen saves the screen state. +// +// Deprecated: please use termenv.Output instead. +func SaveScreen() { + output.SaveScreen() +} + +// AltScreen switches to the alternate screen buffer. The former view can be +// restored with ExitAltScreen(). +// +// Deprecated: please use termenv.Output instead. +func AltScreen() { + output.AltScreen() +} + +// ExitAltScreen exits the alternate screen buffer and returns to the former +// terminal view. +// +// Deprecated: please use termenv.Output instead. +func ExitAltScreen() { + output.ExitAltScreen() +} + +// ClearScreen clears the visible portion of the terminal. +// +// Deprecated: please use termenv.Output instead. +func ClearScreen() { + output.ClearScreen() +} + +// MoveCursor moves the cursor to a given position. +// +// Deprecated: please use termenv.Output instead. +func MoveCursor(row int, column int) { + output.MoveCursor(row, column) +} + +// HideCursor hides the cursor. +// +// Deprecated: please use termenv.Output instead. +func HideCursor() { + output.HideCursor() +} + +// ShowCursor shows the cursor. +// +// Deprecated: please use termenv.Output instead. +func ShowCursor() { + output.ShowCursor() +} + +// SaveCursorPosition saves the cursor position. +// +// Deprecated: please use termenv.Output instead. +func SaveCursorPosition() { + output.SaveCursorPosition() +} + +// RestoreCursorPosition restores a saved cursor position. +// +// Deprecated: please use termenv.Output instead. +func RestoreCursorPosition() { + output.RestoreCursorPosition() +} + +// CursorUp moves the cursor up a given number of lines. +// +// Deprecated: please use termenv.Output instead. +func CursorUp(n int) { + output.CursorUp(n) +} + +// CursorDown moves the cursor down a given number of lines. +// +// Deprecated: please use termenv.Output instead. +func CursorDown(n int) { + output.CursorDown(n) +} + +// CursorForward moves the cursor up a given number of lines. +// +// Deprecated: please use termenv.Output instead. +func CursorForward(n int) { + output.CursorForward(n) +} + +// CursorBack moves the cursor backwards a given number of cells. +// +// Deprecated: please use termenv.Output instead. +func CursorBack(n int) { + output.CursorBack(n) +} + +// CursorNextLine moves the cursor down a given number of lines and places it at +// the beginning of the line. +// +// Deprecated: please use termenv.Output instead. +func CursorNextLine(n int) { + output.CursorNextLine(n) +} + +// CursorPrevLine moves the cursor up a given number of lines and places it at +// the beginning of the line. +// +// Deprecated: please use termenv.Output instead. +func CursorPrevLine(n int) { + output.CursorPrevLine(n) +} + +// ClearLine clears the current line. +// +// Deprecated: please use termenv.Output instead. +func ClearLine() { + output.ClearLine() +} + +// ClearLineLeft clears the line to the left of the cursor. +// +// Deprecated: please use termenv.Output instead. +func ClearLineLeft() { + output.ClearLineLeft() +} + +// ClearLineRight clears the line to the right of the cursor. +// +// Deprecated: please use termenv.Output instead. +func ClearLineRight() { + output.ClearLineRight() +} + +// ClearLines clears a given number of lines. +// +// Deprecated: please use termenv.Output instead. +func ClearLines(n int) { + output.ClearLines(n) +} + +// ChangeScrollingRegion sets the scrolling region of the terminal. +// +// Deprecated: please use termenv.Output instead. +func ChangeScrollingRegion(top, bottom int) { + output.ChangeScrollingRegion(top, bottom) +} + +// InsertLines inserts the given number of lines at the top of the scrollable +// region, pushing lines below down. +// +// Deprecated: please use termenv.Output instead. +func InsertLines(n int) { + output.InsertLines(n) +} + +// DeleteLines deletes the given number of lines, pulling any lines in +// the scrollable region below up. +// +// Deprecated: please use termenv.Output instead. +func DeleteLines(n int) { + output.DeleteLines(n) +} + +// EnableMousePress enables X10 mouse mode. Button press events are sent only. +// +// Deprecated: please use termenv.Output instead. +func EnableMousePress() { + output.EnableMousePress() +} + +// DisableMousePress disables X10 mouse mode. +// +// Deprecated: please use termenv.Output instead. +func DisableMousePress() { + output.DisableMousePress() +} + +// EnableMouse enables Mouse Tracking mode. +// +// Deprecated: please use termenv.Output instead. +func EnableMouse() { + output.EnableMouse() +} + +// DisableMouse disables Mouse Tracking mode. +// +// Deprecated: please use termenv.Output instead. +func DisableMouse() { + output.DisableMouse() +} + +// EnableMouseHilite enables Hilite Mouse Tracking mode. +// +// Deprecated: please use termenv.Output instead. +func EnableMouseHilite() { + output.EnableMouseHilite() +} + +// DisableMouseHilite disables Hilite Mouse Tracking mode. +// +// Deprecated: please use termenv.Output instead. +func DisableMouseHilite() { + output.DisableMouseHilite() +} + +// EnableMouseCellMotion enables Cell Motion Mouse Tracking mode. +// +// Deprecated: please use termenv.Output instead. +func EnableMouseCellMotion() { + output.EnableMouseCellMotion() +} + +// DisableMouseCellMotion disables Cell Motion Mouse Tracking mode. +// +// Deprecated: please use termenv.Output instead. +func DisableMouseCellMotion() { + output.DisableMouseCellMotion() +} + +// EnableMouseAllMotion enables All Motion Mouse mode. +// +// Deprecated: please use termenv.Output instead. +func EnableMouseAllMotion() { + output.EnableMouseAllMotion() +} + +// DisableMouseAllMotion disables All Motion Mouse mode. +// +// Deprecated: please use termenv.Output instead. +func DisableMouseAllMotion() { + output.DisableMouseAllMotion() +} + +// SetWindowTitle sets the terminal window title. +// +// Deprecated: please use termenv.Output instead. +func SetWindowTitle(title string) { + output.SetWindowTitle(title) +} + +// EnableBracketedPaste enables bracketed paste. +// +// Deprecated: please use termenv.Output instead. +func EnableBracketedPaste() { + output.EnableBracketedPaste() +} + +// DisableBracketedPaste disables bracketed paste. +// +// Deprecated: please use termenv.Output instead. +func DisableBracketedPaste() { + output.DisableBracketedPaste() +} diff --git a/vendor/github.com/muesli/termenv/style.go b/vendor/github.com/muesli/termenv/style.go new file mode 100644 index 0000000..dedc1f9 --- /dev/null +++ b/vendor/github.com/muesli/termenv/style.go @@ -0,0 +1,126 @@ +package termenv + +import ( + "fmt" + "strings" + + "github.com/rivo/uniseg" +) + +// Sequence definitions. +const ( + ResetSeq = "0" + BoldSeq = "1" + FaintSeq = "2" + ItalicSeq = "3" + UnderlineSeq = "4" + BlinkSeq = "5" + ReverseSeq = "7" + CrossOutSeq = "9" + OverlineSeq = "53" +) + +// Style is a string that various rendering styles can be applied to. +type Style struct { + profile Profile + string + styles []string +} + +// String returns a new Style. +func String(s ...string) Style { + return Style{ + profile: ANSI, + string: strings.Join(s, " "), + } +} + +func (t Style) String() string { + return t.Styled(t.string) +} + +// Styled renders s with all applied styles. +func (t Style) Styled(s string) string { + if t.profile == Ascii { + return s + } + if len(t.styles) == 0 { + return s + } + + seq := strings.Join(t.styles, ";") + if seq == "" { + return s + } + + return fmt.Sprintf("%s%sm%s%sm", CSI, seq, s, CSI+ResetSeq) +} + +// Foreground sets a foreground color. +func (t Style) Foreground(c Color) Style { + if c != nil { + t.styles = append(t.styles, c.Sequence(false)) + } + return t +} + +// Background sets a background color. +func (t Style) Background(c Color) Style { + if c != nil { + t.styles = append(t.styles, c.Sequence(true)) + } + return t +} + +// Bold enables bold rendering. +func (t Style) Bold() Style { + t.styles = append(t.styles, BoldSeq) + return t +} + +// Faint enables faint rendering. +func (t Style) Faint() Style { + t.styles = append(t.styles, FaintSeq) + return t +} + +// Italic enables italic rendering. +func (t Style) Italic() Style { + t.styles = append(t.styles, ItalicSeq) + return t +} + +// Underline enables underline rendering. +func (t Style) Underline() Style { + t.styles = append(t.styles, UnderlineSeq) + return t +} + +// Overline enables overline rendering. +func (t Style) Overline() Style { + t.styles = append(t.styles, OverlineSeq) + return t +} + +// Blink enables blink mode. +func (t Style) Blink() Style { + t.styles = append(t.styles, BlinkSeq) + return t +} + +// Reverse enables reverse color mode. +func (t Style) Reverse() Style { + t.styles = append(t.styles, ReverseSeq) + return t +} + +// CrossOut enables crossed-out rendering. +func (t Style) CrossOut() Style { + t.styles = append(t.styles, CrossOutSeq) + return t +} + +// Width returns the width required to print all runes in Style. +func (t Style) Width() int { + return uniseg.StringWidth(t.string) +} diff --git a/vendor/github.com/muesli/termenv/templatehelper.go b/vendor/github.com/muesli/termenv/templatehelper.go new file mode 100644 index 0000000..4c7c80f --- /dev/null +++ b/vendor/github.com/muesli/termenv/templatehelper.go @@ -0,0 +1,88 @@ +package termenv + +import ( + "text/template" +) + +// TemplateFuncs returns template helpers for the given output. +func (o Output) TemplateFuncs() template.FuncMap { + return TemplateFuncs(o.Profile) +} + +// TemplateFuncs contains a few useful template helpers. +// +//nolint:mnd +func TemplateFuncs(p Profile) template.FuncMap { + if p == Ascii { + return noopTemplateFuncs + } + + return template.FuncMap{ + "Color": func(values ...interface{}) string { + s := p.String(values[len(values)-1].(string)) + switch len(values) { + case 2: + s = s.Foreground(p.Color(values[0].(string))) + case 3: + s = s. + Foreground(p.Color(values[0].(string))). + Background(p.Color(values[1].(string))) + } + + return s.String() + }, + "Foreground": func(values ...interface{}) string { + s := p.String(values[len(values)-1].(string)) + if len(values) == 2 { + s = s.Foreground(p.Color(values[0].(string))) + } + + return s.String() + }, + "Background": func(values ...interface{}) string { + s := p.String(values[len(values)-1].(string)) + if len(values) == 2 { + s = s.Background(p.Color(values[0].(string))) + } + + return s.String() + }, + "Bold": styleFunc(p, Style.Bold), + "Faint": styleFunc(p, Style.Faint), + "Italic": styleFunc(p, Style.Italic), + "Underline": styleFunc(p, Style.Underline), + "Overline": styleFunc(p, Style.Overline), + "Blink": styleFunc(p, Style.Blink), + "Reverse": styleFunc(p, Style.Reverse), + "CrossOut": styleFunc(p, Style.CrossOut), + } +} + +func styleFunc(p Profile, f func(Style) Style) func(...interface{}) string { + return func(values ...interface{}) string { + s := p.String(values[0].(string)) + return f(s).String() + } +} + +var noopTemplateFuncs = template.FuncMap{ + "Color": noColorFunc, + "Foreground": noColorFunc, + "Background": noColorFunc, + "Bold": noStyleFunc, + "Faint": noStyleFunc, + "Italic": noStyleFunc, + "Underline": noStyleFunc, + "Overline": noStyleFunc, + "Blink": noStyleFunc, + "Reverse": noStyleFunc, + "CrossOut": noStyleFunc, +} + +func noColorFunc(values ...interface{}) string { + return values[len(values)-1].(string) +} + +func noStyleFunc(values ...interface{}) string { + return values[0].(string) +} diff --git a/vendor/github.com/muesli/termenv/termenv.go b/vendor/github.com/muesli/termenv/termenv.go new file mode 100644 index 0000000..d702cd5 --- /dev/null +++ b/vendor/github.com/muesli/termenv/termenv.go @@ -0,0 +1,115 @@ +package termenv + +import ( + "errors" + "os" + + "github.com/mattn/go-isatty" +) + +var ( + // ErrStatusReport gets returned when the terminal can't be queried. + ErrStatusReport = errors.New("unable to retrieve status report") +) + +const ( + // Escape character. + ESC = '\x1b' + // Bell. + BEL = '\a' + // Control Sequence Introducer. + CSI = string(ESC) + "[" + // Operating System Command. + OSC = string(ESC) + "]" + // String Terminator. + ST = string(ESC) + `\` +) + +func (o *Output) isTTY() bool { + if o.assumeTTY || o.unsafe { + return true + } + if len(o.environ.Getenv("CI")) > 0 { + return false + } + if f, ok := o.Writer().(*os.File); ok { + return isatty.IsTerminal(f.Fd()) + } + + return false +} + +// ColorProfile returns the supported color profile: +// Ascii, ANSI, ANSI256, or TrueColor. +func ColorProfile() Profile { + return output.ColorProfile() +} + +// ForegroundColor returns the terminal's default foreground color. +func ForegroundColor() Color { + return output.ForegroundColor() +} + +// BackgroundColor returns the terminal's default background color. +func BackgroundColor() Color { + return output.BackgroundColor() +} + +// HasDarkBackground returns whether terminal uses a dark-ish background. +func HasDarkBackground() bool { + return output.HasDarkBackground() +} + +// EnvNoColor returns true if the environment variables explicitly disable color output +// by setting NO_COLOR (https://no-color.org/) +// or CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/) +// If NO_COLOR is set, this will return true, ignoring CLICOLOR/CLICOLOR_FORCE +// If CLICOLOR=="0", it will be true only if CLICOLOR_FORCE is also "0" or is unset. +func (o *Output) EnvNoColor() bool { + return o.environ.Getenv("NO_COLOR") != "" || (o.environ.Getenv("CLICOLOR") == "0" && !o.cliColorForced()) +} + +// EnvNoColor returns true if the environment variables explicitly disable color output +// by setting NO_COLOR (https://no-color.org/) +// or CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/) +// If NO_COLOR is set, this will return true, ignoring CLICOLOR/CLICOLOR_FORCE +// If CLICOLOR=="0", it will be true only if CLICOLOR_FORCE is also "0" or is unset. +func EnvNoColor() bool { + return output.EnvNoColor() +} + +// EnvColorProfile returns the color profile based on environment variables set +// Supports NO_COLOR (https://no-color.org/) +// and CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/) +// If none of these environment variables are set, this behaves the same as ColorProfile() +// It will return the Ascii color profile if EnvNoColor() returns true +// If the terminal does not support any colors, but CLICOLOR_FORCE is set and not "0" +// then the ANSI color profile will be returned. +func EnvColorProfile() Profile { + return output.EnvColorProfile() +} + +// EnvColorProfile returns the color profile based on environment variables set +// Supports NO_COLOR (https://no-color.org/) +// and CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/) +// If none of these environment variables are set, this behaves the same as ColorProfile() +// It will return the Ascii color profile if EnvNoColor() returns true +// If the terminal does not support any colors, but CLICOLOR_FORCE is set and not "0" +// then the ANSI color profile will be returned. +func (o *Output) EnvColorProfile() Profile { + if o.EnvNoColor() { + return Ascii + } + p := o.ColorProfile() + if o.cliColorForced() && p == Ascii { + return ANSI + } + return p +} + +func (o *Output) cliColorForced() bool { + if forced := o.environ.Getenv("CLICOLOR_FORCE"); forced != "" { + return forced != "0" + } + return false +} diff --git a/vendor/github.com/muesli/termenv/termenv_other.go b/vendor/github.com/muesli/termenv/termenv_other.go new file mode 100644 index 0000000..93a43b6 --- /dev/null +++ b/vendor/github.com/muesli/termenv/termenv_other.go @@ -0,0 +1,30 @@ +//go:build js || plan9 || aix +// +build js plan9 aix + +package termenv + +import "io" + +// ColorProfile returns the supported color profile: +// ANSI256 +func (o Output) ColorProfile() Profile { + return ANSI256 +} + +func (o Output) foregroundColor() Color { + // default gray + return ANSIColor(7) +} + +func (o Output) backgroundColor() Color { + // default black + return ANSIColor(0) +} + +// EnableVirtualTerminalProcessing enables virtual terminal processing on +// Windows for w and returns a function that restores w to its previous state. +// On non-Windows platforms, or if w does not refer to a terminal, then it +// returns a non-nil no-op function and no error. +func EnableVirtualTerminalProcessing(w io.Writer) (func() error, error) { + return func() error { return nil }, nil +} diff --git a/vendor/github.com/muesli/termenv/termenv_posix.go b/vendor/github.com/muesli/termenv/termenv_posix.go new file mode 100644 index 0000000..c971dd9 --- /dev/null +++ b/vendor/github.com/muesli/termenv/termenv_posix.go @@ -0,0 +1,17 @@ +//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || zos +// +build darwin dragonfly freebsd linux netbsd openbsd zos + +package termenv + +import ( + "golang.org/x/sys/unix" +) + +func isForeground(fd int) bool { + pgrp, err := unix.IoctlGetInt(fd, unix.TIOCGPGRP) + if err != nil { + return false + } + + return pgrp == unix.Getpgrp() +} diff --git a/vendor/github.com/muesli/termenv/termenv_solaris.go b/vendor/github.com/muesli/termenv/termenv_solaris.go new file mode 100644 index 0000000..27a95a9 --- /dev/null +++ b/vendor/github.com/muesli/termenv/termenv_solaris.go @@ -0,0 +1,22 @@ +//go:build solaris || illumos +// +build solaris illumos + +package termenv + +import ( + "golang.org/x/sys/unix" +) + +func isForeground(fd int) bool { + pgrp, err := unix.IoctlGetInt(fd, unix.TIOCGPGRP) + if err != nil { + return false + } + + g, err := unix.Getpgrp() + if err != nil { + return false + } + + return pgrp == g +} diff --git a/vendor/github.com/muesli/termenv/termenv_unix.go b/vendor/github.com/muesli/termenv/termenv_unix.go new file mode 100644 index 0000000..bef49ca --- /dev/null +++ b/vendor/github.com/muesli/termenv/termenv_unix.go @@ -0,0 +1,301 @@ +//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos +// +build darwin dragonfly freebsd linux netbsd openbsd solaris zos + +package termenv + +import ( + "fmt" + "io" + "strconv" + "strings" + "time" + + "golang.org/x/sys/unix" +) + +const ( + // timeout for OSC queries. + OSCTimeout = 5 * time.Second +) + +// ColorProfile returns the supported color profile: +// Ascii, ANSI, ANSI256, or TrueColor. +func (o *Output) ColorProfile() Profile { + if !o.isTTY() { + return Ascii + } + + if o.environ.Getenv("GOOGLE_CLOUD_SHELL") == "true" { + return TrueColor + } + + term := o.environ.Getenv("TERM") + colorTerm := o.environ.Getenv("COLORTERM") + + switch strings.ToLower(colorTerm) { + case "24bit": + fallthrough + case "truecolor": + if strings.HasPrefix(term, "screen") { + // tmux supports TrueColor, screen only ANSI256 + if o.environ.Getenv("TERM_PROGRAM") != "tmux" { + return ANSI256 + } + } + return TrueColor + case "yes": + fallthrough + case "true": + return ANSI256 + } + + switch term { + case + "alacritty", + "contour", + "rio", + "wezterm", + "xterm-ghostty", + "xterm-kitty": + return TrueColor + case "linux", "xterm": + return ANSI + } + + if strings.Contains(term, "256color") { + return ANSI256 + } + if strings.Contains(term, "color") { + return ANSI + } + if strings.Contains(term, "ansi") { + return ANSI + } + + return Ascii +} + +//nolint:mnd +func (o Output) foregroundColor() Color { + s, err := o.termStatusReport(10) + if err == nil { + c, err := xTermColor(s) + if err == nil { + return c + } + } + + colorFGBG := o.environ.Getenv("COLORFGBG") + if strings.Contains(colorFGBG, ";") { + c := strings.Split(colorFGBG, ";") + i, err := strconv.Atoi(c[0]) + if err == nil { + return ANSIColor(i) + } + } + + // default gray + return ANSIColor(7) +} + +//nolint:mnd +func (o Output) backgroundColor() Color { + s, err := o.termStatusReport(11) + if err == nil { + c, err := xTermColor(s) + if err == nil { + return c + } + } + + colorFGBG := o.environ.Getenv("COLORFGBG") + if strings.Contains(colorFGBG, ";") { + c := strings.Split(colorFGBG, ";") + i, err := strconv.Atoi(c[len(c)-1]) + if err == nil { + return ANSIColor(i) + } + } + + // default black + return ANSIColor(0) +} + +func (o *Output) waitForData(timeout time.Duration) error { + fd := o.TTY().Fd() + tv := unix.NsecToTimeval(int64(timeout)) + var readfds unix.FdSet + readfds.Set(int(fd)) //nolint:gosec + + for { + n, err := unix.Select(int(fd)+1, &readfds, nil, nil, &tv) //nolint:gosec + if err == unix.EINTR { + continue + } + if err != nil { + return err //nolint:wrapcheck + } + if n == 0 { + return fmt.Errorf("timeout") + } + + break + } + + return nil +} + +func (o *Output) readNextByte() (byte, error) { + if !o.unsafe { + if err := o.waitForData(OSCTimeout); err != nil { + return 0, err + } + } + + var b [1]byte + n, err := o.TTY().Read(b[:]) + if err != nil { + return 0, err //nolint:wrapcheck + } + + if n == 0 { + panic("read returned no data") + } + + return b[0], nil +} + +// readNextResponse reads either an OSC response or a cursor position response: +// - OSC response: "\x1b]11;rgb:1111/1111/1111\x1b\\" +// - cursor position response: "\x1b[42;1R" +func (o *Output) readNextResponse() (response string, isOSC bool, err error) { + start, err := o.readNextByte() + if err != nil { + return "", false, err + } + + // first byte must be ESC + for start != ESC { + start, err = o.readNextByte() + if err != nil { + return "", false, err + } + } + + response += string(start) + + // next byte is either '[' (cursor position response) or ']' (OSC response) + tpe, err := o.readNextByte() + if err != nil { + return "", false, err + } + + response += string(tpe) + + var oscResponse bool + switch tpe { + case '[': + oscResponse = false + case ']': + oscResponse = true + default: + return "", false, ErrStatusReport + } + + for { + b, err := o.readNextByte() + if err != nil { + return "", false, err + } + + response += string(b) + + if oscResponse { + // OSC can be terminated by BEL (\a) or ST (ESC) + if b == BEL || strings.HasSuffix(response, string(ESC)) { + return response, true, nil + } + } else { + // cursor position response is terminated by 'R' + if b == 'R' { + return response, false, nil + } + } + + // both responses have less than 25 bytes, so if we read more, that's an error + if len(response) > 25 { //nolint:mnd + break + } + } + + return "", false, ErrStatusReport +} + +func (o Output) termStatusReport(sequence int) (string, error) { + // screen/tmux can't support OSC, because they can be connected to multiple + // terminals concurrently. + term := o.environ.Getenv("TERM") + if strings.HasPrefix(term, "screen") || strings.HasPrefix(term, "tmux") || strings.HasPrefix(term, "dumb") { + return "", ErrStatusReport + } + + tty := o.TTY() + if tty == nil { + return "", ErrStatusReport + } + + if !o.unsafe { + fd := int(tty.Fd()) //nolint:gosec + // if in background, we can't control the terminal + if !isForeground(fd) { + return "", ErrStatusReport + } + + t, err := unix.IoctlGetTermios(fd, tcgetattr) + if err != nil { + return "", fmt.Errorf("%s: %s", ErrStatusReport, err) + } + defer unix.IoctlSetTermios(fd, tcsetattr, t) //nolint:errcheck + + noecho := *t + noecho.Lflag = noecho.Lflag &^ unix.ECHO + noecho.Lflag = noecho.Lflag &^ unix.ICANON + if err := unix.IoctlSetTermios(fd, tcsetattr, &noecho); err != nil { + return "", fmt.Errorf("%s: %s", ErrStatusReport, err) + } + } + + // first, send OSC query, which is ignored by terminal which do not support it + fmt.Fprintf(tty, OSC+"%d;?"+ST, sequence) //nolint:errcheck + + // then, query cursor position, should be supported by all terminals + fmt.Fprintf(tty, CSI+"6n") //nolint:errcheck + + // read the next response + res, isOSC, err := o.readNextResponse() + if err != nil { + return "", fmt.Errorf("%s: %s", ErrStatusReport, err) + } + + // if this is not OSC response, then the terminal does not support it + if !isOSC { + return "", ErrStatusReport + } + + // read the cursor query response next and discard the result + _, _, err = o.readNextResponse() + if err != nil { + return "", err + } + + // fmt.Println("Rcvd", res[1:]) + return res, nil +} + +// EnableVirtualTerminalProcessing enables virtual terminal processing on +// Windows for w and returns a function that restores w to its previous state. +// On non-Windows platforms, or if w does not refer to a terminal, then it +// returns a non-nil no-op function and no error. +func EnableVirtualTerminalProcessing(_ io.Writer) (func() error, error) { + return func() error { return nil }, nil +} diff --git a/vendor/github.com/muesli/termenv/termenv_windows.go b/vendor/github.com/muesli/termenv/termenv_windows.go new file mode 100644 index 0000000..f9b1def --- /dev/null +++ b/vendor/github.com/muesli/termenv/termenv_windows.go @@ -0,0 +1,140 @@ +//go:build windows +// +build windows + +package termenv + +import ( + "fmt" + "os" + "strconv" + + "golang.org/x/sys/windows" +) + +func (o *Output) ColorProfile() Profile { + if !o.isTTY() { + return Ascii + } + + if o.environ.Getenv("ConEmuANSI") == "ON" { + return TrueColor + } + + winVersion, _, buildNumber := windows.RtlGetNtVersionNumbers() + if buildNumber < 10586 || winVersion < 10 { + // No ANSI support before Windows 10 build 10586. + if o.environ.Getenv("ANSICON") != "" { + conVersion := o.environ.Getenv("ANSICON_VER") + cv, err := strconv.ParseInt(conVersion, 10, 64) + if err != nil || cv < 181 { + // No 8 bit color support before v1.81 release. + return ANSI + } + + return ANSI256 + } + + return Ascii + } + if buildNumber < 14931 { + // No true color support before build 14931. + return ANSI256 + } + + return TrueColor +} + +func (o Output) foregroundColor() Color { + // default gray + return ANSIColor(7) +} + +func (o Output) backgroundColor() Color { + // default black + return ANSIColor(0) +} + +// EnableWindowsANSIConsole enables virtual terminal processing on Windows +// platforms. This allows the use of ANSI escape sequences in Windows console +// applications. Ensure this gets called before anything gets rendered with +// termenv. +// +// Returns the original console mode and an error if one occurred. +func EnableWindowsANSIConsole() (uint32, error) { + handle, err := windows.GetStdHandle(windows.STD_OUTPUT_HANDLE) + if err != nil { + return 0, err + } + + var mode uint32 + err = windows.GetConsoleMode(handle, &mode) + if err != nil { + return 0, err + } + + // See https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences + if mode&windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING { + vtpmode := mode | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING + if err := windows.SetConsoleMode(handle, vtpmode); err != nil { + return 0, err + } + } + + return mode, nil +} + +// RestoreWindowsConsole restores the console mode to a previous state. +func RestoreWindowsConsole(mode uint32) error { + handle, err := windows.GetStdHandle(windows.STD_OUTPUT_HANDLE) + if err != nil { + return err + } + + return windows.SetConsoleMode(handle, mode) +} + +// EnableVirtualTerminalProcessing enables virtual terminal processing on +// Windows for o and returns a function that restores o to its previous state. +// On non-Windows platforms, or if o does not refer to a terminal, then it +// returns a non-nil no-op function and no error. +func EnableVirtualTerminalProcessing(o *Output) (restoreFunc func() error, err error) { + // There is nothing to restore until we set the console mode. + restoreFunc = func() error { + return nil + } + + // If o is not a tty, then there is nothing to do. + tty, ok := o.Writer().(*os.File) + if tty == nil || !ok { + return + } + + // Get the current console mode. If there is an error, assume that o is not + // a terminal, discard the error, and return. + var mode uint32 + if err2 := windows.GetConsoleMode(windows.Handle(tty.Fd()), &mode); err2 != nil { + return + } + + // If virtual terminal processing is already set, then there is nothing to + // do and nothing to restore. + if mode&windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING == windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING { + return + } + + // Enable virtual terminal processing. See + // https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences + if err2 := windows.SetConsoleMode(windows.Handle(tty.Fd()), mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING); err2 != nil { + err = fmt.Errorf("windows.SetConsoleMode: %w", err2) + return + } + + // Set the restore function. We maintain a reference to the tty in the + // closure (rather than just its handle) to ensure that the tty is not + // closed by a finalizer. + restoreFunc = func() error { + return windows.SetConsoleMode(windows.Handle(tty.Fd()), mode) + } + + return +} |
