29 static const std::vector<std::string_view> basic_color_term{
30 "xterm",
"vt100",
"color",
"ansi",
"cygwin",
"linux"};
35 static const std::vector<std::string_view> ansi256_color_term{
"xterm-256",
"xterm-256color"};
40 static const std::vector<std::string_view> truecolor_term{
41 "xterm-truecolor",
"xterm-direct",
"xterm-kitty",
"alacritty"};
48 bool string_contains_ci(std::string_view haystack, std::string_view needle) {
49 if (needle.size() > haystack.size()) {
52 for (
size_t i = 0; i + needle.size() <= haystack.size(); ++i) {
54 for (
size_t j = 0; j < needle.size(); ++j) {
55 if (std::tolower(
static_cast<unsigned char>(haystack[i + j]))
56 != std::tolower(
static_cast<unsigned char>(needle[j]))) {
73 bool contains_utf8_marker(std::string_view value) {
74 return string_contains_ci(value,
"utf-8") || string_contains_ci(value,
"utf8");
88 return contains_utf8_marker(*vars.lc_all);
91 return contains_utf8_marker(*vars.lc_ctype);
94 return contains_utf8_marker(*vars.LANG);
101namespace sham::term {
105 if (vars.COLORTERM) {
106 if (*vars.COLORTERM ==
"truecolor" || *vars.COLORTERM ==
"24bit") {
112 for (
auto term : truecolor_term) {
113 if (*vars.TERM == term) {
117 for (
auto term : ansi256_color_term) {
118 if (*vars.TERM == term) {
122 for (
auto term : basic_color_term) {
123 if (*vars.TERM == term) {
135 bool has_envvar_nocolor = bool(vars.NO_COLOR);
136 bool has_envvar_color = bool(vars.CLICOLOR_FORCE);
138 if (has_envvar_color && has_envvar_nocolor) {
139 throw error_callback(
140 "one can not set both NO_COLOR and CLICOLOR_FORCE",
141 std::source_location::current());
144 if (has_envvar_nocolor) {
148 if (has_envvar_color) {
154 bool has_envvar_no_utf8 = bool(vars.NO_UTF8);
155 bool has_envvar_force_utf8 = bool(vars.FORCE_UTF8);
157 if (has_envvar_no_utf8 && has_envvar_force_utf8) {
158 throw error_callback(
159 "one can not set both NO_UTF8 and FORCE_UTF8", std::source_location::current());
162 if (has_envvar_no_utf8) {
166 if (has_envvar_force_utf8) {
170 auto &res = vars.COLUMN;
175 int val = std::stoi(std::string(*res));
180 }
catch (
const std::invalid_argument &a) {
181 throw error_callback(
182 "Error : COLUMN is not an integer", std::source_location::current());
183 }
catch (
const std::out_of_range &a) {
184 throw error_callback(
185 "Error : COLUMN is out of range", std::source_location::current());
Terminal color escape sequences and enable/disable control.
ColorLevel
The possible levels of terminal color support.
@ TrueColor
24-bit RGB truecolor, \x1b[38;2;r;g;bm.
@ NoColor
No color support, plain ASCII output only.
@ Basic
ANSI/16 colors (basic SGR codes), \x1b[3Xm.
@ ANSI256
256-color palette (16 ANSI + 216-color cube + 24 grayscale), \x1b[38;5;Nm.
void set_color_level(ColorLevel level)
Set the terminal color support level.
void enable_colors()
Enable colors.
void disable_colors()
Disable all colors.
std::function< std::invalid_argument(const char *what, std::source_location where)> term_parse_callback_t
Callback signature for parsing error reporting (returns what, receives source location).
Environment variable parsing for terminal color, size and UTF-8 support configuration (TERM,...
void parse_terminal_support(TermEnvVars vars, const term_parse_callback_t &error_callback)
Parses terminal environment variables to determine color support and set terminal size.
ColorLevel detect_color_level(TermEnvVars vars)
Detect the terminal emulator's color support level from TERM/COLORTERM.
Holds optional terminal environment variables (TERM, COLORTERM, NO_COLOR, CLICOLOR_FORCE,...
This file contains tty info getters.
void set_tty_columns(int columns)
Set the forced width of the terminal.
void set_support_utf8(bool support)
Set whether the current terminal/locale supports UTF-8 output.