// Frontend: Functions for terminal output // SPDX-License-Identifier: GPL-3.0-or-later // Copyright (C) 2021-2024 Simon Ruderich package frontend import ( "fmt" "regexp" ) type Color int const ( _ Color = iota ColorRed ColorGreen ColorCyan ColorMagenta ) func ColorString(isTTY bool, color Color, x string) string { if !isTTY { return x } var code string switch color { case ColorRed: code = "31" case ColorGreen: code = "32" case ColorMagenta: code = "35" case ColorCyan: code = "36" default: panic(fmt.Sprintf("invalid color %v", color)) } // TODO: check terminal support return "\033[" + code + "m" + x + "\033[0m" } var escapeRegexp = regexp.MustCompile(`[\x00-\x08\x0B-\x1F\x7F]`) // EscapeControlCharacters escapes all ASCII control characters (except // newline and tab) by replacing them with their hex value. If the output is // to a TTY then the escaped characters are colored. // // This function must be used when displaying any input from remote hosts to // prevent terminal escape code injections. func EscapeControlCharacters(isTTY bool, x string) string { return escapeRegexp.ReplaceAllStringFunc(x, func(x string) string { if len(x) != 1 { panic("invalid escapeRegexp") } if x == "\r" { x = "\\r" // occurs often and more readable than \x0D } else { x = fmt.Sprintf("\\x%02X", x[0]) } return ColorString(isTTY, ColorMagenta, x) }) }