1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*[toml]
[dependencies]
log = "0.4"
thag_common = { version = "0.2, thag-auto", features = ["color_detect"] }
*/
/// A basic tool I cobbled together that uses different crates to a) test terminal
/// types on different platforms, b) determine and cross-check if a light or dark
/// theme is in use and c) determine the level of colour supported reported by
/// the terminal.
//# Purpose: Allow checking of terminals on platforms to be supported, also test reliability of different crates.
//# Categories: crates, tools
use log::info;
use simplelog::{
ColorChoice, CombinedLogger, Config, LevelFilter, TermLogger, TerminalMode, WriteLogger,
};
use std::fs::File;
use thag_common::{auto_help, help_system::check_help_and_exit, terminal, ColorSupport};
fn main() {
// Check for help first - automatically extracts from source comments
let help = auto_help!();
check_help_and_exit(&help);
CombinedLogger::init(vec![
TermLogger::new(
LevelFilter::Info,
Config::default(),
TerminalMode::Mixed,
ColorChoice::Auto,
),
WriteLogger::new(
LevelFilter::Debug,
Config::default(),
File::create("app.log").unwrap(),
),
])
.unwrap();
info!("Initialized simplelog");
let timeout = std::time::Duration::from_millis(500);
let term = termbg::terminal();
println!(" Term : {term:?}");
let rgb = termbg::rgb(timeout);
let theme = termbg::theme(timeout);
match rgb {
Ok(rgb) => {
// Note: to go from 16-bit color range (0-65535) returned by xterm to 8-bit RGB range (0-255),
// we need to divide by 65535 / 255 = 257.
// While it's clear that 256 x 256 = 65536, it may not be so obvious that 255 * 257 = 65535!
// Search for 257 in https://retrocomputing.stackexchange.com/questions/27436/classic-mac-os-colors-to-modern-rgb.
// Also note that the 16-bit colours are generally doubled up, like D7D7. I.e. 256xD7 + D7, which
// may make dividing by 257 seem more intuitive.
println!(
" Color: R={}, G={}, B={}",
rgb.r / 257,
rgb.g / 257,
rgb.b / 257
);
println!(" Color={rgb:#?}");
}
Err(e) => {
println!(" Color: detection failed {e:?}");
}
}
match theme {
Ok(theme) => {
println!(" Theme: {theme:?}");
}
Err(e) => {
println!(" Theme: detection failed {e:?}");
}
}
println!("\nCrate terminal_light:");
let luma = terminal_light::luma();
println!("luma={luma:#?}");
match luma {
Ok(luma) if luma > 0.5 => {
// Use a "light mode" skin.
println!("Light mode");
}
Ok(luma) if luma < 0.5 => {
// Use a "dark mode" skin.
println!("Dark mode");
}
_ => {
// Either we couldn't determine the mode or it's kind of medium.
// We should use an intermediate skin, or one defining the background.
println!("Intermediate mode");
}
}
match terminal_light::background_color().map(terminal_light::Color::rgb) {
Ok(bg_rgb) => {
let luma_255 = 0.2126_f32.mul_add(
f32::from(bg_rgb.r),
0.7152_f32.mul_add(f32::from(bg_rgb.g), 0.0722_f32 * f32::from(bg_rgb.b)),
);
let luma_0_to_1 = luma_255 / 255.0;
println!(
"\nBackground color is {bg_rgb:#?}, luma_255={luma_255}, luma_0_to_1={luma_0_to_1}"
);
}
Err(_) => println!("terminal_light::background_color() not supported"),
}
println!("\nInternal detection with fallback to crate `supports-color`:");
let color_support = terminal::get_fresh_color_support();
match color_support {
ColorSupport::Undetermined => println!("Color support could not be determined"),
ColorSupport::None => println!("No color support"),
ColorSupport::Basic => println!("Only basic ANSI colors are supported."),
ColorSupport::Color256 => println!("256 colors are supported."),
ColorSupport::TrueColor => println!("16 million (RGB) colors are supported"),
}
}