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
|
/// An example how to use the ANSI escape sequence parser.
use std::io::{Read, Result, Write};
use anes::{
self, execute,
parser::{KeyCode, Parser, Sequence},
queue,
};
use libc::termios as Termios;
const HELP: &str = r#"ANES parser example
* Hit `Esc` to quit
* Hit 'c' to ask for cursor position
* Use your mouse or type anything
"#;
fn main() -> Result<()> {
let mut w = std::io::stdout();
queue!(
w,
anes::SwitchBufferToAlternate,
anes::HideCursor,
anes::EnableMouseEvents
)?;
for line in HELP.split('\n') {
queue!(w, line, anes::MoveCursorToNextLine(1))?;
}
w.flush()?;
let saved_attributes = get_termios()?;
let mut attributes = saved_attributes;
make_raw(&mut attributes);
set_termios(attributes)?;
let mut stdin = std::io::stdin();
let mut stdin_buffer = [0u8; 1024];
let mut parser = Parser::default();
loop {
if let Ok(size) = stdin.read(&mut stdin_buffer) {
parser.advance(&stdin_buffer[..size], false);
let mut break_outer_loop = false;
while let Some(sequence) = parser.next() {
match sequence {
Sequence::Key(KeyCode::Esc, _) => {
break_outer_loop = true;
break;
}
Sequence::Key(KeyCode::Char('c'), _) => {
execute!(w, anes::ReportCursorPosition)?
}
_ => execute!(
w,
anes::ClearLine::Left,
anes::MoveCursorToColumn(1),
format!("{:?}", sequence),
)?,
}
}
if break_outer_loop {
break;
}
}
}
set_termios(saved_attributes)?;
execute!(
w,
anes::DisableMouseEvents,
anes::ShowCursor,
anes::SwitchBufferToNormal
)?;
Ok(())
}
//
// RAW mode
//
fn get_termios() -> Result<Termios> {
unsafe {
let mut termios = std::mem::zeroed();
if libc::tcgetattr(libc::STDIN_FILENO, &mut termios) != -1 {
Ok(termios)
} else {
Err(std::io::Error::last_os_error())
}
}
}
fn set_termios(termios: Termios) -> Result<()> {
if unsafe { libc::tcsetattr(libc::STDIN_FILENO, libc::TCSANOW, &termios) } != -1 {
Ok(())
} else {
Err(std::io::Error::last_os_error())
}
}
fn make_raw(termios: &mut Termios) {
unsafe { libc::cfmakeraw(termios) }
}
|