| /// 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) } | |
| } |