Files
termina/examples/detect-features.rs
2025-04-10 16:05:00 -04:00

85 lines
2.8 KiB
Rust

use std::{
io::{self, Write as _},
time::Duration,
};
use termina::{
escape::{
csi::{self, Csi},
dcs::{self, Dcs},
},
style::RgbColor,
Event, PlatformTerminal, Terminal,
};
const TEST_COLOR: RgbColor = RgbColor::new(150, 150, 150);
#[derive(Debug, Default, Clone, Copy)]
struct Features {
kitty_keyboard: bool,
sychronized_output: bool,
true_color: bool,
extended_underlines: bool,
}
fn main() -> io::Result<()> {
let mut terminal = PlatformTerminal::new()?;
terminal.enter_raw_mode()?;
write!(
terminal,
"{}{}{}{}{}{}{}",
// Kitty keyboard
Csi::Keyboard(csi::Keyboard::QueryFlags),
// Synchronized output
Csi::Mode(csi::Mode::QueryDecPrivateMode(csi::DecPrivateMode::Code(
csi::DecPrivateModeCode::SynchronizedOutput
))),
// True color and while we're at it, extended underlines:
// <https://github.com/termstandard/colors?tab=readme-ov-file#querying-the-terminal>
Csi::Sgr(csi::Sgr::Background(TEST_COLOR.into())),
Csi::Sgr(csi::Sgr::UnderlineColor(TEST_COLOR.into())),
Dcs::Request(dcs::DcsRequest::GraphicRendition),
Csi::Sgr(csi::Sgr::Reset),
// Finally request the primary device attributes
Csi::Device(csi::Device::RequestPrimaryDeviceAttributes),
)?;
terminal.flush()?;
let mut features = Features::default();
loop {
if !terminal.poll(Event::is_escape, Some(Duration::from_millis(100)))? {
eprintln!("Did not receive any responses to queries in 100ms\r");
break;
}
match terminal.read(Event::is_escape)? {
Event::Csi(Csi::Keyboard(csi::Keyboard::ReportFlags(_))) => {
features.kitty_keyboard = true
}
Event::Csi(Csi::Mode(csi::Mode::ReportDecPrivateMode {
mode: csi::DecPrivateMode::Code(csi::DecPrivateModeCode::SynchronizedOutput),
setting,
})) => {
features.sychronized_output = matches!(
setting,
csi::DecModeSetting::Set | csi::DecModeSetting::Reset
);
}
Event::Dcs(Dcs::Response {
value: dcs::DcsResponse::GraphicRendition(sgrs),
..
}) => {
features.true_color = sgrs.contains(&csi::Sgr::Background(TEST_COLOR.into()));
features.extended_underlines =
sgrs.contains(&csi::Sgr::UnderlineColor(TEST_COLOR.into()));
}
Event::Csi(Csi::Device(csi::Device::DeviceAttributes(_))) => break,
other => eprintln!("unexpected event: {other:?}\r"),
}
}
println!("Detected features: {features:?}");
Ok(())
}