mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 11:01:25 +01:00
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>
This commit is contained in:
1 parent
88b91faa54
commit
faea86cd94
27 files changed
+1941
-1
No files matched your search
@@ -0,0 +1,62 @@
|
||||
// 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\\"
|
||||
}
|
||||
Reference in new issue
Block a user