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