Skip to content

Commit

Permalink
Add anes/examples/parser
Browse files Browse the repository at this point in the history
Signed-off-by: Robert Vojta <[email protected]>
  • Loading branch information
zrzka committed Nov 29, 2019
1 parent 267f3bc commit 378ac74
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 0 deletions.
1 change: 1 addition & 0 deletions anes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ bitflags = { version = "1.2", optional = true }

[dev-dependencies]
criterion = "0.3"
libc = "0.2.66"

[[bench]]
name = "bench_main"
Expand Down
106 changes: 106 additions & 0 deletions anes/examples/parser.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,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) }
}

0 comments on commit 378ac74

Please sign in to comment.