use crossterm::{
cursor::MoveToColumn,
event::{
poll as event_poll, read as event_read, Event, KeyCode, KeyEventKind, KeyModifiers,
KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags,
},
terminal::{disable_raw_mode, enable_raw_mode},
ExecutableCommand,
};
use std::{
fmt::Arguments,
io::{self, stdout, Write},
time::Duration,
};
fn main() -> io::Result<()> {
println!("Event Debug Tool");
println!("================");
println!("Press Ctrl+C or 'q' to exit.\n");
enable_raw_mode()?;
let keyboard_flags = KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES
| KeyboardEnhancementFlags::REPORT_ALTERNATE_KEYS;
let _ = stdout().execute(PushKeyboardEnhancementFlags(keyboard_flags));
let _ = crossterm::execute!(stdout(), crossterm::event::EnableMouseCapture);
let result = run_event_loop();
let _ = crossterm::execute!(stdout(), crossterm::event::DisableMouseCapture);
let _ = stdout().execute(PopKeyboardEnhancementFlags);
disable_raw_mode()?;
println!("\nExiting.");
result
}
fn log_line(args: Arguments<'_>) {
let mut out = stdout();
let _ = writeln!(out, "{args}");
let _ = out.execute(MoveToColumn(0));
}
macro_rules! log_line {
($($arg:tt)*) => {
log_line(format_args!($($arg)*))
};
}
fn run_event_loop() -> io::Result<()> {
loop {
if event_poll(Duration::from_millis(100))? {
let event = event_read()?;
match &event {
Event::Key(key_event) => {
if key_event.kind == KeyEventKind::Press {
log_line!(
"Key: code={:?}, modifiers={:?}, kind={:?}, state={:?}",
key_event.code,
key_event.modifiers,
key_event.kind,
key_event.state
);
if key_event.code == KeyCode::Char('c')
&& key_event.modifiers.contains(KeyModifiers::CONTROL)
{
break;
}
if key_event.code == KeyCode::Char('q') && key_event.modifiers.is_empty() {
break;
}
}
}
Event::Mouse(mouse_event) => {
log_line!(
"Mouse: kind={:?}, column={}, row={}, modifiers={:?}",
mouse_event.kind,
mouse_event.column,
mouse_event.row,
mouse_event.modifiers
);
}
Event::Resize(width, height) => {
log_line!("Resize: width={}, height={}", width, height);
}
Event::FocusGained => {
log_line!("Focus: Gained");
}
Event::FocusLost => {
log_line!("Focus: Lost");
}
Event::Paste(text) => {
log_line!("Paste: {:?}", text);
}
}
}
}
Ok(())
}