detect_features/
detect-features.rs1use std::{
2 io::{self, Write as _},
3 time::Duration,
4};
5
6use termina::{
7 escape::{
8 csi::{self, Csi},
9 dcs::{self, Dcs},
10 },
11 style::RgbColor,
12 Event, PlatformTerminal, Terminal,
13};
14
15const TEST_COLOR: RgbColor = RgbColor::new(150, 150, 150);
16
17#[derive(Debug, Default, Clone, Copy)]
18struct Features {
19 kitty_keyboard: bool,
20 sychronized_output: bool,
21 true_color: bool,
22 extended_underlines: bool,
23}
24
25fn main() -> io::Result<()> {
26 let mut terminal = PlatformTerminal::new()?;
27 terminal.enter_raw_mode()?;
28
29 write!(
30 terminal,
31 "{}{}{}{}{}{}{}",
32 Csi::Keyboard(csi::Keyboard::QueryFlags),
34 Csi::Mode(csi::Mode::QueryDecPrivateMode(csi::DecPrivateMode::Code(
36 csi::DecPrivateModeCode::SynchronizedOutput
37 ))),
38 Csi::Sgr(csi::Sgr::Background(TEST_COLOR.into())),
41 Csi::Sgr(csi::Sgr::UnderlineColor(TEST_COLOR.into())),
42 Dcs::Request(dcs::DcsRequest::GraphicRendition),
43 Csi::Sgr(csi::Sgr::Reset),
44 Csi::Device(csi::Device::RequestPrimaryDeviceAttributes),
46 )?;
47 terminal.flush()?;
48
49 let mut features = Features::default();
50 loop {
51 if !terminal.poll(Event::is_escape, Some(Duration::from_millis(100)))? {
52 eprintln!("Did not receive any responses to queries in 100ms\r");
53 break;
54 }
55
56 match terminal.read(Event::is_escape)? {
57 Event::Csi(Csi::Keyboard(csi::Keyboard::ReportFlags(_))) => {
58 features.kitty_keyboard = true
59 }
60 Event::Csi(Csi::Mode(csi::Mode::ReportDecPrivateMode {
61 mode: csi::DecPrivateMode::Code(csi::DecPrivateModeCode::SynchronizedOutput),
62 setting,
63 })) => {
64 features.sychronized_output = matches!(
65 setting,
66 csi::DecModeSetting::Set | csi::DecModeSetting::Reset
67 );
68 }
69 Event::Dcs(Dcs::Response {
70 value: dcs::DcsResponse::GraphicRendition(sgrs),
71 ..
72 }) => {
73 features.true_color = sgrs.contains(&csi::Sgr::Background(TEST_COLOR.into()));
74 features.extended_underlines =
75 sgrs.contains(&csi::Sgr::UnderlineColor(TEST_COLOR.into()));
76 }
77 Event::Csi(Csi::Device(csi::Device::DeviceAttributes(_))) => break,
78 other => eprintln!("unexpected event: {other:?}\r"),
79 }
80 }
81 println!("Detected features: {features:?}");
82
83 Ok(())
84}