Files
gitea-tea/internal/terminal/color.go
T
bircni faea86cd94 refactor: add terminal output and forms package (#1124)
- `internal/terminal`: streams and the prompting policy, interactive forms (issue, PR, review, merge, milestone), editor / pager / browser launching, JSON and `--jq` output.
- An aligned table renderer and a record renderer for human output; both strip control and escape characters from server-supplied text so titles and bodies cannot inject terminal sequences.

Reviewed-on: https://gitea.com/gitea/tea/pulls/1124
Reviewed-by: TheFox0x7 <95654+thefox0x7@noreply.gitea.com>
2026-10-11 17:12:23 +00:00

63 lines
1.8 KiB
Go

// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package terminal
import (
"fmt"
"strconv"
"strings"
"unicode"
)
// ColorEnabled resolves the color preference against terminal and environment policy.
// auto colors TTY stdout unless NO_COLOR is set or TERM is dumb; always forces color; never disables it.
func ColorEnabled(preference string, outTTY bool, getenv func(string) string) bool {
switch preference {
case "always":
return true
case "never":
return false
default: // auto and unknown fall back to terminal detection
if getenv != nil && (getenv("NO_COLOR") != "" || getenv("TERM") == "dumb") {
return false
}
return outTTY
}
}
// Colorize applies a 24-bit foreground color from a six-digit RGB hex value.
func Colorize(hex, text string, enabled bool) string {
if !enabled || text == "" {
return text
}
hex = strings.TrimPrefix(strings.TrimSpace(hex), "#")
if len(hex) != 6 {
return text
}
r, errR := strconv.ParseUint(hex[0:2], 16, 8)
g, errG := strconv.ParseUint(hex[2:4], 16, 8)
b, errB := strconv.ParseUint(hex[4:6], 16, 8)
if errR != nil || errG != nil || errB != nil {
return text
}
return fmt.Sprintf("\x1b[38;2;%d;%d;%dm%s\x1b[0m", r, g, b, text)
}
// Emphasis applies simple bold styling for TTY human tables.
func Emphasis(text string, enabled bool) string {
if !enabled || text == "" {
return text
}
return "\x1b[1m" + text + "\x1b[0m"
}
// Hyperlink wraps text in an OSC 8 terminal hyperlink to url. URLs with control
// characters are left unlinked so server data cannot inject escape sequences.
func Hyperlink(url, text string, enabled bool) string {
if !enabled || url == "" || text == "" || strings.ContainsFunc(url, unicode.IsControl) {
return text
}
return "\x1b]8;;" + url + "\x1b\\" + text + "\x1b]8;;\x1b\\"
}