pax_global_header 0000666 0000000 0000000 00000000064 14313030041 0014477 g ustar 00root root 0000000 0000000 52 comment=d5ed3231917d0f5c9fdc635e10d576f8d5b4b175 termenv-0.13.0/ 0000775 0000000 0000000 00000000000 14313030041 0013240 5 ustar 00root root 0000000 0000000 termenv-0.13.0/.github/ 0000775 0000000 0000000 00000000000 14313030041 0014600 5 ustar 00root root 0000000 0000000 termenv-0.13.0/.github/FUNDING.yml 0000664 0000000 0000000 00000000017 14313030041 0016413 0 ustar 00root root 0000000 0000000 github: muesli termenv-0.13.0/.github/dependabot.yml 0000664 0000000 0000000 00000000423 14313030041 0017427 0 ustar 00root root 0000000 0000000 version: 2 updates: - package-ecosystem: "gomod" directory: "/" schedule: interval: "daily" labels: - "dependencies" - package-ecosystem: "github-actions" directory: "/" schedule: interval: "daily" labels: - "dependencies" termenv-0.13.0/.github/workflows/ 0000775 0000000 0000000 00000000000 14313030041 0016635 5 ustar 00root root 0000000 0000000 termenv-0.13.0/.github/workflows/build.yml 0000664 0000000 0000000 00000001176 14313030041 0020464 0 ustar 00root root 0000000 0000000 name: build on: [push, pull_request] jobs: build: strategy: matrix: go-version: [~1.13, ^1] os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} env: GO111MODULE: "on" steps: - name: Install Go uses: actions/setup-go@v3 with: go-version: ${{ matrix.go-version }} - name: Checkout code uses: actions/checkout@v3 - name: Download Go modules run: go mod download - name: Build run: go build -v ./... - name: Test run: go test ./... if: matrix.platform != 'windows-latest' termenv-0.13.0/.github/workflows/coverage.yml 0000664 0000000 0000000 00000001321 14313030041 0021150 0 ustar 00root root 0000000 0000000 name: coverage on: [push, pull_request] jobs: coverage: strategy: matrix: go-version: [^1] os: [ubuntu-latest] runs-on: ${{ matrix.os }} env: GO111MODULE: "on" steps: - name: Install Go uses: actions/setup-go@v3 with: go-version: ${{ matrix.go-version }} - name: Checkout code uses: actions/checkout@v3 - name: Coverage env: COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | go test -race -covermode atomic -coverprofile=profile.cov ./... GO111MODULE=off go get github.com/mattn/goveralls $(go env GOPATH)/bin/goveralls -coverprofile=profile.cov -service=github termenv-0.13.0/.github/workflows/lint-soft.yml 0000664 0000000 0000000 00000001173 14313030041 0021301 0 ustar 00root root 0000000 0000000 name: lint-soft on: push: pull_request: permissions: contents: read # Optional: allow read access to pull request. Use with `only-new-issues` option. pull-requests: read jobs: golangci: name: lint-soft runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: golangci-lint uses: golangci/golangci-lint-action@v3 with: # Optional: golangci-lint command line arguments. args: --config .golangci-soft.yml --issues-exit-code=0 # Optional: show only new issues if it's a pull request. The default value is `false`. only-new-issues: true termenv-0.13.0/.github/workflows/lint.yml 0000664 0000000 0000000 00000001101 14313030041 0020317 0 ustar 00root root 0000000 0000000 name: lint on: push: pull_request: permissions: contents: read # Optional: allow read access to pull request. Use with `only-new-issues` option. pull-requests: read jobs: golangci: name: lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: golangci-lint uses: golangci/golangci-lint-action@v3 with: # Optional: golangci-lint command line arguments. #args: # Optional: show only new issues if it's a pull request. The default value is `false`. only-new-issues: true termenv-0.13.0/.gitignore 0000664 0000000 0000000 00000000415 14313030041 0015230 0 ustar 00root root 0000000 0000000 # 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/ termenv-0.13.0/.golangci-soft.yml 0000664 0000000 0000000 00000001270 14313030041 0016575 0 ustar 00root root 0000000 0000000 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 termenv-0.13.0/.golangci.yml 0000664 0000000 0000000 00000000605 14313030041 0015625 0 ustar 00root root 0000000 0000000 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 termenv-0.13.0/LICENSE 0000664 0000000 0000000 00000002067 14313030041 0014252 0 ustar 00root root 0000000 0000000 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. termenv-0.13.0/README.md 0000664 0000000 0000000 00000037073 14313030041 0014531 0 ustar 00root root 0000000 0000000
`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() ``` ## 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() ``` ## Optional Feature Support | Terminal | Alt Screen | Query Color Scheme | Query Cursor Position | Set Window Title | Change Cursor Color | Change Default Foreground Setting | Change Default Background Setting | Copy (OSC52) | Hyperlinks (OSC8) | Bracketed Paste | | ---------------- | :--------: | :----------------: | :-------------------: | :--------------: | :-----------------: | :-------------------------------: | :-------------------------------: | :----------: | :---------------: | :-------------: | | alacritty | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌[^alacritty] | ✅ | | foot | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | kitty | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Konsole | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌[^konsole] | ✅ | ✅ | | rxvt | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | | urxvt | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅[^urxvt] | ❌ | ✅ | | screen | ✅ | ⛔[^mux] | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ❌[^screen] | ❌ | | st | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | | tmux | ✅ | ⛔[^mux] | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌[^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). [^mux]: Unavailable as multiplexers (like tmux or screen) can be connected to multiple terminals (with different color settings) at the same time. [^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). You can help improve this list! Check out [how to](ansi_compat.md) and open an issue or pull request. ### 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 ## 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) termenv-0.13.0/ansi_compat.md 0000664 0000000 0000000 00000001722 14313030041 0016061 0 ustar 00root root 0000000 0000000 ## 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 ``` termenv-0.13.0/ansicolors.go 0000664 0000000 0000000 00000006537 14313030041 0015756 0 ustar 00root root 0000000 0000000 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", } termenv-0.13.0/color.go 0000664 0000000 0000000 00000010434 14313030041 0014707 0 ustar 00root root 0000000 0000000 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(bg 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, "\a"): s = strings.TrimSuffix(s, "\a") case strings.HasSuffix(s, "\033"): s = strings.TrimSuffix(s, "\033") case strings.HasSuffix(s, "\033\\"): s = strings.TrimSuffix(s, "\033\\") 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) } termenv-0.13.0/color_test.go 0000664 0000000 0000000 00000002034 14313030041 0015743 0 ustar 00root root 0000000 0000000 package termenv import "testing" func TestXTermColor(t *testing.T) { var tests = []struct { input string color RGBColor valid bool }{ { "\033]11;rgb:fafa/fafa/fafa\033", RGBColor("#fafafa"), true, }, { "\033]11;rgb:fafa/fafa/fafa\033\\", RGBColor("#fafafa"), true, }, { "\033]11;rgb:1212/3434/5656\a", RGBColor("#123456"), true, }, { "\033]11;foo:fafa/fafa/fafaZZ", "", false, }, { "\033]11;rgb:fafa/fafa", "", false, }, { "\033]11;rgb:fafa/fafa/fafaY", "", false, }, { "\033]11;rgb:fafa/fafa/fafaZZ", "", false, }, } for _, test := range tests { t.Run("", func(t *testing.T) { color, err := xTermColor(test.input) if err != nil && test.valid { t.Fatalf("unexpected error for input %q: %v", test.input, err) } if err == nil && !test.valid { t.Fatalf("expected error for input %v not found", test.input) } if color != test.color { t.Fatalf("wrong color returned, want %v, got %v", test.color, color) } }) } } termenv-0.13.0/constants_linux.go 0000664 0000000 0000000 00000000155 14313030041 0017023 0 ustar 00root root 0000000 0000000 package termenv import "golang.org/x/sys/unix" const ( tcgetattr = unix.TCGETS tcsetattr = unix.TCSETS ) termenv-0.13.0/constants_solaris.go 0000664 0000000 0000000 00000000155 14313030041 0017340 0 ustar 00root root 0000000 0000000 package termenv import "golang.org/x/sys/unix" const ( tcgetattr = unix.TCGETS tcsetattr = unix.TCSETS ) termenv-0.13.0/constants_unix.go 0000664 0000000 0000000 00000000443 14313030041 0016647 0 ustar 00root root 0000000 0000000 //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 ) termenv-0.13.0/copy.go 0000664 0000000 0000000 00000000524 14313030041 0014542 0 ustar 00root root 0000000 0000000 package termenv import ( "github.com/aymanbagabas/go-osc52" ) // Copy copies text to clipboard using OSC 52 escape sequence. func (o Output) Copy(str string) { out := osc52.NewOutput(o.tty, o.environ.Environ()) out.Copy(str) } // Copy copies text to clipboard using OSC 52 escape sequence. func Copy(str string) { output.Copy(str) } termenv-0.13.0/examples/ 0000775 0000000 0000000 00000000000 14313030041 0015056 5 ustar 00root root 0000000 0000000 termenv-0.13.0/examples/color-chart/ 0000775 0000000 0000000 00000000000 14313030041 0017273 5 ustar 00root root 0000000 0000000 termenv-0.13.0/examples/color-chart/color-chart.png 0000664 0000000 0000000 00001310177 14313030041 0022230 0 ustar 00root root 0000000 0000000 PNG IHDR o gAMA a cHRM z&