diff options
| -rw-r--r-- | src/main.rs | 47 | ||||
| -rw-r--r-- | src/term.rs | 55 |
2 files changed, 82 insertions, 20 deletions
diff --git a/src/main.rs b/src/main.rs index 75a6ebf..592f89c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,24 +3,9 @@ mod term; use rope::Rope; use std::ffi::{OsStr, OsString}; -use std::io::{Read, Stdin, Write}; +use std::io::Write; use std::path::Path; - -const CTRL_Q: u8 = 17; - -fn read_key(stdin: &mut Stdin) -> Result<u8, String> { - let mut buf = vec![0; 1]; - match stdin.read(&mut buf) { - Err(err) => { - return Err(format!("read input: {}", err)); - } - Ok(0) => { - return Err(String::from("no input")); - } - _ => (), - } - return Ok(buf[0]); -} +use term::Key; fn edit(file: &OsStr) -> Result<(), String> { let _raw_handle = match term::raw() { @@ -53,14 +38,36 @@ fn edit(file: &OsStr) -> Result<(), String> { let mut stdin = std::io::stdin(); loop { - let c = match read_key(&mut stdin) { + let c = match term::read_key(&mut stdin) { Ok(c) => c, Err(err) => { return Err(err); } }; - if c == CTRL_Q { - break; + match c { + Key::CtrlQ => { + break; + } + Key::Up => { + let _ = stdout.write(b"\x1b[A"); + let _ = stdout.flush(); + } + Key::Down => { + let _ = stdout.write(b"\x1b[B"); + let _ = stdout.flush(); + } + Key::Left => { + let _ = stdout.write(b"\x1b[D"); + let _ = stdout.flush(); + } + Key::Right => { + let _ = stdout.write(b"\x1b[C"); + let _ = stdout.flush(); + } + Key::Char(c) => { + print!("{} ", c); + let _ = stdout.flush(); + } } } return Ok(()); diff --git a/src/term.rs b/src/term.rs index 149f00f..20098a0 100644 --- a/src/term.rs +++ b/src/term.rs @@ -1,4 +1,5 @@ use libc::{termios, winsize}; +use std::io::{Read, Stdin}; pub fn size() -> Option<winsize> { unsafe { @@ -59,3 +60,57 @@ pub fn raw() -> Option<RawHandle> { } return Some(RawHandle { old: old }); } + +pub enum Key { + CtrlQ, + Up, + Down, + Left, + Right, + Char(char), +} + +pub fn read_key(stdin: &mut Stdin) -> Result<Key, String> { + const CTRL_Q: u8 = 17; + const ESC: u8 = 27; + + loop { + let mut buf = vec![0; 1]; + if let Err(err) = stdin.read_exact(&mut buf) { + return Err(format!("read input: {}", err)); + } + if buf[0] == CTRL_Q { + return Ok(Key::CtrlQ); + } + if buf[0] != ESC { + return Ok(Key::Char(char::from(buf[0]))); + } + // Try to handle an escape sequence. + let mut buf = vec![0; 2]; + if let Err(err) = stdin.read_exact(&mut buf) { + return Err(format!("read input: {}", err)); + } + if buf[0] != b'[' { + // Unknown escape sequence, just read another key. + continue; + } + match buf[1] { + b'A' => { + return Ok(Key::Up); + } + b'B' => { + return Ok(Key::Down); + } + b'C' => { + return Ok(Key::Right); + } + b'D' => { + return Ok(Key::Left); + } + _ => { + // Unknown key, just ignore it. + continue; + } + } + } +} |
