`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
```
…
```
## Screen
```
…
```
## 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
```
…
```
## Bracketed Paste
```go
// Enables bracketed paste mode
termenv.EnableBracketedPaste()
// Disables bracketed paste mode
termenv.DisableBracketedPaste()
```
## Terminal Feature Support
### Color Support
- 24-bit (RGB): alacritty, foot, iTerm, kitty, Konsole, st, tmux, vte-based, wezterm, Ghostty, Windows Terminal
- 8-bit (256): rxvt, screen, xterm, Apple Terminal
- 4-bit (16): Linux Console
### Control Sequences
Click to show feature matrix
| 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.
### System Commands
Click to show feature matrix
| 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 | ❌ | ❌ | ❌