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
/// Prototype of detecting the light or dark theme in use, and registering it
/// as a static enum value for use in message style selection. Example of using
/// an LLM to generate a prototype to a simple spec. The `clear_screen` function
/// was added manually later. This prototype is one of many that was incorporated
/// into `thag_rs`.
//# Purpose: Demo theme detection with `termbg`, clearing terminal state with `crossterm` and setting it as a static enum value using `lazy_static`.
//# Categories: crates, technique
use crossterm::{
cursor::{MoveTo, Show},
terminal::{Clear, ClearType},
ExecutableCommand,
};
use lazy_static::lazy_static;
use std::io::{stdout, Write};
use termbg::Theme;
// termbg sends an operating system command (OSC) to interrogate the screen
// but with side effects which we undo here.
pub fn clear_screen() {
let mut out = stdout();
out.execute(Clear(ClearType::All)).unwrap();
out.execute(MoveTo(0, 0)).unwrap();
out.execute(Show).unwrap();
out.flush().unwrap();
}
#[derive(Debug, PartialEq)]
enum TermBgLuma {
Light,
Dark,
}
lazy_static! {
static ref TERM_THEME: TermBgLuma = {
let timeout = std::time::Duration::from_millis(100);
// debug!("Check terminal background color");
let theme = termbg::theme(timeout);
clear_screen();
match theme {
Ok(Theme::Light) => TermBgLuma::Light,
Ok(Theme::Dark) | Err(_) => TermBgLuma::Dark,
}
};
}
fn main() {
// Directly match the static variable without a mutex
match *TERM_THEME {
TermBgLuma::Light => println!("The theme is Light"),
TermBgLuma::Dark => println!("The theme is Dark"),
}
}