From 896c0f2f6e3870058e447d6cc0293a955836f681 Mon Sep 17 00:00:00 2001 From: Marc <12819635+LostInCompilation@users.noreply.github.com> Date: Fri, 31 Mar 2023 17:13:48 +0200 Subject: [PATCH] Casting and documentation fixes (#608) Add `-wDocumentation` option. Fix the documentation. Fix c++20/c++17 confusion in tests. Co-authored-by: ArthurSonzogni --- .clang-tidy | 4 +- cmake/ftxui_fuzzer.cmake | 23 +++++------ cmake/ftxui_set_options.cmake | 17 +++++++-- cmake/ftxui_test.cmake | 11 +++++- examples/CMakeLists.txt | 2 +- src/ftxui/component/component.cpp | 6 +-- src/ftxui/component/component_fuzzer.cpp | 3 +- src/ftxui/component/dropdown.cpp | 2 +- src/ftxui/component/hoverable.cpp | 14 +++---- src/ftxui/component/input.cpp | 10 ++--- src/ftxui/component/menu.cpp | 4 +- src/ftxui/component/resizable_split.cpp | 2 +- src/ftxui/component/slider.cpp | 2 +- src/ftxui/component/terminal_input_parser.cpp | 2 +- src/ftxui/dom/canvas.cpp | 38 +++++++++---------- src/ftxui/dom/flexbox_helper.cpp | 4 +- src/ftxui/dom/focus.cpp | 8 ++-- src/ftxui/dom/gauge.cpp | 10 ++--- src/ftxui/dom/gridbox.cpp | 6 +-- src/ftxui/dom/spinner.cpp | 4 +- src/ftxui/dom/table.cpp | 4 +- src/ftxui/screen/terminal.cpp | 2 +- 22 files changed, 96 insertions(+), 82 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 13847e6..cf1723d 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,5 +1,7 @@ --- Checks: "*, + -*-narrowing-conversions + -*-uppercase-literal-suffix, -abseil-*, -altera-*, -android-*, @@ -7,7 +9,6 @@ Checks: "*, -cppcoreguidelines-non-private-member-variables-in-classes, -fuchsia-*, -google-*, - -hicpp-uppercase-literal-suffix, -llvm*, -misc-no-recursion, -misc-non-private-member-variables-in-classes, @@ -19,7 +20,6 @@ Checks: "*, -readability-implicit-bool-conversion, -readability-non-const-parameter, -readability-static-accessed-through-instance, - -readability-uppercase-literal-suffix, -zircon-*, " WarningsAsErrors: '' diff --git a/cmake/ftxui_fuzzer.cmake b/cmake/ftxui_fuzzer.cmake index 5d5d516..8d92f7b 100644 --- a/cmake/ftxui_fuzzer.cmake +++ b/cmake/ftxui_fuzzer.cmake @@ -5,21 +5,18 @@ endif() set(CMAKE_C_COMPILER clang) set(CMAKE_CXX_COMPILER clang++) -function(fuzz name) +function(fuzz source) + set(name "ftxui-${source}") add_executable(${name} - src/ftxui/component/${name}.cpp + src/ftxui/component/${source}.cpp ) - target_include_directories(${name} - PRIVATE src - ) - target_link_libraries(${name} - PRIVATE component - ) - target_compile_options(${name} - PRIVATE -fsanitize=fuzzer,address - ) - target_link_libraries(${name} - PRIVATE -fsanitize=fuzzer,address + target_include_directories(${name} PRIVATE src) + target_link_libraries(${name} PRIVATE component) + target_compile_options(${name} PRIVATE -fsanitize=fuzzer,address) + target_link_libraries(${name} PRIVATE -fsanitize=fuzzer,address) + set_target_properties(${name} PROPERTIES + CXX_STANDARD 20 + CXX_EXTENSIONS OFF ) endfunction(fuzz) diff --git a/cmake/ftxui_set_options.cmake b/cmake/ftxui_set_options.cmake index d608980..31a2608 100644 --- a/cmake/ftxui_set_options.cmake +++ b/cmake/ftxui_set_options.cmake @@ -68,14 +68,25 @@ function(ftxui_set_options library) target_compile_definitions(${library} PRIVATE UNICODE _UNICODE) else() target_compile_options(${library} PRIVATE "-Wall") - target_compile_options(${library} PRIVATE "-Wextra") - target_compile_options(${library} PRIVATE "-pedantic") target_compile_options(${library} PRIVATE "-Werror") - target_compile_options(${library} PRIVATE "-Wmissing-declarations") + target_compile_options(${library} PRIVATE "-Wextra") + + target_compile_options(${library} PRIVATE "-Wcast-align") target_compile_options(${library} PRIVATE "-Wdeprecated") + target_compile_options(${library} PRIVATE "-Wmissing-declarations") + target_compile_options(${library} PRIVATE "-Wnon-virtual-dtor") + target_compile_options(${library} PRIVATE "-Wnull-dereference") + target_compile_options(${library} PRIVATE "-Woverloaded-virtual") + target_compile_options(${library} PRIVATE "-Wpedantic") target_compile_options(${library} PRIVATE "-Wshadow") + target_compile_options(${library} PRIVATE "-Wunused") endif() + if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + target_compile_options(${library} PRIVATE "-Wdocumentation") + endif() + + if (FTXUI_MICROSOFT_TERMINAL_FALLBACK) target_compile_definitions(${library} PRIVATE "FTXUI_MICROSOFT_TERMINAL_FALLBACK") diff --git a/cmake/ftxui_test.cmake b/cmake/ftxui_test.cmake index 456fcb8..5b62cb3 100644 --- a/cmake/ftxui_test.cmake +++ b/cmake/ftxui_test.cmake @@ -57,8 +57,15 @@ target_link_libraries(ftxui-tests target_include_directories(ftxui-tests PRIVATE src ) -ftxui_set_options(ftxui-tests) -target_compile_features(ftxui-tests PUBLIC cxx_std_20) +set_target_properties(ftxui-tests PROPERTIES + CXX_STANDARD 20 + CXX_EXTENSIONS OFF +) + +if (FTXUI_MICROSOFT_TERMINAL_FALLBACK) + target_compile_definitions(ftxui-tests + PRIVATE "FTXUI_MICROSOFT_TERMINAL_FALLBACK") +endif() include(GoogleTest) gtest_discover_tests(ftxui-tests diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 7882708..4660a6b 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -9,7 +9,7 @@ function(example name) file(RELATIVE_PATH dir ${EXAMPLES_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) set_property(GLOBAL APPEND PROPERTY FTXUI::EXAMPLES ${dir}/${name}) set_target_properties(ftxui_example_${name} PROPERTIES - CXX_STANDARD 20 + CXX_STANDARD 17 ) endfunction(example) diff --git a/src/ftxui/component/component.cpp b/src/ftxui/component/component.cpp index db83009..5d2c0aa 100644 --- a/src/ftxui/component/component.cpp +++ b/src/ftxui/component/component.cpp @@ -110,7 +110,7 @@ bool ComponentBase::OnEvent(Event event) { // NOLINT } /// @brief Called in response to an animation event. -/// @param animation_params the parameters of the animation +/// @param params the parameters of the animation /// The default implementation dispatch the event to every child. /// @ingroup component void ComponentBase::OnAnimation(animation::Params& params) { @@ -166,7 +166,7 @@ bool ComponentBase::Focused() const { /// @brief Make the |child| to be the "active" one. /// @param child the child to become active. /// @ingroup component -void ComponentBase::SetActiveChild(ComponentBase* /*child*/) {} +void ComponentBase::SetActiveChild([[maybe_unused]] ComponentBase* child) {} /// @brief Make the |child| to be the "active" one. /// @param child the child to become active. @@ -187,7 +187,7 @@ void ComponentBase::TakeFocus() { /// @brief Take the CapturedMouse if available. There is only one component of /// them. It represents a component taking priority over others. -/// @param event +/// @param event The event /// @ingroup component CapturedMouse ComponentBase::CaptureMouse(const Event& event) { // NOLINT if (event.screen_) { diff --git a/src/ftxui/component/component_fuzzer.cpp b/src/ftxui/component/component_fuzzer.cpp index ec34dec..3198a82 100644 --- a/src/ftxui/component/component_fuzzer.cpp +++ b/src/ftxui/component/component_fuzzer.cpp @@ -96,8 +96,7 @@ MenuOption GeneratorMenuOption(const char* data, size_t size) { MenuOption option; option.underline = GeneratorUnderlineOption(data, size); option.entries = GeneratorMenuEntryOption(data, size); - option.direction = - static_cast(GeneratorInt(data, size) % 4); + option.direction = static_cast(GeneratorInt(data, size) % 4); return option; } diff --git a/src/ftxui/component/dropdown.cpp b/src/ftxui/component/dropdown.cpp index 7f830d3..235d9ae 100644 --- a/src/ftxui/component/dropdown.cpp +++ b/src/ftxui/component/dropdown.cpp @@ -39,7 +39,7 @@ Component Dropdown(ConstStringListRef entries, int* selected) { } Element Render() override { - *selected_ = util::clamp(*selected_, 0, (int)entries_.size() - 1); + *selected_ = util::clamp(*selected_, 0, int(entries_.size()) - 1); title_ = entries_[static_cast(*selected_)]; if (show_) { const int max_height = 12; diff --git a/src/ftxui/component/hoverable.cpp b/src/ftxui/component/hoverable.cpp index 9360b9f..8a51271 100644 --- a/src/ftxui/component/hoverable.cpp +++ b/src/ftxui/component/hoverable.cpp @@ -26,8 +26,8 @@ void Post(std::function f) { /// @brief Wrap a component. Gives the ability to know if it is hovered by the /// mouse. -/// @param component: The wrapped component. -/// @param hover: The value to reflect whether the component is hovered or not. +/// @param component The wrapped component. +/// @param hover The value to reflect whether the component is hovered or not. /// @ingroup component /// /// ### Example @@ -68,10 +68,10 @@ Component Hoverable(Component component, bool* hover) { return Make(component, hover); } -/// @brief Wrap a component. Gives the ability to know if it is hovered by the -/// mouse. -/// @param component: The wrapped component. -/// @param hover: The value to reflect whether the component is hovered or not. +/// @brief Wrap a component. Uses callbacks. +/// @param component The wrapped component. +/// @param on_enter Callback OnEnter +/// @param on_leave Callback OnLeave /// @ingroup component /// /// ### Example @@ -126,7 +126,7 @@ Component Hoverable(Component component, /// @brief Wrap a component. Gives the ability to know if it is hovered by the /// mouse. -/// @param hover: The value to reflect whether the component is hovered or not. +/// @param hover The value to reflect whether the component is hovered or not. /// @ingroup component /// /// ### Example diff --git a/src/ftxui/component/input.cpp b/src/ftxui/component/input.cpp index 5abdaeb..c21bdd4 100644 --- a/src/ftxui/component/input.cpp +++ b/src/ftxui/component/input.cpp @@ -187,7 +187,7 @@ class InputBase : public ComponentBase { } if (event == Event::ArrowRight && - cursor_position() < (int)content_->size()) { + cursor_position() < static_cast(content_->size())) { cursor_position()++; return true; } @@ -242,7 +242,7 @@ class InputBase : public ComponentBase { void HandleRightCtrl() { auto properties = Utf8ToWordBreakProperty(*content_); - const int max = (int)properties.size(); + const int max = properties.size(); // Move right, as long as right is not a word character. while (cursor_position() < max && @@ -280,7 +280,7 @@ class InputBase : public ComponentBase { size_t original_cell = 0; for (size_t i = 0; i < mapping.size(); i++) { if (mapping[i] == original_glyph) { - original_cell = (int)i; + original_cell = i; break; } } @@ -289,8 +289,8 @@ class InputBase : public ComponentBase { } const int target_cell = int(original_cell) + event.mouse().x - cursor_box_.x_min; - int target_glyph = target_cell < (int)mapping.size() ? mapping[target_cell] - : (int)mapping.size(); + int target_glyph = target_cell < int(mapping.size()) ? mapping[target_cell] + : int(mapping.size()); target_glyph = util::clamp(target_glyph, 0, GlyphCount(*content_)); if (cursor_position() != target_glyph) { cursor_position() = target_glyph; diff --git a/src/ftxui/component/menu.cpp b/src/ftxui/component/menu.cpp index 2bca92e..03495bb 100644 --- a/src/ftxui/component/menu.cpp +++ b/src/ftxui/component/menu.cpp @@ -356,7 +356,7 @@ class MenuBase : public ComponentBase { } void UpdateColorTarget() { - if (size() != (int)animation_background_.size()) { + if (size() != int(animation_background_.size())) { animation_background_.resize(size()); animation_foreground_.resize(size()); animator_background_.clear(); @@ -518,7 +518,7 @@ Component Menu(ConstStringListRef entries, /// @brief An horizontal list of elements. The user can navigate through them. /// @param entries The list of selectable entries to display. /// @param selected Reference the selected entry. -/// @param See also |Menu|. +/// See also |Menu|. /// @ingroup component Component Toggle(ConstStringListRef entries, int* selected) { return Menu(entries, selected, MenuOption::Toggle()); diff --git a/src/ftxui/component/resizable_split.cpp b/src/ftxui/component/resizable_split.cpp index 3630d7c..98c5ba2 100644 --- a/src/ftxui/component/resizable_split.cpp +++ b/src/ftxui/component/resizable_split.cpp @@ -135,7 +135,7 @@ class ResizableSplitBase : public ComponentBase { } // namespace /// @brief A split in between two components. -/// @param options: all the parameters. +/// @param options all the parameters. /// /// ### Example /// diff --git a/src/ftxui/component/slider.cpp b/src/ftxui/component/slider.cpp index 8ae3336..dc90148 100644 --- a/src/ftxui/component/slider.cpp +++ b/src/ftxui/component/slider.cpp @@ -309,7 +309,7 @@ Component Slider(ConstStringRef label, } /// @brief A slider in any direction. -/// @param option The options +/// @param options The options /// ### Example /// /// ```cpp diff --git a/src/ftxui/component/terminal_input_parser.cpp b/src/ftxui/component/terminal_input_parser.cpp index 4742818..a77d843 100644 --- a/src/ftxui/component/terminal_input_parser.cpp +++ b/src/ftxui/component/terminal_input_parser.cpp @@ -51,7 +51,7 @@ unsigned char TerminalInputParser::Current() { bool TerminalInputParser::Eat() { position_++; - return position_ < (int)pending_.size(); + return position_ < static_cast(pending_.size()); } void TerminalInputParser::Send(TerminalInputParser::Output output) { diff --git a/src/ftxui/dom/canvas.cpp b/src/ftxui/dom/canvas.cpp index 327b17e..5270ad9 100644 --- a/src/ftxui/dom/canvas.cpp +++ b/src/ftxui/dom/canvas.cpp @@ -321,11 +321,11 @@ void Canvas::DrawPointEllipse(int x, } /// @brief Draw an ellipse made of braille dots. -/// @param x the x coordinate of the center of the ellipse. -/// @param y the y coordinate of the center of the ellipse. +/// @param x1 the x coordinate of the center of the ellipse. +/// @param y1 the y coordinate of the center of the ellipse. /// @param r1 the radius of the ellipse along the x axis. /// @param r2 the radius of the ellipse along the y axis. -/// @param style the style of the ellipse. +/// @param s the style of the ellipse. void Canvas::DrawPointEllipse(int x1, int y1, int r1, @@ -361,8 +361,8 @@ void Canvas::DrawPointEllipse(int x1, } /// @brief Draw a filled ellipse made of braille dots. -/// @param x the x coordinate of the center of the ellipse. -/// @param y the y coordinate of the center of the ellipse. +/// @param x1 the x coordinate of the center of the ellipse. +/// @param y1 the y coordinate of the center of the ellipse. /// @param r1 the radius of the ellipse along the x axis. /// @param r2 the radius of the ellipse along the y axis. void Canvas::DrawPointEllipseFilled(int x1, int y1, int r1, int r2) { @@ -370,8 +370,8 @@ void Canvas::DrawPointEllipseFilled(int x1, int y1, int r1, int r2) { } /// @brief Draw a filled ellipse made of braille dots. -/// @param x the x coordinate of the center of the ellipse. -/// @param y the y coordinate of the center of the ellipse. +/// @param x1 the x coordinate of the center of the ellipse. +/// @param y1 the y coordinate of the center of the ellipse. /// @param r1 the radius of the ellipse along the x axis. /// @param r2 the radius of the ellipse along the y axis. /// @param color the color of the ellipse. @@ -385,11 +385,11 @@ void Canvas::DrawPointEllipseFilled(int x1, } /// @brief Draw a filled ellipse made of braille dots. -/// @param x the x coordinate of the center of the ellipse. -/// @param y the y coordinate of the center of the ellipse. +/// @param x1 the x coordinate of the center of the ellipse. +/// @param y1 the y coordinate of the center of the ellipse. /// @param r1 the radius of the ellipse along the x axis. /// @param r2 the radius of the ellipse along the y axis. -/// @param style the style of the ellipse. +/// @param s the style of the ellipse. void Canvas::DrawPointEllipseFilled(int x1, int y1, int r1, @@ -410,11 +410,11 @@ void Canvas::DrawPointEllipseFilled(int x1, e2 = 2 * err; if (e2 >= dx) { x++; - err += dx += 2 * (long)r2 * r2; // NOLINT + err += dx += 2 * r2 * r2; } if (e2 <= dy) { y++; - err += dy += 2 * (long)r1 * r1; // NOLINT + err += dy += 2 * r1 * r1; } } while (x <= 0); @@ -631,7 +631,7 @@ void Canvas::DrawBlockCircleFilled(int x, /// @param x the x coordinate of the center of the circle. /// @param y the y coordinate of the center of the circle. /// @param radius the radius of the circle. -/// @param style the style of the circle. +/// @param s the style of the circle. void Canvas::DrawBlockCircleFilled(int x, int y, int radius, @@ -664,11 +664,11 @@ void Canvas::DrawBlockEllipse(int x, } /// @brief Draw an ellipse made of block characters. -/// @param x the x coordinate of the center of the ellipse. -/// @param y the y coordinate of the center of the ellipse. +/// @param x1 the x coordinate of the center of the ellipse. +/// @param y1 the y coordinate of the center of the ellipse. /// @param r1 the radius of the ellipse along the x axis. /// @param r2 the radius of the ellipse along the y axis. -/// @param style the style of the ellipse. +/// @param s the style of the ellipse. void Canvas::DrawBlockEllipse(int x1, int y1, int r1, @@ -730,11 +730,11 @@ void Canvas::DrawBlockEllipseFilled(int x, } /// @brief Draw a filled ellipse made of block characters. -/// @param x the x coordinate of the center of the ellipse. -/// @param y the y coordinate of the center of the ellipse. +/// @param x1 the x coordinate of the center of the ellipse. +/// @param y1 the y coordinate of the center of the ellipse. /// @param r1 the radius of the ellipse along the x axis. /// @param r2 the radius of the ellipse along the y axis. -/// @param style the style of the ellipse. +/// @param s the style of the ellipse. void Canvas::DrawBlockEllipseFilled(int x1, int y1, int r1, diff --git a/src/ftxui/dom/flexbox_helper.cpp b/src/ftxui/dom/flexbox_helper.cpp index d3b71fc..bb55726 100644 --- a/src/ftxui/dom/flexbox_helper.cpp +++ b/src/ftxui/dom/flexbox_helper.cpp @@ -328,8 +328,8 @@ void Compute3(Global& global) { line = Line(); } - block.line = (int)lines.size(); - block.line_position = (int)line.blocks.size(); + block.line = lines.size(); + block.line_position = line.blocks.size(); line.blocks.push_back(&block); x += block.min_size_x + global.config.gap_x; } diff --git a/src/ftxui/dom/focus.cpp b/src/ftxui/dom/focus.cpp index dbc6d97..5294eca 100644 --- a/src/ftxui/dom/focus.cpp +++ b/src/ftxui/dom/focus.cpp @@ -36,10 +36,10 @@ Decorator focusPositionRelative(float x, float y) { requirement_.selection = Requirement::Selection::NORMAL; Box& box = requirement_.selected_box; - box.x_min = (int)((float)requirement_.min_x * x_); - box.y_min = (int)((float)requirement_.min_y * y_); - box.x_max = (int)((float)requirement_.min_x * x_); - box.y_max = (int)((float)requirement_.min_y * y_); + box.x_min = int(float(requirement_.min_x) * x_); + box.y_min = int(float(requirement_.min_y) * y_); + box.x_max = int(float(requirement_.min_x) * x_); + box.y_max = int(float(requirement_.min_y) * y_); } private: diff --git a/src/ftxui/dom/gauge.cpp b/src/ftxui/dom/gauge.cpp index 304b9e4..5d7c714 100644 --- a/src/ftxui/dom/gauge.cpp +++ b/src/ftxui/dom/gauge.cpp @@ -99,9 +99,9 @@ class Gauge : public Node { // Draw the progress bar horizontally. { const float progress = invert ? 1.F - progress_ : progress_; - const float limit = - (float)box_.x_min + progress * (float)(box_.x_max - box_.x_min + 1); - const int limit_int = (int)limit; + const auto limit = + float(box_.x_min) + progress * float(box_.x_max - box_.x_min + 1); + const int limit_int = static_cast(limit); int x = box_.x_min; while (x < limit_int) { screen.at(x++, y) = charset_horizontal[9]; // NOLINT @@ -130,8 +130,8 @@ class Gauge : public Node { { const float progress = invert ? progress_ : 1.F - progress_; const float limit = - (float)box_.y_min + progress * (float)(box_.y_max - box_.y_min + 1); - const int limit_int = (int)limit; + float(box_.y_min) + progress * float(box_.y_max - box_.y_min + 1); + const int limit_int = static_cast(limit); int y = box_.y_min; while (y < limit_int) { screen.at(x, y++) = charset_vertical[8]; // NOLINT diff --git a/src/ftxui/dom/gridbox.cpp b/src/ftxui/dom/gridbox.cpp index 6580110..7acbc63 100644 --- a/src/ftxui/dom/gridbox.cpp +++ b/src/ftxui/dom/gridbox.cpp @@ -33,12 +33,12 @@ int Integrate(std::vector& elements) { class GridBox : public Node { public: explicit GridBox(std::vector lines) : lines_(std::move(lines)) { - y_size = (int)lines_.size(); + y_size = lines_.size(); for (const auto& line : lines_) { - x_size = std::max(x_size, (int)line.size()); + x_size = std::max(x_size, int(line.size())); } for (auto& line : lines_) { - while (line.size() < (size_t)x_size) { + while (line.size() < size_t(x_size)) { line.push_back(filler()); } } diff --git a/src/ftxui/dom/spinner.cpp b/src/ftxui/dom/spinner.cpp index 387a2ac..4f1d350 100644 --- a/src/ftxui/dom/spinner.cpp +++ b/src/ftxui/dom/spinner.cpp @@ -286,8 +286,8 @@ Element spinner(int charset_index, size_t image_index) { } return gauge(float(image_index) * 0.05F); // NOLINT } - charset_index %= (int)elements.size(); - image_index %= (int)elements[charset_index].size(); + charset_index %= int(elements.size()); + image_index %= int(elements[charset_index].size()); std::vector lines; for (const auto& it : elements[charset_index][image_index]) { lines.push_back(text(it)); diff --git a/src/ftxui/dom/table.cpp b/src/ftxui/dom/table.cpp index 4de41ac..e6b77d2 100644 --- a/src/ftxui/dom/table.cpp +++ b/src/ftxui/dom/table.cpp @@ -59,10 +59,10 @@ Table::Table(std::vector> input) { } void Table::Initialize(std::vector> input) { - input_dim_y_ = (int)input.size(); + input_dim_y_ = input.size(); input_dim_x_ = 0; for (auto& row : input) { - input_dim_x_ = std::max(input_dim_x_, (int)row.size()); + input_dim_x_ = std::max(input_dim_x_, int(row.size())); } dim_y_ = 2 * input_dim_y_ + 1; diff --git a/src/ftxui/screen/terminal.cpp b/src/ftxui/screen/terminal.cpp index 368212d..a43cab1 100644 --- a/src/ftxui/screen/terminal.cpp +++ b/src/ftxui/screen/terminal.cpp @@ -73,7 +73,7 @@ Terminal::Color ComputeColorSupport() { // colors: https://github.com/microsoft/terminal/issues/1040 // As a fallback, assume microsoft terminal are the ones not setting those // variables, and enable true colors. - if (TERM == "" && COLORTERM == "") { + if (TERM.empty() && COLORTERM.empty()) { return Terminal::Color::TrueColor; } #endif