FTXUI 6.1.9
C++ functional terminal UI.
Loading...
Searching...
No Matches
terminal.cpp
Go to the documentation of this file.
1// Copyright 2020 Arthur Sonzogni. All rights reserved.
2// Use of this source code is governed by the MIT license that can be found in
3// the LICENSE file.
4#include <algorithm> // for std::search
5#include <cctype> // for std::tolower
6#include <cstdlib> // for getenv
7#include <initializer_list>
8#include <string_view> // for string_view
9
11
12#if defined(_WIN32)
13#define WIN32_LEAN_AND_MEAN
14
15#ifndef NOMINMAX
16#define NOMINMAX
17#endif
18
19#include <windows.h>
20#else
21#include <sys/ioctl.h> // for winsize, ioctl, TIOCGWINSZ
22#include <unistd.h> // for STDOUT_FILENO
23#endif
24
25namespace ftxui {
26
27namespace {
28
29bool g_color_support_detected = false; // NOLINT
30Terminal::Quirks g_quirks = [] { // NOLINT
31 Terminal::Quirks quirks;
32#if defined(_WIN32)
33 quirks.block_characters = false;
34 quirks.cursor_hiding = false;
35 quirks.component_ascii = true;
36#endif
37 return quirks;
38}();
39
40Dimensions& FallbackSize() {
41#if defined(__EMSCRIPTEN__)
42 // This dimension was chosen arbitrarily to be able to display:
43 // https://arthursonzogni.com/FTXUI/examples
44 // This will have to be improved when someone has time to implement and need
45 // it.
46 constexpr int fallback_width = 140;
47 constexpr int fallback_height = 43;
48#else
49 // The terminal size in VT100 was 80x24. It is still used nowadays by
50 // default in many terminal emulator. That's a good choice for a fallback
51 // value.
52 constexpr int fallback_width = 80;
53 constexpr int fallback_height = 24;
54#endif
55 static Dimensions g_fallback_size{
56 fallback_width,
57 fallback_height,
58 };
59 return g_fallback_size;
60}
61
62const char* Safe(const char* c) {
63 return (c != nullptr) ? c : "";
64}
65
66bool Contains(std::string_view s, std::string_view key) {
67 if (key.empty()) {
68 return true;
69 }
70 const auto it = std::search( // NOLINT
71 s.begin(), s.end(), key.begin(), key.end(), [](char a, char b) {
72 return std::tolower(static_cast<unsigned char>(a)) ==
73 std::tolower(static_cast<unsigned char>(b));
74 });
75 return it != s.end();
76}
77
78bool ContainsAny(std::string_view s,
79 std::initializer_list<std::string_view> keys) {
80 for (const std::string_view key : keys) {
81 if (Contains(s, key)) {
82 return true;
83 }
84 }
85 return false;
86}
87
88Terminal::Color ComputeColorSupport() {
89#if defined(__EMSCRIPTEN__)
91#endif
92
93 std::string_view COLORTERM = Safe(std::getenv("COLORTERM")); // NOLINT
94 if (ContainsAny(COLORTERM, {"24bit", "truecolor"})) {
96 }
97
98 std::string_view TERM_PROGRAM = Safe(std::getenv("TERM_PROGRAM")); // NOLINT
99 if (ContainsAny(TERM_PROGRAM, {"iterm", "apple_terminal", "vscode", "warp",
100 "ghostty", "wezterm"})) {
102 }
103
104 std::string_view TERM = Safe(std::getenv("TERM")); // NOLINT
105 if (ContainsAny(TERM,
106 {"direct", "truecolor", "kitty", "alacritty", "foot"})) {
108 }
109
110 if (Contains(TERM, "xterm") && !ContainsAny(TERM, {"rxvt", "urxvt"})) {
112 }
113
114 if (ContainsAny(COLORTERM, {"256"}) ||
115 ContainsAny(TERM, {"256", "xterm", "screen", "tmux"}) ||
116 Contains(TERM_PROGRAM, "iterm")) {
118 }
119
121}
122
123} // namespace
124
125namespace Terminal {
126
127/// @brief Get the terminal size.
128/// @return The terminal size.
129/// @ingroup screen
131#if defined(__EMSCRIPTEN__)
132 // This dimension was chosen arbitrarily to be able to display:
133 // https://arthursonzogni.com/FTXUI/examples
134 // This will have to be improved when someone has time to implement and need
135 // it.
136 return FallbackSize();
137#elif defined(_WIN32)
138 CONSOLE_SCREEN_BUFFER_INFO csbi;
139
140 if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) {
141 return Dimensions{csbi.srWindow.Right - csbi.srWindow.Left + 1,
142 csbi.srWindow.Bottom - csbi.srWindow.Top + 1};
143 }
144
145 return FallbackSize();
146#else
147 winsize w{};
148 const int status = ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); // NOLINT
149 // The ioctl return value result should be checked. Some operating systems
150 // don't support TIOCGWINSZ.
151 if (w.ws_col == 0 || w.ws_row == 0 || status < 0) {
152 return FallbackSize();
153 }
154 return Dimensions{w.ws_col, w.ws_row};
155#endif
156}
157
158/// @brief Override terminal size in case auto-detection fails
159/// @param fallbackSize Terminal dimensions to fallback to
160void SetFallbackSize(const Dimensions& fallbackSize) {
161 FallbackSize() = fallbackSize;
162}
163
164/// @brief Get the color support of the terminal.
165/// @ingroup screen
167 if (!g_color_support_detected) {
168 g_quirks.color_support = ComputeColorSupport();
169 g_color_support_detected = true;
170 }
171 return g_quirks.color_support;
172}
173
174/// @brief Override terminal color support in case auto-detection fails
175/// @ingroup dom
177 g_quirks.color_support = color;
178 g_color_support_detected = true;
179}
180
181/// @brief Get the terminal quirks.
182/// @ingroup screen
184 if (!g_color_support_detected) {
185 g_quirks.color_support = ComputeColorSupport();
186 g_color_support_detected = true;
187 }
188 return g_quirks;
189}
190
191/// @brief Override terminal quirks.
192/// @ingroup screen
193void SetQuirks(const Quirks& quirks) {
194 g_quirks = quirks;
195 g_color_support_detected = true;
196}
197
198} // namespace Terminal
199} // namespace ftxui
void SetColorSupport(Color color)
Override terminal color support in case auto-detection fails.
Definition terminal.cpp:176
Decorator color(Color)
Decorate using a foreground color.
Color
Color is an enumeration that represents the color support of the terminal.
Definition terminal.hpp:23
Quirks GetQuirks()
Get the terminal quirks.
Definition terminal.cpp:183
Dimensions Size()
Get the terminal size.
Definition terminal.cpp:130
Color ColorSupport()
Get the color support of the terminal.
Definition terminal.cpp:166
void SetQuirks(const Quirks &quirks)
Override terminal quirks.
Definition terminal.cpp:193
Dimensions is a structure that represents the size of the terminal.
Definition terminal.hpp:11
Quirks is a structure that represents various terminal-specific behaviors that may require fallbacks.
Definition terminal.hpp:35
The FTXUI ftxui::Terminal:: namespace.
void SetFallbackSize(const Dimensions &fallbackSize)
Override terminal size in case auto-detection fails.
Definition terminal.cpp:160
The FTXUI ftxui:: namespace.
Definition animation.hpp:10