This commit is contained in:
15
vendor/github.com/muesli/termenv/.gitignore
generated
vendored
Normal file
15
vendor/github.com/muesli/termenv/.gitignore
generated
vendored
Normal file
@ -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/
|
47
vendor/github.com/muesli/termenv/.golangci-soft.yml
generated
vendored
Normal file
47
vendor/github.com/muesli/termenv/.golangci-soft.yml
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
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
|
||||
- gomnd
|
||||
- gomoddirectives
|
||||
- goprintffuncname
|
||||
- ifshort
|
||||
# - lll
|
||||
- misspell
|
||||
- nakedret
|
||||
- nestif
|
||||
- noctx
|
||||
- nolintlint
|
||||
- prealloc
|
||||
- wrapcheck
|
||||
|
||||
# disable default linters, they are already enabled in .golangci.yml
|
||||
disable:
|
||||
- deadcode
|
||||
- errcheck
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- typecheck
|
||||
- unused
|
||||
- varcheck
|
29
vendor/github.com/muesli/termenv/.golangci.yml
generated
vendored
Normal file
29
vendor/github.com/muesli/termenv/.golangci.yml
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
run:
|
||||
tests: false
|
||||
|
||||
issues:
|
||||
include:
|
||||
- EXC0001
|
||||
- EXC0005
|
||||
- EXC0011
|
||||
- EXC0012
|
||||
- EXC0013
|
||||
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- bodyclose
|
||||
- exportloopref
|
||||
- goimports
|
||||
- gosec
|
||||
- nilerr
|
||||
- predeclared
|
||||
- revive
|
||||
- rowserrcheck
|
||||
- sqlclosecheck
|
||||
- tparallel
|
||||
- unconvert
|
||||
- unparam
|
||||
- whitespace
|
21
vendor/github.com/muesli/termenv/LICENSE
generated
vendored
Normal file
21
vendor/github.com/muesli/termenv/LICENSE
generated
vendored
Normal file
@ -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.
|
431
vendor/github.com/muesli/termenv/README.md
generated
vendored
Normal file
431
vendor/github.com/muesli/termenv/README.md
generated
vendored
Normal file
@ -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, 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 not supported, for more info see [issue#922](https://github.com/alacritty/alacritty/issues/922).
|
||||
|
||||
</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)
|
65
vendor/github.com/muesli/termenv/ansi_compat.md
generated
vendored
Normal file
65
vendor/github.com/muesli/termenv/ansi_compat.md
generated
vendored
Normal file
@ -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\\"
|
||||
```
|
281
vendor/github.com/muesli/termenv/ansicolors.go
generated
vendored
Normal file
281
vendor/github.com/muesli/termenv/ansicolors.go
generated
vendored
Normal file
@ -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",
|
||||
}
|
204
vendor/github.com/muesli/termenv/color.go
generated
vendored
Normal file
204
vendor/github.com/muesli/termenv/color.go
generated
vendored
Normal file
@ -0,0 +1,204 @@
|
||||
package termenv
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"strings"
|
||||
|
||||
"github.com/lucasb-eyer/go-colorful"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrInvalidColor gets returned when a color is invalid.
|
||||
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.
|
||||
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)
|
||||
}
|
||||
return fmt.Sprintf("%d", bgMod(col-8)+90)
|
||||
}
|
||||
|
||||
// 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))
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
8
vendor/github.com/muesli/termenv/constants_linux.go
generated
vendored
Normal file
8
vendor/github.com/muesli/termenv/constants_linux.go
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
package termenv
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
const (
|
||||
tcgetattr = unix.TCGETS
|
||||
tcsetattr = unix.TCSETS
|
||||
)
|
8
vendor/github.com/muesli/termenv/constants_solaris.go
generated
vendored
Normal file
8
vendor/github.com/muesli/termenv/constants_solaris.go
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
package termenv
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
const (
|
||||
tcgetattr = unix.TCGETS
|
||||
tcsetattr = unix.TCSETS
|
||||
)
|
13
vendor/github.com/muesli/termenv/constants_unix.go
generated
vendored
Normal file
13
vendor/github.com/muesli/termenv/constants_unix.go
generated
vendored
Normal file
@ -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
|
||||
)
|
37
vendor/github.com/muesli/termenv/copy.go
generated
vendored
Normal file
37
vendor/github.com/muesli/termenv/copy.go
generated
vendored
Normal file
@ -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)
|
||||
}
|
11
vendor/github.com/muesli/termenv/hyperlink.go
generated
vendored
Normal file
11
vendor/github.com/muesli/termenv/hyperlink.go
generated
vendored
Normal file
@ -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
|
||||
}
|
11
vendor/github.com/muesli/termenv/notification.go
generated
vendored
Normal file
11
vendor/github.com/muesli/termenv/notification.go
generated
vendored
Normal file
@ -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)
|
||||
}
|
197
vendor/github.com/muesli/termenv/output.go
generated
vendored
Normal file
197
vendor/github.com/muesli/termenv/output.go
generated
vendored
Normal file
@ -0,0 +1,197 @@
|
||||
package termenv
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
// output is the default global output.
|
||||
output = NewOutput(os.Stdout)
|
||||
)
|
||||
|
||||
// File represents a file descriptor.
|
||||
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
|
||||
tty 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 file descriptor.
|
||||
func NewOutput(tty io.Writer, opts ...OutputOption) *Output {
|
||||
o := &Output{
|
||||
tty: tty,
|
||||
environ: &osEnviron{},
|
||||
Profile: -1,
|
||||
fgSync: &sync.Once{},
|
||||
fgColor: NoColor{},
|
||||
bgSync: &sync.Once{},
|
||||
bgColor: NoColor{},
|
||||
}
|
||||
|
||||
if o.tty == nil {
|
||||
o.tty = 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
|
||||
}
|
||||
|
||||
// TTY returns the terminal's file descriptor. This may be nil if the output is
|
||||
// not a terminal.
|
||||
func (o Output) TTY() File {
|
||||
if f, ok := o.tty.(File); ok {
|
||||
return f
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o Output) Write(p []byte) (int, error) {
|
||||
return o.tty.Write(p)
|
||||
}
|
||||
|
||||
// WriteString writes the given string to the output.
|
||||
func (o Output) WriteString(s string) (int, error) {
|
||||
return o.Write([]byte(s))
|
||||
}
|
97
vendor/github.com/muesli/termenv/profile.go
generated
vendored
Normal file
97
vendor/github.com/muesli/termenv/profile.go
generated
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
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
|
||||
)
|
||||
|
||||
// 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 {
|
||||
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())
|
||||
}
|
590
vendor/github.com/muesli/termenv/screen.go
generated
vendored
Normal file
590
vendor/github.com/muesli/termenv/screen.go
generated
vendored
Normal file
@ -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.tty, CSI+ResetSeq+"m")
|
||||
}
|
||||
|
||||
// SetForegroundColor sets the default foreground color.
|
||||
func (o Output) SetForegroundColor(color Color) {
|
||||
fmt.Fprintf(o.tty, OSC+SetForegroundColorSeq, color)
|
||||
}
|
||||
|
||||
// SetBackgroundColor sets the default background color.
|
||||
func (o Output) SetBackgroundColor(color Color) {
|
||||
fmt.Fprintf(o.tty, OSC+SetBackgroundColorSeq, color)
|
||||
}
|
||||
|
||||
// SetCursorColor sets the cursor color.
|
||||
func (o Output) SetCursorColor(color Color) {
|
||||
fmt.Fprintf(o.tty, OSC+SetCursorColorSeq, color)
|
||||
}
|
||||
|
||||
// RestoreScreen restores a previously saved screen state.
|
||||
func (o Output) RestoreScreen() {
|
||||
fmt.Fprint(o.tty, CSI+RestoreScreenSeq)
|
||||
}
|
||||
|
||||
// SaveScreen saves the screen state.
|
||||
func (o Output) SaveScreen() {
|
||||
fmt.Fprint(o.tty, CSI+SaveScreenSeq)
|
||||
}
|
||||
|
||||
// AltScreen switches to the alternate screen buffer. The former view can be
|
||||
// restored with ExitAltScreen().
|
||||
func (o Output) AltScreen() {
|
||||
fmt.Fprint(o.tty, CSI+AltScreenSeq)
|
||||
}
|
||||
|
||||
// ExitAltScreen exits the alternate screen buffer and returns to the former
|
||||
// terminal view.
|
||||
func (o Output) ExitAltScreen() {
|
||||
fmt.Fprint(o.tty, CSI+ExitAltScreenSeq)
|
||||
}
|
||||
|
||||
// ClearScreen clears the visible portion of the terminal.
|
||||
func (o Output) ClearScreen() {
|
||||
fmt.Fprintf(o.tty, CSI+EraseDisplaySeq, 2)
|
||||
o.MoveCursor(1, 1)
|
||||
}
|
||||
|
||||
// MoveCursor moves the cursor to a given position.
|
||||
func (o Output) MoveCursor(row int, column int) {
|
||||
fmt.Fprintf(o.tty, CSI+CursorPositionSeq, row, column)
|
||||
}
|
||||
|
||||
// HideCursor hides the cursor.
|
||||
func (o Output) HideCursor() {
|
||||
fmt.Fprint(o.tty, CSI+HideCursorSeq)
|
||||
}
|
||||
|
||||
// ShowCursor shows the cursor.
|
||||
func (o Output) ShowCursor() {
|
||||
fmt.Fprint(o.tty, CSI+ShowCursorSeq)
|
||||
}
|
||||
|
||||
// SaveCursorPosition saves the cursor position.
|
||||
func (o Output) SaveCursorPosition() {
|
||||
fmt.Fprint(o.tty, CSI+SaveCursorPositionSeq)
|
||||
}
|
||||
|
||||
// RestoreCursorPosition restores a saved cursor position.
|
||||
func (o Output) RestoreCursorPosition() {
|
||||
fmt.Fprint(o.tty, CSI+RestoreCursorPositionSeq)
|
||||
}
|
||||
|
||||
// CursorUp moves the cursor up a given number of lines.
|
||||
func (o Output) CursorUp(n int) {
|
||||
fmt.Fprintf(o.tty, CSI+CursorUpSeq, n)
|
||||
}
|
||||
|
||||
// CursorDown moves the cursor down a given number of lines.
|
||||
func (o Output) CursorDown(n int) {
|
||||
fmt.Fprintf(o.tty, CSI+CursorDownSeq, n)
|
||||
}
|
||||
|
||||
// CursorForward moves the cursor up a given number of lines.
|
||||
func (o Output) CursorForward(n int) {
|
||||
fmt.Fprintf(o.tty, CSI+CursorForwardSeq, n)
|
||||
}
|
||||
|
||||
// CursorBack moves the cursor backwards a given number of cells.
|
||||
func (o Output) CursorBack(n int) {
|
||||
fmt.Fprintf(o.tty, CSI+CursorBackSeq, n)
|
||||
}
|
||||
|
||||
// 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.tty, CSI+CursorNextLineSeq, n)
|
||||
}
|
||||
|
||||
// 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.tty, CSI+CursorPreviousLineSeq, n)
|
||||
}
|
||||
|
||||
// ClearLine clears the current line.
|
||||
func (o Output) ClearLine() {
|
||||
fmt.Fprint(o.tty, CSI+EraseEntireLineSeq)
|
||||
}
|
||||
|
||||
// ClearLineLeft clears the line to the left of the cursor.
|
||||
func (o Output) ClearLineLeft() {
|
||||
fmt.Fprint(o.tty, CSI+EraseLineLeftSeq)
|
||||
}
|
||||
|
||||
// ClearLineRight clears the line to the right of the cursor.
|
||||
func (o Output) ClearLineRight() {
|
||||
fmt.Fprint(o.tty, CSI+EraseLineRightSeq)
|
||||
}
|
||||
|
||||
// ClearLines clears a given number of lines.
|
||||
func (o Output) ClearLines(n int) {
|
||||
clearLine := fmt.Sprintf(CSI+EraseLineSeq, 2)
|
||||
cursorUp := fmt.Sprintf(CSI+CursorUpSeq, 1)
|
||||
fmt.Fprint(o.tty, clearLine+strings.Repeat(cursorUp+clearLine, n))
|
||||
}
|
||||
|
||||
// ChangeScrollingRegion sets the scrolling region of the terminal.
|
||||
func (o Output) ChangeScrollingRegion(top, bottom int) {
|
||||
fmt.Fprintf(o.tty, CSI+ChangeScrollingRegionSeq, top, bottom)
|
||||
}
|
||||
|
||||
// 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.tty, CSI+InsertLineSeq, n)
|
||||
}
|
||||
|
||||
// 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.tty, CSI+DeleteLineSeq, n)
|
||||
}
|
||||
|
||||
// EnableMousePress enables X10 mouse mode. Button press events are sent only.
|
||||
func (o Output) EnableMousePress() {
|
||||
fmt.Fprint(o.tty, CSI+EnableMousePressSeq)
|
||||
}
|
||||
|
||||
// DisableMousePress disables X10 mouse mode.
|
||||
func (o Output) DisableMousePress() {
|
||||
fmt.Fprint(o.tty, CSI+DisableMousePressSeq)
|
||||
}
|
||||
|
||||
// EnableMouse enables Mouse Tracking mode.
|
||||
func (o Output) EnableMouse() {
|
||||
fmt.Fprint(o.tty, CSI+EnableMouseSeq)
|
||||
}
|
||||
|
||||
// DisableMouse disables Mouse Tracking mode.
|
||||
func (o Output) DisableMouse() {
|
||||
fmt.Fprint(o.tty, CSI+DisableMouseSeq)
|
||||
}
|
||||
|
||||
// EnableMouseHilite enables Hilite Mouse Tracking mode.
|
||||
func (o Output) EnableMouseHilite() {
|
||||
fmt.Fprint(o.tty, CSI+EnableMouseHiliteSeq)
|
||||
}
|
||||
|
||||
// DisableMouseHilite disables Hilite Mouse Tracking mode.
|
||||
func (o Output) DisableMouseHilite() {
|
||||
fmt.Fprint(o.tty, CSI+DisableMouseHiliteSeq)
|
||||
}
|
||||
|
||||
// EnableMouseCellMotion enables Cell Motion Mouse Tracking mode.
|
||||
func (o Output) EnableMouseCellMotion() {
|
||||
fmt.Fprint(o.tty, CSI+EnableMouseCellMotionSeq)
|
||||
}
|
||||
|
||||
// DisableMouseCellMotion disables Cell Motion Mouse Tracking mode.
|
||||
func (o Output) DisableMouseCellMotion() {
|
||||
fmt.Fprint(o.tty, CSI+DisableMouseCellMotionSeq)
|
||||
}
|
||||
|
||||
// EnableMouseAllMotion enables All Motion Mouse mode.
|
||||
func (o Output) EnableMouseAllMotion() {
|
||||
fmt.Fprint(o.tty, CSI+EnableMouseAllMotionSeq)
|
||||
}
|
||||
|
||||
// DisableMouseAllMotion disables All Motion Mouse mode.
|
||||
func (o Output) DisableMouseAllMotion() {
|
||||
fmt.Fprint(o.tty, CSI+DisableMouseAllMotionSeq)
|
||||
}
|
||||
|
||||
// EnableMouseExtendedMotion enables Extended Mouse mode (SGR). This should be
|
||||
// enabled in conjunction with EnableMouseCellMotion, and EnableMouseAllMotion.
|
||||
func (o Output) EnableMouseExtendedMode() {
|
||||
fmt.Fprint(o.tty, CSI+EnableMouseExtendedModeSeq)
|
||||
}
|
||||
|
||||
// DisableMouseExtendedMotion disables Extended Mouse mode (SGR).
|
||||
func (o Output) DisableMouseExtendedMode() {
|
||||
fmt.Fprint(o.tty, CSI+DisableMouseExtendedModeSeq)
|
||||
}
|
||||
|
||||
// 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.tty, CSI+EnableMousePixelsModeSeq)
|
||||
}
|
||||
|
||||
// DisableMousePixelsMotion disables Pixel Motion Mouse mode (SGR-Pixels).
|
||||
func (o Output) DisableMousePixelsMode() {
|
||||
fmt.Fprint(o.tty, CSI+DisableMousePixelsModeSeq)
|
||||
}
|
||||
|
||||
// SetWindowTitle sets the terminal window title.
|
||||
func (o Output) SetWindowTitle(title string) {
|
||||
fmt.Fprintf(o.tty, OSC+SetWindowTitleSeq, title)
|
||||
}
|
||||
|
||||
// EnableBracketedPaste enables bracketed paste.
|
||||
func (o Output) EnableBracketedPaste() {
|
||||
fmt.Fprintf(o.tty, CSI+EnableBracketedPasteSeq)
|
||||
}
|
||||
|
||||
// DisableBracketedPaste disables bracketed paste.
|
||||
func (o Output) DisableBracketedPaste() {
|
||||
fmt.Fprintf(o.tty, CSI+DisableBracketedPasteSeq)
|
||||
}
|
||||
|
||||
// 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()
|
||||
}
|
126
vendor/github.com/muesli/termenv/style.go
generated
vendored
Normal file
126
vendor/github.com/muesli/termenv/style.go
generated
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
package termenv
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/mattn/go-runewidth"
|
||||
)
|
||||
|
||||
// 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 runewidth.StringWidth(t.string)
|
||||
}
|
86
vendor/github.com/muesli/termenv/templatehelper.go
generated
vendored
Normal file
86
vendor/github.com/muesli/termenv/templatehelper.go
generated
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
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.
|
||||
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)
|
||||
}
|
114
vendor/github.com/muesli/termenv/termenv.go
generated
vendored
Normal file
114
vendor/github.com/muesli/termenv/termenv.go
generated
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
package termenv
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"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 o.TTY() == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return isatty.IsTerminal(o.TTY().Fd())
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
30
vendor/github.com/muesli/termenv/termenv_other.go
generated
vendored
Normal file
30
vendor/github.com/muesli/termenv/termenv_other.go
generated
vendored
Normal file
@ -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
|
||||
}
|
17
vendor/github.com/muesli/termenv/termenv_posix.go
generated
vendored
Normal file
17
vendor/github.com/muesli/termenv/termenv_posix.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
|
||||
// +build darwin dragonfly freebsd linux netbsd openbsd
|
||||
|
||||
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()
|
||||
}
|
22
vendor/github.com/muesli/termenv/termenv_solaris.go
generated
vendored
Normal file
22
vendor/github.com/muesli/termenv/termenv_solaris.go
generated
vendored
Normal file
@ -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
|
||||
}
|
293
vendor/github.com/muesli/termenv/termenv_unix.go
generated
vendored
Normal file
293
vendor/github.com/muesli/termenv/termenv_unix.go
generated
vendored
Normal file
@ -0,0 +1,293 @@
|
||||
//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
||||
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
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 "xterm-kitty", "wezterm":
|
||||
return TrueColor
|
||||
case "linux":
|
||||
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
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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))
|
||||
|
||||
for {
|
||||
n, err := unix.Select(int(fd)+1, &readfds, nil, nil, &tv)
|
||||
if err == unix.EINTR {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
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 {
|
||||
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") {
|
||||
return "", ErrStatusReport
|
||||
}
|
||||
|
||||
tty := o.TTY()
|
||||
if tty == nil {
|
||||
return "", ErrStatusReport
|
||||
}
|
||||
|
||||
if !o.unsafe {
|
||||
fd := int(tty.Fd())
|
||||
// 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)
|
||||
|
||||
// then, query cursor position, should be supported by all terminals
|
||||
fmt.Fprintf(tty, CSI+"6n")
|
||||
|
||||
// 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
|
||||
}
|
139
vendor/github.com/muesli/termenv/termenv_windows.go
generated
vendored
Normal file
139
vendor/github.com/muesli/termenv/termenv_windows.go
generated
vendored
Normal file
@ -0,0 +1,139 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package termenv
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"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 := o.TTY()
|
||||
if tty == nil {
|
||||
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
|
||||
}
|
Reference in New Issue
Block a user