[tint][utils] Add light theme, detect dark / light
Add a new tint `--color` command line flag to explicitly control color
output and theme.
Change-Id: I54bbdf8ecb86dfdd0c74e020b2858a81850a6102
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/176120
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/cmd/common/helper.cc b/src/tint/cmd/common/helper.cc
index 2e9ce37..a1fbaf0 100644
--- a/src/tint/cmd/common/helper.cc
+++ b/src/tint/cmd/common/helper.cc
@@ -269,9 +269,13 @@
PrintWGSL(std::cout, info.program);
}
- auto printer = tint::StyledTextPrinter::Create(stderr);
tint::diag::Formatter formatter;
- printer->Print(formatter.Format(info.program.Diagnostics()));
+ if (opts.printer) {
+ opts.printer->Print(formatter.Format(info.program.Diagnostics()));
+ } else {
+ tint::StyledTextPrinter::Create(stderr)->Print(
+ formatter.Format(info.program.Diagnostics()));
+ }
}
if (!info.program.IsValid()) {
diff --git a/src/tint/cmd/common/helper.h b/src/tint/cmd/common/helper.h
index 04e6961..dbc8e38 100644
--- a/src/tint/cmd/common/helper.h
+++ b/src/tint/cmd/common/helper.h
@@ -82,6 +82,8 @@
bool use_ir = false;
tint::spirv::reader::Options spirv_reader_options;
#endif
+ /// The text printer to use for output
+ StyledTextPrinter* printer = nullptr;
};
/// Loads the source and program information for the given file.
diff --git a/src/tint/cmd/tint/BUILD.bazel b/src/tint/cmd/tint/BUILD.bazel
index d77264b..bdba7b0 100644
--- a/src/tint/cmd/tint/BUILD.bazel
+++ b/src/tint/cmd/tint/BUILD.bazel
@@ -76,6 +76,7 @@
"//src/tint/utils/rtti",
"//src/tint/utils/strconv",
"//src/tint/utils/symbol",
+ "//src/tint/utils/system",
"//src/tint/utils/text",
"//src/tint/utils/traits",
] + select({
diff --git a/src/tint/cmd/tint/BUILD.cmake b/src/tint/cmd/tint/BUILD.cmake
index f354d49..8ed82d1 100644
--- a/src/tint/cmd/tint/BUILD.cmake
+++ b/src/tint/cmd/tint/BUILD.cmake
@@ -77,6 +77,7 @@
tint_utils_rtti
tint_utils_strconv
tint_utils_symbol
+ tint_utils_system
tint_utils_text
tint_utils_traits
)
diff --git a/src/tint/cmd/tint/BUILD.gn b/src/tint/cmd/tint/BUILD.gn
index e51fbf4..7f3584f 100644
--- a/src/tint/cmd/tint/BUILD.gn
+++ b/src/tint/cmd/tint/BUILD.gn
@@ -76,6 +76,7 @@
"${tint_src_dir}/utils/rtti",
"${tint_src_dir}/utils/strconv",
"${tint_src_dir}/utils/symbol",
+ "${tint_src_dir}/utils/system",
"${tint_src_dir}/utils/text",
"${tint_src_dir}/utils/traits",
]
diff --git a/src/tint/cmd/tint/main.cc b/src/tint/cmd/tint/main.cc
index f4913a9..5a11673 100644
--- a/src/tint/cmd/tint/main.cc
+++ b/src/tint/cmd/tint/main.cc
@@ -57,6 +57,8 @@
#include "src/tint/utils/containers/transform.h"
#include "src/tint/utils/diagnostic/formatter.h"
#include "src/tint/utils/macros/defer.h"
+#include "src/tint/utils/system/env.h"
+#include "src/tint/utils/system/terminal.h"
#include "src/tint/utils/text/string.h"
#include "src/tint/utils/text/string_stream.h"
#include "src/tint/utils/text/styled_text.h"
@@ -151,9 +153,14 @@
constexpr uint32_t kMinShaderModelForPackUnpack4x8InHLSL = 66u;
#endif // TINT_BUILD_HLSL_WRITER
+/// An enumerator of color-output modes
+enum class ColorMode { kPlain, kDark, kLight };
+
struct Options {
bool verbose = false;
+ std::unique_ptr<tint::StyledTextPrinter> printer;
+
std::string input_filename;
std::string output_file = "-"; // Default to stdout
@@ -209,9 +216,38 @@
#endif // TINT_BUILD_SYNTAX_TREE_WRITER
};
+/// @returns the default ColorMode when no `--color` flag is specified.
+ColorMode ColorModeDefault() {
+ if (!tint::TerminalSupportsColors(stdout)) {
+ return ColorMode::kPlain;
+ }
+ if (auto res = tint::TerminalIsDark(stdout)) {
+ return *res ? ColorMode::kDark : ColorMode::kLight;
+ }
+ if (auto env = tint::GetEnvVar("DARK_BACKGROUND_COLOR"); !env.empty()) {
+ return env != "0" ? ColorMode::kDark : ColorMode::kLight;
+ }
+ if (auto env = tint::GetEnvVar("LIGHT_BACKGROUND_COLOR"); !env.empty()) {
+ return env != "0" ? ColorMode::kLight : ColorMode::kDark;
+ }
+ return ColorMode::kDark;
+}
+
+std::unique_ptr<tint::StyledTextPrinter> CreatePrinter(ColorMode mode) {
+ switch (mode) {
+ case ColorMode::kLight:
+ return tint::StyledTextPrinter::Create(stderr, tint::StyledTextTheme::kDefaultLight);
+ case ColorMode::kDark:
+ return tint::StyledTextPrinter::Create(stderr, tint::StyledTextTheme::kDefaultDark);
+ case ColorMode::kPlain:
+ break;
+ }
+ return tint::StyledTextPrinter::CreatePlain(stderr);
+}
+
/// @param filename the filename to inspect
/// @returns the inferred format for the filename suffix
-Format infer_format(const std::string& filename) {
+Format InferFormat(const std::string& filename) {
(void)filename;
#if TINT_BUILD_SPV_WRITER
@@ -272,6 +308,15 @@
format_enum_names, ShortName{"f"});
TINT_DEFER(opts->format = fmt.value.value_or(Format::kUnknown));
+ auto& col = options.Add<EnumOption<ColorMode>>("color", "Use colored output",
+ tint::Vector{
+ EnumName{ColorMode::kPlain, "off"},
+ EnumName{ColorMode::kDark, "dark"},
+ EnumName{ColorMode::kLight, "light"},
+ },
+ ShortName{"col"}, Default{ColorModeDefault()});
+ TINT_DEFER(opts->printer = CreatePrinter(*col.value));
+
auto& ep = options.Add<StringOption>("entry-point", "Output single entry point",
ShortName{"ep"}, Parameter{"name"});
TINT_DEFER({
@@ -790,9 +835,8 @@
auto source = std::make_unique<tint::Source::File>(options.input_filename, result->wgsl);
auto reparsed_program = tint::wgsl::reader::Parse(source.get(), parser_options);
if (!reparsed_program.IsValid()) {
- auto printer = tint::StyledTextPrinter::Create(stderr);
tint::diag::Formatter diag_formatter;
- printer->Print(diag_formatter.Format(reparsed_program.Diagnostics()));
+ options.printer->Print(diag_formatter.Format(reparsed_program.Diagnostics()));
return false;
}
}
@@ -1255,7 +1299,7 @@
// Implement output format defaults.
if (options.format == Format::kUnknown) {
// Try inferring from filename.
- options.format = infer_format(options.output_file);
+ options.format = InferFormat(options.output_file);
}
if (options.format == Format::kUnknown) {
// Ultimately, default to SPIR-V assembly. That's nice for interactive use.
@@ -1264,6 +1308,7 @@
tint::cmd::LoadProgramOptions opts;
opts.filename = options.input_filename;
+ opts.printer = options.printer.get();
#if TINT_BUILD_SPV_READER
opts.use_ir = options.use_ir_reader;
opts.spirv_reader_options = options.spirv_reader_options;
diff --git a/src/tint/utils/BUILD.cmake b/src/tint/utils/BUILD.cmake
index badeb73..1771b07 100644
--- a/src/tint/utils/BUILD.cmake
+++ b/src/tint/utils/BUILD.cmake
@@ -53,5 +53,6 @@
include(utils/socket/BUILD.cmake)
include(utils/strconv/BUILD.cmake)
include(utils/symbol/BUILD.cmake)
+include(utils/system/BUILD.cmake)
include(utils/text/BUILD.cmake)
include(utils/traits/BUILD.cmake)
diff --git a/src/tint/utils/system/BUILD.bazel b/src/tint/utils/system/BUILD.bazel
new file mode 100644
index 0000000..1cac5ca
--- /dev/null
+++ b/src/tint/utils/system/BUILD.bazel
@@ -0,0 +1,121 @@
+# Copyright 2024 The Dawn & Tint Authors
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+################################################################################
+# File generated by 'tools/src/cmd/gen' using the template:
+# tools/src/cmd/gen/build/BUILD.bazel.tmpl
+#
+# To regenerate run: './tools/run gen'
+#
+# Do not modify this file directly
+################################################################################
+
+load("//src/tint:flags.bzl", "COPTS")
+load("@bazel_skylib//lib:selects.bzl", "selects")
+cc_library(
+ name = "system",
+ srcs = [
+ ] + select({
+ ":_not_tint_build_is_linux__and__not_tint_build_is_mac__and__not_tint_build_is_win_": [
+ "terminal_other.cc",
+ ],
+ "//conditions:default": [],
+ }) + select({
+ ":_not_tint_build_is_win_": [
+ "env_other.cc",
+ ],
+ "//conditions:default": [],
+ }) + select({
+ ":tint_build_is_linux_or_tint_build_is_mac": [
+ "terminal_posix.cc",
+ ],
+ "//conditions:default": [],
+ }) + select({
+ ":tint_build_is_win": [
+ "env_windows.cc",
+ "terminal_windows.cc",
+ ],
+ "//conditions:default": [],
+ }),
+ hdrs = [
+ "env.h",
+ "terminal.h",
+ ],
+ deps = [
+ "//src/tint/utils/macros",
+ ],
+ copts = COPTS,
+ visibility = ["//visibility:public"],
+)
+
+alias(
+ name = "tint_build_is_linux",
+ actual = "//src/tint:tint_build_is_linux_true",
+)
+
+alias(
+ name = "_not_tint_build_is_linux_",
+ actual = "//src/tint:tint_build_is_linux_false",
+)
+
+alias(
+ name = "tint_build_is_mac",
+ actual = "//src/tint:tint_build_is_mac_true",
+)
+
+alias(
+ name = "_not_tint_build_is_mac_",
+ actual = "//src/tint:tint_build_is_mac_false",
+)
+
+alias(
+ name = "tint_build_is_win",
+ actual = "//src/tint:tint_build_is_win_true",
+)
+
+alias(
+ name = "_not_tint_build_is_win_",
+ actual = "//src/tint:tint_build_is_win_false",
+)
+
+selects.config_setting_group(
+ name = "tint_build_is_linux_or_tint_build_is_mac",
+ match_any = [
+ "tint_build_is_linux",
+ "tint_build_is_mac",
+ ],
+)
+
+selects.config_setting_group(
+ name = "_not_tint_build_is_linux__and__not_tint_build_is_mac__and__not_tint_build_is_win_",
+ match_all = [
+ ":_not_tint_build_is_linux_",
+ ":_not_tint_build_is_mac_",
+ ":_not_tint_build_is_win_",
+ ],
+)
+
diff --git a/src/tint/utils/system/BUILD.cmake b/src/tint/utils/system/BUILD.cmake
new file mode 100644
index 0000000..748da7d
--- /dev/null
+++ b/src/tint/utils/system/BUILD.cmake
@@ -0,0 +1,73 @@
+# Copyright 2024 The Dawn & Tint Authors
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+################################################################################
+# File generated by 'tools/src/cmd/gen' using the template:
+# tools/src/cmd/gen/build/BUILD.cmake.tmpl
+#
+# To regenerate run: './tools/run gen'
+#
+# Do not modify this file directly
+################################################################################
+
+################################################################################
+# Target: tint_utils_system
+# Kind: lib
+################################################################################
+tint_add_target(tint_utils_system lib
+ utils/system/env.h
+ utils/system/terminal.h
+)
+
+tint_target_add_dependencies(tint_utils_system lib
+ tint_utils_macros
+)
+
+if((NOT TINT_BUILD_IS_LINUX) AND (NOT TINT_BUILD_IS_MAC) AND (NOT TINT_BUILD_IS_WIN))
+ tint_target_add_sources(tint_utils_system lib
+ "utils/system/terminal_other.cc"
+ )
+endif((NOT TINT_BUILD_IS_LINUX) AND (NOT TINT_BUILD_IS_MAC) AND (NOT TINT_BUILD_IS_WIN))
+
+if((NOT TINT_BUILD_IS_WIN))
+ tint_target_add_sources(tint_utils_system lib
+ "utils/system/env_other.cc"
+ )
+endif((NOT TINT_BUILD_IS_WIN))
+
+if(TINT_BUILD_IS_LINUX OR TINT_BUILD_IS_MAC)
+ tint_target_add_sources(tint_utils_system lib
+ "utils/system/terminal_posix.cc"
+ )
+endif(TINT_BUILD_IS_LINUX OR TINT_BUILD_IS_MAC)
+
+if(TINT_BUILD_IS_WIN)
+ tint_target_add_sources(tint_utils_system lib
+ "utils/system/env_windows.cc"
+ "utils/system/terminal_windows.cc"
+ )
+endif(TINT_BUILD_IS_WIN)
diff --git a/src/tint/utils/system/BUILD.gn b/src/tint/utils/system/BUILD.gn
new file mode 100644
index 0000000..5f101c1
--- /dev/null
+++ b/src/tint/utils/system/BUILD.gn
@@ -0,0 +1,66 @@
+# Copyright 2024 The Dawn & Tint Authors
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+################################################################################
+# File generated by 'tools/src/cmd/gen' using the template:
+# tools/src/cmd/gen/build/BUILD.gn.tmpl
+#
+# To regenerate run: './tools/run gen'
+#
+# Do not modify this file directly
+################################################################################
+
+import("../../../../scripts/tint_overrides_with_defaults.gni")
+
+import("${tint_src_dir}/tint.gni")
+
+libtint_source_set("system") {
+ sources = [
+ "env.h",
+ "terminal.h",
+ ]
+ deps = [ "${tint_src_dir}/utils/macros" ]
+
+ if (!tint_build_is_linux && !tint_build_is_mac && !tint_build_is_win) {
+ sources += [ "terminal_other.cc" ]
+ }
+
+ if (!tint_build_is_win) {
+ sources += [ "env_other.cc" ]
+ }
+
+ if (tint_build_is_linux || tint_build_is_mac) {
+ sources += [ "terminal_posix.cc" ]
+ }
+
+ if (tint_build_is_win) {
+ sources += [
+ "env_windows.cc",
+ "terminal_windows.cc",
+ ]
+ }
+}
diff --git a/src/tint/utils/system/env.h b/src/tint/utils/system/env.h
new file mode 100644
index 0000000..bcf2b46
--- /dev/null
+++ b/src/tint/utils/system/env.h
@@ -0,0 +1,42 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_TINT_UTILS_SYSTEM_ENV_H_
+#define SRC_TINT_UTILS_SYSTEM_ENV_H_
+
+#include <string>
+
+namespace tint {
+
+/// @param name the name of the environment variable
+/// @returns the environment variable value with the given name, or an empty string if the variable
+/// was not found.
+std::string GetEnvVar(std::string_view name);
+
+} // namespace tint
+
+#endif // SRC_TINT_UTILS_SYSTEM_ENV_H_
diff --git a/src/tint/utils/system/env_other.cc b/src/tint/utils/system/env_other.cc
new file mode 100644
index 0000000..cdf5759
--- /dev/null
+++ b/src/tint/utils/system/env_other.cc
@@ -0,0 +1,44 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// GEN_BUILD:CONDITION(!tint_build_is_win)
+
+#include "src/tint/utils/system/env.h"
+
+#include <cstdlib>
+#include <string_view>
+
+namespace tint {
+
+std::string GetEnvVar(std::string_view name) {
+ if (auto* val = std::getenv(name.data())) {
+ return val;
+ }
+ return "";
+}
+
+} // namespace tint
diff --git a/src/tint/utils/system/env_windows.cc b/src/tint/utils/system/env_windows.cc
new file mode 100644
index 0000000..534b358
--- /dev/null
+++ b/src/tint/utils/system/env_windows.cc
@@ -0,0 +1,49 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// GEN_BUILD:CONDITION(tint_build_is_win)
+
+#include "src/tint/utils/system/env.h"
+
+#include <stdlib.h>
+#include <string_view>
+
+namespace tint {
+
+std::string GetEnvVar(std::string_view name) {
+ // Use _dupenv_s to avoid unsafe warnings about std::getenv
+ char* value = nullptr;
+ _dupenv_s(&value, nullptr, name.data());
+ if (value) {
+ std::string result = value;
+ free(value);
+ return result;
+ }
+ return "";
+}
+
+} // namespace tint
diff --git a/src/tint/utils/system/terminal.h b/src/tint/utils/system/terminal.h
new file mode 100644
index 0000000..2374496
--- /dev/null
+++ b/src/tint/utils/system/terminal.h
@@ -0,0 +1,49 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_TINT_UTILS_SYSTEM_TERMINAL_H_
+#define SRC_TINT_UTILS_SYSTEM_TERMINAL_H_
+
+#include <cstdio>
+#include <optional>
+
+namespace tint {
+
+/// Detects whether the terminal at @p out supports color output.
+/// @param out the file to print to.
+/// @return true if the terminal supports colors.
+bool TerminalSupportsColors(FILE* out);
+
+/// Attempts to detect whether the terminal at @p out is dark.
+/// @param out the file to print to.
+/// @returns true if the terminal is dark, false if the terminal is light, or nullopt if
+/// unknown.
+std::optional<bool> TerminalIsDark(FILE* out);
+
+} // namespace tint
+
+#endif // SRC_TINT_UTILS_SYSTEM_TERMINAL_H_
diff --git a/src/tint/utils/system/terminal_other.cc b/src/tint/utils/system/terminal_other.cc
new file mode 100644
index 0000000..96e7263
--- /dev/null
+++ b/src/tint/utils/system/terminal_other.cc
@@ -0,0 +1,42 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// GEN_BUILD:CONDITION((!tint_build_is_linux) && (!tint_build_is_mac) && (!tint_build_is_win))
+
+#include "src/tint/utils/system/terminal.h"
+
+namespace tint {
+
+bool TerminalSupportsColors(FILE*) {
+ return false;
+}
+
+std::optional<bool> TerminalIsDark(FILE*) {
+ return std::nullopt;
+}
+
+} // namespace tint
diff --git a/src/tint/utils/system/terminal_posix.cc b/src/tint/utils/system/terminal_posix.cc
new file mode 100644
index 0000000..699966d
--- /dev/null
+++ b/src/tint/utils/system/terminal_posix.cc
@@ -0,0 +1,184 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// GEN_BUILD:CONDITION(tint_build_is_linux || tint_build_is_mac)
+
+#include <unistd.h>
+
+#include <termios.h>
+#include <chrono>
+#include <cstdint>
+#include <cstdio>
+#include <cstring>
+#include <optional>
+#include <string_view>
+#include <utility>
+
+#include "src/tint/utils/macros/defer.h"
+#include "src/tint/utils/system/env.h"
+#include "src/tint/utils/system/terminal.h"
+
+namespace tint {
+
+bool TerminalSupportsColors(FILE* f) {
+ if (!isatty(fileno(f))) {
+ return false;
+ }
+
+ if (auto term = GetEnvVar("TERM"); !term.empty()) {
+ return term == "cygwin" || term == "linux" || term == "rxvt-unicode-256color" ||
+ term == "rxvt-unicode" || term == "screen-256color" || term == "screen" ||
+ term == "tmux-256color" || term == "tmux" || term == "xterm-256color" ||
+ term == "xterm-color" || term == "xterm";
+ }
+
+ return false;
+}
+
+/// Probes the terminal using a Device Control escape sequence to get the background color.
+/// @see https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Device-Control-functions
+std::optional<bool> TerminalIsDark(FILE* out) {
+ if (!TerminalSupportsColors(out)) {
+ return std::nullopt;
+ }
+
+ // Get the file descriptor for 'out'
+ int out_fd = fileno(out);
+ if (out_fd == -1) {
+ return std::nullopt;
+ }
+
+ // Store the current attributes for 'out', restore it before returning
+ termios original_state{};
+ tcgetattr(out_fd, &original_state);
+ TINT_DEFER(tcsetattr(out_fd, TCSADRAIN, &original_state));
+
+ // Prevent echoing.
+ termios state = original_state;
+ state.c_lflag &= ~static_cast<tcflag_t>(ECHO | ICANON);
+ tcsetattr(out_fd, TCSADRAIN, &state);
+
+ // Emit the device control escape sequence to query the terminal colors.
+ static constexpr std::string_view kQuery = "\x1b]11;?\x07";
+ fwrite(kQuery.data(), 1, kQuery.length(), out);
+ fflush(out);
+
+ // Timeout for attempting to read the response.
+ static constexpr auto kTimeout = std::chrono::milliseconds(100);
+
+ // Record the start time.
+ auto start = std::chrono::steady_clock::now();
+
+ // Helpers for parsing the response.
+ std::optional<char> peek;
+ auto read = [&]() -> std::optional<char> {
+ if (peek) {
+ char c = *peek;
+ peek.reset();
+ return c;
+ }
+ while ((std::chrono::steady_clock::now() - start) < kTimeout) {
+ char c;
+ if (fread(&c, 1, 1, stdin) == 1) {
+ return c;
+ }
+ }
+ return std::nullopt;
+ };
+
+ auto match = [&](std::string_view str) {
+ for (char c : str) {
+ if (c != read()) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ struct Hex {
+ uint32_t num = 0; // The parsed hex number
+ uint32_t len = 0; // Number of hex digits parsed
+ };
+ auto hex = [&] {
+ uint32_t num = 0;
+ uint32_t len = 0;
+ while (auto c = read()) {
+ if (c >= '0' && c <= '9') {
+ num = num * 16 + static_cast<uint32_t>(*c - '0');
+ len++;
+ } else if (c >= 'a' && c <= 'z') {
+ num = num * 16 + 10 + static_cast<uint32_t>(*c - 'a');
+ len++;
+ } else if (c >= 'A' && c <= 'Z') {
+ num = num * 16 + 10 + static_cast<uint32_t>(*c - 'A');
+ len++;
+ } else {
+ peek = c;
+ break;
+ }
+ }
+ return Hex{num, len};
+ };
+
+ if (!match("\033]11;rgb:")) {
+ return std::nullopt;
+ }
+
+ auto r_i = hex();
+ if (!match("/")) {
+ return std::nullopt;
+ }
+ auto g_i = hex();
+ if (!match("/")) {
+ return std::nullopt;
+ }
+ auto b_i = hex();
+
+ if (r_i.len != g_i.len || g_i.len != b_i.len) {
+ return std::nullopt;
+ }
+
+ uint32_t max = 0;
+ switch (r_i.len) {
+ case 2: // rr/gg/bb
+ max = 0xff;
+ break;
+ case 4: // rrrr/gggg/bbbb
+ max = 0xffff;
+ break;
+ default:
+ return std::nullopt;
+ }
+
+ // https://en.wikipedia.org/wiki/Relative_luminance
+ float r = static_cast<float>(r_i.num) / static_cast<float>(max);
+ float g = static_cast<float>(g_i.num) / static_cast<float>(max);
+ float b = static_cast<float>(b_i.num) / static_cast<float>(max);
+ return (0.2126f * r + 0.7152f * g + 0.0722f * b) < 0.5f;
+}
+
+} // namespace tint
diff --git a/src/tint/utils/system/terminal_windows.cc b/src/tint/utils/system/terminal_windows.cc
new file mode 100644
index 0000000..4ed2f78
--- /dev/null
+++ b/src/tint/utils/system/terminal_windows.cc
@@ -0,0 +1,92 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// GEN_BUILD:CONDITION(tint_build_is_win)
+
+#include "src/tint/utils/macros/defer.h"
+#include "src/tint/utils/system/env.h"
+#include "src/tint/utils/system/terminal.h"
+
+#define WIN32_LEAN_AND_MEAN 1
+#include <Windows.h>
+
+namespace tint {
+namespace {
+
+HANDLE ConsoleHandleFrom(FILE* file) {
+ HANDLE handle = INVALID_HANDLE_VALUE;
+ if (file == stdout) {
+ handle = GetStdHandle(STD_OUTPUT_HANDLE);
+ } else if (file == stderr) {
+ handle = GetStdHandle(STD_ERROR_HANDLE);
+ } else {
+ return INVALID_HANDLE_VALUE;
+ }
+
+ CONSOLE_SCREEN_BUFFER_INFO info{};
+ if (GetConsoleScreenBufferInfo(handle, &info) == 0) {
+ return INVALID_HANDLE_VALUE;
+ }
+ return handle;
+}
+
+} // namespace
+
+bool TerminalSupportsColors(FILE* out) {
+ return ConsoleHandleFrom(out) != INVALID_HANDLE_VALUE;
+}
+
+std::optional<bool> TerminalIsDark(FILE* out) {
+ if (!GetEnvVar("WT_SESSION").empty()) {
+ // Windows terminal does not support querying the palette
+ // See: https://github.com/microsoft/terminal/issues/10639
+ return std::nullopt;
+ }
+
+ if (HANDLE handle = ConsoleHandleFrom(out); handle != INVALID_HANDLE_VALUE) {
+ if (HANDLE screen_buffer = CreateConsoleScreenBuffer(GENERIC_READ, FILE_SHARE_READ,
+ /* lpSecurityAttributes */ nullptr,
+ CONSOLE_TEXTMODE_BUFFER, nullptr)) {
+ TINT_DEFER(CloseHandle(screen_buffer));
+ CONSOLE_SCREEN_BUFFER_INFOEX info{};
+ info.cbSize = sizeof(info);
+ if (GetConsoleScreenBufferInfoEx(screen_buffer, &info)) {
+ COLORREF background = info.ColorTable[(info.wAttributes & 0xf0) >> 4];
+ // https://en.wikipedia.org/wiki/Relative_luminance
+ float r = static_cast<float>((background >> 0) & 0xff) / 255.0f;
+ float g = static_cast<float>((background >> 8) & 0xff) / 255.0f;
+ float b = static_cast<float>((background >> 16) & 0xff) / 255.0f;
+ return (0.2126f * r + 0.7152f * g + 0.0722f * b) < 0.5f;
+ }
+ }
+ }
+
+ // Unknown
+ return std::nullopt;
+}
+
+} // namespace tint
diff --git a/src/tint/utils/text/BUILD.bazel b/src/tint/utils/text/BUILD.bazel
index 0e7ee03..e73f66e 100644
--- a/src/tint/utils/text/BUILD.bazel
+++ b/src/tint/utils/text/BUILD.bazel
@@ -80,6 +80,7 @@
"//src/tint/utils/math",
"//src/tint/utils/memory",
"//src/tint/utils/rtti",
+ "//src/tint/utils/system",
"//src/tint/utils/traits",
],
copts = COPTS,
diff --git a/src/tint/utils/text/BUILD.cmake b/src/tint/utils/text/BUILD.cmake
index 7b19a11..2aa69bf 100644
--- a/src/tint/utils/text/BUILD.cmake
+++ b/src/tint/utils/text/BUILD.cmake
@@ -64,6 +64,7 @@
tint_utils_math
tint_utils_memory
tint_utils_rtti
+ tint_utils_system
tint_utils_traits
)
diff --git a/src/tint/utils/text/BUILD.gn b/src/tint/utils/text/BUILD.gn
index 8aaadd2..5460394 100644
--- a/src/tint/utils/text/BUILD.gn
+++ b/src/tint/utils/text/BUILD.gn
@@ -68,6 +68,7 @@
"${tint_src_dir}/utils/math",
"${tint_src_dir}/utils/memory",
"${tint_src_dir}/utils/rtti",
+ "${tint_src_dir}/utils/system",
"${tint_src_dir}/utils/traits",
]
diff --git a/src/tint/utils/text/styled_text_printer.cc b/src/tint/utils/text/styled_text_printer.cc
index be83c03..557b3ff 100644
--- a/src/tint/utils/text/styled_text_printer.cc
+++ b/src/tint/utils/text/styled_text_printer.cc
@@ -27,6 +27,7 @@
#include <cstring>
+#include "src/tint/utils/system/terminal.h"
#include "src/tint/utils/text/styled_text_printer.h"
namespace tint {
@@ -51,7 +52,8 @@
return std::make_unique<Plain>(out);
}
std::unique_ptr<StyledTextPrinter> StyledTextPrinter::Create(FILE* out) {
- return Create(out, StyledTextTheme::kDefault);
+ bool is_dark = TerminalIsDark(out).value_or(true);
+ return Create(out, is_dark ? StyledTextTheme::kDefaultDark : StyledTextTheme::kDefaultLight);
}
StyledTextPrinter::~StyledTextPrinter() = default;
diff --git a/src/tint/utils/text/styled_text_printer_other.cc b/src/tint/utils/text/styled_text_printer_other.cc
index eec09c0..4f32526 100644
--- a/src/tint/utils/text/styled_text_printer_other.cc
+++ b/src/tint/utils/text/styled_text_printer_other.cc
@@ -27,8 +27,6 @@
// GEN_BUILD:CONDITION((!tint_build_is_linux) && (!tint_build_is_mac) && (!tint_build_is_win))
-#include <cstring>
-
#include "src/tint/utils/text/styled_text_printer.h"
namespace tint {
diff --git a/src/tint/utils/text/styled_text_printer_posix.cc b/src/tint/utils/text/styled_text_printer_posix.cc
index e03ab52..7d34fed 100644
--- a/src/tint/utils/text/styled_text_printer_posix.cc
+++ b/src/tint/utils/text/styled_text_printer_posix.cc
@@ -28,43 +28,16 @@
// GEN_BUILD:CONDITION(tint_build_is_linux || tint_build_is_mac)
#include <unistd.h>
+#include <memory>
-#include <cstring>
-
-#include "src/tint/utils/text/styled_text.h"
+#include "src/tint/utils/system/terminal.h"
#include "src/tint/utils/text/styled_text_printer.h"
-#include "src/tint/utils/text/styled_text_theme.h"
-#include "src/tint/utils/text/text_style.h"
namespace tint {
-namespace {
-
-bool SupportsANSIEscape(FILE* f) {
- if (!isatty(fileno(f))) {
- return false;
- }
-
- const char* cterm = getenv("TERM");
- if (cterm == nullptr) {
- return false;
- }
-
- std::string term = getenv("TERM");
- if (term != "cygwin" && term != "linux" && term != "rxvt-unicode-256color" &&
- term != "rxvt-unicode" && term != "screen-256color" && term != "screen" &&
- term != "tmux-256color" && term != "tmux" && term != "xterm-256color" &&
- term != "xterm-color" && term != "xterm") {
- return false;
- }
-
- return true;
-}
-
-} // namespace
std::unique_ptr<StyledTextPrinter> StyledTextPrinter::Create(FILE* out,
const StyledTextTheme& theme) {
- if (SupportsANSIEscape(out)) {
+ if (TerminalSupportsColors(out)) {
return CreateANSI(out, theme);
}
return CreatePlain(out);
diff --git a/src/tint/utils/text/styled_text_theme.cc b/src/tint/utils/text/styled_text_theme.cc
index ba2944a..e243cd5 100644
--- a/src/tint/utils/text/styled_text_theme.cc
+++ b/src/tint/utils/text/styled_text_theme.cc
@@ -30,7 +30,7 @@
namespace tint {
-const StyledTextTheme StyledTextTheme::kDefault{
+const StyledTextTheme StyledTextTheme::kDefaultDark{
/* compare_match */ StyledTextTheme::Attributes{
/* foreground */ std::nullopt,
/* background */ Color{20, 100, 20},
@@ -137,6 +137,113 @@
},
};
+const StyledTextTheme StyledTextTheme::kDefaultLight{
+ /* compare_match */ StyledTextTheme::Attributes{
+ /* foreground */ std::nullopt,
+ /* background */ Color{190, 240, 190},
+ /* bold */ std::nullopt,
+ /* underlined */ std::nullopt,
+ },
+ /* compare_mismatch */
+ StyledTextTheme::Attributes{
+ /* foreground */ std::nullopt,
+ /* background */ Color{240, 190, 190},
+ /* bold */ std::nullopt,
+ /* underlined */ std::nullopt,
+ },
+ /* severity_success */
+ StyledTextTheme::Attributes{
+ /* foreground */ Color{0, 200, 0},
+ /* background */ std::nullopt,
+ /* bold */ std::nullopt,
+ /* underlined */ std::nullopt,
+ },
+ /* severity_warning */
+ StyledTextTheme::Attributes{
+ /* foreground */ Color{200, 200, 0},
+ /* background */ std::nullopt,
+ /* bold */ std::nullopt,
+ /* underlined */ std::nullopt,
+ },
+ /* severity_failure */
+ StyledTextTheme::Attributes{
+ /* foreground */ Color{200, 0, 0},
+ /* background */ std::nullopt,
+ /* bold */ std::nullopt,
+ /* underlined */ std::nullopt,
+ },
+ /* severity_fatal */
+ StyledTextTheme::Attributes{
+ /* foreground */ Color{200, 0, 200},
+ /* background */ std::nullopt,
+ /* bold */ std::nullopt,
+ /* underlined */ std::nullopt,
+ },
+ /* kind_code */
+ StyledTextTheme::Attributes{
+ /* foreground */ Color{10, 10, 10},
+ /* background */ Color{248, 248, 248},
+ /* bold */ std::nullopt,
+ /* underlined */ std::nullopt,
+ },
+ /* kind_keyword */
+ StyledTextTheme::Attributes{
+ /* foreground */ Color{175, 0, 219},
+ /* background */ std::nullopt,
+ /* bold */ std::nullopt,
+ /* underlined */ std::nullopt,
+ },
+ /* kind_variable */
+ StyledTextTheme::Attributes{
+ /* foreground */ Color{0, 16, 128},
+ /* background */ std::nullopt,
+ /* bold */ std::nullopt,
+ /* underlined */ std::nullopt,
+ },
+ /* kind_type */
+ StyledTextTheme::Attributes{
+ /* foreground */ Color{38, 127, 153},
+ /* background */ std::nullopt,
+ /* bold */ std::nullopt,
+ /* underlined */ std::nullopt,
+ },
+ /* kind_function */
+ StyledTextTheme::Attributes{
+ /* foreground */ Color{121, 94, 38},
+ /* background */ std::nullopt,
+ /* bold */ std::nullopt,
+ /* underlined */ std::nullopt,
+ },
+ /* kind_enum */
+ StyledTextTheme::Attributes{
+ /* foreground */ Color{0, 112, 193},
+ /* background */ std::nullopt,
+ /* bold */ std::nullopt,
+ /* underlined */ std::nullopt,
+ },
+ /* kind_literal */
+ StyledTextTheme::Attributes{
+ /* foreground */ Color{9, 134, 88},
+ /* background */ std::nullopt,
+ /* bold */ std::nullopt,
+ /* underlined */ std::nullopt,
+ },
+ /* kind_attribute */
+ StyledTextTheme::Attributes{
+ /* foreground */ Color{156, 220, 254},
+ /* background */ std::nullopt,
+ /* bold */ std::nullopt,
+ /* underlined */ std::nullopt,
+ },
+ /* kind_squiggle */
+ StyledTextTheme::Attributes{
+ /* foreground */ Color{0, 200, 255},
+ /* background */ std::nullopt,
+ /* bold */ std::nullopt,
+ /* underlined */ std::nullopt,
+ },
+};
+
StyledTextTheme::Attributes StyledTextTheme::Get(TextStyle text_style) const {
Attributes out;
out.bold = false;
diff --git a/src/tint/utils/text/styled_text_theme.h b/src/tint/utils/text/styled_text_theme.h
index c9dcfbb..b36db4f 100644
--- a/src/tint/utils/text/styled_text_theme.h
+++ b/src/tint/utils/text/styled_text_theme.h
@@ -40,8 +40,10 @@
/// StyledTextTheme describes the display theming for TextStyles
struct StyledTextTheme {
- /// The default theme
- static const StyledTextTheme kDefault;
+ /// The default dark theme
+ static const StyledTextTheme kDefaultDark;
+ /// The default light theme
+ static const StyledTextTheme kDefaultLight;
/// Color holds a 24-bit RGB color
struct Color {